/* ============================================================
   100Media UI/UX Design Standards v3 — tokens.css
   Drop in first. Change --brand-500 and the ramp follows.
   Every value here traces to a rule in the standard.
   ============================================================ */

:root {
  /* ---- Brand ramp -------------------------------------------------
     [V 4:55] One primary color. Lighten it for backgrounds, darken it
     for text. That gets you a ramp; the ramp builds everything else.
     Only edit --brand-h / --brand-s / --brand-l. -------------------- */
  --brand-h: 217;
  --brand-s: 91%;
  --brand-l: 50%;

  --brand-50:  hsl(var(--brand-h) var(--brand-s) 97%);
  --brand-100: hsl(var(--brand-h) var(--brand-s) 93%);
  --brand-200: hsl(var(--brand-h) var(--brand-s) 86%);
  --brand-300: hsl(var(--brand-h) var(--brand-s) 74%);
  --brand-400: hsl(var(--brand-h) var(--brand-s) 62%);
  --brand-500: hsl(var(--brand-h) var(--brand-s) var(--brand-l));
  --brand-600: hsl(var(--brand-h) var(--brand-s) 44%);
  --brand-700: hsl(var(--brand-h) var(--brand-s) 37%);
  --brand-800: hsl(var(--brand-h) var(--brand-s) 30%);
  --brand-900: hsl(var(--brand-h) calc(var(--brand-s) - 30%) 22%);
  --brand-950: hsl(var(--brand-h) calc(var(--brand-s) - 40%) 14%);

  /* ---- Semantic colors --------------------------------------------
     [V 5:24] Colors that carry meaning. Each has three depths:
     surface tint / border / text — so no state is color-only. ------ */
  --success:     #15803d;  --success-bg: #dcfce7;  --success-br: #86efac;
  --warning:     #a16207;  --warning-bg: #fef9c3;  --warning-br: #fde047;
  --danger:      #b91c1c;  --danger-bg:  #fee2e2;  --danger-br:  #fca5a5;
  --info:        var(--brand-700);
  --info-bg:     var(--brand-50);
  --info-br:     var(--brand-200);

  /* ---- Neutrals & surfaces ---------------------------------------- */
  --bg:          #fbfbfd;
  --surface:     #ffffff;
  --surface-2:   #f4f4f7;
  --border:      #e3e3e9;
  --border-str:  #c9c9d4;
  --text:        #17171c;   /* 16.9:1 on --bg */
  --text-2:      #4b4b57;   /*  8.2:1 on --bg */
  --text-3:      #6b6b7a;   /*  5.1:1 on --bg — floor for body */
  --text-inv:    #fbfbfd;

  /* ---- Spacing — 4pt system ---------------------------------------
     [V 3:03] Every value is a multiple of 4, so anything can be
     cleanly halved. That's the whole reason. ----------------------- */
  --s-1:  4px;   --s-2:  8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 20px;   --s-6: 24px;   --s-8: 32px;  --s-10: 40px;
  --s-12: 48px;  --s-16: 64px;  --s-20: 80px; --s-24: 96px;
  --s-32: 128px;

  /* Grouping gaps — between-group must be >=1.5x within-group */
  /* Annotated on screen at 2:58 as 16 within / 32 between. Exactly 2:1. */
  --gap-in:   var(--s-4);   /* 16px */
  --gap-out:  var(--s-8);   /* 32px */

  /* ---- Type ------------------------------------------------------
     [V 3:18] One typeface. Mono only for code / IDs / numerics.
     [V 4:06] <=6 sizes on marketing. Dashboards cap near 24px. ----- */
  --font: ui-sans-serif, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Two six-step scales, read off the video's own on-screen annotations.
     See references/08-measured-scales.md. These are NOT a modular scale:
     the marketing ratios run 1.52 / 1.31 / 1.60 / 1.25 / 1.14, expansive
     at the top and compressed at the bottom. A uniform 1.25 scale, which
     is the common default, produces a visibly flatter result. */

  /* Marketing / landing  [O 4:08] */
  --fs-h1: 64px;  --lh-h1: 72px;   /* 1.125, nearly set solid */
  --fs-h2: 42px;  --lh-h2: 48px;
  --fs-h3: 32px;  --lh-h3: 40px;
  --fs-h4: 20px;  --lh-h4: 28px;   /* 1.40  [O 2:46] */
  --fs-h5: 16px;  --lh-h5: 20px;   /* 1.25, button/label pairing [O 2:48] */
  --fs-h6: 14px;  --lh-h6: 18px;   /* 1.286 [O 2:50] */

  /* Dashboard / dense interface  [O 4:18] — six steps, capped at 24 */
  --fs-ui-1: 24px; --fs-ui-2: 20px; --fs-ui-3: 18px;
  --fs-ui-4: 16px; --fs-ui-5: 14px; --fs-ui-6: 12px;

  /* Fluid display for hero use, anchored to the 64px top step */
  --fs-display: clamp(2.5rem, 5vw + 1rem, 4rem);
  --fs-body:    1rem;
  --fs-sm:      0.875rem;

  --ls-display: -0.03em;
  --ls-heading: -0.02em;
  --ls-body:     0;

  --lh-display: 1.08;
  --lh-heading: 1.2;
  --lh-body:    1.55;
  --lh-dense:   1.4;

  --measure: 65ch;   /* 45-75 characters */

  /* ---- Radius ----------------------------------------------------- */
  --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-full: 999px;

  /* ---- Elevation ---------------------------------------------------
     [V 6:22] Most shadows are too strong: lower opacity, raise blur.
     [V 6:36] Cards need less; popovers need more. Max 4 levels. ---- */
  /* ---- Elevation --------------------------------------------------
     Rebuilt from frame measurements, not taste. Sampled falloff below
     a card edge peaked at ~20% darkening and reached zero by ~48px,
     so blur radius runs many times the y-offset at modest opacity.
     [V 6:22] lower the opacity, raise the blur. This is that, measured. */
  --shadow-hue: 216 28% 12%;
  --e-1: 0 1px 2px  hsl(var(--shadow-hue) / 0.05),
         0 4px 16px hsl(var(--shadow-hue) / 0.06);
  --e-2: 0 2px 4px  hsl(var(--shadow-hue) / 0.06),
         0 8px 28px hsl(var(--shadow-hue) / 0.08);
  --e-3: 0 4px 10px hsl(var(--shadow-hue) / 0.08),
         0 16px 48px hsl(var(--shadow-hue) / 0.12);
  --e-4: 0 8px 20px hsl(var(--shadow-hue) / 0.10),
         0 28px 72px hsl(var(--shadow-hue) / 0.16);

  /* Raised tactile button. Four layers: top highlight, bottom inner
     shade, contact shadow, lift. [V 6:44] inner and outer combined. */
  --e-raised:
    inset 0 1px 0 rgb(255 255 255 / 0.28),
    inset 0 -1px 0 rgb(0 0 0 / 0.10),
    0 1px 2px  hsl(var(--shadow-hue) / 0.16),
    0 4px 12px hsl(var(--shadow-hue) / 0.14);
  /* Pressed inverts the stack rather than just darkening the fill. */
  --e-pressed:
    inset 0 2px 5px rgb(0 0 0 / 0.22),
    inset 0 -1px 0 rgb(255 255 255 / 0.06),
    0 1px 1px hsl(var(--shadow-hue) / 0.10);

  /* ---- Motion ------------------------------------------------------
     [C @HarrisonEpperson] Animation is optional; feedback is not.
     [C @gubx42] Acknowledgement must land under 100ms. ------------- */
  --t-instant: 80ms;
  --t-state:  120ms;
  --t-enter:  220ms;
  --t-exit:   150ms;
  --t-large:  320ms;
  --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:    cubic-bezier(0.4, 0, 1, 1);
  --ease-std:   cubic-bezier(0.4, 0, 0.2, 1);
  --ack-budget: 100ms;   /* documentation of the hard ceiling */

  /* ---- Focus ------------------------------------------------------- */
  --focus-ring: 2px solid var(--brand-600);
  --focus-offset: 2px;

  /* ---- Layout ------------------------------------------------------ */
  --container: 1200px;
  --tap-min: 44px;   /* 390px touch-target floor */
}

/* ============================================================
   DARK MODE
   [V 5:49] Four corrections, not an inversion:
   1. Lower border contrast
   2. Depth = lighter surface, not shadow
   3. Dim saturated fills, flip the text brightness
   4. Deep purples/reds/greens are valid, not just navy or grey
   ============================================================ */
@media (prefers-color-scheme: dark) {
  :root {
    /* Never pure #000 background or pure #fff text — halation. */
    /* Measured off the source frames: the card sits ~7.6x the page
       luminance in dark mode, versus ~1.02x in light. Depth is carried
       entirely by lightness here, so the steps have to be large. */
    --bg:         hsl(var(--brand-h) 14% 7%);    /* L ~= 0.008 */
    --surface:    hsl(var(--brand-h) 13% 13%);   /* ~4x  the page */
    --surface-2:  hsl(var(--brand-h) 12% 17%);   /* ~7x  the page */
    --surface-3:  hsl(var(--brand-h) 11% 22%);   /* ~12x, for popovers */
    --border:     hsl(var(--brand-h) 12% 19%);   /* pulled way in */
    --border-str: hsl(var(--brand-h) 11% 28%);
    --text:       #e9e9ee;
    --text-2:     #b4b4c0;
    --text-3:     #8f8f9e;
    --text-inv:   #17171c;

    /* Fills dimmed, text brightened — the flip. */
    --success:    #6ee7a8; --success-bg: hsl(150 30% 14%); --success-br: hsl(150 25% 26%);
    --warning:    #fbd24e; --warning-bg: hsl(45 35% 14%);  --warning-br: hsl(45 30% 27%);
    --danger:     #fda4a4; --danger-bg:  hsl(0 35% 15%);   --danger-br:  hsl(0 30% 28%);
    --info:       var(--brand-300);
    --info-bg:    hsl(var(--brand-h) 35% 15%);
    --info-br:    hsl(var(--brand-h) 30% 28%);

    --brand-600:  hsl(var(--brand-h) 80% 58%);
    --brand-700:  hsl(var(--brand-h) 80% 64%);
    --brand-800:  hsl(var(--brand-h) 80% 70%);

    /* Shadows demoted, not deleted. Lightness does the work; these only
       help a floating element separate from a busy background. */
    --e-1: 0 1px 2px hsl(0 0% 0% / 0.30);
    --e-2: 0 4px 12px hsl(0 0% 0% / 0.36);
    --e-3: 0 8px 24px hsl(0 0% 0% / 0.44);
    --e-4: 0 16px 48px hsl(0 0% 0% / 0.55);

    --focus-ring: 2px solid var(--brand-300);
  }
}

/* Manual override hooks */
[data-theme="light"] { color-scheme: light; }
[data-theme="dark"]  { color-scheme: dark; }

/* ============================================================
   REDUCED MOTION — non-negotiable house rule.
   Feedback still fires; it just stops moving.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  :root {
    --t-instant: 0.01ms; --t-state: 0.01ms; --t-enter: 0.01ms;
    --t-exit: 0.01ms;    --t-large: 0.01ms;
  }
  /* Collapse sticky-scroll sections to a static stack. */
  [data-sticky-scroll] { position: static !important; height: auto !important; }
}

/* ============================================================
   BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 { margin: 0; letter-spacing: var(--ls-heading); line-height: var(--lh-heading); }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }

.display {
  font-size: var(--fs-display);
  letter-spacing: var(--ls-display);
  line-height: var(--lh-display);
  font-weight: 700;
}

p { margin: 0; max-width: var(--measure); }
.muted { color: var(--text-3); }
.num { font-variant-numeric: tabular-nums; }
code, pre, .mono { font-family: var(--font-mono); }

/* Focus is never removed — only replaced. */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--s-6);
}

/* Grouping: tight inside, loose between. Ratio >= 1.5x. */
.group      { display: flex; flex-direction: column; gap: var(--gap-in); }
.group-stack{ display: flex; flex-direction: column; gap: var(--gap-out); }

/* Icons match the line-height of adjacent text. [V 6:55] */
.icon { width: 1lh; height: 1lh; flex: none; display: block; }
@supports not (width: 1lh) { .icon { width: 1.55em; height: 1.55em; } }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
