/* ============================================================================
   jonathanrewers.com — v2 Design Tokens
   UI / Visual Design Lead — ground-up redesign
   ----------------------------------------------------------------------------
   Settled rules carried forward (THEO-HANDOFF.md, do not relitigate):
   · White site: white + cool light greys, slate ink.
   · ONE accent: Danish Ramp blue #0090CC.
   · Cyber #00C2FF is dark-backgrounds ONLY — it does not appear in this file
     for any light-surface token, and must never be used on white.
   · Danish sensibility: simple, unframed, generous white space.
   · No caption on the hero portrait. Ever.
   · Type pairing kept from v1: Fraunces (display) + Plus Jakarta Sans (UI/body).

   What v2 changes: a graded blue-grey palette (blues AND greys, plural,
   in measured steps — still restrained), photographic project tiles treated
   as one family by a single image grade (see photographic-grade.md), and a
   teaching / interactive-product feel built from hairlines, numbered kickers
   and file rows — not from boxes, fills or extra colours.
   ============================================================================ */

:root {
  /* ------------------------------------------------------------------------
     1. COLOUR — PAPER & COOL GREYS
     The working surface scale. Grey steps are blue-shifted (slate family)
     so backgrounds, hairlines and ink read as one cool system. Warm paper
     (#FAF8F4 / #F1EDE4 / #E3DED2 from v1) is retired — it fought the photos.
     ------------------------------------------------------------------------ */
  --paper:            #FFFFFF;  /* primary surface; hero ground */
  --paper-raised:     #FFFFFF;  /* tiles / panels on a grey band */
  --grey-50:          #F7F9FB;  /* faintest band; skeleton base */
  --grey-100:         #F2F5F8;  /* section band (replaces v1 .section-tint) */
  --grey-150:         #EDF1F5;  /* stats band, ICS band ground, footer ground */
  --grey-200:         #E2E8F0;  /* hairline on white; tile border */
  --grey-250:         #D6DEE7;  /* stronger hairline; scrubber track */
  --grey-300:         #CBD5E1;  /* chip border; disabled border */
  --grey-400:         #94A3B8;  /* decorative only — never text on white */
  --grey-500:         #7C8DA6;  /* credential strip (large/caps, non-essential) */

  /* ------------------------------------------------------------------------
     2. COLOUR — SLATE INK (text)
     Contrast on --paper, verified targets:
       ink-900 ≈ 17.9:1 · ink-700 ≈ 12.6:1 · ink-500 ≈ 7.5:1 · ink-400 ≈ 4.8:1
     ink-400 is the floor for any text. ink-300 / grey-400 are decoration only.
     ------------------------------------------------------------------------ */
  --ink-900:          #0F172A;  /* headings, tile titles, primary text alt */
  --ink-800:          #16233A;  /* body emphasis */
  --ink-700:          #1E293B;  /* body text (preferred over pure 900 for runs) */
  --ink-600:          #334155;  /* secondary body, study-panel prose */
  --ink-500:          #475569;  /* sub-heads, meta, captions, ledes */
  --ink-400:          #64748B;  /* years, file sizes, smallest legible meta */
  --ink-300:          #94A3B8;  /* NON-TEXT ONLY: icons at large size, rules */
  --ink:              var(--ink-900);   /* legacy alias for builders */
  --muted:            var(--ink-500);   /* legacy alias for builders */

  /* ------------------------------------------------------------------------
     3. COLOUR — BLUE (graded, Ramp-anchored)
     Ramp #0090CC is THE accent: edges, kickers, numerals, active states,
     hero emphasis word. It is ~3.3:1 on white — a graphic/UI accent and
     large display colour ONLY, never body text or text links.
     ------------------------------------------------------------------------ */
  --blue-50:          #EAF6FB;  /* active chip wash; selected tile wash */
  --blue-100:         #D3EDF8;  /* hover wash on file rows; focus halo base */
  --blue-200:         #A6D8EF;  /* scrubber fill (non-text), chart accents */
  --blue-300:         #5EB6DE;  /* large graphic accents on white only */
  --blue-400:         #26A3D6;  /* large graphic accents on white only */
  --blue-500-ramp:    #0090CC;  /* ★ RAMP — the one accent */
  --blue-600-link:    #00799E;  /* ★ text links on light bg (≈4.9:1, AA) */
  --blue-700:         #00607F;  /* link hover/active on light bg (≈6.9:1) */
  --blue-800:         #0B3B54;  /* small blue headings on grey-50/100 if needed */
  --blue-900-navy:    #0B1D33;  /* ★ deep navy — SPARINGLY: footer rule, modal
                                   scrim tint base, study-panel header rule.
                                   Not a section background in v2. */

  --accent:           var(--blue-500-ramp);
  --link:             var(--blue-600-link);
  --link-hover:       var(--blue-700);
  --link-visited:     var(--blue-600-link); /* no purple; visited = same + underline stays */

  /* Dark-surface note (only place Cyber may exist):
     --on-dark-accent: #00C2FF is permitted ONLY on --blue-900-navy or darker
     photographic scrims. It is intentionally NOT defined as a token here so
     it cannot be picked up by accident on a light component. If a dark
     component is ever built, define it locally inside that component. */

  /* ------------------------------------------------------------------------
     4. COLOUR — SEMANTIC (kept inside the blue-grey family; no rainbow)
     ------------------------------------------------------------------------ */
  --focus-ring:       #00799E;  /* see §10 */
  --selected:         var(--blue-500-ramp);
  --success:          #1F7A5C;  /* form confirmation only; never decorative */
  --warning:          #9A6A00;  /* form only */
  --error:            #B42318;  /* form only */
  --scrim:            rgba(11, 29, 51, 0.64);  /* modal/sheet, from navy */
  --overlay-photo:    rgba(11, 29, 51, 0.08); /* grade overlay, see §11 */

  /* ------------------------------------------------------------------------
     5. TYPE — FAMILIES
     ------------------------------------------------------------------------ */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-sans:    "Plus Jakarta Sans", "Helvetica Neue", Arial, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
                  /* file sizes, page counts, timeline years only */

  /* ------------------------------------------------------------------------
     6. TYPE — SCALE (1.25 ratio, fluid display; px equivalents at 16px root)
     Body is 17px — portfolio-plus-teaching product, read at arm's length.
     ------------------------------------------------------------------------ */
  --text-2xs:  0.6875rem;  /* 11px — category labels, PDF marks */
  --text-xs:   0.75rem;    /* 12px — kickers, chip labels (caps, tracked) */
  --text-sm:   0.875rem;   /* 14px — meta, file rows, captions */
  --text-base: 1.0625rem;  /* 17px — body */
  --text-md:   1.1875rem;  /* 19px — ledes, study-panel prose */
  --text-lg:   1.375rem;   /* 22px — tile titles (Fraunces), pull-quotes min */
  --text-xl:   1.75rem;    /* 28px — panel H, book titles */
  --text-2xl:  2.25rem;    /* 36px — section H2 floor */
  --display-2: clamp(2rem, 1.55rem + 2.2vw, 2.875rem);       /* 32→46px H2 */
  --display-1: clamp(2.625rem, 1.9rem + 3.4vw, 4.25rem);     /* 42→68px hero H1 */
  --stat-num:  clamp(2.125rem, 1.6rem + 2.4vw, 3.25rem);     /* 34→52px stats */

  --leading-tight:   1.06;  /* hero H1 */
  --leading-display: 1.15;  /* H2, tile titles */
  --leading-snug:    1.4;   /* pull-quotes, ledes */
  --leading-body:    1.65;  /* body runs — do not go below 1.55 */

  --weight-light: 300; --weight-regular: 400; --weight-medium: 500;
  --weight-semibold: 600; --weight-bold: 700; --weight-extrabold: 800;

  --tracking-kicker: 0.22em;  /* numbered kickers, eyebrows (caps) */
  --tracking-label:  0.14em;  /* category labels, file-row labels */
  --tracking-caps:   0.04em;  /* nav links */
  --tracking-display: -0.015em; /* Fraunces at display sizes */

  /* ------------------------------------------------------------------------
     7. SPACING — 4pt base, editorial jumps (white space is the luxury)
     ------------------------------------------------------------------------ */
  --space-0: 0;       --space-1: 0.25rem;   /* 4 */
  --space-2: 0.5rem;  --space-3: 0.75rem;   /* 8 / 12 */
  --space-4: 1rem;    --space-5: 1.25rem;   /* 16 / 20 */
  --space-6: 1.5rem;  --space-8: 2rem;      /* 24 / 32 */
  --space-10: 2.5rem; --space-12: 3rem;     /* 40 / 48 */
  --space-16: 4rem;   --space-20: 5rem;     /* 64 / 80 */
  --space-24: 6.5rem; --space-32: 8.5rem;   /* 104 / 136 — section rhythm */

  --section-pad-y:    clamp(4.5rem, 10vw, 7.5rem);  /* replaces fixed 110px */
  --page-gutter:      4vw;
  --wrap-max:         1120px;  /* reading / content column (kept from v1) */
  --wrap-wide:        1280px;  /* tile grid, timeline — wider than reading col */
  --prose-max:        44em;    /* ledes & study-panel prose measure */

  /* ------------------------------------------------------------------------
     8. RADII — DANISH: MINIMAL
     v1's 10–22px cards, 999px role pills and round flip-book are retired.
     Sharp is the design. Pills survive ONLY where the shape is the affordance
     (filter chips, scrubber thumb) — never as decoration.
     ------------------------------------------------------------------------ */
  --radius-0: 0;          /* tiles, images, panels, section art — DEFAULT */
  --radius-sm: 2px;       /* inputs, file rows on hover wash */
  --radius-md: 4px;       /* buttons, academia cards if a border is unavoidable */
  --radius-pill: 999px;   /* filter chips + scrubber thumb ONLY */
  --radius-circle: 50%;   /* timeline nodes, avatar dots ONLY */

  /* ------------------------------------------------------------------------
     9. SHADOWS — BARELY THERE (light comes from hairlines, not elevation)
     No shadow at rest for tiles/cards. Shadow appears only on lift (hover),
     floating layers (modal/sheet) and the hero portrait's contact shadow.
     ------------------------------------------------------------------------ */
  --shadow-none: none;
  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-lift: 0 12px 28px -12px rgba(15, 23, 42, 0.18),
                 0 2px 6px rgba(15, 23, 42, 0.06);       /* tile hover */
  --shadow-panel: 0 20px 44px -18px rgba(11, 29, 51, 0.22); /* study panel open */
  --shadow-modal: 0 32px 80px -16px rgba(11, 29, 51, 0.38);
  --shadow-portrait: 0 24px 48px -20px rgba(15, 23, 42, 0.16);
                     /* only if portrait is ever inset; full-bleed hero = none */

  --border-hairline: 1px solid var(--grey-200);
  --border-strong:   1px solid var(--grey-300);
  --border-accent-top: 2px solid var(--blue-500-ramp); /* tile hover edge, see spec */

  /* ------------------------------------------------------------------------
     10. FOCUS — ONE SPEC, EVERYWHERE (WCAG 2.4.13 ambition)
     :focus-visible = 2px solid --focus-ring, offset 3px, PLUS a 5px soft
     halo so the ring survives on grey bands and on photographic covers.
     Never remove the outline without this replacement. Never Ramp alone
     (3.3:1) — the ring colour is link blue #00799E (≈4.9:1 on white,
     ≥3:1 against every grey band and against the graded photo overlay).
     ------------------------------------------------------------------------ */
  --focus-outline: 2px solid var(--focus-ring);
  --focus-offset: 3px;
  --focus-halo: 0 0 0 5px rgba(0, 121, 158, 0.18);

  /* ------------------------------------------------------------------------
     11. PHOTOGRAPHIC TILES & IMAGE GRADE (see photographic-grade.md)
     The CSS half is deliberately weak — the grade is baked at export.
     CSS only unifies the last 5%: a whisper of desaturation + contrast so
     a late-swapped image still sits in the family. Do NOT stack heavy
     filters here to "fix" ungraded source photos.
     ------------------------------------------------------------------------ */
  --tile-aspect: 4 / 3;           /* all project tiles, no exceptions */
  --tile-aspect-wide: 16 / 10;    /* featured / first tile at ≥1024px only */
  --acad-aspect: 3 / 2;
  --portrait-aspect: 4 / 5;       /* academia / story imagery if used */

  --img-grade-filter: saturate(0.88) contrast(1.04) brightness(1.02);
  --img-grade-filter-hover: saturate(0.96) contrast(1.04) brightness(1.02);
                      /* hover returns ~half the colour — "the work wakes up",
                         it does not zoom-crop or rainbow */
  --img-grade-overlay: linear-gradient(180deg,
                         rgba(0, 144, 204, 0.05) 0%,
                         rgba(11, 29, 51, 0.07) 100%);
                      /* applied on a ::after at mix-blend-mode: normal,
                         pointer-events:none — cools shadows toward navy */
  --img-skeleton: linear-gradient(100deg,
                    var(--grey-100) 40%, var(--grey-150) 50%, var(--grey-100) 60%);

  /* ------------------------------------------------------------------------
     12. MOTION — CALM, PRODUCT-LIKE (nothing bounces, nothing bobs)
     v1's bobbing scroll arrow and 0.8s reveals are retired.
     ------------------------------------------------------------------------ */
  --duration-instant: 80ms;   /* chip press, checkbox */
  --duration-fast: 160ms;     /* hover lifts, link underlines, tile edge */
  --duration-med: 260ms;      /* panel expand, filter re-flow */
  --duration-slow: 420ms;     /* modal/sheet entry, hero load settle */
  --ease-out: cubic-bezier(0.2, 0, 0, 1);        /* default — enter / lift */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);    /* scrubber, panel height */
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);        /* dismiss only */
  --lift-y: -4px;             /* tile hover translate — never more */
  --reveal-y: 14px;           /* scroll reveal distance — never more */

  /* ------------------------------------------------------------------------
     13. LAYOUT / BREAKPOINTS (reference values)
     CSS custom properties cannot drive @media — these tokens are the single
     source of truth to copy into media queries and JS matchMedia checks:
       --bp-sm: 620px   1-col tiles / books
       --bp-md: 760px   (legacy token; nav collapses at 900px — see base.css)
       --bp-lg: 960px   3-col → 2-col tiles; hero stacks
       --bp-xl: 1200px  wide wrap engages
     ------------------------------------------------------------------------ */
  --bp-sm: 620px; --bp-md: 760px; --bp-lg: 960px; --bp-xl: 1200px;

  --nav-h: 68px;          /* 56px scrolled */
  --nav-h-scrolled: 56px;
  --tap-min: 44px;        /* every interactive target ≥44×44px */
  --z-nav: 100; --z-progress: 200; --z-sheet: 300; --z-modal: 320;
}

/* ---- Focus spec — implement verbatim ------------------------------------ */
:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  box-shadow: var(--focus-halo);
}
/* On photographic covers the halo alone can vanish into a busy photo:
   tiles therefore also draw the ring as an inset border on :focus-visible. */
.tile:focus-visible { box-shadow: inset 0 0 0 2px var(--paper),
                                inset 0 0 0 4px var(--focus-ring); }

/* ---- Graded image — implement verbatim ----------------------------------- */
.img-graded { filter: var(--img-grade-filter); }
.tile:hover .img-graded,
.tile:focus-visible .img-graded { filter: var(--img-grade-filter-hover); }

/* ---- Reduced motion — non-negotiable ------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms; --duration-med: 0ms; --duration-slow: 0ms;
    --lift-y: 0px; --reveal-y: 0px;
  }
  html { scroll-behavior: auto; }
}
