/* ═══════════════════════════════════════════════════════════════════════════
   sst-context.css — TLC 5.0 CONTEXT INK. One file, every site.

   SLOT NAMES ARE --ctx-*, NOT --ink / --line, AND THAT IS NOT COSMETIC. Measured
   2026-08-31 the moment this was wired to a real page: ops-dashboard.css:100
   already declares --ink: color-mix(in srgb, var(--color1) 16%, #14171c) and :103
   --line: color-mix(in srgb, var(--color1) 15%, transparent), and it loads AFTER
   this sheet — so on cololamb.com/ops/dashboard --ink resolved to rgb(21,26,37),
   the dashboard's own navy, not this file's rgba(0,0,0,.85). CraigWhitlock's pages
   declare --ink: #EBE3D4 for themselves too. Taking those names would have silently
   repainted two existing tools on their first load. Never reclaim them.

   WHAT THIS REPLACES. Measured 2026-08-31 on the legacy sheets:
       per site   8 contexts · 91 distinct --on<Ctx>_* tokens · 197 references
                  across 209 .on* rules      (MongooseYouthSports: 796 / 1075 / 1089)
   and of those, 19 --onLt_color* references still resolve to NOTHING on
   ColoradoLamb, EPIC4, EPIC4contests, EPIC4portal and SweetwaterCreek, because the
   token is named --onLt_flexcolor* everywhere it is actually emitted. Re-measured
   2026-08-31: it was 22, and the 3 ANCHOR ones were already repaired earlier the
   same day to var(--onLt_flexcolor2l, var(--LinkColor)) — headings, buttons, .tag
   and .sectionHeader are the 19 left, and they are out of scope until asked.
   A component asking a brand token "what color am I on this background" is what
   made that sprawl; it is 5 slots below, and the context sets them once.

   THIS FILE IS PURELY ADDITIVE AND CANNOT REPAINT AN OLD PAGE. It declares custom
   properties and sets no property on any element. Nothing changes until a component
   reads var(--ctx-ink). Craig, 2026-08-31: "OLD pages on all our old sites do NOT need
   to be reconned for" — so the old .on* rules stay where they are and die on their
   own, and this never has to fight them.

   THE FORMULA IS PORTED VERBATIM from shared/style-guide/v1/style-guide.js, which is
   the implementation already approved and already live on the guide's BG pills:
       lumSrgb01(hex)        = (0.299*r + 0.587*g + 0.114*b) / 255
       resolveOnColorForBg() = lum > T ? rgba(0,0,0,0.85) : rgba(255,255,255,0.92)
   Do not "upgrade" this to WCAG relative luminance. The two disagree near the
   threshold and the guide's rendering is the one Craig signed off; changing the
   weights silently re-inks every context on every site.

   T IS NOT A CONSTANT. IT IS 0.75 + 0.10 x CHROMA, and the chroma term is Craig's
   own distinction, drawn 2026-08-31 in his own two examples:

     gold  #ffd700  lum 0.794  chroma 1.00  -> WHITE   "my Stingers soccer uniform
        at 6years old was white numbers and borders on yellow Umbro and it was
        phenomenal. it was light, it was fast! we did not need black numbers"
     grey  #CCCCCC  lum 0.800  chroma 0.00  -> dark    "yellow hits a luminocity
        that is a little higher than white more like light gray which also looks
        really good with white on it (although looks disabled on web buttons)"

   SAME LUMINANCE, OPPOSITE ANSWER. Luminance alone cannot tell those two apart —
   they are six thousandths apart — so a flat threshold gets one of them wrong no
   matter where it is put. Saturation is what separates them, so saturation is in
   the formula. A saturated surface earns white all the way up to 0.85, the "15%"
   Craig asked for; a neutral one flips at 0.75, before white starts reading as a
   disabled control.

   THE WHOLE POINT IS THE FEELING, not the ratio. Craig, 25+ years designing:
   "Seeing white text on a bright blue or light blue button is a feeling of light
   and colorful. seeing black text on a bright blue or light blue button is a
   feeling of darkness, constraint, it just hits different." White is the default
   and dark ink is the exception, not the other way round.

   MEASURED, every surface Craig named plus the estate's own:
     gold #ffd700    0.794 c1.00 T.850 WHITE 1.40 | 20% grey  0.800 c0.00 T.750 dark 1.61
     bright blue     0.455 c0.88 T.838 WHITE 3.13 | pale blue 0.820 c0.28 T.778 dark 1.46
     light blue      0.654 c0.56 T.806 WHITE 2.06 | 15% grey  0.851 c0.00 T.750 dark 1.41
     CL red          0.333 c0.65 T.815 WHITE 5.75 | near white 0.988 c0.00 T.750 dark 1.03
     CL blue         0.170 c0.23 T.773 WHITE 13.81
     mix grey        0.400 c0.00 T.750 WHITE 5.74
     Sweetwater pink 0.704 c0.33 T.783 WHITE 2.16
     amber #ffc107   0.746 c0.97 T.847 WHITE 1.63
   DECLARED: gold and amber take white at 1.40 and 1.63, below AA. That is the
   deliberate answer to "sometimes i still want white on yellow/gold", and it is
   why the neutral floor exists — the low-contrast licence is spent on saturated
   colour, never on grey. Pale blue #AEDCF5 goes dark at 1.46; --on<Ctx>Ink forces
   white there if a page wants it.

   .btn-yellow IS A SEPARATE, EARLIER LOCKED DECISION and this file does not touch
   it. style-guide.css keeps dark ink on .btn-yellow deliberately (Craig 2026-08-20,
   #ffd700 dark 11.34 PASS, "Do not 'fix' .btn-yellow to white ink"). A component
   that opts into var(--ctx-ink) gets the rule above; .btn-yellow does not opt in.

   ═══════════════════════════════════════════════════════════════════════════ */

/* ── the switch, shared by every context ─────────────────────────────────── */
:root,
.onLt, .onDrk, .onMix {
  /* 0-1 perceived luminance of THIS context's surface */
  --_lum:  calc((0.299 * var(--_r, 252) + 0.587 * var(--_g, 252) + 0.114 * var(--_b, 252)) / 255);
  /* Saturation, 0 neutral -> 1 fully saturated. max()/min() rather than abs(),
     which is Chrome 133+ and unavailable on the legacy stack. */
  --_chroma: calc((max(var(--_r, 252), var(--_g, 252), var(--_b, 252))
                 - min(var(--_r, 252), var(--_g, 252), var(--_b, 252))) / 255);
  /* 0.75 neutral -> 0.85 saturated. See the Stingers note in the header. */
  --_T:    calc(0.75 + 0.10 * var(--_chroma));
  /* 1 = surface is light, so ink goes dark. 0 = ink goes light. The 10000
     multiplier makes clamp() a hard step at T rather than a ramp. */
  --_dark: clamp(0, calc((var(--_lum) - var(--_T)) * 10000), 1);

  --_inkAuto: color-mix(in srgb,
                rgba(0,0,0,.85) calc(var(--_dark) * 100%),
                rgba(255,255,255,.92));
  --ctx-ink: var(--_inkAuto);

  /* ── THE LINK, SAME AUTO APPROACH ──────────────────────────────────────
     The brand link is left alone on a surface that suits it and pulled toward
     the ink on one that does not. Two facts decide the shape, both measured
     2026-08-31 against every --LinkColor in the estate:

       1. A MID-GREY SURFACE ADMITS NO COLOURED LINK AT ALL. On #666666 the best
          any hue manages is under 4:1 — white itself is only 5.74:1 and black
          3.66:1. So near mid-luminance the link has to BECOME the ink and be
          told apart by its underline, not its hue. A fixed lift cannot do that:
          at a flat 45% the light and dark contexts passed and mix failed for
          all five brands (#c52040 2.15 · #ed99a5 3.81 · #009ae1 3.05 · #e6a97c
          3.95 · #414141 1.97).
       2. AT THE EXTREMES A LIFT THAT BIG WOULD THROW THE BRAND AWAY for nothing,
          because a dark surface takes a lightened brand link comfortably.

     --_mid is 4L(1-L): 0 at either end, 1 at mid-grey. Written that way rather
     than 1-abs(2L-1) because abs() is Chrome 133+ and this file has to work on
     the legacy stack today. Lift runs 45% -> 100% across it.
     Measured with p = .45 + .55 * 4L(1-L), 24 of 30 brand x surface pairs pass
     AA; all six failures are #B3B3B3, the band named above. */
  --_inkPure:   color-mix(in srgb, #000 calc(var(--_dark) * 100%), #fff);
  /* HOW FAR THE SURFACE IS FROM THE INK'S OWN EXTREME: L on a dark-ink surface,
     1-L on a white-ink one. Written without a conditional as
     L + (1-2L)(1-dark) — dark=1 gives L, dark=0 gives 1-L.
     REPLACES a 4L(1-L) mid-tone curve that measured 1.02:1 on gold and 1.31:1 on
     amber LIVE: that curve is symmetric, so it read gold (L .794) as "near mid
     grey" and lifted the link 81% toward white, on a surface whose white ink is
     already only 1.40:1. The link vanished. This form lifts by how much room
     there actually is, so gold measured 3.21 and amber 2.59 after.
     Peak lift is 0.8, never 1.0, ON PURPOSE — a link that reaches the ink exactly
     is a link you can only find by its underline. A threshold-relative variant was
     tried at K=1.6 and did exactly that: pure #ffffff on both #222222 and #1d2a57. */
  --_linkLum:   calc((0.299 * var(--sfLinkR, 197) + 0.587 * var(--sfLinkG, 32)
                    + 0.114 * var(--sfLinkB, 64)) / 255);
  /* THE LIFT IS DRIVEN BY COLLISION, NOT BY THE SURFACE ALONE. Squared gap rather
     than abs(), same Chrome-133 reason as --_chroma. x16 so a gap of .25 in
     luminance counts as "far apart" and the brand color is left completely alone. */
  --_gapD:      calc(var(--_linkLum) - var(--_lum));
  --_need:      calc(1 - min(1, var(--_gapD) * var(--_gapD) * 16));
  --_linkLift:  clamp(0%, calc(var(--_need) * 0.85 * 100%), 85%);
  --_linkAuto:  color-mix(in srgb, var(--_inkPure) var(--_linkLift), var(--LinkColor));

  /* One ink, three weights, derived — so a context can never disagree with itself.
     The percentages are chosen to reproduce the guide's approved light-context
     scale exactly: .85 -> .68 (--txt-s), .40 (--txt-m), .09 (--bdr). */
  --ctx-ink-2: color-mix(in srgb, var(--ctx-ink) 80%,   transparent);
  --ctx-ink-3: color-mix(in srgb, var(--ctx-ink) 47%,   transparent);
  --ctx-line:  color-mix(in srgb, var(--ctx-ink) 10.6%, transparent);

  --ctx-link: var(--_linkAuto);
}

/* ── the three surfaces ──────────────────────────────────────────────────── */
:root, .onLt {
  --_r: var(--sfLtR, 252); --_g: var(--sfLtG, 252); --_b: var(--sfLtB, 252);
  --ctx-surface: var(--sfLt, #EFEFEF);
}
.onDrk {
  --_r: var(--sfDrkR, 18); --_g: var(--sfDrkG, 18); --_b: var(--sfDrkB, 18);
  --ctx-surface: var(--sfDrk, #121212);
}
.onMix {
  --_r: var(--sfMixR, 102); --_g: var(--sfMixG, 102); --_b: var(--sfMixB, 102);
  --ctx-surface: var(--sfMix, #666666);
}

/* ── designer overrides, per context ─────────────────────────────────────── */
.onLt  { --ctx-ink: var(--onLtInk,  var(--_inkAuto)); --ctx-link: var(--onLtLink,  var(--_linkAuto)); }
.onDrk { --ctx-ink: var(--onDrkInk, var(--_inkAuto)); --ctx-link: var(--onDrkLink, var(--_linkAuto)); }
.onMix { --ctx-ink: var(--onMixInk, var(--_inkAuto)); --ctx-link: var(--onMixLink, var(--_linkAuto)); }
