/* ═══════════════════════════════════════════════════════════
   SKIPPER SITE
   Shared by index.html, join.html and welcome.html.

   It exists because the three pages had drifted into three different
   visual languages: the marketing page, the "find my program" page and
   the post-signup setup wizard each carried their own copy of the
   colours, the type scale and the buttons. Anyone clicking through hit
   a seam. One file, one set of tokens, no drift.

   Page-specific rules stay in a <style> block on the page that needs
   them. Nothing that only one page uses belongs here.
   ═══════════════════════════════════════════════════════════ */

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

/* ── TOKENS ──
   Dark is the brand default. Light is the same token names redefined under
   :root[data-theme="light"] — js/theme.js resolves "follow my device" in
   <head> and always stamps a concrete value, so there is exactly ONE light
   palette here and no prefers-color-scheme copy to keep in step by hand.
   (That drift is what app.css had grown before the app's theme control
   landed, and it had to be unpicked.)

   Anything a rule below needs in a theme-dependent colour has to be a token.
   A literal rgba(0,0,0,.9) shadow reads as depth on black and as a bruise on
   white, which is how a "light mode" ships looking broken while every colour
   in it is technically correct. */
:root{
  /* Brand accent. The SAME gold in both themes — a brand colour that changes
     with the theme is not a brand colour. --gold-text is the readable
     derivative for gold set as text or as a meaningful icon: #F5A623 on white
     is 1.9:1, so under light the eyebrows, the funding section's statement and
     every check mark in the pricing table would have been decoration nobody
     could read.
     Same move as --accent-text in the app's tokens.css. */
  --gold:#F5A623;--gold-2:#FFC15E;--gold-text:#F5A623;
  --on-gold:#000;
  --gold-dim:rgba(245,166,35,.12);--gold-line:rgba(245,166,35,.28);
  --gold-wash:rgba(245,166,35,.07);--gold-glow:rgba(245,166,35,.14);

  --bg:#08080A;--s1:#111113;--s2:#17171B;--s3:#1E1E23;
  --border:#222226;--border-2:#2E2E34;
  /* --border-2 is a DIVIDER. --control-border is the edge of a thing you can
     press, and it is a different token because WCAG 1.4.11 wants 3:1 for it:
     on a ghost button or a text input the border IS the control, and
     #2E2E34 on #08080A is 1.5:1 — the same reading that put Present mode's
     controls under the bar. Do not collapse the two back together. */
  --control-border:#6A6A73;

  --text-1:#fff;--text-2:#B8B8C0;--gray:#8A8A93;
  /* Placeholders and the copyright line. Was #3a3a40, which is 1.8:1 on the
     page background — invisible, and a pre-existing AA failure in the dark
     theme that only got measured when the light one forced a contrast pass. */
  --gray-3:#82828C;

  --green:#22C55E;--red:#EF4444;

  --scrim:rgba(0,0,0,.85);
  --shadow-shot:0 40px 80px -30px rgba(0,0,0,.9);
  --shadow-shot-sm:0 30px 60px -30px rgba(0,0,0,.85);
  --noise-opacity:.3;
  --select-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238A8A93' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  --r:14px;
  --measure:62ch;
  --ease:cubic-bezier(.2,.8,.3,1);

  color-scheme:dark;
}

:root[data-theme="light"]{
  /* Gold, dark enough to read as text. The first pass at this was #986716 —
     4.9:1 on white, which looked fine and then failed at 4.38:1 the moment the
     audit drove the pages into their real states: gold set on a GOLD-TINTED
     surface (an active sport button) and on --s2 (the subdomain box) has less
     to work with than gold on white. Sample the worst surface a token lands
     on, not the page background. */
  --gold-text:#8E6014;
  --gold-dim:rgba(245,166,35,.16);--gold-line:rgba(245,166,35,.55);
  --gold-wash:rgba(245,166,35,.16);--gold-glow:rgba(245,166,35,.2);

  --bg:#F7F7F5;--s1:#FFFFFF;--s2:#F1F1EE;--s3:#E7E7E3;
  --border:#E3E3DE;--border-2:#C9C9C3;
  /* Same lesson as --gold-text: #8C8C94 cleared 3:1 against the page and the
     card and then came in at 2.95:1 on --s2, which is where the wizard's Copy
     button actually sits. Measured against the darkest surface a control lands
     on, not the lightest. */
  --control-border:#85858C;

  --text-1:#17171A;--text-2:#4E4E57;--gray:#5A5A62;--gray-3:#6C6C74;

  --green:#157A3D;--red:#C81E1E;

  --scrim:rgba(20,20,22,.5);
  --shadow-shot:0 30px 60px -28px rgba(20,20,22,.3);
  --shadow-shot-sm:0 22px 44px -26px rgba(20,20,22,.26);
  /* The grain is a dark speckle either way, so on a light ground it needs
     more of itself to read as the same texture. */
  --noise-opacity:.5;
  --select-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235A5A62' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  color-scheme:light;
}

/* Compatibility alias. `--white` was the name for the primary text colour, and
   under light it is near-black, so the name lies — every rule here and in the
   three pages now says --text-1 instead. NOTHING references --white today.
   It stays because an undefined custom property does not error, it resolves to
   nothing: a rule copied forward out of git history would set no colour at all
   and inherit one that happens to look fine, which is the silent kind of
   wrong. Delete it when that stops being a plausible way to touch this file. */
:root{--white:var(--text-1)}

html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--text-1);font-family:'DM Sans',sans-serif;line-height:1.55;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
::selection{background:var(--gold);color:var(--on-gold)}
:focus-visible{outline:2px solid var(--gold-text);outline-offset:3px;border-radius:4px}

.wrap{max-width:1140px;margin:0 auto;padding:0 clamp(18px,5vw,24px)}
/* The nav is fixed, so an anchor jump lands with the heading underneath it.
   Every in-page target has to clear it, on the phone most of all — the whole
   nav menu is anchor links. */
section[id]{scroll-margin-top:76px}
.display{font-family:'Bebas Neue',sans-serif;letter-spacing:1px;line-height:.92;font-weight:400}

/* Type scale. Clamp everywhere so nothing needs a mobile override. */
h1.display{font-size:clamp(38px,5.2vw,66px)}
h2.display{font-size:clamp(32px,4.6vw,56px)}
h3.display{font-size:clamp(24px,3vw,34px)}
.lede{font-size:clamp(16px,1.5vw,19px);color:var(--text-2);max-width:var(--measure)}
.small{font-size:14px;color:var(--gray)}

/* One quiet texture, not a glow behind every section. */
body::before{content:'';position:fixed;inset:0;z-index:0;pointer-events:none;opacity:var(--noise-opacity);
  background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E")}
main,nav,footer{position:relative;z-index:1}

/* ── NAV ──
   Two groups. `.nav-menu` collapses behind the toggle on a phone; `.nav-actions`
   is what stays on screen at every width. The links used to be `display:none`
   below 720px with nothing to open them, so on a phone — where most of this
   site is read — Pricing and "Find my program" were simply unreachable. */
nav{position:fixed;top:0;left:0;right:0;z-index:100;display:flex;align-items:center;justify-content:space-between;
  padding:14px 28px;background:color-mix(in srgb,var(--bg) 80%,transparent);backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;transition:border-color .2s,padding .2s;gap:10px}
nav.scrolled{border-bottom-color:var(--border);padding:10px 28px}
.nav-logo img{height:32px;width:auto}
.nav-menu,.nav-actions{display:flex;align-items:center;gap:6px}
.nav-menu{margin-left:auto}
.nav-link{font-size:14.5px;font-weight:500;color:var(--text-2);padding:9px 13px;border-radius:8px;transition:color .15s}
.nav-link:hover{color:var(--text-1)}
.btn-nav{font-size:14.5px;font-weight:600;padding:9px 18px;border-radius:9px;cursor:pointer;border:1px solid transparent;
  display:inline-block;white-space:nowrap;transition:border-color .15s,background .15s,color .15s}
.btn-outline-nav{border-color:var(--control-border);color:var(--text-1)}
.btn-outline-nav:hover{border-color:var(--gold-text)}
.btn-gold-nav{background:var(--gold);color:var(--on-gold)}
.btn-gold-nav:hover{background:var(--gold-2)}
.nav-toggle{display:none;align-items:center;justify-content:center;width:42px;height:42px;flex-shrink:0;
  background:transparent;border:1px solid var(--control-border);border-radius:10px;color:var(--text-1);cursor:pointer}
.nav-toggle .x{display:none}
nav.open .nav-toggle .x{display:block}
nav.open .nav-toggle .bars{display:none}
@media(max-width:720px){
  nav{padding:10px 16px}
  nav.scrolled{padding:8px 16px}
  .nav-logo img{height:28px}
  .nav-toggle{display:flex}
  /* The panel drops out of the nav bar itself, so it cannot be scrolled past
     while it is open and it never covers the whole screen. */
  .nav-menu{position:absolute;top:100%;left:0;right:0;margin:0;display:none;flex-direction:column;
    align-items:stretch;gap:2px;padding:10px 16px 16px;background:var(--bg);border-bottom:1px solid var(--border)}
  nav.open .nav-menu{display:flex}
  .nav-menu .nav-link{padding:13px 4px;font-size:16px;color:var(--text-1);border-bottom:1px solid var(--border)}
  .nav-menu .nav-link:last-of-type{border-bottom:0}
  .nav-menu .btn-nav{margin-top:10px;text-align:center;padding:13px 18px;font-size:15.5px}
}

/* ── THEME CONTROL ──
   One button cycling system → light → dark, sitting in `.nav-actions` so it
   is on screen at every width rather than behind the phone menu. Three
   states, not a switch: a two-state toggle makes "follow my device" —
   the state every visitor starts in — unreachable the moment it is pressed
   once.

   The icon is driven off `data-theme-choice`, which js/theme.js stamps in
   <head> next to `data-theme`. So the button shows the right face on the
   first frame, and it shows what was CHOSEN (a monitor for "system"), not
   what that resolved to — a moon on a page whose owner picked "follow my
   device" would be answering a different question. */
.theme-toggle{display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;flex-shrink:0;
  background:transparent;border:1px solid var(--control-border);border-radius:10px;color:var(--text-1);
  cursor:pointer;transition:border-color .15s,color .15s}
.theme-toggle:hover{border-color:var(--gold-text)}
.theme-toggle svg{display:none}
:root[data-theme-choice="system"] .theme-toggle .ic-system,
:root[data-theme-choice="light"] .theme-toggle .ic-light,
:root[data-theme-choice="dark"] .theme-toggle .ic-dark{display:block}
/* No stamped choice at all (js/theme.js blocked or failed): show something
   rather than an empty square. */
:root:not([data-theme-choice]) .theme-toggle .ic-system{display:block}

/* Announced-only text. The button's accessible name changes as it cycles and
   a changed label on an already-focused control is not announced by itself. */
.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}

/* ── BUTTONS ── */
.btn-primary,.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-size:16px;font-weight:600;padding:15px 28px;border-radius:11px;cursor:pointer;border:1px solid transparent;
  transition:background .16s var(--ease),border-color .16s,transform .12s var(--ease)}
.btn-primary{background:var(--gold);color:var(--on-gold)}
.btn-primary:hover{background:var(--gold-2)}
.btn-primary:active,.btn-ghost:active{transform:translateY(1px)}
.btn-ghost{border-color:var(--control-border);color:var(--text-1);background:transparent}
.btn-ghost:hover{border-color:var(--gold-text)}

/* ── SECTION RHYTHM ──
   Deliberately NOT one repeating shape. Sections alternate between a full-bleed
   statement, an asymmetric two-column row, and a dense typographic list, because
   four identical card grids in a row is the thing that reads as generated. */
section{padding:clamp(56px,10vw,132px) 0;position:relative}
.rule{height:1px;background:linear-gradient(90deg,transparent,var(--border-2),transparent)}

/* ── MOTION ──
   Elements that Motion will animate start hidden. If the script fails to load
   for any reason the page must still be readable, so .no-motion (set by the
   script's own failure path, and by the reduced-motion check) puts them back. */
[data-anim]{opacity:0}
.no-motion [data-anim]{opacity:1!important;transform:none!important}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  [data-anim]{opacity:1!important;transform:none!important}
}

/* ── FORM PRIMITIVES ──
   join.html and welcome.html both collect input. They had separate,
   slightly different versions of all of this; these are the shared ones. */
.field{margin-bottom:16px}
.field label{display:block;font-size:11.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--gray);margin-bottom:8px}
/* 16px, not 15: iOS Safari zooms the page in on focus for anything smaller,
   and it does not zoom back out. */
.input{width:100%;padding:13px 14px;background:var(--s2);border:1px solid var(--control-border);border-radius:10px;
  color:var(--text-1);font-size:16px;font-family:inherit;transition:border-color .15s}
.input::placeholder{color:var(--gray-3)}
.input:focus{outline:none;border-color:var(--gold-text)}
select.input{appearance:none;cursor:pointer;background-image:var(--select-chevron);
  background-repeat:no-repeat;background-position:right 12px center;padding-right:38px}
.err{font-size:13.5px;color:var(--red);margin-top:10px;display:none}
.err.show{display:block}
.hint{font-size:12.5px;color:var(--gray);margin-top:7px;line-height:1.5}

/* A page that is a single centred card: join's request form, welcome's wizard. */
.page-narrow{max-width:560px;margin:0 auto;padding:0 20px}
.card{background:var(--s1);border:1px solid var(--border);border-radius:18px;padding:clamp(24px,4vw,38px)}
.card-eyebrow{font-size:11.5px;font-weight:700;letter-spacing:2.2px;text-transform:uppercase;
  color:var(--gold-text);margin-bottom:12px}
.card-title{font-family:'Bebas Neue',sans-serif;font-size:clamp(28px,4vw,38px);letter-spacing:1px;
  line-height:1;margin-bottom:10px}
.card-sub{font-size:14.5px;color:var(--text-2);line-height:1.6;margin-bottom:26px}

/* Full-width action button inside a card. */
.btn-block{width:100%;padding:15px;border-radius:11px;font-size:16px;font-weight:600;cursor:pointer;
  font-family:inherit;border:1px solid transparent;background:var(--gold);color:var(--on-gold);
  transition:background .15s,opacity .15s}
.btn-block:hover:not(:disabled){background:var(--gold-2)}
.btn-block:disabled{opacity:.6;cursor:not-allowed}
.btn-block.ghost{background:transparent;border-color:var(--control-border);color:var(--text-1)}
.btn-block.ghost:hover:not(:disabled){border-color:var(--gold-text)}

/* Success state shared by both flows. */
.done{text-align:center}
.done-mark{color:var(--green);display:block;margin:0 auto 18px;width:52px;height:52px}
