/*
 * DESIGN TOKENS: Mike the Media Buyer (Michael O'Brien), operator-portfolio
 * Status: LOCKED 2026-10-10
 *
 * Source: owner 2B decision "i like all." (concepts/approved-concept.md). One HTML structure,
 * one copy set, three skins switched by data-skin on <html>:
 *   v1 "Signal Room"  <- concepts/visual-1.html
 *   v2 "The Ledger"   <- concepts/visual-2.html
 *   v3 "Stack"        <- concepts/visual-3.html
 * At ship the chosen skin's block is the only skin left; the other two blocks, their font
 * links and the preview toggle are deleted.
 *
 * Rule: the build's :root is THIS file verbatim. Every spacing, font-size, radius, shadow and
 * color in page CSS references a token here (or a calc() of one). A needed value that is not
 * here gets ADDED here with a one-line justification comment, never inlined.
 * craft-detector.js runs with --tokens pointing at this file.
 *
 * Band remaps: a section painted with another band (dark, tint, orange) re-maps roles in ITS
 * selector, e.g. [data-skin="v3"] .s-proof { --color-bg: var(--color-dark-section); --color-ink:
 * var(--color-dark-ink); --color-cta: var(--color-cta-on-dark); ... }. Custom properties resolve
 * where they are declared, so a token built from another token (--color-border, --shadow-cta,
 * --shadow-raised) must be re-declared in that same rule too, or it keeps the :root value.
 *
 * Normalized (mockup -> tokens):
 *  - Spacing: ~25 ad-hoc px values across the three mockups (2, 6, 7, 9, 10, 11, 14, 18, 22, 26,
 *    30, 36, 44, 72, 88 ...) -> one 4px-based scale (--space-1..10). Section rhythm keeps each
 *    mockup's own clamp (v1/v2 share one; v3 overrides).
 *  - Radii: v1 had 6/7/8/9/10/12/16/18 -> 10 + 16. v2 had 4/8 -> kept 4 + 8 (frames stay square).
 *    v3 had 2/5/6/10/12/16/20/24 -> 10 + 24 (hero 2x2 cells 16 -> 24; shots and fact chips
 *    12 -> 10). Circles (status dots, pips, lightbox close disc) are shapes, not radius language.
 *  - Shadows: v1 CTA hover glow variant dropped (hover = lift + lighter fill, same recipe).
 *    v1 focus ring moved from box-shadow to outline. v3 nav-CTA 3px offset -> the 5px recipe.
 *  - Type: mockup vw-only middles (5.4vw, 9.4vw ...) rewritten as rem + vw so text still scales
 *    with browser zoom (WCAG 1.4.4). Mono/label sizes 10.5-12.5px -> 13px floor.
 *
 * Corrected (mockup value failed a rule):
 *  - H1 display sizes: the mockups set a 4-word H1. The locked H1 is 14 words. Mockup sizes would
 *    wrap to 5-7 lines (hard cap is 4). The H1 is now two-tier in ONE <h1>: .h1-a "Full-stack
 *    growth marketing" at the display size, .h1-b "for brands doing six figures to close to $1B a
 *    year." at --text-display-sub. Display ceilings lowered (v1 4.9 -> 4rem, v2 9.25 -> 8rem,
 *    v3 7.25 -> 6.5rem) and floors lowered so .h1-a holds 2 lines at 375 and the total stays <= 4.
 *    v1's max-width:13ch is removed.
 *  - v1 --ink-faint rgba(237,235,229,.38) = 3.15:1 on #0A0C0F. Fails AA as text (it carried labels,
 *    indexes and caption keys). Text now uses --color-subtle at .55 = 5.44:1; .38 survives only as
 *    --color-decor for non-text (rails, inactive node strokes).
 *  - v2 --ink-55 rgba(23,20,15,.58) = 4.28:1 on #F3EEE4 (4.14 on paper-2). Fails AA (it carried
 *    dates and captions). Now --color-subtle at .65 = 5.40 / 5.19:1.
 *
 * WCAG AA check (computed, alpha composited onto the actual surface):
 *  v1  body ink #EDEBE5 on #0A0C0F 16.43 | on surface #111419 15.48 | muted .66 7.40 | subtle .55 5.44
 *      CTA label #0A0C0F on #C8FF2E 16.60 (highest ratio on the page) | fill vs bg luminance delta .84
 *  v2  body ink #17140F on #F3EEE4 15.88 | on paper-2 14.39 | muted .72 6.82 | subtle .65 5.40
 *      CTA label #FBF8F2 on #A3290F 6.88 (AA pass) | fill vs paper 6.30, delta .76. The only solid
 *      saturated fill on the page = highest-salience element. Ink body text has the higher raw
 *      ratio; the CTA wins on chroma + fill, not on text ratio. Brick text on paper 6.30 (links,
 *      numerals, "Does not show"). NEVER brick on ink (2.52) and NEVER the brick CTA on a dark band
 *      (fill delta .09 < .15): v2 has no CTA on a dark band by design.
 *  v3  body ink #111111 on #FFFFFF 18.88 | on surface #F7F7F7 17.63 | muted .70 7.11
 *      CTA (panel round 1): label #111111 on #FF5A1F 6.06 + the ink offset block; hover #FF7A47 7.31.
 *      On the orange band the CTA is ink with a #FFFFFF label (18.88) and a white offset block.
 *      Orange #FF5A1F on white = 3.12: AA-LARGE ONLY (>= 24px, or >= 18.66px bold). Never body
 *      text, never white-on-orange (3.12). Ink on orange 6.06 (orange band copy uses full ink;
 *      muted ink on orange = 3.92, banned). On the dark band the CTA flips to a white fill.
 *
 * FONT LINKS (preview loads all three; ship keeps only the chosen skin's link)
 *  v1  <link rel="preconnect" href="https://fonts.googleapis.com">
 *      <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
 *      <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
 *  v2  <link rel="preconnect" href="https://api.fontshare.com">
 *      <link rel="preconnect" href="https://cdn.fontshare.com" crossorigin>
 *      <link href="https://api.fontshare.com/v2/css?f[]=zodiak@400,700&display=swap" rel="stylesheet">
 *      <link href="https://api.fontshare.com/v2/css?f[]=switzer@400,500,600&display=swap" rel="stylesheet">
 *  v3  <link rel="preconnect" href="https://api.fontshare.com">
 *      <link rel="preconnect" href="https://cdn.fontshare.com" crossorigin>
 *      <link href="https://api.fontshare.com/v2/css?f[]=cabinet-grotesk@500,700,800&display=swap" rel="stylesheet">
 *      <link href="https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700&display=swap" rel="stylesheet">
 *      CORRECTED at QA (2026-10-11): one link per family. A merged f[]=a&f[]=b request returns
 *      only the FIRST family from the Fontshare API, so Switzer (v2 body) and Satoshi (v3 body)
 *      silently fell back to system fonts. Woff2 files are served from cdn.fontshare.com.
 */

/* =====================================================================================
   SHARED BASE (all skins)
   ===================================================================================== */
:root {
  /* ---- Spacing scale: one scale, every margin / padding / gap on every page ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;
  --section-gap: clamp(56px, 7vw, 96px);      /* v1 + v2 mockups; v3 overrides */
  --gutter: clamp(16px, 4vw, 48px);           /* 16px side gutter at 375 in every skin */

  /* ---- Containers ---- */
  --max-container: 1280px;                    /* per-skin override below */
  --max-body: 680px;                          /* reading column: privacy, About text, FAQ */
  --max-narrow: 560px;                        /* deck, proof line, form column (v1 mockup 560) */
  --max-media: 960px;                         /* S5c player, hero stage (v3 940 -> 960) */

  /* ---- Fluid type ramp (rem + vw so zoom still scales text) ---- */
  --text-label: 0.8125rem;                                     /* 13px: uppercase/mono labels, tags. Never sentences. */
  --text-caption: 0.9375rem;                                   /* 15px: captions, microcopy, chips, nav, card meta */
  --text-body: clamp(1rem, 0.95rem + 0.25vw, 1.0625rem);       /* 16px at 375 -> 17px desktop (all mockups 17/16) */
  --text-lead: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);       /* section intros, pillar outcome lines, FAQ questions */
  --text-figure: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);      /* receipt card-face headline figure */
  --text-stat: clamp(2rem, 1.4rem + 2.6vw, 3.5rem);            /* proof strip figures (craft card metric scale) */
  --text-deck: clamp(1.25rem, 1rem + 1.2vw, 1.75rem);          /* the four "We solve" lines; per-skin override */
  --text-h3: clamp(1.375rem, 1.1rem + 1.2vw, 2rem);            /* per-skin override */
  --text-h2: clamp(2rem, 1.3rem + 3vw, 3.5rem);                /* per-skin override */
  --text-display-sub: clamp(1.25rem, 1rem + 1vw, 2rem);        /* .h1-b, the range clause of the H1 */
  --text-display: clamp(2.1rem, 1.2rem + 3.6vw, 4rem);         /* .h1-a; per-skin override */

  --leading-display: 1;
  --leading-heading: 1.05;
  --leading-snug: 1.3;
  --leading-body: 1.55;                                        /* all three mockups */

  /* ---- Media ---- */
  --ratio-well: 16 / 10;            /* tier-1 card-face screenshot well (object-fit: contain) */
  --ratio-strip: 2 / 1;             /* tier-2 TikTok preview well (contain: thin strips read as tape) */
  --ratio-thumb: 4 / 3;             /* tier-3 wall thumbnail (object-fit: cover, top-left) */
  --ratio-video: 1152 / 720;        /* fast.mp4 is 1152x720 (16:10), not 16:9: frame matches source, no bars */
  --ratio-portrait: 1332 / 2048;    /* me.jpg natural */

  /* ---- Interaction ---- */
  --tap-min: 44px;                  /* every link/button/summary on mobile */
  --cta-height: 56px;               /* all three mockups */
  --cta-height-sm: 40px;            /* nav button */
  --field-height: 52px;             /* /book/ inputs (craft card 52px+ mobile) */
  --focus-width: 2px;
  --focus-offset: 3px;

  /* ---- Motion ---- */
  --dur-fast: 200ms;
  --dur-base: 350ms;
  --dur-reveal: 600ms;
  --dur-step: 900ms;                /* v1 pulse hop */
  --dur-draw: 1100ms;               /* v2 rule draw, v1 spine fill hop */
  --ease-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0.01ms;
    --dur-base: 0.01ms;
    --dur-reveal: 0.01ms;
    --dur-step: 0.01ms;
    --dur-draw: 0.01ms;
  }
}

/* =====================================================================================
   V1 "SIGNAL ROOM" (dark, systems). Source: visual-1.html
   Dark-majority is the owner's approved pick; it outranks the craft card's light-majority
   default (authority order: brand/mockup > card). Lime = booking only (CTA, nav button, focus).
   ===================================================================================== */
[data-skin="v1"] {
  /* Color roles */
  --color-bg: #0A0C0F;                          /* mockup --base */
  --color-surface: #111419;                     /* mockup --base-2 */
  --color-ink: #EDEBE5;                         /* mockup --ink */
  --color-muted: rgba(237, 235, 229, 0.66);     /* mockup --ink-muted, 7.40:1 */
  --color-subtle: rgba(237, 235, 229, 0.55);    /* CORRECTED from .38 (3.15:1) -> 5.44:1 */
  --color-decor: rgba(237, 235, 229, 0.38);     /* NON-TEXT only: rails, inactive node strokes */
  --color-dot: rgba(237, 235, 229, 0.07);       /* hero + final CTA dot-grid (28px) */
  --color-line: rgba(237, 235, 229, 0.12);      /* mockup --line */
  --color-line-strong: rgba(237, 235, 229, 0.28);
  --color-border: var(--color-line);
  --color-accent: #C8FF2E;                      /* mockup --signal */
  --color-accent-ink: #0A0C0F;
  --color-cta: #C8FF2E;
  --color-cta-ink: #0A0C0F;
  --color-cta-hover: #D4FF5C;                   /* lightened, not darkened: on near-black, darker = less salient; mockup hover intensified */
  --color-cta-on-dark: #C8FF2E;                 /* the whole skin is the dark band */
  --color-cta-ink-on-dark: #0A0C0F;
  --color-tint: rgba(200, 255, 46, 0.08);       /* mockup .book-sm hover wash */
  --color-dark-section: #0A0C0F;                /* v1 IS the dark; rhythm alternates bg / surface */
  --color-dark-ink: #EDEBE5;
  --color-dark-muted: rgba(237, 235, 229, 0.66);
  --color-chrome: #1A1E25;                      /* screenshot frame chrome bar (mockup .frame .chrome) */
  --color-shot-bg: #FFFFFF;                     /* behind white-UI screenshots */
  --color-photo-bg: #FFFFFF;                    /* me.jpg is a white studio shot */
  --color-error: #FF8A7A;                       /* ADDED: /book/ validation text; lime is booking-only. 8.55:1 on bg, 8.06 on surface */

  /* Families */
  --font-display: "Space Grotesk", system-ui, sans-serif;
  --font-body: "Space Grotesk", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  /* Weights */
  --weight-display: 700;
  --weight-display-sub: 500;
  --weight-heading: 700;
  --weight-deck: 500;                           /* deck noun in <b> at --weight-heading */
  --weight-body: 400;
  --weight-strong: 600;
  --weight-mono: 400;
  --weight-label: 500;
  --weight-cta: 700;

  /* Tracking */
  --track-display: -0.035em;
  --track-h2: -0.03em;
  --track-h3: -0.03em;
  --track-deck: -0.015em;
  --track-body: 0;
  --track-mono: 0.02em;
  --track-label: 0.06em;                        /* uppercase mono labels (mockup .04-.08 -> .06) */

  /* Per-skin ramp overrides (anchored to visual-1) */
  --text-display: clamp(2.1rem, 1.2rem + 3.6vw, 4rem);
  --text-display-sub: clamp(1.25rem, 1rem + 1vw, 2rem);
  --text-h2: clamp(2rem, 1.3rem + 2.9vw, 3.4rem);
  --text-h3: clamp(1.75rem, 1.2rem + 2.2vw, 3rem);       /* pillar titles are big in v1 */
  --text-deck: clamp(1.25rem, 0.95rem + 1.1vw, 1.7rem);
  --leading-display: 1;

  /* Radius language (2) */
  --radius-s: 10px;                             /* CTA, inputs, chips, pipeline nodes, tags */
  --radius-l: 16px;                             /* panels, screenshot frames, cards, lightbox */

  /* Shadow recipes (3) */
  --shadow-card: 0 24px 60px rgba(0, 0, 0, 0.45);                                   /* screenshot frames */
  --shadow-raised: 0 0 0 4px rgba(237, 235, 229, 0.14), 0 0 18px rgba(237, 235, 229, 0.55); /* live pulse + lit node */
  --shadow-cta: 0 0 0 1px rgba(200, 255, 46, 0.55), 0 10px 34px rgba(200, 255, 46, 0.22);

  /* Layout + motion */
  --max-container: 1280px;
  --gutter: clamp(16px, 4vw, 48px);
  --ease-signature: cubic-bezier(0.6, 0.05, 0.3, 1);   /* pulse travel + spine fill */
  --focus-color: #C8FF2E;
  --pulse-size: 9px;                            /* hero signal-path pulse dot (mockup .pulse) */
  --node-size: 35px;                            /* pipeline node square (mockup .node .dot; 32px <= 640px) */
}

/* =====================================================================================
   ADDED AT BUILD (2026-10-10). Values the page needed that the locked set did not carry.
   Each line carries its justification. Nothing below changes a locked value.
   ===================================================================================== */
:root {
  --dot-grid: 28px;                 /* ADDED: v1 hero + final CTA dot-grid pitch (mockup background-size 28px) */
  --preview-bg: #FFFFFF;            /* ADDED: preview-only skin toggle panel; belongs to no skin (section-treatments §0). Deleted at ship */
  --preview-ink: #111111;           /* ADDED: preview-only skin toggle ink + 1px border. Deleted at ship */
  --rule-w: 1px;                    /* ADDED: hairline rule weight (all three mockups) */
  --tile-w: 2px;                    /* ADDED: v3 tile border + v1 excerpt rule weight (mockups) */
  --chrome-h: 28px;                 /* ADDED: v1 browser-chrome bar height (mockup .frame .chrome) */
  --chrome-dot: 8px;                /* ADDED: v1 chrome bar dots (mockup) */
  --bullet: 8px;                    /* ADDED: v3 orange square bullet + v1 group node glyph (mockups 8-9px) */
  --pip-w: 22px;                    /* ADDED: v3 cycler pip width (mockup .pips i) */
  --pip-h: 4px;                     /* ADDED: v3 cycler pip height (mockup) */
  --lb-max-h: 80vh;                 /* ADDED: lightbox image cap (section-treatments §0: 92vw x 80vh) */
  --lb-max-w: 92vw;                 /* ADDED: lightbox image cap (section-treatments §0) */
  --cal-min-h: 640px;               /* ADDED: Cal.com slot min-height desktop (section-treatments §17) */
  --cal-min-h-m: 720px;             /* ADDED: Cal.com slot min-height mobile (section-treatments §17) */
  --leading-tap: 2.95;              /* ADDED: line pitch for inline "See it" link runs: 15px x 2.95 = 44px, so each padded link line is a 44px tap target with no overlap */
  --ratio-living: 21 / 9;           /* ADDED R5 (2026-10-11): Problem living element, desktop frame; object-fit cover trims only empty stone above and below the row (living-elements README) */
  --ratio-living-sm: 16 / 9;        /* ADDED R5: living element at <= 640px, the loop's native 16:9 so all four blocks stay large */
  --ratio-contrast: 16 / 9;         /* ADDED R5: contrast-section Remotion renders are 1920x1080: frame matches the source, no bars */
  --color-living-plate: #0A0C0F;    /* ADDED R5: the V1 living loop's near-black plate, painted while its poster loads (R5 audit: V2 and V3 now have their own light-ground loops and paint --color-bg instead) */
  --ratio-contrast-sm: 4 / 5;       /* ADDED R5 audit (design P1-3): the contrast video's 4:5 mobile render (1080x1350), served below 700px */
  --icon-m: 18px;                   /* ADDED R5 audit (craft P2-6): CTA arrow icon, was a literal */
  --icon-s: 16px;                   /* ADDED R5 audit (craft P2-6): V1 pipeline node icon, was a literal */
  --max-hero-media: 520px;          /* ADDED R5 audit (craft P2-6): V1 mockup hero panel width below 981px, was a literal */
  --max-cta: 420px;                 /* ADDED R5 audit (craft P2-6): V3 centered hero CTA cap at 375 to 760, was a literal */
  --deck-pad-top: 0.32em;           /* ADDED R5 audit (craft P2-6): V2 deck row, optical and em-relative to the deck size */
  --deck-pad-bottom: 0.28em;        /* ADDED R5 audit (craft P2-6): V2 deck row, optical and em-relative to the deck size */
  --leading-tight: 1.15;            /* ADDED R5 audit (craft P2-6): V2 deck lines and the V3 cycler slot; no locked leading matched (1.05 / 1.3) */
  --offset-cta: 5px;                /* ADDED R5 audit (design P2-8): the V3 CTA offset block depth (same 5px as --shadow-cta), so a full-width CTA can leave room for it */
  --crop-r1-zoom: 1.9;              /* ADDED R5 audit (design P1-8): pillar 01 plate, CSS viewing window onto the attribution table's figures (pixels untouched; lightbox shows the whole file) */
  --crop-r8-zoom: 1.9;              /* ADDED R5 audit (design P1-8): pillar 04 plate, window onto cost per result, amount spent and the total */
  --crop-motion-zoom: 2.15;         /* ADDED R5 audit (design P1-6): How-it-works plate, window onto two Motion report cards (ROAS and the four scores) */
  --crop-t5-zoom: 1.4;              /* ADDED R5 audit (design P1-6): interview-section plate, window onto the test-campaign rows and their total */
  --strip-zoom: 2.4;                /* ADDED R5 audit (design P2-13): thin TikTok strips in their 2:1 wells, so the row reads instead of a hairline */
}
[data-skin="v1"] { --text-h3-flow: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem); } /* ADDED R5 audit (design P2-1): V1 in-flow statements (bridge, end card, subheads) sit a clear step below --text-h2 */
[data-skin="v1"] { --color-backdrop: rgba(5, 6, 8, 0.86); } /* ADDED: lightbox backdrop (mockup dialog.lb::backdrop) */
