/* apps2/shared/chartkit.css — shared chrome for CK-mounted charts (CHART-RULES items 1-20).
   Load alongside chartkit.js. Neutral tokens so it drops onto any apps2 page theme. */

/* #12 visible data Y-stretch slider (matches _view.php's per-panel "Y" cluster) */
.ck-yl, .yl { display:inline-flex; align-items:center; gap:4px; font-size:10px; color:#68736e;
  border:1px solid #dfe3df; border-radius:6px; padding:2px 6px; background:#fafafa; }
.ck-yl input[type=range], .yl input[type=range] { width:70px; }
.ck-yl b, .yl b { min-width:2.6em; text-align:right; color:#17201c; font-variant-numeric:tabular-nums; }

/* #12b per-chart canvas HEIGHT drag-grip (L:W ratio, persisted) — distinct from #12 Y-stretch.
   Sits flush under a chart shell; drag vertically to change the whole canvas height.
   touch-action:none is REQUIRED — without it a tablet gives the vertical gesture to the page
   scroller and the pointer stream is cancelled before the first pointermove, so the drag never
   happens. The grip is also a touch target, so it is taller on coarse pointers. */
.hgrip, .ck-grip { display:flex; align-items:center; justify-content:center; height:14px; cursor:ns-resize;
  user-select:none; -webkit-user-select:none; touch-action:none; border:1px solid #dfe3df; border-top:0; border-radius:0 0 6px 6px;
  background:#f7f8f6; color:#68736e; font-size:9px; letter-spacing:.03em; }
.hgrip:hover, .hgrip.dragging, .ck-grip:hover, .ck-grip.dragging { background:#eef1ee; color:#17201c; }
/* min-height, NOT height — and the difference is the whole point. FOUR pages (basis, regime,
   surface, volts) ship their own `.hgrip{height:14px}` and hand-roll their grip wiring, so they
   never call CK.heightGrip and the inline JS floor cannot reach them. Against `height:26px` here
   the page's own `height:14px` simply wins the cascade and the grip stays at half the touch floor
   — measured, on all four. Against `min-height` there is no contest at all: it is a DIFFERENT
   property, so it applies whatever the page declares, and it still cannot cap a page that wants a
   BIGGER grip (basics 44px, ants 34px stay exactly as they are). A floor that a caller can lose a
   cascade fight with is not a floor. */
@media (pointer:coarse){ .hgrip, .ck-grip { height:26px; min-height:26px; font-size:10.5px; } }
/* BOTH properties, deliberately. `height` is the kit's own default size for a grip the page has not
   styled; `min-height` is the FLOOR that survives a page override. Shipping only min-height turned
   the harness assertion red (it asserts the kit RAISES the grip via `height`) — the invariant was
   stronger, but the test was right that the declaration had gone, so the CODE was changed to satisfy
   it rather than the test being edited to match the code. Computed outcome is identical either way:
   nothing here can cap a page that declares a bigger grip. */

/* #12b VISIBLE canvas HEIGHT slider — the no-drag path (CK.heightSlider). Sits beside the Y slider. */
.ck-hl { display:inline-flex; align-items:center; gap:4px; font-size:10px; color:#68736e;
  border:1px solid #dfe3df; border-radius:6px; padding:2px 6px; background:#fafafa; }
.ck-hl input[type=range] { width:82px; }
.ck-hl b { min-width:3.4em; text-align:right; color:#17201c; font-variant-numeric:tabular-nums; }
@media (pointer:coarse){ .ck-hl input[type=range], .ck-yl input[type=range], .yl input[type=range] { height:26px; } }
/* touch-action:none on the SLIDERS too, for the same reason it is on the grip above — and this
   was missing until 2026-08-10 even though the comment at the top of this file already stated the
   rule. Measured: the grip carried `touch-action:none`, both range inputs computed `auto`, so on a
   tablet a vertical drag on a slider went to the page scroller and the slider never moved. That
   matters more here than on the grip, because the slider EXISTS as the fallback for the drag that
   already failed on tablet — a broken fallback leaves no working path at all. Applies to every
   CK-mounted chart in apps2, not just the page this was found on. */
.ck-hl input[type=range], .ck-yl input[type=range], .yl input[type=range] { touch-action:none; }

/* ── CK.freshness — the live "seconds since last update" LIVENESS counter ───────────────────
   QUIET WHEN HEALTHY (no badge, no colour — just muted text), loud only when actually wrong.
   Colours come from the host page's tokens where they exist (--muted/--warn/--neg/--faint), so
   it follows dark mode automatically; the fallbacks keep it sane on pages with no tokens. */
.ck-fresh { display:inline-flex; flex-wrap:wrap; align-items:center; gap:4px 10px;
  font-size:11px; line-height:1.35; color:var(--muted,#68736e); font-variant-numeric:tabular-nums; }
.ck-fresh .ck-fr-t { display:inline-flex; align-items:center; gap:4px; min-height:22px;
  padding:1px 2px; border-radius:5px; cursor:help; max-width:100%; }
.ck-fresh .ck-fr-t:focus-visible { outline:2px solid var(--cc,#1565c0); outline-offset:1px; }
/* multi-clock row reads as one sentence: futures 38s · options 4m · OI settled 08-06 */
.ck-fresh .ck-fr-t + .ck-fr-t::before { content:"·"; margin-right:6px; color:var(--faint,#8a938d); opacity:.7; }
.ck-fresh .ck-fr-l { font-weight:600; color:var(--faint,#8a938d); font-size:10px;
  letter-spacing:.02em; text-transform:lowercase; }
/* the ticking value is width-stable so the once-a-second update never shifts layout */
.ck-fresh .ck-fr-v { white-space:nowrap; }
.ck-fresh .ck-fr-dot { width:6px; height:6px; border-radius:50%; flex:0 0 auto;
  background:var(--faint,#8a938d); opacity:.55; }
/* healthy + paused: NEUTRAL. A 5-min options feed at 3am is correct behaviour, not an error —
   screaming red overnight trains the reader to ignore the indicator, which destroys it. */
.ck-fresh .ck-fr-t[data-state="ok"] .ck-fr-dot { background:var(--pos,#0d7d74); opacity:.5; }
.ck-fresh .ck-fr-t[data-state="paused"] .ck-fr-dot { background:var(--faint,#8a938d); opacity:.4; }
.ck-fresh .ck-fr-t[data-state="unknown"] { font-style:italic; }
.ck-fresh .ck-fr-t[data-state="unknown"] .ck-fr-dot,
.ck-fresh .ck-fr-t[data-state="skew"] .ck-fr-dot { background:transparent;
  box-shadow:inset 0 0 0 1.5px var(--faint,#8a938d); opacity:.8; }
/* overdue — visibly amber */
.ck-fresh .ck-fr-t[data-state="late"] { color:var(--warn,#b26a00); font-weight:600; }
.ck-fresh .ck-fr-t[data-state="late"] .ck-fr-l { color:var(--warn,#b26a00); }
.ck-fresh .ck-fr-t[data-state="late"] .ck-fr-dot { background:var(--warn,#b26a00); opacity:1; }
/* stale — clearly red */
.ck-fresh .ck-fr-t[data-state="stale"] { color:var(--neg,#c62828); font-weight:700;
  background:color-mix(in srgb, var(--neg,#c62828) 9%, transparent); padding:1px 6px; }
.ck-fresh .ck-fr-t[data-state="stale"] .ck-fr-l { color:var(--neg,#c62828); }
.ck-fresh .ck-fr-t[data-state="stale"] .ck-fr-dot { background:var(--neg,#c62828); opacity:1;
  animation:ck-fr-pulse 2s ease-in-out infinite; }
@keyframes ck-fr-pulse { 50% { opacity:.35; } }
@media (prefers-reduced-motion:reduce){ .ck-fresh .ck-fr-t[data-state="stale"] .ck-fr-dot { animation:none; } }
@media (pointer:coarse){ .ck-fresh { font-size:11.5px; } .ck-fresh .ck-fr-t { min-height:30px; } }
.ck-fr-sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0);
  clip-path:inset(50%); white-space:nowrap; }

/* #13 per-chart fill-screen: the kit sets this body class while any chart is fullscreen. */
body.ck-full-open { overflow:hidden; }
/* a height grip is meaningless while a chart fills the screen — hide it there. */
body.ck-full-open .hgrip, body.ck-full-open .ck-grip { display:none; }

/* ══ ACKNOWLEDGMENT — "I heard your click" (user 2026-08-11) ═════════════════════════════════
   A control that fetches before it redraws gives nothing back for the length of the fetch, so the
   click reads as ignored. Three additive pieces, used through CK.ack / CK.busy (chartkit.js):
     .ck-ack      a 220ms press flash on the control itself, applied in the click's OWN tick
     .ck-busy     the chart shell is being replaced — the existing render STAYS, lightly quieted
     .ck-busybar  a thin indeterminate bar along the top of that shell, delayed ~140ms so a fast
                  response never flickers
   Nothing here blanks a chart: stale-but-labelled always beats empty. */
@keyframes ck-ack-flash { from { box-shadow:0 0 0 0 rgba(23,32,28,.45); } to { box-shadow:0 0 0 4px rgba(23,32,28,0); } }
.ck-ack { animation:ck-ack-flash .22s ease-out; }
.ck-busy { position:relative; }
.ck-busy > canvas { opacity:.78; transition:opacity .12s ease; }
.ck-busybar { position:absolute; left:0; right:0; top:0; height:2px; z-index:9; overflow:hidden;
  background:rgba(23,32,28,.07); pointer-events:none; }
.ck-busybar::after { content:""; position:absolute; top:0; bottom:0; width:34%; left:-34%;
  background:var(--ink,#17201c); opacity:.5; animation:ck-busyslide 1.05s ease-in-out infinite; }
@keyframes ck-busyslide { from { left:-34%; } to { left:100%; } }
/* a fetch that FAILED resolves the state instead of leaving it pending for ever */
.ck-busyfail { box-shadow:inset 0 2px 0 0 var(--neg,#c62828); }
@media (prefers-reduced-motion:reduce){
  .ck-ack { animation:none; box-shadow:0 0 0 2px rgba(23,32,28,.35); }
  .ck-busybar::after { animation:none; left:0; width:100%; opacity:.28; }
  .ck-busy > canvas { transition:none; }
}

/* #16 SPX / NAS100 backdrop controls — share the date axis, own price scale, opacity slider */
.ck-ref { display:inline-flex; flex-wrap:wrap; align-items:center; gap:6px 10px; font-size:11px;
  color:#68736e; border:1px solid #dfe3df; border-radius:6px; padding:3px 8px; background:#fafafa; }
.ck-ref label { display:inline-flex; align-items:center; gap:4px; cursor:pointer; user-select:none; color:#17201c; }
.ck-ref input[type=range] { width:72px; touch-action:none; }
.ck-ref b { min-width:2.4em; font-variant-numeric:tabular-nums; color:#17201c; }
