/* ==========================================================================
   TutorSuite design system
   Mobile-first. System font stack (zero network font requests = fast LCP).
   All colour pairs meet WCAG AA (4.5:1 body, 3:1 large/UI).
   ========================================================================== */

/* ----- 1. Tokens ---------------------------------------------------------- */
:root {
  color-scheme: light dark;

  /* Brand — sampled directly from the TutorSuite Technologies logo.
     #394A94 is the exact logo indigo; #B2CFEF the exact logo sky blue. */
  --indigo-50:  #EEF2FB;
  --indigo-100: #DDE6F8;
  --indigo-200: #B2CFEF;   /* logo sky */
  --indigo-300: #8FAEE2;
  --indigo-400: #6076BE;
  --indigo-500: #4A5CA6;
  --indigo-600: #394A94;   /* logo indigo — primary */
  --indigo-700: #2E3B76;
  --indigo-800: #232D5A;
  --indigo-900: #161D3B;

  /* Accent — warm gold. Complements indigo and carries discount/price emphasis. */
  --gold-100: #FFF3D6;
  --gold-300: #FFD98A;
  --gold-400: #F5B32E;
  --gold-600: #8A5D00;     /* AA on white */
  --gold-900: #26190A;     /* ink on gold */

  /* Green — trust, guarantees and "included" signals. Sits between the indigo
     brand and the gold discount accent without competing with either. */
  --green-100: #DCFAEC;
  --green-300: #6FE0AC;
  --green-400: #12A366;
  --green-600: #0B7A4B;   /* AA on white */
  --green-900: #062B1B;

  --rose-100: #FFE4E9;
  --rose-500: #FF4D6D;
  --rose-700: #B3123A;

  /* Neutrals */
  --ink-900: #10162B;
  --ink-800: #161E38;
  --ink-700: #232D4F;
  --ink-500: #4A5468;
  --ink-400: #6B7488;
  --ink-300: #A8B0C0;
  --ink-200: #D7DBE4;
  --ink-100: #EDEFF4;
  --ink-50:  #F6F8FC;
  --white:   #FFFFFF;

  /* Semantic — light theme */
  --bg: var(--white);
  --bg-alt: var(--ink-50);
  --bg-sunk: var(--ink-100);
  --surface: var(--white);
  --surface-2: var(--ink-50);
  --border: var(--ink-200);
  --border-strong: var(--ink-300);
  --text: var(--ink-900);
  --text-muted: var(--ink-500);
  --text-faint: var(--ink-400);
  --brand: var(--indigo-600);
  --brand-strong: var(--indigo-700);
  --brand-text: var(--indigo-600);
  --brand-soft: var(--indigo-50);
  --accent: var(--gold-400);
  --accent-text: var(--gold-600);
  --accent-soft: var(--gold-100);
  --warn: var(--gold-400);
  --warn-text: var(--gold-600);
  --warn-soft: var(--gold-100);
  --danger-text: var(--rose-700);
  --danger-soft: var(--rose-100);
  --on-brand: #FFFFFF;
  --on-accent: var(--gold-900);
  --success: var(--green-600);
  --success-soft: var(--green-100);
  --success-ink: #153D2C;
  --on-success: #FFFFFF;
  --gloss-top: rgba(255, 255, 255, 0.92);
  --gloss-bottom: rgba(255, 255, 255, 0.42);
  --gloss-edge: rgba(255, 255, 255, 0.85);

  /* Type scale — fluid, mobile-first */
  --step--1: clamp(0.82rem, 0.79rem + 0.14vw, 0.89rem);
  --step-0:  clamp(1rem, 0.96rem + 0.2vw, 1.06rem);
  --step-1:  clamp(1.18rem, 1.1rem + 0.38vw, 1.4rem);
  --step-2:  clamp(1.25rem, 1.05rem + 0.89vw, 1.85rem);
  --step-3:  clamp(1.5rem, 1.19rem + 1.39vw, 2.44rem);
  --step-4:  clamp(1.8rem, 1.34rem + 2.08vw, 3.22rem);
  --step-5:  clamp(2.05rem, 1.33rem + 3.24vw, 4.25rem);

  /* Space */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;

  /* Shape */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(22, 29, 59, 0.06), 0 1px 3px rgba(22, 29, 59, 0.04);
  --shadow-md: 0 4px 12px rgba(22, 29, 59, 0.07), 0 2px 4px rgba(22, 29, 59, 0.04);
  --shadow-lg: 0 18px 40px rgba(22, 29, 59, 0.10), 0 4px 12px rgba(22, 29, 59, 0.05);
  --shadow-brand: 0 10px 30px rgba(57, 74, 148, 0.26);

  --container: 1140px;
  --nav-h: 60px;
  --dock-h: 68px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: var(--ink-900);
    --bg-alt: var(--ink-800);
    --bg-sunk: #0A0F1F;
    --surface: #1A2340;
    --surface-2: var(--ink-700);
    --border: #2C3760;
    --border-strong: #3D4A7A;
    --text: #EEF2FB;
    --text-muted: #A9B4CC;
    --text-faint: #8590AB;
    --brand: var(--indigo-300);
    --brand-strong: var(--indigo-200);
    --brand-text: #A8C2EA;
    --brand-soft: #222E52;
    --accent: var(--gold-400);
    --accent-text: var(--gold-300);
    --accent-soft: #3A2D0C;
    --warn-text: var(--gold-300);
    --warn-soft: #3A2D0C;
    --danger-text: #FF9FB2;
    --danger-soft: #451021;
    --on-brand: #0C1226;
    --on-accent: var(--gold-900);
    --success: var(--green-300);
    --success-soft: #0C3325;
    --success-ink: #A9E9CC;
    --on-success: #062B1B;
    --gloss-top: rgba(255, 255, 255, 0.10);
    --gloss-bottom: rgba(255, 255, 255, 0.02);
    --gloss-edge: rgba(255, 255, 255, 0.16);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 18px 40px rgba(0, 0, 0, 0.55);
    --shadow-brand: 0 10px 30px rgba(143, 174, 226, 0.30);
  }
}

:root[data-theme='dark'] {
  --bg: var(--ink-900);
  --bg-alt: var(--ink-800);
  --bg-sunk: #0A0F1F;
  --surface: #1A2340;
  --surface-2: var(--ink-700);
  --border: #2C3760;
  --border-strong: #3D4A7A;
  --text: #EEF2FB;
  --text-muted: #A9B4CC;
  --text-faint: #8590AB;
  --brand: var(--indigo-300);
  --brand-strong: var(--indigo-200);
  --brand-text: #A8C2EA;
  --brand-soft: #222E52;
  --accent: var(--gold-400);
  --accent-text: var(--gold-300);
  --accent-soft: #3A2D0C;
  --warn-text: var(--gold-300);
  --warn-soft: #3A2D0C;
  --danger-text: #FF9FB2;
  --danger-soft: #451021;
  --on-brand: #0C1226;
  --on-accent: var(--gold-900);
  --success: var(--green-300);
  --success-soft: #0C3325;
  --success-ink: #A9E9CC;
  --on-success: #062B1B;
  --gloss-top: rgba(255, 255, 255, 0.10);
  --gloss-bottom: rgba(255, 255, 255, 0.02);
  --gloss-edge: rgba(255, 255, 255, 0.16);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 18px 40px rgba(0, 0, 0, 0.55);
}

/* ----- 2. Reset ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--sp-4));
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--sp-3);
  line-height: 1.12;
  letter-spacing: -0.022em;
  font-weight: 800;
  text-wrap: balance;
}
h1 { font-size: var(--step-5); letter-spacing: -0.034em; }
h2 { font-size: var(--step-4); letter-spacing: -0.028em; }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
p  { margin: 0 0 var(--sp-4); text-wrap: pretty; }

a { color: var(--brand-text); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }

img, svg, video { max-width: 100%; height: auto; display: block; }
ul, ol { margin: 0 0 var(--sp-4); padding-left: 1.15rem; }
li { margin-bottom: var(--sp-2); }
strong { font-weight: 700; color: var(--text); }
small { font-size: var(--step--1); }
hr { border: 0; border-top: 1px solid var(--border); margin: var(--sp-6) 0; }

button, input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ----- 3. Layout primitives ---------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--sp-4);
}
@media (min-width: 720px) { .container { padding-inline: var(--sp-6); } }

.section { padding-block: var(--sp-7); }
@media (min-width: 720px) { .section { padding-block: var(--sp-9); } }
.section--tight { padding-block: var(--sp-6); }
.section--alt { background: var(--bg-alt); }

.stack > * + * { margin-top: var(--sp-4); }
.center { text-align: center; }
.mx-auto { margin-inline: auto; }
.measure { max-width: 62ch; }
.measure-narrow { max-width: 48ch; }

.grid { display: grid; gap: var(--sp-4); }
@media (min-width: 640px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 640px)  { .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 640px)  { .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px)  { .grid--4 { grid-template-columns: repeat(4, 1fr); } }

.cluster { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.cluster--center { justify-content: center; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--sp-3); top: -100px; z-index: 200;
  background: var(--brand); color: #fff; padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md); font-weight: 700; text-decoration: none;
  transition: top 0.15s var(--ease);
}
.skip-link:focus { top: var(--sp-3); }

/* ----- 4. Type helpers ---------------------------------------------------- */
.eyebrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--brand-text);
  background: var(--brand-soft); padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-pill); margin-bottom: var(--sp-3);
}
.lede { font-size: var(--step-1); color: var(--text-muted); line-height: 1.55; }
.muted { color: var(--text-muted); }
.gradient-text {
  background: linear-gradient(100deg, var(--indigo-700) 0%, var(--indigo-500) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .gradient-text {
    background: linear-gradient(100deg, var(--indigo-300) 0%, var(--indigo-200) 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
.section-head { max-width: 60ch; margin-bottom: var(--sp-6); }
.section-head--center { margin-inline: auto; text-align: center; }

/* ----- 5. Buttons --------------------------------------------------------- */
.btn {
  --btn-bg: var(--brand);
  --btn-fg: var(--on-brand);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 48px; padding: var(--sp-3) var(--sp-5);
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid transparent; border-radius: var(--r-pill);
  font-weight: 700; font-size: var(--step-0); line-height: 1.2;
  text-decoration: none; cursor: pointer; text-align: center;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background-color 0.18s var(--ease);
  box-shadow: var(--shadow-brand);
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 14px 34px rgba(57, 74, 148, 0.34); text-decoration: none; }
.btn:active { transform: translateY(0); }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none; }

.btn--accent { --btn-bg: var(--gold-400); --btn-fg: var(--gold-900); box-shadow: 0 10px 30px rgba(245, 179, 46, 0.34); }
.btn--accent:hover { box-shadow: 0 14px 34px rgba(245, 179, 46, 0.44); }

/* WhatsApp — the official brand green (#25D366) everywhere the button appears,
   so it is recognised instantly. White label text on that green is only 1.98:1,
   which fails WCAG AA, so the label uses the near-black green ink (9.9:1). The
   glyph itself stays white, the way the WhatsApp mark is drawn. The colour is
   fixed in both themes: a brand colour that shifts is not a brand colour. */
.btn--whatsapp {
  --btn-bg: #25D366;
  --btn-fg: var(--green-900);
  border-color: #1EBE5A;
  box-shadow: 0 10px 30px rgba(37, 211, 102, 0.34);
}
.btn--whatsapp:hover {
  --btn-bg: #1EBE5A;
  box-shadow: 0 14px 34px rgba(37, 211, 102, 0.44);
}
.btn__wa {
  width: 20px; height: 20px; flex: none;
  fill: #FFFFFF;
  /* Keeps the white mark visible against the green at small sizes. */
  filter: drop-shadow(0 1px 1px rgba(6, 43, 27, 0.28));
}

.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--text);
  border-color: var(--border-strong); box-shadow: none;
}
.btn--ghost:hover { background: var(--surface-2); box-shadow: var(--shadow-sm); }

.btn--light { --btn-bg: rgba(255,255,255,0.14); --btn-fg: #fff; border-color: rgba(255,255,255,0.4); box-shadow: none; }
.btn--light:hover { background: rgba(255,255,255,0.24); box-shadow: none; }

.btn--sm { min-height: 40px; padding: var(--sp-2) var(--sp-4); font-size: var(--step--1); }
.btn--block { width: 100%; }
@media (max-width: 519px) { .btn--block-mobile { width: 100%; } }

.link-arrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 700; text-decoration: none; color: var(--brand-text);
}
.link-arrow::after { content: '→'; transition: transform 0.18s var(--ease); }
.link-arrow:hover::after { transform: translateX(4px); }

/* ----- 6. Cards ----------------------------------------------------------- */
.card {
  position: relative; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--sp-5); box-shadow: var(--shadow-sm);
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease), border-color 0.22s var(--ease);
}
.card--link:hover, .card--link:focus-within {
  transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--indigo-200);
}
.card h3 { margin-bottom: var(--sp-2); font-size: var(--step-1); }
.card p:last-child { margin-bottom: 0; }
.card__icon {
  width: 46px; height: 46px; display: grid; place-items: center;
  border-radius: var(--r-md); background: var(--brand-soft); color: var(--brand-text);
  margin-bottom: var(--sp-4); font-size: 22px; line-height: 1;
}
.card__link::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--step--1); font-weight: 700; line-height: 1.2;
  padding: 5px var(--sp-3); border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border);
}
.badge--brand { background: var(--brand-soft); color: var(--brand-text); border-color: transparent; }
.badge--accent { background: var(--accent-soft); color: var(--accent-text); border-color: transparent; }
.badge--warn { background: var(--warn-soft); color: var(--warn-text); border-color: transparent; }

/* ----- 7. Scroll rails (mobile-first horizontal carousels) ---------------- */
.rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: 82%;
  gap: var(--sp-4); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  padding: var(--sp-1) var(--sp-4) var(--sp-5);
  margin-inline: calc(var(--sp-4) * -1);
  scrollbar-width: thin;
}
.rail > * { scroll-snap-align: center; }
.rail::-webkit-scrollbar { height: 6px; }
.rail::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--r-pill); }
@media (min-width: 560px) { .rail { grid-auto-columns: 46%; } }
@media (min-width: 960px) {
  .rail {
    grid-auto-flow: row; grid-template-columns: repeat(3, 1fr); grid-auto-columns: auto;
    overflow: visible; padding: 0; margin-inline: 0;
  }
}

/* ----- 8. Forms ----------------------------------------------------------- */
.field { display: block; margin-bottom: var(--sp-4); }
.field__label {
  display: block; font-weight: 700; font-size: var(--step--1);
  margin-bottom: var(--sp-2); color: var(--text);
}
.field__hint { display: block; font-size: var(--step--1); color: var(--text-muted); margin-top: var(--sp-2); }
.field__error { display: block; font-size: var(--step--1); color: var(--danger-text); margin-top: var(--sp-2); font-weight: 600; }

.input, .select, .textarea {
  width: 100%; min-height: 48px; padding: var(--sp-3) var(--sp-4);
  background: var(--surface); color: var(--text);
  border: 1.5px solid var(--border-strong); border-radius: var(--r-md);
  font-size: 16px; /* prevents iOS zoom-on-focus */
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--brand); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 4px var(--brand-soft);
}
.textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' fill='none' viewBox='0 0 14 9'%3E%3Cpath stroke='%234A5468' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 1 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--sp-4) center;
  padding-right: var(--sp-7);
}
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

/* Segmented chip picker — big thumb targets on mobile */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: var(--sp-2) var(--sp-4);
  border: 1.5px solid var(--border-strong); border-radius: var(--r-pill);
  background: var(--surface); color: var(--text); font-weight: 600;
  font-size: var(--step--1); cursor: pointer;
  transition: all 0.16s var(--ease);
}
.chip:hover { border-color: var(--brand); color: var(--brand-text); }
.chip[aria-pressed='true'], .chip--on {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand);
  box-shadow: var(--shadow-brand);
}

/* ----- 9. Site chrome ----------------------------------------------------- */
.header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.header__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); height: var(--nav-h);
}
.logo {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-weight: 800; font-size: 1.15rem; letter-spacing: -0.03em;
  color: var(--text); text-decoration: none; white-space: nowrap;
}
.logo__mark {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  background: linear-gradient(135deg, var(--indigo-600), var(--indigo-300));
  display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 900;
}
.nav { display: none; }
@media (min-width: 1000px) {
  .nav { display: flex; align-items: center; gap: var(--sp-1); }
  .nav__link {
    padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
    font-weight: 600; font-size: 0.95rem; color: var(--text-muted); text-decoration: none;
    transition: color 0.15s var(--ease), background 0.15s var(--ease);
  }
  .nav__link:hover, .nav__link[aria-current='page'] { color: var(--text); background: var(--surface-2); }
  .header__cta { display: flex; align-items: center; gap: var(--sp-3); }
}
/* ----- 9b. Services mega-menu (desktop nav) ------------------------------- */
/* The Services nav item opens a panel listing every sub-service with a one-line
   description. Built on <details>/<summary> so the entries are real crawlable
   links and the menu opens with no JavaScript; site.js only adds the niceties
   (close on outside click, on Escape, and when another menu opens).
   The whole thing is hidden below 1000px — mobile uses the drawer instead. */
.navdrop { display: none; }
@media (min-width: 1000px) {
  /* Deliberately NOT position:relative. The panel is far wider than the nav
     item, so anchoring it here made `left:50%` centre on the toggle and pushed
     the panel 172px off the left edge of the viewport. Left static, the panel
     resolves against the sticky .header instead, which spans the full width,
     so `left:50% / translateX(-50%)` centres it on screen. */
  .navdrop { display: block; }
  .navdrop__toggle {
    display: inline-flex; align-items: center; gap: 4px;
    cursor: pointer; list-style: none; user-select: none;
  }
  .navdrop__toggle::-webkit-details-marker { display: none; }
  .navdrop__toggle:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
  .navdrop__chev { width: 15px; height: 15px; transition: transform 0.18s var(--ease); }
  .navdrop[open] .navdrop__toggle { color: var(--text); background: var(--surface-2); }
  .navdrop[open] .navdrop__chev { transform: rotate(180deg); }

  .navdrop__panel {
    position: absolute;
    top: calc(100% + 10px);
    /* Anchored to the viewport centre rather than the toggle: the panel is far
       wider than the nav item, so hanging it off the left edge pushes it off
       screen on a 1024px laptop. */
    left: 50%;
    transform: translateX(-50%);
    /* Deliberately narrower and shorter than the viewport. At 1320px/86vh the
       panel covered the whole page, so the menu stopped feeling like a layer
       over the site and the user lost all sense of what was behind it. Capping
       it here keeps the page visible around and below the panel. */
    width: min(980px, calc(100vw - var(--sp-7)));
    max-height: min(72vh, 600px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
  }
  /* A 3x2 grid, with the three largest groups in row one. Multi-column balanced
     the height well but let a group split across a break, so its last entry
     orphaned under the *next* group's heading and looked like it belonged there.
     A grid keeps every group whole; ordering by size keeps the two row heights
     close, which is what multi-column was buying us. */
  .navdrop__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3) var(--sp-6);
    align-items: start;
  }
  .navdrop__col { min-width: 0; }
  .navdrop__title {
    break-after: avoid;
    -webkit-column-break-after: avoid;
  }
  .navdrop__title {
    margin: 0 0 var(--sp-2);
    font-size: var(--step--1); font-weight: 800;
    letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted);
  }
  .navdrop__title a { color: inherit; text-decoration: none; }
  .navdrop__title a:hover { color: var(--brand-text); text-decoration: underline; }
  .navdrop__col ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }
  .navdrop__col a {
    display: block; padding: 4px var(--sp-3);
    border-radius: var(--r-sm); text-decoration: none;
  }
  .navdrop__col li a:hover { background: var(--brand-soft); }
  .navdrop__name {
    display: block; font-weight: 700; font-size: 0.94rem;
    color: var(--text); line-height: 1.25;
  }
  /* Hidden in the desktop mega-menu, not deleted: the descriptions are what
     made the panel tall enough to cover the page. Names alone let all six
     groups fit at a glance with no scrolling, and the drawer still shows the
     descriptions on mobile where there is room to read them. */
  .navdrop__desc { display: none; }
  .navdrop__col li a:hover .navdrop__name { color: var(--brand-text); }
  .navdrop__all {
    display: flex; flex-wrap: wrap; gap: var(--sp-3);
    align-items: center; justify-content: space-between;
    margin: var(--sp-3) 0 0; padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
  }
  .navdrop__all a { font-weight: 700; }
}
/* Below 1180px the four columns get too narrow, but three make the panel taller
   than the viewport allows — so the descriptions tighten instead. */
/* Six groups and 28 entries only balance into four columns; three makes the
   panel taller than any laptop viewport. Four starts as early as the panel can
   carry it. */
@media (min-width: 1000px) and (max-width: 1079px) {
  .navdrop__panel { max-height: min(58vh, 460px); padding: var(--sp-3); }
  .navdrop__col a { padding: 4px var(--sp-2); }
  .navdrop__desc { font-size: 0.74rem; line-height: 1.32; }
  .navdrop__col { padding-bottom: var(--sp-3); }
}

.header__actions { display: flex; align-items: center; gap: var(--sp-2); }
.burger {
  display: grid; place-items: center; width: 46px; height: 46px;
  background: transparent; border: 1.5px solid var(--border-strong);
  border-radius: var(--r-md); cursor: pointer;
}
.burger__box { display: block; width: 18px; height: 12px; position: relative; }
.burger__box span {
  position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
  background: var(--text); transition: transform 0.2s var(--ease), opacity 0.2s var(--ease);
}
.burger__box span:nth-child(1) { top: 0; }
.burger__box span:nth-child(2) { top: 5px; }
.burger__box span:nth-child(3) { top: 10px; }
.burger[aria-expanded='true'] .burger__box span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded='true'] .burger__box span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] .burger__box span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* Desktop shows the full nav, so the drawer trigger is hidden.
   Declared AFTER the base rule above — otherwise equal specificity means the
   later `display: grid` wins and the burger stays visible at all widths. */
@media (min-width: 1000px) { .burger { display: none; } }

/* A panel, not a takeover. It used to run edge to edge from the header to the
   bottom of the screen, which hid the page completely and left no cue that the
   site was still behind it. Capping the height keeps the page visible under the
   panel, so closing the menu feels like returning rather than navigating. */
.drawer {
  position: fixed; inset: var(--nav-h) 0 auto 0; z-index: 99;
  max-height: min(68vh, calc(100dvh - var(--nav-h) - var(--dock-h) - var(--sp-4)));
  background: var(--bg); overflow-y: auto; overscroll-behavior: contain;
  padding: var(--sp-4) 0 var(--sp-5);
  border-bottom: 1px solid var(--border);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  box-shadow: var(--e4);
  animation: drawer-in 0.22s var(--ease);
}
@keyframes drawer-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.drawer__group + .drawer__group { margin-top: var(--sp-5); border-top: 1px solid var(--border); padding-top: var(--sp-5); }

/* Tablets and big phones in landscape: a single column of links leaves a wide
   empty gutter and pushes the arrow miles from its label. Two columns fill the
   width and roughly halve the scroll. */
@media (min-width: 640px) and (max-width: 999px) {
  .drawer__group {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--sp-5);
    align-items: start;
  }
  .drawer__title { grid-column: 1 / -1; }
}
.drawer__title {
  font-size: var(--step--1); text-transform: uppercase; letter-spacing: 0.08em;
  font-weight: 800; color: var(--text-faint); margin-bottom: var(--sp-3);
}
.drawer__link {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  min-height: 52px; padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md); font-weight: 600; color: var(--text); text-decoration: none;
}
.drawer__link:hover { background: var(--surface-2); }
.drawer__link { align-items: flex-start; padding-block: var(--sp-3); }
.drawer__text { display: block; min-width: 0; }
.drawer__arrow { flex: none; color: var(--text-faint); }
.drawer__link small {
  display: block; margin-top: 2px;
  font-size: var(--step--1); line-height: 1.45;
  font-weight: 400; color: var(--text-muted);
}
.drawer__title a { color: inherit; text-decoration: none; }
.drawer__title a:hover { color: var(--brand-text); text-decoration: underline; }

/* Mobile sticky action dock — the primary conversion surface on phones */
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 98;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3) calc(var(--sp-2) + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--border);
}
@media (min-width: 1000px) { .dock { display: none; } }
.dock .btn { min-height: 50px; padding-inline: var(--sp-3); font-size: 0.95rem; }
body { padding-bottom: calc(var(--dock-h) + env(safe-area-inset-bottom)); }
@media (min-width: 1000px) { body { padding-bottom: 0; } }

/* ----- 10. Hero ----------------------------------------------------------- */
.hero {
  position: relative; overflow: hidden;
  padding-block: var(--sp-6) var(--sp-7);
  background:
    radial-gradient(900px 500px at 12% -10%, var(--indigo-100) 0%, transparent 60%),
    radial-gradient(700px 460px at 92% 4%, var(--gold-100) 0%, transparent 62%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hero {
    background:
      radial-gradient(900px 500px at 12% -10%, #1E2A57 0%, transparent 62%),
      radial-gradient(700px 460px at 92% 4%, #3A2D0C 0%, transparent 64%);
  }
}
:root[data-theme='dark'] .hero {
  background:
    radial-gradient(900px 500px at 12% -10%, #1E2A57 0%, transparent 62%),
    radial-gradient(700px 460px at 92% 4%, #3A2D0C 0%, transparent 64%);
}
@media (min-width: 960px) {
  .hero { padding-block: var(--sp-8) var(--sp-9); }
  .hero__grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: var(--sp-7); align-items: center; }
  .hero__grid > * { min-width: 0; }
}
.hero h1 { margin-bottom: var(--sp-4); }
.hero__sub { font-size: var(--step-1); color: var(--text-muted); max-width: 34ch; margin-bottom: var(--sp-5); }
@media (min-width: 960px) { .hero__sub { max-width: 46ch; } }

/* The "we specialise in" line is a supporting list, not a second lede, so it
   sits a step smaller and closer to the paragraph above it. */
.hero__sub--tight {
  font-size: var(--step-0);
  margin-top: calc(var(--sp-5) * -1 + var(--sp-3));
  margin-bottom: var(--sp-4);
}
.hero__sub--tight a { color: var(--brand-text); text-decoration-thickness: 1.5px; }

/* The eyebrow is normally a short label, so it is uppercase and letter-spaced.
   A full sentence in that treatment reads badly and wraps to two lines on a
   phone, so this variant keeps sentence case. */
.eyebrow--sentence {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--step-0);
  font-weight: 700;
}

/* Closing promise: the one line that has to survive a two-second glance. */
.hero__kicker {
  font-size: var(--step-1);
  color: var(--text);
  max-width: 34ch;
  margin-bottom: var(--sp-5);
}
@media (min-width: 960px) { .hero__kicker { max-width: 46ch; } }

.trustbar {
  display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--border);
}
.trustbar__item {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--step--1); font-weight: 600; color: var(--text-muted);
}
.trustbar__item svg { flex: none; color: var(--accent-text); }

/* ----- 11. Quote calculator ---------------------------------------------- */
.quote {
  min-width: 0;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-xl); box-shadow: var(--shadow-lg); overflow: hidden;
}
.quote__head {
  padding: var(--sp-4) var(--sp-5);
  background: linear-gradient(120deg, var(--indigo-800), var(--indigo-600) 55%, var(--indigo-500));
  color: #fff;
}
.quote__head h2, .quote__head p { color: #fff; margin: 0; }
.quote__head h2 { font-size: var(--step-1); }
.quote__head p { font-size: var(--step--1); opacity: 0.92; margin-top: 4px; }
.quote__body { padding: var(--sp-5); }
.quote__row { display: grid; gap: var(--sp-4); }
@media (min-width: 480px) { .quote__row--2 { grid-template-columns: 1fr 1fr; } }
.quote__total {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-4); margin-block: var(--sp-4);
  background: var(--accent-soft); border-radius: var(--r-md);
}
.quote__price { font-size: var(--step-3); font-weight: 900; letter-spacing: -0.03em; color: var(--accent-text); }
.quote__price-note { font-size: var(--step--1); color: var(--text-muted); }
.stepper { display: flex; align-items: center; gap: var(--sp-2); }
.stepper button {
  width: 48px; height: 48px; flex: none; border-radius: var(--r-md);
  border: 1.5px solid var(--border-strong); background: var(--surface);
  font-size: 20px; font-weight: 700; cursor: pointer; line-height: 1;
}
.stepper button:hover { border-color: var(--brand); color: var(--brand-text); }
.stepper .input { text-align: center; }

/* ----- 11b. Service sub-navigation --------------------------------------- */
/* A dropdown for jumping between the services in the same family, so a student
   who lands on the wrong page does not have to go back up to a hub to fix it.
   Built on <details>/<summary> rather than a <select>, for three reasons: the
   entries stay real crawlable <a> links, it needs no JavaScript, and it is
   keyboard- and screen-reader-accessible for free. The panel opens in normal
   flow rather than overlaying — an absolutely positioned menu is what causes
   sideways-scroll bugs on a 360px screen. */
.svcnav {
  margin: var(--sp-4) 0 var(--sp-2);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: inset 0 1px 2px rgba(22, 29, 59, 0.07);
  min-width: 0;
}
.svcnav__toggle {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  min-height: 48px;
  cursor: pointer;
  list-style: none;
  font-weight: 700;
  border-radius: var(--r-md);
}
.svcnav__toggle::-webkit-details-marker { display: none; }
.svcnav__toggle:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
.svcnav__eyebrow {
  display: block;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.svcnav__current { display: block; color: var(--text); }
.svcnav__chev {
  margin-left: auto; flex: none;
  width: 20px; height: 20px;
  color: var(--brand-text);
  transition: transform 0.18s var(--ease);
}
.svcnav[open] .svcnav__chev { transform: rotate(180deg); }
.svcnav__list {
  margin: 0; padding: var(--sp-2);
  list-style: none;
  border-top: 1px solid var(--border);
  display: grid; gap: 2px;
}
.svcnav__list a {
  display: block;
  padding: var(--sp-3) var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
}
.svcnav__list a:hover { background: var(--brand-soft); color: var(--brand-text); }
.svcnav__list a[aria-current='page'] {
  background: var(--brand-soft);
  color: var(--brand-text);
  font-weight: 800;
}
.svcnav__all {
  border-top: 1px solid var(--border);
  margin-top: var(--sp-2); padding-top: var(--sp-2);
}
@media (min-width: 720px) {
  .svcnav { max-width: 520px; }
  .svcnav__list { grid-template-columns: 1fr 1fr; }
  .svcnav__all { grid-column: 1 / -1; }
}

/* ----- 12. Steps / process ----------------------------------------------- */
.steps { counter-reset: step; display: grid; gap: var(--sp-4); }
@media (min-width: 860px) { .steps--3 { grid-template-columns: repeat(3, 1fr); } }
.step { position: relative; padding-left: 62px; }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 46px; height: 46px; display: grid; place-items: center;
  border-radius: var(--r-md); font-weight: 900; font-size: 1.1rem;
  background: var(--brand); color: var(--on-brand); box-shadow: var(--shadow-brand);
}
.step h3 { font-size: var(--step-1); margin-bottom: var(--sp-2); }

/* ----- 13. FAQ / accordion ------------------------------------------------ */
.faq { border-top: 1px solid var(--border); }
.faq details {
  border-bottom: 1px solid var(--border);
}
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-4) 0; min-height: 56px;
  font-weight: 700; font-size: var(--step-0); cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: var(--r-pill); background: var(--surface-2); color: var(--brand-text);
  font-size: 20px; font-weight: 700; transition: transform 0.2s var(--ease);
}
.faq details[open] summary::after { content: '−'; transform: rotate(180deg); }
.faq details[open] summary { color: var(--brand-text); }
.faq__answer { padding-bottom: var(--sp-4); color: var(--text-muted); }
.faq__answer p:last-child, .faq__answer ul:last-child { margin-bottom: 0; }

/* ----- 14. Prose (article body) ------------------------------------------ */
.prose { max-width: 68ch; }
.prose h2 { font-size: var(--step-3); margin-top: var(--sp-7); }
.prose h3 { font-size: var(--step-2); margin-top: var(--sp-6); }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.3rem; }
.prose li::marker { color: var(--brand); font-weight: 700; }
.prose blockquote {
  margin: var(--sp-5) 0; padding: var(--sp-4) var(--sp-5);
  border-left: 4px solid var(--brand); background: var(--brand-soft);
  border-radius: 0 var(--r-md) var(--r-md) 0; font-size: var(--step-1); font-style: italic;
}
.prose blockquote p:last-child { margin-bottom: 0; }
.prose table { margin: var(--sp-5) 0; font-size: var(--step--1); }
.prose th, .prose td { padding: var(--sp-3); border-bottom: 1px solid var(--border); text-align: left; }
.prose th { font-weight: 800; background: var(--surface-2); }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ----- 15. Callouts ------------------------------------------------------- */
.callout {
  padding: var(--sp-4) var(--sp-5); border-radius: var(--r-lg);
  background: var(--surface-2); border: 1px solid var(--border);
  margin-block: var(--sp-5);
}
.callout--brand { background: var(--brand-soft); border-color: transparent; }
.callout--warn { background: var(--warn-soft); border-color: transparent; }
.callout__title { font-weight: 800; margin-bottom: var(--sp-2); display: flex; gap: var(--sp-2); align-items: center; }
.callout p:last-child { margin-bottom: 0; }

.checklist { list-style: none; padding: 0; }
.checklist li {
  position: relative; padding-left: 30px; margin-bottom: var(--sp-3);
}
.checklist li::before {
  content: ''; position: absolute; left: 0; top: 0.45em;
  width: 18px; height: 18px; border-radius: var(--r-pill);
  background: var(--accent-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' viewBox='0 0 12 12'%3E%3Cpath stroke='%23394A94' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.2' d='m2 6.2 2.6 2.6L10 3.4'/%3E%3C/svg%3E") center / 12px no-repeat;
}

/* ----- 16. CTA band ------------------------------------------------------- */
.cta-band {
  position: relative; overflow: hidden;
  padding: var(--sp-7) var(--sp-5); border-radius: var(--r-xl);
  background: linear-gradient(125deg, var(--indigo-900) 0%, var(--indigo-700) 45%, var(--indigo-500) 100%);
  color: #fff; text-align: center;
}
.cta-band::after {
  content: ''; position: absolute; right: -80px; bottom: -110px;
  width: 320px; height: 320px; border-radius: 50%;
  background: radial-gradient(circle, rgba(245, 179, 46, 0.45), transparent 66%);
  pointer-events: none;
}
.cta-band h2 { color: #fff; position: relative; }
.cta-band p { color: rgba(255,255,255,0.9); position: relative; max-width: 52ch; margin-inline: auto; }
.cta-band .cluster { position: relative; }

/* ----- 17. Stats ---------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-4); }
@media (min-width: 860px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat {
  position: relative;
  overflow: hidden;
  /* Lets .metric__num--fit size itself against the card rather than the
     viewport, so a word-length stat value shrinks to fit instead of being
     clipped by the overflow rule above. */
  container-type: inline-size;
  text-align: center;
  padding: var(--sp-5) var(--sp-3);
  background-image: linear-gradient(180deg, var(--gloss-top), var(--gloss-bottom));
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: inset 0 1px 0 var(--gloss-edge), var(--shadow-sm);
}
.stat__num {
  display: block; font-size: var(--step-3); font-weight: 900;
  letter-spacing: -0.03em; color: var(--brand-text); line-height: 1.1;
  /* Backstop: .stat clips its overflow, so a value too long for its card would
     vanish silently rather than look wrong. Wrapping makes any future overlong
     value visibly awkward instead of invisible. */
  overflow-wrap: break-word;
  min-width: 0;
}
.stat__label { font-size: var(--step--1); color: var(--text-muted); font-weight: 600; }

/* ----- 18. Footer --------------------------------------------------------- */
.footer { background: var(--bg-alt); border-top: 1px solid var(--border); padding-block: var(--sp-7) var(--sp-5); margin-top: var(--sp-8); }
.footer__grid { display: grid; gap: var(--sp-6); }
@media (min-width: 640px) { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
/* Five link columns since "By course" was added; the brand column keeps a
   little extra width so the address does not wrap awkwardly. */
@media (min-width: 960px) { .footer__grid { grid-template-columns: 1.5fr repeat(4, 1fr); } }
@media (min-width: 1120px) { .footer__grid { grid-template-columns: 1.4fr repeat(5, 1fr); } }
.footer__title { font-size: var(--step--1); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 800; margin-bottom: var(--sp-3); color: var(--text); }
.footer__list { list-style: none; padding: 0; margin: 0; }
.footer__list li { margin-bottom: var(--sp-2); }
.footer__list a { color: var(--text-muted); text-decoration: none; font-size: 0.95rem; }
.footer__list a:hover { color: var(--brand-text); text-decoration: underline; }
.footer__bottom {
  margin-top: var(--sp-6); padding-top: var(--sp-4); border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: space-between;
  font-size: var(--step--1); color: var(--text-muted);
}

/* ----- 19. Breadcrumbs ---------------------------------------------------- */
.crumbs { padding-block: var(--sp-4) 0; font-size: var(--step--1); }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-2); padding: 0; margin: 0; }
.crumbs li { display: flex; align-items: center; gap: var(--sp-2); margin: 0; color: var(--text-muted); }
.crumbs li + li::before { content: '/'; color: var(--text-faint); }
.crumbs a { color: var(--text-muted); text-decoration: none; }
.crumbs a:hover { color: var(--brand-text); text-decoration: underline; }

/* ----- 20. Utility -------------------------------------------------------- */
/* Section heading that introduces a card grid sitting directly under the h1.
   Deliberately a step down from a normal h2: its job is to make the document
   outline correct (h1 -> h2 -> h3 card titles) without competing with the h1
   right above it. */
.section-subhead {
  font-size: var(--step-2);
  margin-bottom: var(--sp-4);
}

.pill-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.divider-soft { height: 1px; background: var(--border); margin-block: var(--sp-6); border: 0; }
.reveal { animation: reveal 0.5s var(--ease) both; }
@keyframes reveal { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.spinner {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  border: 2.5px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Desktop-only header CTA — the mobile equivalent lives in the sticky dock */
.cta-desktop { display: none; }
@media (min-width: 1000px) { .cta-desktop { display: inline-flex; } }

/* ==========================================================================
   Brand logo — the supplied TutorSuite Technologies lockup
   ========================================================================== */
.logo__img {
  display: block;
  height: 34px;
  width: auto;
}
@media (min-width: 1000px) { .logo__img { height: 40px; } }
.footer .logo__img { height: 44px; }

/* The logo is deep indigo, so on a dark surface it needs a light plate to stay
   legible. Keeps the brand colours exact rather than recolouring the artwork. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .logo__img {
    background: #fff;
    padding: 5px 9px;
    border-radius: 10px;
  }
}
:root[data-theme='dark'] .logo__img {
  background: #fff;
  padding: 5px 9px;
  border-radius: 10px;
}

/* ==========================================================================
   Announcement marquee — first-order discount, scrolling right to left
   ========================================================================== */
.announce {
  position: relative;
  /* The track is `white-space: nowrap` and far wider than the viewport.
     `overflow: hidden` alone does not stop that width propagating upward as a
     min-content contribution, so ancestors were being forced wide (pricing.html
     overflowed to 636px on a 360px screen). Size containment makes this
     element's inline size independent of its contents. */
  contain: inline-size;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  background: linear-gradient(90deg, #F5B32E 0%, #FFCE63 50%, #F5B32E 100%);
  color: var(--gold-900);
  border-block: 1px solid rgba(38, 25, 10, 0.18);
}
/* Static, centred, and fully readable — for everyone, not just reduced-motion.
   This used to scroll on a 32s infinite loop. Two problems with that: a reader
   could never take the offer in at a glance because the text was always moving
   out from under them, and an animation that never ends means the page never
   counts as visually complete. Lighthouse scored the homepage's Speed Index at
   9.2s because of it — 84 overall against 96 with the scroll off. Delaying the
   start made it worse, not better: it just moved the instability later into the
   measurement window. A still bar says the same thing and reads faster. */
.announce__track {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  width: 100%;
  padding-block: 9px;
}
.announce { white-space: normal; }
/* The track carries the message twice over plus a duplicate block, because a
   seamless loop needs a second copy to scroll into. Standing still, that reads
   as a stutter — so everything past the first "offer • detail" pair is hidden.
   The markup is left alone so the scroll can be restored by CSS alone. */
.announce__track > *:nth-child(n + 4) { display: none; }

.announce__item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding-inline: var(--sp-5);
  font-size: var(--step--1);
  font-weight: 800;
  letter-spacing: 0.01em;
}
.announce__item b { font-weight: 900; }
.announce__sep { opacity: 0.55; font-weight: 900; }


/* (The reduced-motion override that used to live here is gone: the bar is now
   static for everyone, so there is nothing left to reduce.) */

/* ==========================================================================
   Price display — list price struck through beside the discounted price
   ========================================================================== */
.price-was {
  text-decoration: line-through;
  color: var(--text-muted);
  font-weight: 600;
}
.save-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--gold-400);
  color: var(--gold-900);
  font-size: var(--step--1);
  font-weight: 900;
  letter-spacing: 0.02em;
  white-space: nowrap;
}


/* Utility used by the optional "Something else" box in the quote form. */
[hidden] { display: none !important; }

/* ==========================================================================
   Emphasis system — Apple's pattern: key points are not body copy. A muted
   lead-in sets context, then each point lands as one large, semibold sentence
   with the number or benefit leading. Sizes mirror apple.com (28px list
   statements, 40px hero statement).
   ========================================================================== */

.statement-lead {
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-faint);
  margin-bottom: var(--sp-4);
  text-wrap: balance;
}

.statement {
  font-size: var(--step-3);
  font-weight: 800;
  line-height: 1.14;
  letter-spacing: -0.028em;
  color: var(--text);
  max-width: 22ch;
  text-wrap: balance;
}
.statement--wide { max-width: 34ch; }

/* The "here's what you get" list: large statements, green tick, generous air. */
.statements {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--sp-5);
}
.statements > li {
  position: relative;
  margin: 0;
  padding-left: 46px;
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.018em;
  text-wrap: pretty;
}
.statements > li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.12em;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--success-soft)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' fill='none' viewBox='0 0 12 12'%3E%3Cpath stroke='%230B7A4B' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.4' d='m2 6.2 2.6 2.6L10 3.4'/%3E%3C/svg%3E")
    center / 17px no-repeat;
  box-shadow: 0 1px 2px rgba(11, 122, 75, 0.22);
}
.statements > li small,
.statements > li .statements__note {
  display: block;
  margin-top: 6px;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--text-muted);
}

/* Inline highlighter. Washes only the lower part of the line, so the text keeps
   the page's own contrast rather than sitting on a solid block. */

/* Big single metric, Apple's "6x faster" treatment. */
.metric__num {
  display: block;
  font-size: var(--step-5);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.045em;
  background: linear-gradient(120deg, var(--indigo-700), var(--indigo-500) 55%, var(--green-600));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Word-length stat values ("Unlimited") cannot take the full display size that
   suits a short one ("23") — at 68px it ran 82px past the edge of its card and
   was silently clipped. This scales the value to the card's own width, capped at
   the normal display size so it never grows larger than the short values.
   The first declaration is the fallback: a browser without container query units
   discards the second and keeps a size that always fits. */
.metric__num--fit {
  font-size: var(--step-3);
  font-size: max(1.35rem, min(var(--step-5), 20cqi));
}

.metric__label {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--step-0);
  font-weight: 700;
  color: var(--text-muted);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .metric__num {
    background: linear-gradient(120deg, var(--indigo-200), var(--indigo-300) 50%, var(--green-300));
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
:root[data-theme='dark'] .metric__num {
  background: linear-gradient(120deg, var(--indigo-200), var(--indigo-300) 50%, var(--green-300));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* Full-bleed statement band — the Apple dark interstitial. */
.spotlight {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  padding: var(--sp-8) var(--sp-5);
  text-align: center;
  color: #fff;
  background:
    radial-gradient(700px 340px at 78% 14%, rgba(18, 163, 102, 0.42), transparent 62%),
    linear-gradient(155deg, var(--indigo-900) 0%, var(--indigo-700) 52%, var(--indigo-600) 100%);
}
.spotlight::after {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 46%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.14), transparent);
  pointer-events: none;
}
.spotlight > * { position: relative; }
.spotlight .statement,
.spotlight h2 { color: #fff; margin-inline: auto; }
.spotlight .statement-lead { color: rgba(255, 255, 255, 0.72); }

/* ==========================================================================
   Gloss — a specular sheen and a light top edge, so panels read as glass
   rather than flat fills.
   ========================================================================== */
.glossy {
  position: relative;
  overflow: hidden;
  background-image: linear-gradient(180deg, var(--gloss-top), var(--gloss-bottom));
  background-color: var(--surface);
  border: 1px solid var(--border);
  box-shadow: inset 0 1px 0 var(--gloss-edge), var(--shadow-lg);
}
.glossy::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 44%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0));
  pointer-events: none;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .glossy::before {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0));
  }
}
:root[data-theme='dark'] .glossy::before {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0));
}
.glossy > * { position: relative; }

/* Gloss on the primary button and the quote header. */
.btn {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 58%);
}
.btn--ghost { background-image: none; }

/* Two-line button: the action on top, the qualifier under it in a smaller,
   lighter face. Keeps the reassurance attached to the button it qualifies
   instead of floating as loose text beside it. */
.btn--stack {
  flex-direction: column;
  gap: 2px;
  padding-block: var(--sp-2);
  line-height: 1.15;
}
.btn__label { font-weight: 700; }
.btn__note {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  opacity: 0.72;
  text-transform: none;
}

.quote { position: relative; }
.quote__head {
  position: relative;
  overflow: hidden;
  background-image:
    linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 62%),
    linear-gradient(120deg, var(--indigo-800), var(--indigo-600) 55%, var(--indigo-500));
}
.quote__head::after {
  content: '';
  position: absolute;
  right: -60px;
  top: -90px;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(111, 224, 172, 0.34), transparent 68%);
  pointer-events: none;
}
.quote__head > * { position: relative; }

/* Guarantee / trust items pick up the green. */
.trustbar__item svg { color: var(--success); }
.checklist li::before {
  background-color: var(--success-soft);
  box-shadow: 0 1px 2px rgba(11, 122, 75, 0.18);
}
.badge--success {
  background: var(--success-soft);
  color: var(--success-ink);
  border-color: transparent;
}

/* Section that alternates to a tinted ground, Apple-style rhythm. */
.section--tint {
  background:
    radial-gradient(620px 320px at 10% 0%, var(--brand-soft), transparent 62%),
    radial-gradient(560px 300px at 92% 8%, var(--success-soft), transparent 60%),
    var(--bg-alt);
}

/* ==========================================================================
   Mobile-first refinements
   ~90% of this audience is on a phone, so the phone layout is the real layout.
   Everything below narrows the gap between "works on mobile" and "designed for
   mobile": the interactive element comes first, chrome is trimmed, and touch
   targets are sized for thumbs.
   ========================================================================== */

@media (max-width: 959px) {
  /* Reading order on a phone: say what this is, then ask for the order.
     The calculator still sits high — it is the conversion element and must stay
     reachable on the first screen — but it now comes *after* the paragraph that
     explains the service, not before it. Putting the form first left the closing
     promise stranded above the copy it was meant to summarise.
     What follows the form is supporting detail: the specialism list, and the
     closing line that reads as a summary once you have the context. */
  .hero__grid { display: flex; flex-direction: column; gap: 0; }
  .hero__col { display: contents; }

  /* The offer line ("up to 50% off") has to be read BEFORE the calculator,
     otherwise the price lands with no discount context and the promise reads
     like an afterthought below the form. */
  .hero .eyebrow      { order: 1; }
  .hero h1            { order: 2; }
  .hero__sub          { order: 3; margin-bottom: var(--sp-4); }
  .hero__sub--tight   { order: 4; margin-top: 0; margin-bottom: var(--sp-3); }
  .hero__kicker       { order: 5; margin-bottom: var(--sp-4); }
  .hero__quote        { order: 6; margin: 0 0 var(--sp-5); }
  .hero .cluster      { order: 7; }
  .hero .trustbar     { order: 8; }

  /* The calculator carries its own CTA and the sticky dock repeats "Get a
     quote", so the primary hero button is noise on a phone. */
  .hero .cluster > .btn:first-child { display: none; }
  .hero .cluster > .btn { width: 100%; }

  /* Trust points read as a compact two-up block rather than four stacked rows. */
  .trustbar {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-3) var(--sp-4);
    margin-top: var(--sp-4);
    padding-top: var(--sp-4);
  }
  .trustbar__item { font-size: 0.8rem; line-height: 1.35; align-items: flex-start; }
  .trustbar__item svg { margin-top: 2px; }

  .spotlight { padding: var(--sp-6) var(--sp-4); border-radius: var(--r-lg); }
  .statements { gap: var(--sp-4); }
  .statements > li { padding-left: 38px; }
  .statements > li::before { width: 26px; height: 26px; background-size: 15px; }
}

@media (max-width: 559px) {
  /* Section rhythm tightened so more of the page is content, less is padding. */
  .section { padding-block: var(--sp-6); }
  .cta-band { padding: var(--sp-6) var(--sp-4); }
  .card { padding: var(--sp-4); }
  .quote__body { padding: var(--sp-4); }
  .quote__head { padding: var(--sp-4); }

  /* Stacked CTAs are easier to hit than a wrapped row. */
  .cluster > .btn { width: 100%; }
  .cta-band .cluster { flex-direction: column; }
}

/* Thumb-sized hit areas on touch devices. Vertical padding on an inline link
   grows the tap target without changing the line box, so copy still wraps
   normally. */
@media (pointer: coarse) {
  .prose p a,
  .prose li a,
  .checklist a,
  .footer__list a,
  .crumbs a,
  .link-arrow { padding-block: 9px; }

  .faq summary { min-height: 60px; }
  .drawer__link { min-height: 56px; }
}

/* Horizontal card rails get a nudge of padding so the first card is not flush
   to the edge, and momentum scrolling stays smooth. */
@media (max-width: 959px) {
  .rail { scroll-padding-inline: var(--sp-4); }
}

/* Landscape phones: the sticky dock eats too much of a short viewport. */
@media (max-height: 460px) and (orientation: landscape) {
  .dock { position: static; }
  body { padding-bottom: 0; }
}

/* Hero spacing now lives here rather than in an inline style, so the mobile
   reorder above can actually control it. */
.hero__quote { margin-top: var(--sp-6); }

@media (max-width: 959px) {
  .hero { padding-block: var(--sp-5) var(--sp-6); }
  .hero__quote { margin: 0 0 var(--sp-5); }
  /* Shorter measure and tighter leading so the standfirst is 3 lines, not 5. */
  .hero__sub {
    font-size: 1.03rem;
    line-height: 1.5;
    max-width: 38ch;
    margin-bottom: var(--sp-4);
  }
  .hero h1 { margin-bottom: var(--sp-3); }
  .eyebrow { margin-bottom: var(--sp-3); }
}

/* Safety net: grid and flex children default to `min-width: auto`, which lets a
   wide child (a long word, a table, a nowrap row) push the whole page sideways.
   Nothing in this design needs that behaviour. */
.grid > *,
.hero__grid > *,
.quote__row > * { min-width: 0; }

/* ==========================================================================
   Depth — layered elevation
   Real objects cast more than one shadow: a tight contact shadow plus a wide
   ambient one. Stacking them is what separates "a box with a drop shadow" from
   something that reads as a physical surface.
   ========================================================================== */
:root {
  --e1:
    0 1px 1px rgba(22, 29, 59, 0.05),
    0 2px 4px rgba(22, 29, 59, 0.05);
  --e2:
    0 1px 1px rgba(22, 29, 59, 0.05),
    0 2px 4px rgba(22, 29, 59, 0.05),
    0 6px 12px rgba(22, 29, 59, 0.06);
  --e3:
    0 1px 1px rgba(22, 29, 59, 0.05),
    0 3px 6px rgba(22, 29, 59, 0.06),
    0 10px 20px rgba(22, 29, 59, 0.07),
    0 20px 36px rgba(22, 29, 59, 0.07);
  --e4:
    0 2px 2px rgba(22, 29, 59, 0.05),
    0 6px 10px rgba(22, 29, 59, 0.06),
    0 16px 28px rgba(22, 29, 59, 0.08),
    0 32px 60px rgba(22, 29, 59, 0.10);
  --edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  --edge-dark: inset 0 -1px 0 rgba(22, 29, 59, 0.06);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --e1: 0 1px 2px rgba(0,0,0,.5);
    --e2: 0 1px 2px rgba(0,0,0,.45), 0 4px 10px rgba(0,0,0,.4);
    --e3: 0 1px 2px rgba(0,0,0,.45), 0 6px 14px rgba(0,0,0,.45), 0 16px 30px rgba(0,0,0,.4);
    --e4: 0 2px 4px rgba(0,0,0,.5), 0 10px 20px rgba(0,0,0,.45), 0 28px 56px rgba(0,0,0,.5);
    --edge-light: inset 0 1px 0 rgba(255,255,255,.09);
    --edge-dark: inset 0 -1px 0 rgba(0,0,0,.3);
  }
}
:root[data-theme='dark'] {
  --e1: 0 1px 2px rgba(0,0,0,.5);
  --e2: 0 1px 2px rgba(0,0,0,.45), 0 4px 10px rgba(0,0,0,.4);
  --e3: 0 1px 2px rgba(0,0,0,.45), 0 6px 14px rgba(0,0,0,.45), 0 16px 30px rgba(0,0,0,.4);
  --e4: 0 2px 4px rgba(0,0,0,.5), 0 10px 20px rgba(0,0,0,.45), 0 28px 56px rgba(0,0,0,.5);
  --edge-light: inset 0 1px 0 rgba(255,255,255,.09);
  --edge-dark: inset 0 -1px 0 rgba(0,0,0,.3);
}

.card { box-shadow: var(--edge-light), var(--edge-dark), var(--e2); }
.card--link:hover,
.card--link:focus-within {
  transform: translateY(-5px);
  box-shadow: var(--edge-light), var(--e3);
}
.card--link:active { transform: translateY(-1px); box-shadow: var(--edge-light), var(--e1); }

.stat { box-shadow: var(--edge-light), var(--edge-dark), var(--e2); }
.quote { box-shadow: var(--edge-light), var(--e4); }
.glossy { box-shadow: var(--edge-light), var(--e3); }
.spotlight { box-shadow: var(--e4); }

/* Filled buttons read as extruded: light along the top edge, a darker lip
   underneath, and they physically depress when pressed. */
.btn {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    inset 0 -2px 0 rgba(0, 0, 0, 0.14),
    var(--e2);
  transition: transform 0.14s var(--ease), box-shadow 0.18s var(--ease), background-color 0.18s var(--ease);
}
.btn:hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.34),
    inset 0 -2px 0 rgba(0, 0, 0, 0.14),
    var(--e3);
}
.btn:active {
  transform: translateY(1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -1px 0 rgba(0, 0, 0, 0.12),
    var(--e1);
}
.btn--ghost {
  box-shadow: var(--edge-light), var(--e1);
}
.btn--ghost:hover { box-shadow: var(--edge-light), var(--e2); transform: translateY(-2px); }
.btn--ghost:active { transform: translateY(1px); box-shadow: var(--e1); }
.btn--light { box-shadow: inset 0 1px 0 rgba(255,255,255,.25); }

/* Inputs sit *into* the surface rather than on it. */
.input, .select, .textarea {
  box-shadow: inset 0 1px 2px rgba(22, 29, 59, 0.07);
}
.input:focus, .select:focus, .textarea:focus {
  box-shadow: inset 0 1px 2px rgba(22, 29, 59, 0.05), 0 0 0 4px var(--brand-soft);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .input,
  :root:not([data-theme='light']) .select,
  :root:not([data-theme='light']) .textarea { box-shadow: inset 0 1px 3px rgba(0,0,0,.4); }
}

.chip { box-shadow: var(--edge-light), var(--e1); transition: all .16s var(--ease); }
.chip:active { transform: translateY(1px); box-shadow: none; }
.chip[aria-pressed='true'] {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 -2px 0 rgba(0,0,0,.14), var(--e2);
}

.header { box-shadow: 0 1px 0 var(--border), 0 4px 16px rgba(22, 29, 59, 0.04); }
.dock { box-shadow: 0 -1px 0 var(--border), 0 -8px 28px rgba(22, 29, 59, 0.10); }

/* ==========================================================================
   Mobile dock — WhatsApp · Menu · Get a quote
   The menu moves off the top-right corner and into the thumb zone, which is
   where a one-handed phone user can actually reach it.
   ========================================================================== */
.dock {
  /* Four actions: WhatsApp · Call · Menu · Get a quote. The three compact ones
     size to their content; the primary CTA takes whatever is left, so it stays
     the widest target on the bar at every width. */
  grid-template-columns: auto auto auto minmax(0, 1fr);
  align-items: center;
  /* Above the drawer, so the same button that opened the menu can close it. */
  z-index: 120;
}

/* Compact dock button: icon stacked over a small caps label, matching the
   Menu button beside it so the whole bar reads as one row of controls. */
.btn--dockicon {
  flex-direction: column;
  gap: 3px;
  min-width: 60px;
  min-height: 50px;
  height: 50px;
  padding: var(--sp-2);
  font-size: var(--step--1);
}
.btn--dockicon svg { flex: none; }
.btn__label-sm {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
}
.dock .btn:not(.btn--dockicon) { padding-inline: var(--sp-4); }

/* Phones (≤480px): drop the small caps labels on the two icon buttons so the
   primary CTA keeps a usable width. The aria-label on each anchor still names
   it for a screen reader, and the WhatsApp and handset glyphs are unambiguous.

   This was 360px and that was wrong: at 390px — iPhone 12/13/14, the single most
   common width — the labels reappeared, squeezed "Get a quote" to 102px and
   wrapped it onto two lines. 480px clears every common phone, and above it the
   bar has room for labels and a one-line CTA together. */
@media (max-width: 480px) {
  .btn--dockicon { min-width: 46px; }
  .btn--dockicon .btn__label-sm { display: none; }
  .burger--dock { min-width: 56px; }
}
.burger--dock {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: auto;
  min-width: 74px;
  height: 50px;
  padding-inline: var(--sp-3);
  background: var(--surface);
  box-shadow: var(--edge-light), var(--e1);
}
.burger--dock:active { transform: translateY(1px); box-shadow: none; }
.burger__label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
  line-height: 1;
}
.burger--dock[aria-expanded='true'] {
  background: var(--brand);
  border-color: var(--brand);
}
.burger--dock[aria-expanded='true'] .burger__box span { background: var(--on-brand); }
.burger--dock[aria-expanded='true'] .burger__label { color: var(--on-brand); }

/* With the menu in the dock, the mobile header is just the logo. */
@media (max-width: 999px) {
  .header__bar { justify-content: center; }
  .header__actions { display: none; }
}

/* ==========================================================================
   Auth — sign in / sign up
   A two-column split: the reassurance rail on the left, the form on the right.
   Collapses to form-first on mobile, because someone who came here to log in
   should not have to scroll past a sales pitch to reach the password field.
   ========================================================================== */
.auth {
  position: relative;
  display: flex;
  align-items: center;
  /* Fill the viewport below the header so the card sits optically centred
     rather than stranded above a band of empty page. */
  min-height: calc(100dvh - var(--nav-h));
  padding-block: var(--sp-6) var(--sp-8);
  background:
    radial-gradient(900px 520px at 8% -10%, var(--indigo-100) 0%, transparent 62%),
    radial-gradient(680px 440px at 96% 6%, var(--gold-100) 0%, transparent 60%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .auth {
    background:
      radial-gradient(900px 520px at 8% -10%, #1E2A57 0%, transparent 64%),
      radial-gradient(680px 440px at 96% 6%, #3A2D0C 0%, transparent 62%);
  }
}
:root[data-theme='dark'] .auth {
  background:
    radial-gradient(900px 520px at 8% -10%, #1E2A57 0%, transparent 64%),
    radial-gradient(680px 440px at 96% 6%, #3A2D0C 0%, transparent 62%);
}

.auth__grid { display: flex; flex-direction: column; gap: var(--sp-6); }
.auth__grid > * { min-width: 0; }
@media (min-width: 960px) {
  .auth__grid {
    display: grid;
    grid-template-columns: 1fr minmax(0, 480px);
    gap: var(--sp-8);
    align-items: center;
  }
}

/* Form first on mobile, rail underneath. */
.auth__rail { order: 2; }
.auth__panel { order: 1; }
@media (min-width: 960px) { .auth__rail, .auth__panel { order: 0; } }

.auth__rail h1 { font-size: var(--step-4); margin-bottom: var(--sp-4); }
.auth__rail .lede { max-width: 44ch; }

.auth__points { list-style: none; margin: var(--sp-5) 0 0; padding: 0; display: grid; gap: var(--sp-4); }
.auth__point { display: flex; align-items: flex-start; gap: var(--sp-3); margin: 0; }
.auth__point-icon {
  flex: none; display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: var(--r-md);
  background: var(--surface); border: 1px solid var(--border);
  color: var(--brand-text); box-shadow: var(--edge-light), var(--e1);
}
.auth__point-title { display: block; font-weight: 700; line-height: 1.3; }
.auth__point-desc { display: block; font-size: var(--step--1); color: var(--text-muted); }

/* The form card */
.auth__card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: var(--sp-5);
  box-shadow: var(--edge-light), var(--e4);
}
@media (min-width: 560px) { .auth__card { padding: var(--sp-6); } }
.auth__card h2 { font-size: var(--step-3); text-align: center; margin-bottom: var(--sp-2); }
.auth__card-sub { text-align: center; color: var(--text-muted); margin-bottom: var(--sp-5); }

/* Input with a leading icon and, for passwords, a trailing reveal button. */
.field__wrap { position: relative; display: block; }
.field__icon {
  position: absolute; left: var(--sp-3); top: 50%; transform: translateY(-50%);
  color: var(--text-faint); pointer-events: none;
}
.field__wrap .input { padding-left: calc(var(--sp-3) * 2 + 20px); }
.field__wrap--pw .input { padding-right: calc(var(--sp-3) * 2 + 20px); }
.field__reveal {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 40px; height: 40px;
  background: none; border: 0; border-radius: var(--r-sm);
  color: var(--text-faint); cursor: pointer;
}
.field__reveal:hover { color: var(--text); background: var(--surface-2); }

.auth__row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-5);
}
.auth__check { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--step--1); margin: 0; }
/* `color-scheme: light dark` on :root lets the UA pick the checkbox rendering,
   which drew a pale light-mode box on the dark card. Pinning the scheme to the
   surface it sits on keeps the control legible in both themes. */
.auth__check input {
  width: 18px; height: 18px; flex: none; margin: 0;
  accent-color: var(--brand);
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .auth__check input { color-scheme: dark; }
}
:root[data-theme='dark'] .auth__check input { color-scheme: dark; }

/* "Or continue with" rule */
.auth__sep {
  display: flex; align-items: center; gap: var(--sp-3);
  margin: var(--sp-5) 0; color: var(--text-faint); font-size: var(--step--1);
}
.auth__sep::before, .auth__sep::after { content: ''; flex: 1; height: 1px; background: var(--border); }

.auth__oauth { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2); }
.auth__oauth .btn {
  padding-inline: var(--sp-2); font-size: var(--step--1); gap: var(--sp-2);
  min-height: 46px; box-shadow: var(--edge-light), var(--e1);
}
.auth__oauth .btn svg, .auth__oauth .btn img { flex: none; }
@media (max-width: 420px) {
  .auth__oauth { grid-template-columns: 1fr; }
}

.auth__foot { text-align: center; margin: var(--sp-5) 0 0; font-size: var(--step--1); }
.auth__legal {
  display: flex; align-items: flex-start; justify-content: center; gap: var(--sp-2);
  margin: var(--sp-4) 0 0; font-size: var(--step--1); color: var(--text-muted);
  text-align: center;
}
.auth__legal svg { flex: none; margin-top: 2px; color: var(--text-faint); }

/* Admin sign-in: security posture strip under the rail. Every claim in it must
   be one the platform actually delivers — a sign-in page is the worst place to
   describe a control that does not exist. */
.auth__secure {
  list-style: none; margin: var(--sp-6) 0 0; padding: var(--sp-4);
  display: grid; gap: var(--sp-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--edge-light), var(--e1);
}
/* Stays a single column: the rail is ~460px at desktop, and three columns there
   broke every label onto two lines. Vertical space is what this rail has spare. */
.auth__secure li { display: flex; align-items: flex-start; gap: var(--sp-3); margin: 0; }
.auth__secure svg { flex: none; color: var(--success); margin-top: 2px; }
.auth__secure b { display: block; font-size: var(--step--1); line-height: 1.3; }
.auth__secure span { display: block; font-size: 0.74rem; color: var(--text-muted); line-height: 1.35; }

/* Restricted-access notice above the legal line. */
.auth__restricted {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  margin: var(--sp-5) 0 0; padding: var(--sp-3);
  background: var(--warn-soft); color: var(--warn-text);
  border-radius: var(--r-md); font-size: var(--step--1); font-weight: 700;
  text-align: center;
}
.auth__restricted svg { flex: none; }

/* Drawer account row: Log in / Sign up, side by side, directly under Contact.
   Declared after the tablet two-column rule for .drawer__group so it keeps its
   own 50/50 split at every width — two short labels always fit, even at 360px. */
.drawer__auth {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  align-items: center;
}

/* ==========================================================================
   CMS safety net (1 Oct 2026)
   Copy is now edited from the admin panel, so any text may get longer or
   shorter than the design was drawn with. Text always wraps inside its box:
   a long word or pasted URL breaks instead of pushing the layout sideways,
   and short labels that normally sit on one line may wrap rather than spill.
   ========================================================================== */
h1, h2, h3, h4, h5, h6, p, li, dt, dd, th, td, caption, figcaption, summary,
blockquote, label, legend, .btn, .badge, .save-badge, .eyebrow, .lede {
  overflow-wrap: break-word;
}
.btn, .badge, .save-badge { max-width: 100%; }
.save-badge { white-space: normal; }
.btn > span, .badge > span { min-width: 0; }
