/* ============================
   TOKENS
============================ */
:root{
  --cream:      #FDF9F0;
  --cream-2:    #FBF3E1;
  --plum:       #3B1E45;
  --plum-2:     #2B1730;
  --sky:        #4FB8DE;
  --gold:       #F4B93F;
  --coral:      #EE5F79;
  --green:      #2E9E5B;
  --ink:        #2B1730;
  --muted:      #6B5C74;
  --white:      #FFFFFF;

  --font-display: 'Baloo 2', system-ui, sans-serif;
  --font-body:    'Inter', system-ui, sans-serif;

  --radius: 18px;
  --shadow: 0 10px 30px rgba(59,30,69,0.10);
}

*{ box-sizing: border-box; }
/* overflow-anchor:none on .site-header alone only stops the header
   from being chosen AS the anchor node — it doesn't stop the browser
   picking some other element further down the page as the anchor and
   compensating scrollY for the header's own height change that way,
   which is still enough to fight the shrink-on-scroll threshold in
   js/script.js. Disabling it here for the whole document is the
   version that actually stops it. */
html{ scroll-behavior: smooth; overflow-anchor: none; }
:root{ --header-h: 100px; }

body{
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.6;
}

h1,h2,h3{
  font-family: var(--font-display);
  color: var(--plum);
  margin: 0 0 0.5em;
}

h1{ font-size: clamp(1.8rem, 4vw, 2.6rem); text-align:center; }
h2{ font-size: clamp(1.5rem, 3vw, 2rem); text-align:center; }
h3{ font-size: 1.15rem; }

p{ margin: 0 0 1em; }

a{ color: var(--coral); }

.section-intro{
  text-align:center;
  color: var(--muted);
  max-width: 640px;
  margin: 0 auto 2.2rem;
}

/* ============================
   HEADER / BANNER + LOGO
============================ */
.site-header{
  background: var(--plum);
  position: sticky;
  top: 0;
  z-index: 50;
}
.banner-inner{
  max-width: 1300px;
  margin: 0 auto;
  padding: 1rem 1.5rem 1rem 0.5rem;
  display:flex;
  align-items:center;
  gap: 1rem;
  transition: padding .25s ease;
}
.logo-banner{
  flex: 0 0 auto;
}
.slogan{
  flex: 0 0 auto;
  max-width: 96px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(0.95rem, 2.2vw, 1.25rem);
  line-height: 1.15;
  color: var(--gold);
  text-align: center;
  transform: rotate(-9deg) skewX(-8deg);
  transition: font-size .25s ease, max-width .25s ease;
}
.logo-img{
  width: min(380px, 55vw);
  height: auto;
  display:block;
  background: var(--cream);
  border-radius: 20px;
  padding: 0.7rem 1.4rem;
  box-shadow: 0 8px 20px rgba(0,0,0,0.18);
  transition: width .25s ease, padding .25s ease;
}
.logo-img[hidden]{ display:none; }

/* Once scrolled a bit past the top, the header shrinks — the full
   logo/slogan is a nice first impression, but staying that tall while
   scrolling eats too much of the viewport for content. Toggled by
   .is-scrolled on .site-header (js/script.js), not a plain :hover/etc
   — sticky headers have no native "am I still at the top" selector. */
.site-header.is-scrolled .banner-inner{
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.site-header.is-scrolled .logo-img{
  width: min(150px, 30vw);
  padding: 0.35rem 0.8rem;
}
.site-header.is-scrolled .slogan{
  font-size: 0.72rem;
  max-width: 70px;
}

/* ============================
   NAV + TAGLINE (right of logo)
============================ */
.banner-right{
  flex: 1 1 auto;
  display:flex;
  flex-direction:column;
  gap: 0.6rem;
  min-width: 0;
}
.navbar{
  background: transparent;
}
.nav-list{
  list-style:none;
  display:flex;
  flex-wrap:wrap;
  justify-content:flex-start;
  gap: 0.2rem 0.7rem;
  margin: 0;
  padding: 0;
}
.nav-list a{
  color: var(--cream);
  text-decoration:none;
  font-weight:600;
  font-size: 0.78rem;
  letter-spacing: 0.01em;
  padding: 0.3rem 0.1rem;
  border-bottom: 2px solid transparent;
  transition: border-color .2s ease, color .2s ease;
  white-space: nowrap;
}
.nav-list a:hover,
.nav-list a:focus-visible{
  border-bottom-color: var(--gold);
  color: var(--gold);
}
.btn-login{
  background: #FF0044;
  color: var(--white) !important;
  text-decoration: none;
  display: inline-block;
  flex: 0 0 auto;
  font-weight: 700 !important;
  text-transform: uppercase;
  font-size: 0.78rem !important;
  letter-spacing: 0.03em;
  padding: 0.5rem 1.1rem !important;
  border-radius: 999px;
  border: none !important;
  cursor: pointer;
  transition: background .2s ease, transform .15s ease;
}
.btn-login:hover,
.btn-login:focus-visible{
  background: #E0003C;
  color: var(--white) !important;
  transform: translateY(-1px);
}
.nav-toggle{
  display:none;
  background:none;
  border:none;
  width: 40px;
  height: 40px;
  cursor:pointer;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:5px;
}
.nav-toggle span{
  width: 24px;
  height: 3px;
  background: var(--cream);
  border-radius: 2px;
}
.tagline-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap: 1rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(253,249,240,0.18);
}
.tagline{
  color: var(--gold);
  font-family: var(--font-display);
  font-weight:600;
  font-size: clamp(0.8rem, 1.4vw, 1rem);
  letter-spacing: 0.01em;
  margin: 0;
  flex: 1 1 auto;
  text-align: center;
}
.ribbon-accent{
  height: 8px;
  background: var(--gold);
}

/* ============================
   SECTIONS (GENERAL)
============================ */
.section{
  max-width: 1080px;
  margin: 0 auto;
  padding: 4rem 1.5rem;
  scroll-margin-top: var(--header-h);
}
.section:nth-of-type(even){
  background: var(--cream-2);
}

.hero .lede{
  max-width: 700px;
  margin: 0 auto;
  text-align:center;
  color: var(--muted);
  font-size: 1.05rem;
}

/* ============================
   CARDS
============================ */
.card-grid{
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.6rem;
  margin-top: 2rem;
}
.card{
  background: var(--white);
  border-radius: var(--radius);
  padding: 1.8rem 1.5rem;
  box-shadow: var(--shadow);
  text-align:center;
}
.card p{ color: var(--muted); margin-bottom:0; }

.card-icon{
  width: 60px; height: 60px;
  margin: 0 auto 1rem;
  border-radius: 50%;
  display:flex;
  align-items:center;
  justify-content:center;
}
.card-icon svg{
  width: 32px; height:32px;
  fill:none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.icon-blue{ background: rgba(79,184,222,0.15); color: var(--sky); }
.icon-pink{ background: rgba(238,95,121,0.15); color: var(--coral); }
.icon-gold{ background: rgba(244,185,63,0.18); color: #C98A1F; }
.icon-neutral{ background: rgba(59,30,69,0.08); color: var(--plum); }
.card-icon img{ width: 36px; height: 36px; object-fit: contain; }

/* Pricing */
.price-card{ position:relative; }
.price-card.featured{
  border: 2px solid var(--gold);
  transform: translateY(-6px);
}
.badge{
  position:absolute;
  top: -14px; left:50%;
  transform: translateX(-50%);
  background: var(--gold);
  color: var(--plum);
  font-weight:700;
  font-size: 0.75rem;
  padding: 0.25rem 0.8rem;
  border-radius: 999px;
}
.price{
  font-family: var(--font-display);
  font-size: 2rem;
  color: var(--plum);
  margin: 0.4rem 0;
}
.price span{ font-size: 0.9rem; color: var(--muted); font-family: var(--font-body); }
.price-info-btn{
  position:absolute;
  top: 0.7rem;
  right: 0.7rem;
  width: 24px;
  height: 24px;
  border-radius:50%;
  border: none;
  background: rgba(59,30,69,0.08);
  color: var(--plum);
  font-family: Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-weight:700;
  font-size: 0.85rem;
  line-height:1;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  transition: background .15s ease, color .15s ease;
}
.price-info-btn:hover,
.price-info-btn:focus-visible{
  background: var(--gold);
  color: var(--plum);
}
.pricing-note{
  text-align:center;
  color: var(--muted);
  font-style: italic;
  font-size: 0.9rem;
  margin: 1.6rem 0 0;
}


/* ============================
   BOOKING FORM
============================ */
.booking-form{
  max-width: 640px;
  margin: 0 auto;
  background: var(--white);
  padding: 2rem;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display:grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.2rem;
}
.booking-form[hidden]{ display:none; }
#bookingSuccess{
  max-width: 640px;
  margin: 0 auto;
  text-align:center;
  font-size: 1rem;
}
.form-row{ display:flex; flex-direction:column; gap:0.4rem; }
.form-row[hidden]{ display:none; }
.form-row.full{ grid-column: 1 / -1; }
/* Groups a label/input and its own "Show on public site" checkbox
   together (Settings > Branding/Plain Text/etc.), with a divider +
   gap before the next field — otherwise consecutive fields in the
   same form run straight into each other and it's unclear which
   checkbox belongs to which input. The last field in a form keeps
   this too (no :last-of-type exception), so there's the same
   separation before the "Save Changes" button as between fields. */
.site-field-group{
  padding-bottom: 1rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--cream-2);
}
.form-row label{ font-weight:600; font-size:0.9rem; color: var(--plum); }
.form-row-label{ font-weight:600; font-size:0.9rem; color: var(--plum); }
.required-mark{ color: var(--coral); }
.required-note{
  grid-column: 1 / -1;
  color: var(--coral);
  font-weight:600;
  margin: 0 0 0.4rem;
}
.field-hint{
  font-size: 0.82rem;
  color: var(--muted);
  margin: -0.2rem 0 0;
}
.day-checkboxes{
  display:flex;
  flex-direction:column;
  gap: 0.5rem;
  padding: 0.7rem 0.8rem;
  border: 1.5px solid #E4DCEA;
  border-radius: 10px;
  background: var(--cream);
}
.day-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap: 0.5rem;
}
.day-check{
  display:flex;
  align-items:center;
  gap: 0.4rem;
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--ink);
  cursor:pointer;
  min-width: 110px;
}
.day-checkbox{
  width: 16px;
  height: 16px;
  accent-color: var(--coral);
  cursor:pointer;
}
.day-time{
  border: 1.5px solid #E4DCEA;
  border-radius: 8px;
  padding: 0.4rem 0.6rem;
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--ink);
  background-color: var(--white);
  flex: 0 0 auto;
  width: 130px;
}
.field-error{
  color: var(--coral);
  font-size: 0.85rem;
  font-weight: 600;
  margin: 0.3rem 0 0;
}
.form-row input,
.form-row select,
.form-row textarea{
  border: 1.5px solid #E4DCEA;
  border-radius: 10px;
  padding: 0.7rem 0.8rem;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--cream);
}
.form-row select{
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236B5C74'%3E%3Cpath d='M5.5 7.5l4.5 4.5 4.5-4.5' stroke='%236B5C74' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8rem center;
  padding-right: 2.2rem;
}
.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus{
  outline: 2px solid var(--sky);
  outline-offset: 1px;
}

/* Same look as .form-row input/select, for a field that isn't inside a
   .form-row — e.g. members-dashboard.js's children table (year-level
   select, birth-date input), inline table-cell editors rather than
   form fields. Not scoped as ".data-table input/select" — that would
   also catch .th-filter-select/.table-filter-item select (both already
   styled, more compact, for table-header/calendar filters) and be
   specific enough to override them unintentionally. */
.inline-input,
.inline-select{
  border: 1.5px solid #E4DCEA;
  border-radius: 10px;
  padding: 0.5rem 0.7rem;
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--ink);
  background: var(--cream);
}
.inline-select{
  /* A little wider than its content alone would size it to, so a
     longer option label ("Year 5") doesn't sit flush against the
     dropdown arrow. */
  min-width: 120px;
  padding-right: 2.2rem;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236B5C74'%3E%3Cpath d='M5.5 7.5l4.5 4.5 4.5-4.5' stroke='%236B5C74' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
}
.inline-input:focus,
.inline-select:focus{
  outline: 2px solid var(--sky);
  outline-offset: 1px;
}

.btn-primary{
  grid-column: 1 / -1;
  justify-self:center;
  background: var(--coral);
  color: var(--white);
  border:none;
  font-family: var(--font-display);
  font-weight:700;
  font-size: 1rem;
  padding: 0.85rem 2.2rem;
  border-radius: 999px;
  cursor:pointer;
  text-decoration:none;
  display:inline-block;
  transition: transform .15s ease, background .15s ease;
}
.btn-primary:hover{ background: #DA4A65; transform: translateY(-2px); }

/* Generic submit/action-in-progress spinner — the public booking form
   (btn-primary, solid coral fill) and admin.html/teacher-dashboard.html's
   Send Invite/Reset PIN/Resend PIN buttons (btn-secondary, transparent
   background) all use this same .btn-loading class. Hides the button's
   own text via color:transparent rather than swapping textContent, so
   it works regardless of whatever label happens to be showing (an
   admin-editable one on the public form, "Reset PIN" vs "Send Invite"
   here). Default spinner color is plum, since every button that isn't
   .btn-primary is an outlined/transparent style (light background) by
   default — .btn-primary's own solid coral fill needs a white spinner
   instead, overridden below. */
.btn-loading{
  color: transparent !important;
  pointer-events: none;
  position: relative;
}
.btn-loading::after{
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border: 2px solid rgba(59,30,69,0.25);
  border-top-color: var(--plum);
  border-radius: 50%;
  animation: btn-spin 0.7s linear infinite;
}
.btn-primary.btn-loading::after{
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border-color: rgba(255,255,255,0.4);
  border-top-color: var(--white);
}
@keyframes btn-spin{
  to{ transform: rotate(360deg); }
}

/* ============================
   ASSESSMENT CTA
============================ */
/* Bookings + Free Assessment sit side by side as a matched pair of
   purple boxes — .assessment-box itself stays usable standalone (the
   Login chooser modal reuses it below at its own 780px max-width). */
.cta-row{
  display:flex;
  gap: 2rem;
  align-items:stretch;
  justify-content:center;
}
/* flex-start (not center) keeps both headings flush with the top of
   the row regardless of how long each box's intro text runs; the
   button's margin-top:auto then pushes it (and only it) down to sit
   flush with the bottom, so the two buttons line up too. */
.cta-row .assessment-box{
  flex: 1 1 0;
  max-width: 480px;
  display:flex;
  flex-direction:column;
  justify-content:flex-start;
}
.cta-row .assessment-box .btn-primary{ margin-top:auto; }
/* The intro paragraph fills whatever space is left between the
   (top-aligned) heading and the (bottom-aligned) button, and centers
   its text within that space — so a short intro like Bookings' isn't
   left stranded up against the heading. */
.cta-row .assessment-box p{
  flex: 1;
  display:flex;
  align-items:center;
  justify-content:center;
}
.assessment-box{
  background: var(--plum);
  color: var(--cream);
  border-radius: var(--radius);
  padding: 3rem 2rem;
  text-align:center;
  max-width: 780px;
  margin: 0 auto;
}
.assessment-box h2{ color: var(--cream); }
.assessment-box p{ color: #E7DCEC; max-width: 560px; margin: 0 auto 1.6rem; }
.login-section{
  padding-top: 4.5rem;
  padding-bottom: 4.5rem;
}
.login-box{
  position: relative;
}
.login-box h1{
  color: var(--cream);
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 0 1rem;
}
.login-note{
  color: var(--gold) !important;
  font-weight: 700;
  margin-bottom: 0.8rem !important;
}
.close-btn{
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  z-index: 5;
  width: 34px;
  height: 34px;
  display:flex;
  align-items:center;
  justify-content:center;
  /* This class is used on both <a> (teacher-login.html/login.html,
     navigates back to index.html) and <button> (the modal overlays'
     own close × — index.html's login chooser, Free Assessment,
     Booking Success) — a <button> keeps the browser's default white
     chrome unless explicitly reset here. */
  background: none;
  border: none;
  font-family: inherit;
  color: #FFFFFF;
  font-size: 1.8rem;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  border-radius: 50%;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.close-btn:hover,
.close-btn:focus-visible{
  background: rgba(253,249,240,0.15);
  color: var(--gold);
}

/* Login chooser modal (index.html) — reuses .assessment-box/.login-box,
   just constrained to modal width and centered via .modal-overlay */
.modal-login-box{
  max-width: 420px;
}
.login-choice-row{
  display:flex;
  gap: 1rem;
  justify-content:center;
  flex-wrap:wrap;
  margin-top: 1.6rem;
}
/* Login/teacher-login forms sit directly on the dark .login-box
   background (not a white card like .booking-form), so the generic
   .form-row label/.field-hint/.alert colors (tuned for light
   backgrounds) need a light-on-dark override here. */
.login-box .form-row label{ color: var(--cream); }
.login-box .field-hint{ color: #E7DCEC; }
.login-box .alert{ background: rgba(253,249,240,0.95); }
/* Login/teacher-login/forgot-password forms otherwise stretch to
   .login-box's full width (780px, shared with .assessment-box) —
   narrower and still centered (auto margins) reads much better for
   just two stacked fields. margin-bottom on each row also gives the
   password field breathing room before the submit button, which
   directly follows the last .form-row with no gap otherwise. */
.login-box form{
  max-width: 360px;
  margin: 0 auto;
}
.login-box .form-row{ margin-bottom: 1rem; }
/* Plain-text button styled as a link — "Forgot password?"/"Back to
   Login" toggles between .login-box's panels; a <button> rather than
   an <a href> since there's nowhere real to navigate to, just a panel
   swap. */
.text-link{
  display:inline-block;
  margin-top:0.8rem;
  margin-bottom:0.8rem;
  background:none;
  border:none;
  padding:0;
  font:inherit;
  color: var(--gold);
  text-decoration: underline;
  cursor:pointer;
}
.text-link:hover, .text-link:focus-visible{ color: var(--cream); }

/* ============================
   REFERENCES
============================ */
.quote-card{
  background: var(--white);
  border-radius: var(--radius);
  padding: 1.8rem;
  box-shadow: var(--shadow);
  margin:0;
  border-left: 5px solid var(--gold);
}
.quote-card p{ font-style: italic; color: var(--ink); }
.quote-card cite{ color: var(--muted); font-size:0.85rem; font-style:normal; }
.quote-cite{ display:flex; justify-content:space-between; align-items:baseline; gap:0.75rem; }
.quote-cite .quote-year{ flex-shrink:0; }

/* ============================
   MEET THE TEAM
============================ */
.team-grid{ display:flex; flex-direction:column; gap:1.5rem; }
.team-member{
  display:flex;
  gap:1.5rem;
  align-items:flex-start;
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
  border-left: 5px solid var(--gold);
}
.team-photo{
  width:120px;
  height:120px;
  border-radius:50%;
  object-fit:cover;
  flex-shrink:0;
  background: var(--cream, #e9e2d8);
}
.team-info h3{ margin:0 0 0.25rem; }
.team-email{ color: var(--muted); font-size:0.9rem; margin:0 0 0.6rem; }
.team-about{ margin:0; color: var(--ink); white-space: pre-line; }

@media (max-width: 560px){
  .team-member{ flex-direction:column; align-items:center; text-align:center; }
}

/* ============================
   HOURGLASS (SIGNATURE)
============================ */
.hourglass-section{
  text-align:center;
  padding-bottom: 5rem;
}
.hourglass-wrap{
  display:flex;
  justify-content:center;
  margin-top: 1.5rem;
}
.hourglass-frame{
  width: min(160px, 34vw);
  height: auto;
}
.glass-outline{
  fill: rgba(255,255,255,0.45);
  stroke: var(--plum);
  stroke-width: 5;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.glass-shine{
  fill: none;
  stroke: rgba(255,255,255,0.75);
  stroke-width: 5;
  stroke-linecap: round;
}
.frame-cap{
  fill: var(--gold);
  stroke: var(--plum);
  stroke-width: 4;
}
.frame-post{
  fill: #C98A1F;
  stroke: var(--plum);
  stroke-width: 3;
}
.icon-piece{
  transition: opacity .3s ease;
}
@keyframes shimmer{
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

/* ============================
   FOOTER
============================ */
.site-footer{
  background: var(--plum-2);
  color: var(--cream);
  text-align:center;
  padding: 3rem 1.5rem 2rem;
  scroll-margin-top: var(--header-h);
}
.site-footer h2{ color: var(--cream); max-width: 700px; margin: 0 auto 2rem; }
.footer-grid{
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(200px,1fr));
  gap: 1.5rem;
  max-width: 1200px;
  margin: 0 auto 2rem;
}
.footer-grid .label{
  display:block;
  color: var(--gold);
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  margin-bottom: 0.3rem;
}
.footer-grid p{ margin:0; overflow-wrap: anywhere; word-break: break-word; }
.footer-grid a{ color: var(--cream); }
.copyright{
  color: #B6A6BE;
  font-size: 0.85rem;
  margin: 0;
}
.footer-bottom{
  display:flex;
  justify-content:center;
  align-items:center;
  flex-wrap:wrap;
  gap: 0.5rem;
}
.nzbn-notice::before{
  content: "\00b7";
  margin-right: 0.5rem;
  color: #B6A6BE;
}

/* ============================
   ADMIN CONSOLE (admin.html, teacher-login.html)
============================ */
.admin-shell{
  max-width: 1500px;
  margin: 0 auto;
  padding: 3rem 1.5rem 5rem;
}
.admin-shell h1{ text-align:left; }
.admin-toolbar{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap: 1rem;
  margin-bottom: 1.6rem;
}
.admin-toolbar-actions{
  display:flex;
  gap: 0.6rem;
  flex-wrap:wrap;
}
.admin-card{
  background: var(--white);
  border-radius: var(--radius);
  padding: 2rem;
  box-shadow: var(--shadow);
}
.admin-card + .admin-card{ margin-top: 1.6rem; }
/* members-dashboard.html's own Phone field — scoped to this one form
   (not a general .admin-card/.form-row rule) so admin.html's/
   teacher-dashboard.html's own .admin-card forms (e.g. "My Profile")
   are untouched. Phone numbers don't need the field's full default
   width; margin-bottom creates the gap before the Save button that
   directly follows in the DOM. */
#parentProfileForm .form-row{
  max-width: 220px;
  margin-bottom: 1rem;
}
/* Change Password card (members-dashboard.html and teacher-dashboard.html
   share the same #changePasswordForm markup/id) — same "no gap before
   the button that directly follows in the DOM" fix as
   #parentProfileForm above, plus the same narrower max-width (a
   password field doesn't need the field's full default width either). */
#changePasswordForm .form-row{
  max-width: 240px;
  margin-bottom: 1rem;
}
/* Reminders card's form (members-dashboard.html and
   teacher-dashboard.html share the same #reminderForm markup/id) —
   same "no gap before the button that directly follows in the DOM"
   fix as #changePasswordForm above. */
#reminderForm .form-row{
  margin-bottom: 1rem;
}
/* The "Remind me" lead-time dropdown specifically (not the checkbox
   row above it, which has a longer field-hint that needs the full
   card width to read comfortably) — members-dashboard.html only, per
   that request; teacher-dashboard.html's equivalent row has its own
   id (#teacherBookingReminderMinutesRow) and wasn't asked for. */
#parentReminderMinutesRow{
  max-width: 220px;
}
/* Email Verification Code (2FA) card's confirm-code step
   (members-dashboard.html and teacher-dashboard.html share the same
   #mfaConfirmRow markup/id) — same "no gap before the button(s) that
   directly follow in the DOM" fix as #changePasswordForm above; this
   one has two buttons (Confirm, Resend) right after the field. */
#mfaConfirmRow .form-row{
  margin-bottom: 1rem;
}
/* Login form's Password field -> Log In button (admin.html's own login
   view, shown again after an idle-timeout sign-out) — same "no gap
   before the button that directly follows in the DOM" fix as the two
   above. #loginForm is the same shared id in login.html/
   teacher-login.html too, so this fixes their login forms the same way
   at no extra cost — they had the identical gap, just not reported. */
#loginForm .form-row{
  margin-bottom: 1rem;
}
/* Teacher/admin "block out" form (teacher-dashboard.html's Availability
   tab) — same "gap before the button that directly follows" fix as the
   three forms above, plus a max-width: Type/Day of week/Date/Time don't
   need to stretch to the full card width like a longer field (e.g. a
   name or address) would. */
.unavailability-form .form-row{
  max-width: 320px;
  margin-bottom: 1rem;
}
.unavail-time-range{
  display:flex;
  align-items:center;
  gap: 0.6rem;
}
.unavail-time-range input[type="time"]{ flex:1; min-width:0; }
/* #unavailTimeToWrap ("to" label + its input) is itself a flex item of
   .unavail-time-range, so without this its content-sized width (rather
   than an equal flex:1 share) is what was making the "from" input grow
   to fill the leftover space and the "to" input stay its own natural
   (narrower) size. display:contents dissolves the wrapper for layout —
   its "to" label and input become direct flex items instead, so the
   `input[type="time"]{ flex:1 }` rule above sizes both inputs equally.
   Guarded by :not([hidden]) since display:contents would otherwise
   override the browser's default `[hidden]{ display:none }` and defeat
   toggleUnavailAllDay()'s hiding. */
.unavail-time-range-to:not([hidden]){ display:contents; }
.unavail-allday-check{
  display:flex;
  align-items:center;
  gap:0.4rem;
  font-weight:600;
}
.unavail-time-range-sep{
  font-size: 0.85rem;
  font-weight:600;
  color: var(--muted);
}
.admin-login-card{
  max-width: 420px;
  margin: 3rem auto;
}

/* Section switcher (admin.html: Teachers / Pending Bookings) — sits on
   the light admin-shell background, unlike .tab-btn which is styled
   for the dark .login-box. */
.section-tabs{
  display:flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1.8rem;
}
.section-tab{
  background: var(--cream-2);
  border: 1.5px solid #E4DCEA;
  color: var(--muted);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9rem;
  padding: 0.6rem 1.4rem;
  border-radius: 999px;
  cursor:pointer;
  transition: background .15s ease, color .15s ease;
}
.section-tab.active{
  background: var(--plum);
  border-color: var(--plum);
  color: var(--cream);
}

.btn-secondary{
  background: transparent;
  color: var(--plum);
  border: 1.5px solid var(--plum);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.6rem 1.4rem;
  border-radius: 999px;
  cursor:pointer;
  text-decoration:none;
  display:inline-block;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.btn-secondary:hover{ background: var(--plum); color: var(--cream); }
/* Same fix, same reasoning, for every button variant that sets its own
   `display` — author styles always win over the browser's default
   [hidden]{display:none} UA rule regardless of matching specificity, so
   any class here that declares `display` silently defeats a plain
   `el.hidden = true/false` toggle unless it's given this same explicit
   override. .btn-primary is the one that actually caused a reported bug
   (Email Verification Code (2FA)'s Enable/Disable buttons both staying
   visible regardless of MFA status, since Enable uses .btn-primary) —
   .btn-danger/.btn-success are covered defensively, in case either
   picks up its own `display` declaration later. */
.btn-secondary[hidden]{ display:none; }
.btn-primary[hidden]{ display:none; }
.btn-danger[hidden]{ display:none; }
.btn-success[hidden]{ display:none; }
/* .btn-secondary defaults assume a light parent (admin-card, etc.) —
   the header banner is dark plum, so a plum-on-transparent button
   would be nearly invisible there. Scoped override for header use. */
.site-header .btn-secondary{
  background: transparent;
  color: var(--cream);
  border-color: rgba(253,249,240,0.5);
}
.site-header .btn-secondary:hover{
  background: transparent;
  color: var(--gold);
  border-color: var(--gold);
}
.btn-small{
  padding: 0.35rem 0.9rem !important;
  font-size: 0.75rem !important;
}
.btn-danger{
  background: transparent;
  color: var(--coral);
  border: 1.5px solid var(--coral);
}
.btn-danger:hover{ background: var(--coral); color: var(--white); }
.btn-success{
  background: transparent;
  color: var(--green);
  border: 1.5px solid var(--green);
}
.btn-success:hover{ background: var(--green); color: var(--white); }

/* Data table */
.table-wrap{
  overflow-x: auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--white);
}
.data-table{
  width:100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  min-width: 720px;
}
.data-table th,
.data-table td{
  text-align:left;
  padding: 0.8rem 1rem;
  border-bottom: 1px solid #EFE8F2;
  white-space: nowrap;
}
.data-table th{
  background: var(--cream-2);
  color: var(--plum);
  font-family: var(--font-display);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  vertical-align: top;
}
.data-table tr:last-child td{ border-bottom:none; }
.data-table td.wrap{ white-space: normal; }
.row-actions{ display:flex; gap: 0.5rem; flex-wrap:wrap; }
.row-clickable{ cursor:pointer; }
.teacher-link{
  background:none;
  border:none;
  padding:0;
  font: inherit;
  color: var(--coral);
  text-decoration: underline;
  cursor: pointer;
}

.data-table th.sortable{
  cursor: pointer;
  user-select: none;
}
.data-table th.sortable:hover .th-label{ color: var(--coral); }
.sort-indicator{ display:inline-block; width: 0.9em; }
.th-label{ display:inline-flex; align-items:center; gap: 2px; }

/* Table column filters live inside their own <th> (below the label) —
   see .th-filter-select below. Calendar filters (no table header to
   attach to) keep a separate toolbar row above the calendar. */
.data-table th.filterable{
  white-space: normal;
  min-width: 130px;
}
.th-filter-select{
  display:block;
  width:100%;
  margin-top: 0.4rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  text-transform: none;
  letter-spacing: normal;
  padding: 0.25rem 0.35rem;
  border-radius: 6px;
  border: 1px solid #EFE8F2;
  background: var(--white);
  color: var(--ink);
}

.calendar-filters{
  display:flex;
  flex-wrap:wrap;
  gap: 0.75rem 1.25rem;
  align-items:center;
  margin-bottom: 1rem;
}
.calendar-filters[hidden]{ display:none; }
.table-filter-item{
  display:flex;
  flex-direction:column;
  gap: 0.2rem;
  font-size: 0.75rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.table-filter-item select{
  font-family: var(--font-body);
  font-size: 0.85rem;
  padding: 0.35rem 0.5rem;
  border-radius: 8px;
  border: 1px solid #EFE8F2;
  background: var(--white);
  color: var(--ink);
  text-transform: none;
  letter-spacing: normal;
  min-width: 140px;
}
.row-clickable:hover td{ background: var(--cream-2); }

/* Table/Calendar view toggle — reuses .section-tab's look at a smaller
   scale (this is a sub-choice within one tab, not a top-level tab). */
.view-toggle{
  display:flex;
  gap: 0.5rem;
  margin-bottom: 1.2rem;
}
.view-toggle .section-tab{
  padding: 0.45rem 1.1rem;
  font-size: 0.8rem;
}

/* Booking calendar (js/calendar-view.js) */
.calendar-wrap{
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}
.calendar-nav{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin-bottom: 1rem;
}
.calendar-month-label{
  margin:0;
  font-size: 1.1rem;
}
.calendar-grid{
  display:flex;
  flex-direction:column;
  gap: 2px;
  border: 1px solid #EFE8F2;
  border-radius: 10px;
  overflow: hidden;
}
.calendar-row{
  display:grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.calendar-weekday-header{
  background: var(--cream-2);
  color: var(--plum);
  font-family: var(--font-display);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  text-align:center;
  padding: 0.5rem 0.25rem;
}
.calendar-day{
  background: var(--white);
  min-height: 90px;
  padding: 0.35rem;
  display:flex;
  flex-direction:column;
  gap: 0.25rem;
}
.calendar-day--empty{ background: var(--cream); }
/* Uses background-image (not the `background` shorthand) so it layers
   on top of .calendar-day's own background-color instead of overwriting
   it, regardless of which class was defined later in the stylesheet. */
.calendar-day--unavailable{
  background-image: repeating-linear-gradient(
    45deg,
    rgba(107,92,116,0.16),
    rgba(107,92,116,0.16) 6px,
    transparent 6px,
    transparent 12px
  );
}
.calendar-day-number{
  font-family: var(--font-display);
  font-weight:700;
  font-size: 0.8rem;
  color: var(--plum);
}
/* "Today" used to tint the whole cell gold, which read too close to
   calendar-day--empty's cream tint on the previous/next month's days —
   a red ring around just the day number stands out without implying
   the whole day (bookings, blockouts) is somehow special. align-self
   keeps the circle from being stretched into an oval by .calendar-day's
   default flex stretch. */
.calendar-day--today .calendar-day-number{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  align-self: flex-start;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  border: 2px solid var(--coral);
  color: var(--coral);
}
.calendar-chip{
  background: rgba(59,30,69,0.07);
  color: var(--ink);
  border-radius: 6px;
  border-left: 6px solid transparent;
  padding: 0.15rem 0.35rem 0.15rem 0.5rem;
  font-size: 0.7rem;
  line-height: 1.3;
  word-break: break-word;
}
.calendar-chip--assessment{
  background: rgba(238,95,121,0.15);
}
.calendar-chip--status-pending{ border-left-color: var(--muted); background: rgba(107,92,116,0.14); }
.calendar-chip--status-confirmed{ border-left-color: #1E7A9C; background: rgba(79,184,222,0.18); }
.calendar-chip--status-cancelled{ border-left-color: var(--muted); opacity: 0.65; text-decoration: line-through; }
.calendar-chip--status-completed{ border-left-color: #C98A1F; background: rgba(244,185,63,0.18); }
.calendar-chip--assessment.calendar-chip--status-pending,
.calendar-chip--assessment.calendar-chip--status-confirmed,
.calendar-chip--assessment.calendar-chip--status-cancelled,
.calendar-chip--assessment.calendar-chip--status-completed{
  background: rgba(238,95,121,0.15);
}
.calendar-chip--unavailable{
  border-left-color: var(--muted);
  background-color: var(--white);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(107,92,116,0.16),
    rgba(107,92,116,0.16) 6px,
    transparent 6px,
    transparent 12px
  );
  font-style: italic;
}
.calendar-chip-badge{
  display:inline-block;
  background: var(--coral);
  color: var(--white);
  border-radius: 4px;
  padding: 0 0.3rem;
  font-weight:700;
  font-size: 0.65rem;
  margin-right: 0.3rem;
}
.calendar-legend{
  display:flex;
  flex-wrap:wrap;
  gap: 1.25rem;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  color: var(--ink);
}
.calendar-legend-item{
  display:flex;
  align-items:center;
  gap: 0.5rem;
  font-weight: 600;
}
.calendar-legend-dot{
  display:inline-block;
  width: 26px;
  height: 14px;
  border-radius: 4px;
}
.calendar-legend-dot--pending{ background: var(--muted); }
.calendar-legend-dot--confirmed{ background: #1E7A9C; }
.calendar-legend-dot--completed{ background: #C98A1F; }
.calendar-legend-swatch{
  display:inline-block;
  width: 26px;
  height: 14px;
  border-radius: 4px;
  border: 1px solid #EFE8F2;
  background-color: var(--white);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(107,92,116,0.16),
    rgba(107,92,116,0.16) 6px,
    transparent 6px,
    transparent 12px
  );
}

@media (max-width: 700px){
  .calendar-day{ min-height: 60px; }
  .calendar-weekday-header{ font-size: 0.65rem; }
  .calendar-chip{ font-size: 0.62rem; }
}

/* Status pills */
.status-pill{
  display:inline-block;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
}
.status-pill--active{ background: rgba(79,184,222,0.15); color: #1E7A9C; }
.status-pill--deleted{ background: rgba(107,92,116,0.15); color: var(--muted); }
.status-pill--claimed{ background: rgba(244,185,63,0.2); color: #C98A1F; }
.status-pill--pending{ background: rgba(107,92,116,0.12); color: var(--muted); }
.status-pill--admin{ background: rgba(238,95,121,0.15); color: var(--coral); }

/* Inline alerts */
.alert{
  border-radius: 10px;
  padding: 0.8rem 1rem;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 1.2rem;
}
.alert[hidden]{ display:none; }
.alert-error{ background: rgba(238,95,121,0.12); color: #C22B47; }
.alert-success{ background: rgba(79,184,222,0.12); color: #1E7A9C; }
/* Neutral notice — e.g. "you were logged out due to inactivity" isn't
   an error (nothing went wrong) or a success, just informational. */
.alert-info{ background: rgba(107,92,116,0.12); color: var(--plum); }

/* Modal (add/edit teacher) */
.modal-overlay{
  position: fixed;
  inset: 0;
  background: rgba(43,23,48,0.55);
  display:flex;
  align-items:center;
  justify-content:center;
  padding: 1.5rem;
  z-index: 100;
}
.modal-overlay[hidden]{ display:none; }
.modal-box{
  background: var(--white);
  border-radius: var(--radius);
  padding: 2rem;
  max-width: 480px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow);
  position: relative;
}
.modal-box .close-btn{ color: var(--plum); top: 0.6rem; right: 0.6rem; }
.modal-box .close-btn:hover{ background: var(--cream-2); color: var(--coral); }
.modal-box--wide{ max-width: 900px; }
/* Popup info text (Pricing "i" icon) is admin-entered free text —
   preserve line breaks the admin typed instead of collapsing them. */
#priceInfoModalText{ white-space: pre-line; }
/* The public booking form (.booking-form) is a real card in its own
   right (own background/shadow/padding) — when it sits inside a modal
   box (its own Request a Booking modal, or reparented into the Free
   Assessment modal, js/script.js), nesting it inside another card looks
   redundant, so flatten it to just fill the modal box. */
#bookingModalBox .booking-form,
#freeAssessmentModalBox .booking-form,
#contactModalBox .booking-form{
  background: none;
  box-shadow: none;
  padding: 0;
  max-width: none;
  margin: 0;
}
.modal-box form{
  display:grid;
  gap: 1.1rem;
  margin-top: 1rem;
}

/* ============================
   RESPONSIVE
============================ */
@media (max-width: 900px){
  .banner-inner{
    flex-direction: column;
    align-items: center;
    text-align:center;
    gap: 1rem;
  }
  .banner-right{
    align-items:center;
    width:100%;
  }
  .navbar{
    width:100%;
    display:flex;
    flex-direction:column;
    align-items:center;
  }
  .nav-toggle{ display:flex; }
  .nav-list{
    display:none;
    flex-direction:column;
    align-items:center;
    padding-bottom: 1rem;
    justify-content:center;
  }
  .nav-list.open{ display:flex; }
  .tagline-row{
    flex-direction: column;
    border-top: none;
    padding-top: 0;
  }
  .tagline{
    text-align:center;
  }
  .booking-form{ grid-template-columns: 1fr; }
  .cta-row{ flex-direction:column; align-items:center; }
  .cta-row .assessment-box{ max-width: 780px; width:100%; }
  .admin-toolbar{ flex-direction: column; align-items:stretch; }
  .section-tabs{
    gap: 0.4rem;
    justify-content:center;
  }
  .section-tab{
    padding: 0.5rem 1rem;
    font-size: 0.82rem;
  }
}

/* Phone-specific — the 900px breakpoint above already stacks the
   banner into a column (slogan, then logo, then nav/tagline/login),
   but at an actual phone width that stack alone was tall enough to
   push most of the top bar into almost half the screen (reported
   directly). Two things drove that: the logo sizing to min(380px,55vw)
   — still ~200px+ wide on a phone — and the long tagline sentence
   wrapping to 2-3 lines on top of everything already stacked below the
   logo. A real native app replaces this banner entirely later; this is
   just making the interim website behave on a phone in the meantime. */
@media (max-width: 480px){
  .banner-inner{
    padding: 0.6rem 1rem;
    gap: 0.5rem;
  }
  .logo-img{
    width: min(130px, 42vw);
    padding: 0.4rem 0.9rem;
    border-radius: 14px;
  }
  .slogan{
    max-width: 76px;
    font-size: 0.8rem;
  }
  .site-header.is-scrolled .banner-inner{
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
  }
  .site-header.is-scrolled .logo-img{
    width: min(80px, 26vw);
    padding: 0.25rem 0.6rem;
  }
  .site-header.is-scrolled .slogan{
    max-width: 54px;
    font-size: 0.6rem;
  }
  /* The descriptive tagline sentence is decorative flavor text on the
     marketing pages (index.html/login.html/team.html/teacher-login.html)
     — dropped on a phone so the Login button (still fully visible/
     usable) isn't sitting underneath several extra wrapped lines of it.
     :not(#currentUserLabel) excludes the *other* thing .tagline is used
     for — admin.html/teacher-dashboard.html/members-dashboard.html
     repurpose this same class for the signed-in-user label ("Nicky —
     Admin Teacher"), which is functional, not decorative, and must stay
     visible on mobile for those pages. */
  .tagline:not(#currentUserLabel){
    display:none;
  }
  .tagline-row{
    justify-content:center;
  }
}

@media (prefers-reduced-motion: reduce){
  *{ animation: none !important; transition: none !important; }
}
