/* QS Gauge: Roboto (Latin subset, Apache 2.0, pwa/fonts/LICENSE-Roboto.txt) for the gauge text only, so the fixed gauge rows
   (explore.js G_U) fit the same on every device (owner 2026-11-10: Roboto over Noto, narrower). Weight 600 uses the bold file. */
@font-face { font-family: "QS Gauge"; src: url(fonts/qs-gauge-400.woff2) format("woff2"); font-weight: 100 549; font-display: block; }
@font-face { font-family: "QS Gauge"; src: url(fonts/qs-gauge-700.woff2) format("woff2"); font-weight: 550 900; font-display: block; }
@font-face { font-family: "Oxanium Unit"; src: url(fonts/oxanium-400-unit.woff2) format("woff2"); font-weight: 400; font-display: block; unicode-range: U+24, U+166; }  /* Ŧ and $ only (1 KB), the header Ŧ | $ switch (owner 2026-11-11) */
@font-face { font-family: "Oxanium"; src: url(fonts/oxanium-500-600.woff2) format("woff2"); font-weight: 500 600; font-display: swap; }  /* the wordmark face, for card titles and tab labels (owner 2026-11-10) */
:root { --ice: #1f7fb5; --hot: #c2410c; --warm: #a16207;
  /* type scale (owner-approved 2026-11-03): nothing under 12px outside charts; chart text 10px (motion.js normLabels) */
  --fs-display: 28px; --fs-head: 18px; --fs-body: 16px; --fs-small: 14px; --fs-label: 12px;
  --bg: #f6f7f9; --card: #ffffff; --ink: #14171c; --muted: #5d6673; --line: #dfe3e8;
  --track: #e8ebef; --ok: #1f8a4c; --warn: #882501; --bad: #c53030; --accent: #2b6cb0;
  --brand: #fac800; --ink-on-brand: #1a1f25; --brand-edge: var(--ink); --focus-c: var(--ink); --focus-off: 0px; --focus-halo: 0 0 0 4px var(--brand);
  --sheen: rgb(255 255 255 / .45);  /* live row sweep highlight */
  --heat: #074550; --brand-ink: #0f2a1a; --nowc: #0f2a1a; --gpast: 35%;  /* wordmark letters: radar green on light, as quotasense-wordmark-mono-green */
  --s0: #0075e7; --s1: #d97757; --s2: #09b079; --s3: #eca10b; --s4: #f470a4; --s5: #008300; --s6: #6343eb;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --ice: #8fd3ff; --hot: #ff8a3d; --warm: #f5c26b;
    --bg: #111418; --card: #1a1f25; --ink: #e9edf2; --muted: #98a2ae; --line: #2a313a;
    --track: #2a313a; --ok: #48bb78; --warn: #fecda1; --bad: #fc8181; --accent: #63b3ed;
  --brand: #fac800; --ink-on-brand: #1a1f25; --brand-edge: transparent; --focus-c: var(--brand); --focus-off: 2px; --focus-halo: none;
  --heat: #a8e6ee; --brand-ink: #e9edf2; --nowc: var(--brand); --gpast: 50%; --sheen: rgb(255 255 255 / .22);
    --s0: #3a94fe; --s1: #d97757; --s2: #07ae7a; --s3: #c98502; --s4: #f4488c; --s5: #059804; --s6: #907efd;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] { --ice: #8fd3ff; --hot: #ff8a3d; --warm: #f5c26b;
  --s0: #3a94fe; --s1: #d97757; --s2: #07ae7a; --s3: #c98502; --s4: #f4488c; --s5: #059804; --s6: #907efd;
  --bg: #111418; --card: #1a1f25; --ink: #e9edf2; --muted: #98a2ae; --line: #2a313a;
  --track: #2a313a; --ok: #48bb78; --warn: #fecda1; --bad: #fc8181; --accent: #63b3ed;
  --brand: #fac800; --ink-on-brand: #1a1f25; --brand-edge: transparent; --focus-c: var(--brand); --focus-off: 2px; --focus-halo: none;
  --heat: #a8e6ee; --brand-ink: #e9edf2; --nowc: var(--brand); --gpast: 50%; --sheen: rgb(255 255 255 / .22);
  color-scheme: dark;
}

* { box-sizing: border-box; }
/* The page colour sits on html (not only body), so the root canvas, the iOS overscroll band and the status-bar area
   are --bg in both themes. body stays transparent: a body background would cover the clouds canvas (z-index -1). */
html { background: var(--bg); }
body {
  margin: 0; padding: 0 max(8px, env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
  color: var(--ink);  /* no background: html carries --bg (above) */
  font: 16px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
.top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
h1 { font-size: var(--fs-head); margin: 0; }
h2 { font: 600 16px/1.25 "Oxanium", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; text-transform: uppercase; letter-spacing: .06em; color: var(--ink); margin: 0 0 8px; }  /* card titles: Oxanium SemiBold 16px, ink (owner 2026-11-10; was system 14px bold) */
.muted { color: var(--muted); font-size: var(--fs-small); }
.help { margin: 0 0 12px; }

main { display: grid; gap: 12px; grid-template-columns: 1fr; max-width: 1100px; margin: 0 auto; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 2px; padding: 8px; min-width: 0; }

.big { font-size: var(--fs-display); font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1.1; }
.row { display: flex; justify-content: space-between; gap: 8px; font-variant-numeric: tabular-nums; }
.row + .row { margin-top: 4px; }
.sub { font-size: var(--fs-small); color: var(--muted); }
.sub.foot { margin-top: 8px; }

.bar { position: relative; height: 10px; background: var(--track); border-radius: 2px; overflow: hidden; margin: 8px 0 4px; }
.bar > i { position: absolute; inset: 0 auto 0 0; background: var(--accent); border-radius: 2px; }
.bar > b { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink); opacity: .55; }
.ok > i { background: var(--ok); } .warn > i { background: var(--warn); } .bad > i { background: var(--bad); }

.pill { display: inline-block; white-space: nowrap; align-self: center; padding: 1px 8px; border-radius: 2px; font-size: var(--fs-label); border: 1px solid var(--line); color: var(--muted); }
.pill.ok { color: var(--ok); border-color: currentColor; }
.pill.warn { color: var(--warn); border-color: currentColor; }
.pill.bad { color: var(--bad); border-color: currentColor; }

footer { max-width: 1100px; margin: 16px auto 0; text-align: center; }
.err { color: var(--bad); }

.chart { display: block; width: 100%; height: auto; margin: 8px 0 4px; }
.chart .frame { fill: none; stroke: var(--line); }
.chart .ghost { fill: none; stroke: var(--ptone, var(--s1)); stroke-opacity: .40; stroke-width: 1.2; }  /* past windows: light tone of the 5h card provider (--ptone) */
.chart .band { fill: var(--ptone, var(--s1)); fill-opacity: .30; stroke: none; }
.chart .now { fill: none; stroke: var(--ptone, var(--s1)); stroke-width: 2.4; stroke-linejoin: round; }
.chart .now.codex { stroke: var(--s0); }
.legend i.sw.lg-ghost { background: color-mix(in srgb, var(--ptone, var(--s1)) 40%, transparent); height: 2px; vertical-align: 3px; }
.chart .tick { stroke: var(--ink); stroke-opacity: .3; stroke-dasharray: 2 3; }

.details { display: grid; gap: 12px; grid-template-columns: 1fr; max-width: 1100px; margin: 12px auto 0; }
/* Desktop (owner 2026-11-07): as many card columns as fit at >= 380px each, never fewer than 2 or more than 4, so
   1280 -> 2, 1600 -> 3, 1920 and up -> 4; the 2276px cap keeps 4 columns <= 560px. Wide cards span 2 columns.
   Under 900px the phone layout is unchanged. Placed after the main/.details/footer base rules so these win. */
@media (min-width: 900px) {
  main, .details { grid-template-columns: repeat(auto-fill, minmax(max(min(380px, (100% - 12px) / 2), (100% - 36px) / 4), 1fr)); }
  .card.wide { grid-column: span 2; }
  /* masonry (owner 2026-11-11): 4px rows, no row gap; app.js masFit gives each card span = (its height + 12px) / 4 */
  main, .details { grid-auto-rows: 4px; row-gap: 0; }
  .tabp > .card { align-self: start; }  /* its own height, not the rows it spans (else the span would grow it) */
  .top, body > p.help, main, .details, footer { max-width: 2276px; margin-left: auto; margin-right: auto; }
}
h3 { font-size: var(--fs-small); font-weight: 600; margin: 12px 0 6px; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { font: inherit; font-size: var(--fs-small); padding: 6px 14px; min-height: 36px; border-radius: 2px; border: 1px solid var(--line); background: transparent; color: var(--ink); cursor: pointer; }
.chip[aria-pressed="true"] { background: var(--brand); border-color: var(--brand-edge); color: var(--ink-on-brand); }
.stack { display: block; width: 100%; height: auto; max-height: 260px; }
.heat { display: block; max-width: 100%; height: auto; }
.heat .cell { fill: var(--accent); }
.heat-key { align-items: center; gap: 4px; font-size: var(--fs-label); }
.heat-key i { width: 10px; height: 10px; margin: 0; background: var(--accent); }
.axis { fill: var(--muted); font-size: 10px; }
.stack .grid { stroke: var(--line); }
/* token types: s2..s6 and muted, never the provider slots s0/s1 */
.c0 { fill: var(--s2); background: var(--s2); } .c1 { fill: var(--s3); background: var(--s3); } .c2 { fill: var(--s4); background: var(--s4); }
.c3 { fill: var(--s6); background: var(--s6); } .c4 { fill: var(--muted); background: var(--muted); }
.legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: var(--fs-small); color: var(--muted); margin-top: 6px; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; vertical-align: -1px; }
/* This week bars: opaque fills so the day text inside meets 4.5:1 (light 7.8:1, dark 4.9:1; today 18:1 / 14:1). Ink, not accent: blue reads as Codex */
.wkbars { display: block; flex: 1 1 0; min-width: 0; overflow: visible; } .wkbars rect { fill: color-mix(in srgb, var(--muted) 55%, var(--card)); } .wkbars rect.today { fill: var(--ink); }
.wkbars text { paint-order: stroke; stroke-width: 3px; stroke-linejoin: round; } .wkbars text.axis { stroke: var(--card); }
.wkbars text.in { fill: var(--ink); font-size: 10px; stroke: color-mix(in srgb, var(--muted) 55%, var(--card)); } .wkbars text.in.today { fill: var(--card); stroke: var(--ink); font-weight: 600; }
.wkbars .avg { stroke: var(--brand); stroke-width: 1.5; stroke-dasharray: 3 2; } .wkbars .avg-h { stroke: var(--card); stroke-width: 3; }
.wkbars rect.hit { fill: transparent; cursor: pointer; } .wkbars rect.hit:focus-visible { outline: none; stroke: var(--focus-c); stroke-width: 2; }
.wktop { align-items: flex-end; gap: 12px; } .wkfig { display: flex; flex-direction: column; flex: none; } .wkfig .sub { white-space: nowrap; }

.tip + .tip { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.tip strong { font-size: var(--fs-body); font-weight: 600; }
[hidden] { display: none !important; }

/* Explore (trial views) */
.micro { fill: var(--muted); font-size: 10px; }
.rhythm, .lanes { display: block; width: 100%; height: auto; }
.sankey { display: block; width: calc(100% + 28px); max-width: none; height: auto; margin: 4px -14px; max-height: 520px; }
.sk-label { fill: var(--ink); font-size: 10px; paint-order: stroke; stroke: var(--card); stroke-width: 3px; stroke-linejoin: round; }
.rhythm .cell { fill: var(--s0); }
.lanes .grid { stroke: var(--line); }
.rows { width: 100%; border-collapse: collapse; font-size: var(--fs-small); font-variant-numeric: tabular-nums; }
.rows th { text-align: left; font-weight: 600; color: var(--muted); font-size: var(--fs-label); padding: 2px 4px; border-bottom: 1px solid var(--line); }
.rows td { padding: 3px 4px; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.rows .n { text-align: right; white-space: nowrap; }
.rows .pill { font-size: var(--fs-label); padding: 0 6px; }
.rings { display: flex; flex-wrap: wrap; gap: 8px 14px; justify-content: space-around; }
.ring { text-align: center; }
.ring-track { fill: none; stroke: var(--track); }
.ring-time { fill: none; stroke: var(--muted); }
.ring-used { fill: none; stroke: var(--accent); stroke-linecap: round; }
.ring-used.ok { stroke: var(--ok); } .ring-used.warn { stroke: var(--warn); } .ring-used.bad { stroke: var(--bad); }
.ring-num { fill: var(--ink); font-size: 13px; font-weight: 600; }
.micro-t { font-size: var(--fs-label); line-height: 1.25; }
.clock { display: block; width: 100%; max-width: 240px; height: auto; margin: 0 auto; }
.clock .spoke { stroke: var(--accent); }
.clock .wedge { stroke: var(--card); stroke-width: 0.6; }
.clock .today-ring { fill: none; stroke: var(--ink); stroke-opacity: 0.18; }
.clock .radar { fill-opacity: 0.18; stroke-width: 2; stroke-linejoin: round; }
.clock .radar.s0 { stroke: var(--s0); } .clock .radar.s1 { stroke: var(--s1); }
.clock .hub { fill: var(--card); stroke: var(--line); }
.clock text.b { font-weight: 700; font-size: 14px; fill: var(--ink); }
.receipt { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: var(--fs-label); max-width: 300px; margin: 0 auto;
  padding: 10px 12px; border: 1px dashed var(--line); border-radius: 2px; }
.rc-head, .rc-foot { text-align: center; color: var(--muted); letter-spacing: .06em; }
.rc-head { margin-bottom: 6px; } .rc-foot { margin-top: 6px; font-size: var(--fs-label); }
.rc-row { display: flex; justify-content: space-between; gap: 8px; }
.rc-sub { border-top: 1px solid var(--line); margin-top: 2px; padding-top: 2px; }
.rc-cut { border-top: 1px dashed var(--muted); margin: 6px 0; }
.rc-total { font-weight: 700; font-size: var(--fs-small); }
.s0 { fill: var(--s0); } .s1 { fill: var(--s1); } .s2 { fill: var(--s2); } .s3 { fill: var(--s3); }
.s4 { fill: var(--s4); } .s5 { fill: var(--s5); } .s6 { fill: var(--s6); } .s-other { fill: var(--muted); } .s-node { fill: var(--muted); }
.readout { position: fixed; left: 50%; bottom: calc(14px + var(--tabbar-h, 0px)); transform: translate(-50%, 24px); max-width: calc(100% - 32px);
  opacity: 0; filter: blur(var(--blur-small)); pointer-events: none;
  transition: opacity var(--duration-medium) var(--ease-smooth-out), transform var(--duration-medium) var(--ease-smooth-out), filter var(--duration-medium) var(--ease-smooth-out);
  background: var(--ink); color: var(--card); font-size: var(--fs-small); padding: 6px 12px; border-radius: 2px; z-index: 10;
  font-variant-numeric: tabular-nums; box-shadow: 0 2px 8px rgba(0,0,0,.25); }
.mix, .ctx { display: block; width: 100%; height: auto; }
.legend i.sw { width: 10px; height: 10px; border-radius: 2px; display: inline-block; vertical-align: -1px; margin-right: 4px; }
.legend i.s0 { background: var(--s0); } .legend i.s1 { background: var(--s1); } .legend i.s2 { background: var(--s2); }
.legend i.s3 { background: var(--s3); } .legend i.s4 { background: var(--s4); } .legend i.s5 { background: var(--s5); } .legend i.s-other { background: var(--muted); }
.trend, .runway { display: block; width: 100%; height: auto; }
.trend .grid { stroke: var(--line); } .trend .guide { stroke: var(--warn); stroke-dasharray: 3 3; }
.trend .line { fill: none; stroke: var(--s0); stroke-width: 2; stroke-linejoin: round; }
.trend .hit { fill: transparent; }
.runway .fill { fill: var(--accent); } .runway .fill.ok { fill: var(--ok); } .runway .fill.warn { fill: var(--warn); } .runway .fill.bad { fill: var(--bad); }
.runway .ghost { fill: var(--accent); fill-opacity: .22; } .runway .ghost.ok { fill: var(--ok); } .runway .ghost.warn { fill: var(--warn); } .runway .ghost.bad { fill: var(--bad); }
.runway .ghost.ok, .runway .ghost.warn, .runway .ghost.bad { fill-opacity: .22; }
.runway .now { stroke: var(--ink); stroke-width: 1.5; }
.rw { margin-bottom: 8px; }
.multiples { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
.mult svg { display: block; width: 100%; height: auto; margin: 2px 0; }
/* tile outline in the main machine's tone (as .rbar.outlined); --tone set by JS */
.mult { padding: 4px 6px; border-radius: 2px; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tone, var(--muted)) 70%, var(--line)); min-width: 0; }
.mult.tap { cursor: pointer; } .mult.tap:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.mult .base { stroke: var(--line); }
.mult-x { display: none; justify-content: space-between; font-size: 10px; color: var(--muted); }  /* axis text, as .micro */
.mult.last-row .mult-x { display: flex; }
@media (min-width: 720px) { .multiples { grid-template-columns: repeat(3, 1fr); } }
.saws { display: grid; gap: 10px; } @media (min-width: 720px) { .saws { grid-template-columns: 1fr 1fr; } }
.legend i.s6 { background: var(--s6); }

/* ---- polish: header, refresh, explore sections and card anatomy ---- */
.topr { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }  /* 28px touch areas + 4px gap = 24px frames 8px apart */
.hmsg { flex: 1 1 auto; min-width: 0; padding: 0 4px; text-align: center; font-size: var(--fs-label); line-height: 1.2; color: var(--ink);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; text-wrap: balance; }  /* bell result, max 2 lines */
.hmsg[hidden] { display: none; }
.topr, .topr > .iconbtn { flex: none; }  /* the alerts note shrinks, never the buttons */
@media (max-width: 359px) { .topr { gap: 0; } }
/* Header (owner 2026-11-07: fixed, never collapses): sticky at the top with the full mark and wordmark at all times.
   52px on a phone, wordmark 42px tall (the mark is the refresh button, 44px hit area).
   --wm-n = mark size in px (wordmark height); text is the artwork's "Quota / Sense" outlines, 110/1024 gap, ink 776/1024 tall. */
:root { --hdr-h: 52px; }
.top { --wm-n: 42; --wm: calc(var(--wm-n) * 1px);
  position: sticky; top: 0; z-index: 25; height: calc(var(--hdr-h) + env(safe-area-inset-top)); padding-top: env(safe-area-inset-top); }
/* opaque full-bleed background past the body gutters, so cards scrolling under the header never show through */
.top::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: var(--bg);
  box-shadow: 0 0 0 100vmax var(--bg); clip-path: inset(-100vmax -100vmax 0); }  /* also above the header: no subpixel strip under the status bar */
.brand { display: inline-flex; align-items: center; flex: none; }
/* hit area: 44px, or the mark itself when bigger (desktop 56px); a mark wider than its grid cell would hang off the right
   and eat the wordmark gap. The margin trims the box back to the mark size, so the gap is always 110/1024 of the mark. */
.logobtn { --hit: max(44px, var(--wm)); display: inline-grid; place-items: center; flex: none; width: var(--hit); height: var(--hit); margin: calc((var(--wm) - var(--hit)) / 2); padding: 0; border: 0; border-radius: 8px; background: none; cursor: pointer; }
.logobtn .logo { display: block; width: var(--wm); height: var(--wm); flex: none; }
.wmtext { margin: 0 0 0 calc(var(--wm) * 110 / 1024); line-height: 0; }
.wmtext svg { display: block; height: calc(var(--wm) * 776 / 1024); width: auto; aspect-ratio: 1250 / 776; fill: var(--brand-ink); }
@media (max-width: 359px) { .top { --wm-n: 36; } }
.logobtn:active { scale: .94; } .logobtn:disabled { cursor: progress; }
.logobtn:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
/* QuotaSense header mark (docs/logo/quotasense-icon-anim.svg, lean: one drop shadow, no rim/inset filters). Phone: the sweep
   and blips run only while .loading is on the button. Desktop (>=900px, mouse): they run all the time, and html.qs-idle
   (clouds.js: hidden tab, window blur, 60 s idle) pauses them unless a load is in flight. Both rules compute the same
   animation, so .loading coming and going never restarts it; --qs-d carries each blip's delay through the shorthand. */
.qs-mark #sweep-glow,.qs-mark #sweep-arm{transform-origin:512px 512px;transform-box:view-box;--qs-a:qs-spin}
.qs-mark [id^=blip-]{--qs-a:qs-blip} .qs-mark #blip-1{--qs-d:-0.100s} .qs-mark #blip-2{--qs-d:-1.633s} .qs-mark #blip-3{--qs-d:-1.033s}
.loading .qs-mark :is(#sweep-glow,#sweep-arm,[id^=blip-]){animation:var(--qs-a) 2.4s linear var(--qs-d,0s) infinite}
@media (min-width: 900px) and (hover: hover) and (pointer: fine) {
  .qs-mark :is(#sweep-glow,#sweep-arm,[id^=blip-]){animation:var(--qs-a) 2.4s linear var(--qs-d,0s) infinite}
  html.qs-idle .logobtn:not(.loading) .qs-mark :is(#sweep-glow,#sweep-arm,[id^=blip-]){animation-play-state:paused}
}
/* cube turn: a moving sweep re-renders the header's live snapshot every frame, which flickers on phones; hold it still */
html[data-cube] .qs-mark :is(#sweep-glow,#sweep-arm,[id^=blip-]){animation-play-state:paused}
@keyframes qs-spin{to{transform:rotate(360deg)}}
@keyframes qs-blip{0%{opacity:1;animation-timing-function:ease-out}50%{opacity:.25}100%{opacity:.25}}
@media (prefers-reduced-motion:reduce){.qs-mark #sweep-glow,.qs-mark #sweep-arm,.qs-mark [id^=blip-]{animation:none!important}}
@media (prefers-reduced-motion: reduce) { .logobtn.loading .logo { opacity: .5; } }  /* no motion: dim while loading instead */
.iconbtn { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 2px; border: 1px solid var(--line);
  background: var(--card); color: var(--ink); cursor: pointer; padding: 0; }
.iconbtn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ico.ph, .iconbtn svg.ph { fill: currentColor; stroke: none; }  /* Phosphor glyphs are filled shapes, not strokes */
.iconbtn:active { transform: scale(.94); } .iconbtn:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }

.card { box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 4px 14px rgba(16, 24, 40, .04); }
.card h2 { display: flex; align-items: center; gap: 6px; }
.card h2 .ttl > .ico:not(.hq) { width: 16px; height: 16px; }  /* title icon at cap size; the help mark keeps its own size */
.ico { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.card .head { margin: -2px 0 8px; font-size: 14px; font-weight: 500; line-height: 1.35; color: var(--head-c); }  /* headline: 13px gold under the title (owner 2026-11-10) */
:root { --head-c: #b39a2a; }  /* light: the app's light-theme gold (letter wave), owner 2026-11-10 */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --head-c: #fac800; } }
:root[data-theme="dark"] { --head-c: #fac800; }
.details .sub { font-size: var(--fs-small); line-height: 1.4; margin-top: 6px; }


/* capsule meters in tables */
.cap { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.cap b { display: inline-block; width: 46px; height: 7px; border-radius: 2px; background: var(--track); overflow: hidden; }
.cap b i { display: block; height: 100%; border-radius: 2px; background: var(--accent); }
.cap.ok b i { background: var(--ok); } .cap.warn b i { background: var(--warn); } .cap.bad b i { background: var(--bad); }
.cap.bad { color: var(--bad); }
.plan { display: inline-flex; align-items: center; gap: 6px; }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.s0b { background: var(--s0); } .s1b { background: var(--s1); }

/* runway: hatched projection, dot on the time marker */
.hatch-bg { fill: transparent; } .hatch-ln { stroke-width: 2.2; stroke: var(--accent); stroke-opacity: .45; }
.runway .proj.ok ~ * .hatch-ln { stroke: var(--ok); }
.runway .now-dot { fill: var(--ink); }
.runway .fill { filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .18)); }
.rings { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; justify-items: center; }

/* flow builder */
.fb-controls { display: grid; gap: 8px; margin-bottom: 6px; }
.fb-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.fb select { font: inherit; font-size: var(--fs-small); padding: 5px 8px; border-radius: 2px; border: 1px solid var(--line); background: var(--card); color: var(--ink); max-width: 9.5rem; }
.fb-swap, .fb-btn { font: inherit; font-size: var(--fs-small); width: 28px; height: 28px; border-radius: 2px; border: 1px solid var(--line); background: var(--card); color: var(--accent); cursor: pointer; padding: 0; }
.fb-btn:disabled { opacity: .35; cursor: default; }
/* The Flow presets are one unwrapped .seg (its sliding pill needs one row), wider than a phone card: it scrolls inside
   itself (pill scrolls with it) and fades its right edge while options are out of sight (explore.js .seg-more). */
@media (max-width: 359px) { .fb .seg button { padding-left: 8px; padding-right: 8px; } }
.fb-controls { grid-template-columns: minmax(0, 1fr); }
.fb .seg { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.fb .seg::-webkit-scrollbar { display: none; }
.fb .seg button { flex: none; white-space: nowrap; }
.fb .seg.seg-more { mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 2px; overflow: hidden; }
.seg button { font: inherit; font-size: var(--fs-small); padding: 4px 12px; border: 0; background: var(--card); color: var(--muted); cursor: pointer; }
.seg button[aria-pressed="true"] { background: var(--brand); color: var(--ink-on-brand); }
.seg { position: relative; }
.seg button { position: relative; z-index: 1; transition: color var(--tabs-dur) var(--tabs-ease); }
.seg.has-pill button[aria-pressed="true"] { background: transparent; }
.seg.has-pill button { background: transparent; }
.fb-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.fb-presets .chip { font: inherit; font-size: var(--fs-small); padding: 3px 10px; border-radius: 2px; border: 1px solid var(--line); background: var(--card); color: var(--ink); cursor: pointer; }
.fb-presets .chip[aria-pressed="true"] { background: var(--brand); border-color: var(--brand-edge); color: var(--ink-on-brand); }
.sankey .hitbox { fill: transparent; cursor: pointer; }
.sankey .lk-hit { fill: transparent; stroke: transparent; }  /* per-link stroke-width: a thin link is >= 6 units tall to tap */
svg text, .clock .hand { pointer-events: none; }  /* labels and the hand never cover a mark's tap */
.sankey rect.on { stroke: var(--ink); stroke-width: 1.5; }
.sankey .sk-label { font-size: var(--fs-label); stroke-width: 2px; }  /* 1 unit = 1px: 12px text, 1px card halo each side */
.sankey .sk-label.on { font-weight: 700; }
.sankey .lk { transition: fill-opacity .2s; }
@media (prefers-reduced-motion: reduce) { .sankey .lk { transition: none; } }
.clock-seg { display: flex; width: fit-content; max-width: 100%; margin: 0 auto 6px; }
.clock-seg button { padding: 4px 8px; font-size: var(--fs-small); white-space: nowrap; }
.clock-legend { justify-content: center; }
.clock-legend .lg { font: inherit; font-size: var(--fs-small); color: var(--muted); background: none; border: 1px solid transparent; border-radius: 2px; padding: 2px 8px; cursor: pointer; }
.clock-legend .lg[aria-pressed="true"] { border-color: var(--line); color: var(--ink); }
.dials { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: start; }
.dial-col { min-width: 0; }
.dials .clock-seg button { padding: 3px 6px; font-size: var(--fs-label); }
.dials .clock-legend .lg { font-size: var(--fs-label); padding: 1px 5px; }
.dials .sub { font-size: var(--fs-small); }
.clock .radar.s6 { stroke: var(--s6); fill: var(--s6); }
.clock .radar.peak { fill: none; stroke-dasharray: 3 3; stroke-width: 1.2; }
.clock .wedge.hit { fill: transparent; stroke: none; }
.clock-sel { display: block; margin: 0 auto 6px; font: inherit; font-size: var(--fs-small); padding: 4px 8px; border-radius: 2px; border: 1px solid var(--line); background: var(--card); color: var(--ink); max-width: 100%; }
.clock-ctl { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; margin-bottom: 6px; }
.clock-ctl .clock-sel, .clock-ctl .clock-seg { margin: 0; }
.rhythm .cell.today, .clock .wedge.s0.today { fill: var(--s1); }
.rhythm text.b { font-weight: 700; fill: var(--ink); }
.legend i.sw.shade { background: var(--s0); } .legend i.sw.shade.today { background: var(--s1); }

/* ── Motion, adapted from transitions.dev (free set). Tokens keep its names. ── */
:root {
  --duration-quick: 150ms; --duration-fast: 250ms; --duration-medium: 350ms; --duration-slow: 400ms; --duration-very-slow: 500ms;
  --ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1); --ease-bounce: cubic-bezier(0.34, 1.36, 0.64, 1); --blur-small: 2px;
  --resize-dur: 300ms; --digit-dur: 500ms; --digit-distance: 8px; --digit-stagger: 70ms; --digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
  --text-swap-dur: 150ms; --text-swap-translate-y: 4px;
  --dropdown-open-dur: 250ms; --dropdown-close-dur: 150ms; --dropdown-pre-scale: 0.97; --dropdown-closing-scale: 0.99;
  --tabs-dur: 250ms; --tabs-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --shake-distance: 6px; --shake-overshoot: 4px;
  --enter-dur: 1200ms; --enter-stagger: 70ms; --enter-delay: 300ms;  /* data entrance: row fills, line draw, chart wipe */
  --p27-dur: 350ms; --p27-ease: cubic-bezier(0.34, 1.35, 0.64, 1); --p27-travel: 14px;  /* toggle: thumb overshoots ~1px past its end, settles */
}
/* Card resize */
.t-resize { transition: height var(--resize-dur) var(--ease-smooth-out); }
/* Number pop-in */
@keyframes t-digit-pop-in { 0% { transform: translateY(var(--digit-distance)); opacity: 0; filter: blur(var(--blur-small)); } 100% { transform: none; opacity: 1; filter: blur(0); } }
.t-digit-group { display: inline; }
.big .t-digit-group { white-space: nowrap; }  /* a figure never wraps between its popping digits */
.t-digit { display: inline-block; }
.t-digit-group.is-animating .t-digit { animation: t-digit-pop-in var(--digit-dur) var(--digit-ease) both; }
.t-digit-group.is-animating .t-digit[data-stagger="1"] { animation-delay: var(--digit-stagger); }
.t-digit-group.is-animating .t-digit[data-stagger="2"] { animation-delay: calc(var(--digit-stagger) * 2); }
.t-digit-group.is-animating .t-digit[data-same] { animation: none; }
/* Text states swap: headlines that changed, and captions/legends rebuilt by a toggle */
@keyframes t-text-swap-in { from { opacity: 0; transform: translateY(var(--text-swap-translate-y)); filter: blur(var(--blur-small)); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes t-text-swap-out { to { opacity: 0; transform: translateY(calc(var(--text-swap-translate-y) * -1)); filter: blur(var(--blur-small)); } }
.t-swap-out { animation: t-text-swap-out var(--text-swap-dur) ease-in-out both; }
.t-swap-in, .t-live .sub, .t-live .legend, .t-live .head { animation: t-text-swap-in var(--text-swap-dur) ease-in-out both; }
.t-live svg { animation: t-text-swap-in var(--duration-fast) ease-in-out both; }
/* Data entrance: a card waits hidden until it scrolls in; charts wipe in under a mask (masks keep taps working) */
.t-await .g-dial, .t-await .m-dial, .t-await .rbar > .f, .t-await .rbar > .pj, .t-await .rbar > .pace, .t-await .rbar .segs, .t-await svg[role="img"]:not(.rd-mini), .t-await p.head, .t-await .big { opacity: 0; }
.t-wipe { -webkit-mask: linear-gradient(90deg, #000 33.4%, transparent 66.6%) 0 0 / 300% 100% no-repeat; mask: linear-gradient(90deg, #000 33.4%, transparent 66.6%) 0 0 / 300% 100% no-repeat; }
/* Menu dropdown */
.t-menu { position: relative; display: inline-block; max-width: 100%; }
.t-menu .clock-sel { margin: 0; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.t-menu .caret { font-size: var(--fs-label); color: var(--muted); }
.t-dropdown { position: absolute; top: calc(100% + 4px); left: 0; z-index: 20; min-width: 100%; margin: 0; padding: 4px; list-style: none;
  background: var(--card); border: 1px solid var(--line); border-radius: 2px; box-shadow: 0 6px 20px rgba(16, 24, 40, .14);
  transform-origin: top left; transform: scale(var(--dropdown-pre-scale)); opacity: 0; pointer-events: none;
  transition: transform var(--dropdown-open-dur) var(--ease-smooth-out), opacity var(--dropdown-open-dur) var(--ease-smooth-out); }
.t-dropdown[data-origin="top-right"] { left: auto; right: 0; transform-origin: top right; }
.t-dropdown.is-open { transform: scale(1); opacity: 1; pointer-events: auto; }
.t-dropdown.is-closing { transform: scale(var(--dropdown-closing-scale)); opacity: 0; pointer-events: none;
  transition: transform var(--dropdown-close-dur) var(--ease-smooth-out), opacity var(--dropdown-close-dur) var(--ease-smooth-out); }
.t-dropdown li { padding: 8px 12px; font-size: var(--fs-small); border-radius: 2px; white-space: nowrap; cursor: pointer; color: var(--ink); }
.t-dropdown li[aria-selected="true"] { color: var(--ink); font-weight: 600; box-shadow: inset 3px 0 0 var(--brand); }
.t-dropdown li:hover, .t-dropdown li:focus { background: var(--track); outline: none; }
/* Tabs sliding (pill under the chosen .seg option) */
.t-tabs-pill { position: absolute; top: 0; bottom: 0; left: 0; width: 0; background: var(--brand); box-shadow: inset 0 0 0 1px var(--brand-edge); z-index: 0; pointer-events: none;
  transition: transform var(--tabs-dur) var(--tabs-ease), width var(--tabs-dur) var(--tabs-ease); }
/* Panel reveal (tap readout) */
.readout.on { opacity: 1; transform: translate(-50%, 0); filter: blur(0); }
/* Notification badge (quota warnings on the Now chip) */
@keyframes t-badge-in { 0% { transform: translate(-6px, 8px) scale(.4); opacity: 0; filter: blur(var(--blur-small)); } 100% { transform: none; opacity: 1; filter: blur(0); } }
.t-badge { display: inline-grid; place-items: center; min-width: 16px; height: 16px; padding: 0 4px; margin-left: 2px; border-radius: 2px;
  background: var(--bad); color: #fff; font-size: var(--fs-label); font-weight: 700; animation: t-badge-in var(--duration-very-slow) var(--ease-bounce) both; }
/* Error shake (freshness label when stale or unreachable) */
@keyframes t-shake { 0%, 100% { transform: none; } 20% { transform: translateX(calc(var(--shake-distance) * -1)); } 40% { transform: translateX(var(--shake-distance)); }
  60% { transform: translateX(calc(var(--shake-overshoot) * -1)); } 80% { transform: translateX(var(--shake-overshoot)); } }
#fresh .pill.warn, #fresh .err { display: inline-block; animation: t-shake 360ms var(--ease-smooth-out); }
@media (prefers-reduced-motion: reduce) {
  .t-resize, .t-dropdown, .t-tabs-pill, .seg button, .readout { transition: none !important; }
  .t-digit, .t-swap-in, .t-swap-out, .t-live .sub, .t-live .legend, .t-live .head, .t-live svg, .iconbtn svg, .t-badge, #fresh .pill.warn, #fresh .err { animation: none !important; }
}
/* Control height: one 24px size for buttons, chips, toggles, dropdowns and menu options (legend keys excluded). */
.iconbtn { width: 24px; height: 24px; } .iconbtn svg { width: 14px; height: 14px; }
.iconbtn[aria-pressed="true"] { background: var(--brand); color: var(--ink-on-brand); border-color: var(--brand-edge); }
.chip, .fb-presets .chip { min-height: 0; height: 24px; padding-top: 0; padding-bottom: 0; display: inline-flex; align-items: center; box-sizing: border-box; }
.seg { height: 24px; box-sizing: border-box; } .seg button { height: 22px; padding-top: 0; padding-bottom: 0; }
.clock-sel, .t-menu .clock-sel, .fb select { height: 24px; padding-top: 0; padding-bottom: 0; box-sizing: border-box; }
.fb-swap, .fb-btn { width: 24px; height: 24px; }
.t-dropdown li { height: 24px; padding-top: 0; padding-bottom: 0; display: flex; align-items: center; }
/* $ | Ŧ toggles: wider so each side is an easy target */
.seg[aria-label="Measure"] button, .seg[aria-label="Size by"] button { min-width: 36px; }
/* Agent clock legend: full-width grid under both dials */
.clock-legend { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px 4px; margin: 6px 0 2px; }
.clock-legend .lg { font-size: var(--fs-label); display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 4px; align-items: center; min-width: 0; width: 100%; text-align: left; white-space: nowrap; padding: 2px; line-height: 1.2; }
.clock-legend .lg .sw { grid-row: span 2; margin-right: 0; }
.clock-legend .lg .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.clock-legend .lg .pc { font-variant-numeric: tabular-nums; color: var(--muted); font-size: var(--fs-label); }
/* Day compare chips: blue = set A, orange = set B */
.daychips { display: flex; justify-content: center; gap: 4px; margin-bottom: 6px; }
.daychip { font: inherit; font-size: var(--fs-label); min-width: 30px; height: 24px; padding: 0 6px; border-radius: 2px; border: 1px solid var(--line); background: var(--card); color: var(--muted); cursor: pointer; }
.daychip.a { background: var(--s0); border-color: var(--s0); color: #fff; }
.daychip.b { background: var(--s1); border-color: var(--s1); color: #fff; }
.daychip:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
/* Clock face: bezel ticks, hour labels, now pill */
.clock .tick { stroke: var(--muted); stroke-width: 1; stroke-opacity: .5; } .clock .tick.q { stroke: var(--ink); stroke-width: 1.5; stroke-opacity: .8; }
.clock .hr { font-size: 11px; font-weight: 600; fill: var(--ink); }
.clock .hand-hi { fill: var(--ink); } .clock .hand-lo { fill: color-mix(in srgb, var(--ink) 65%, var(--card)); } .clock .hand-tip { fill: var(--brand); }  /* dauphine: two-tone ink facets, lume tip */
.clock .hand-cap { fill: var(--ink); stroke: var(--card); stroke-width: 1.2; }  /* owner 2026-11-11: hands in brand #fac800, as the rhythm today outline */
/* Row bars (quota): row = track, tinted provider fill behind the label, values right-aligned in tabular figures */
.rbar { position: relative; display: flex; justify-content: space-between; align-items: center; gap: 8px; height: 28px; padding: 0 8px; margin: 4px 0;
  border-radius: 2px; background: var(--track); overflow: hidden; font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rbar .f { position: absolute; inset: 0 auto 0 0; background: color-mix(in srgb, var(--tone) 55%, transparent);
  transition: width var(--duration-slow, 400ms) var(--ease-smooth-out, ease-out); }
/* markers (share end, now, limit) sit in 6px lanes at the top and bottom edge so they never run through text */
.rbar .f::after { content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 1px; --mk: var(--tone); }
.rbar .f::after, .rbar .pace, .rbar .pj.over::after { background: var(--mk); opacity: .75; z-index: 0; }  /* thin full-height markers at 75%, behind the text chip */
.rbar .l, .rbar .r { position: relative; z-index: 1; }
.rbar .l { color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.rbar .r { color: var(--muted); } .rbar .r.warn { color: var(--warn); } .rbar .r.bad { color: var(--bad); }
/* "now" marker: full-height line behind the text, with caliper notches at top and bottom edges */
.rbar .pace { position: absolute; top: 0; bottom: 0; width: 1px; --mk: var(--nowc); }  /* now: radar green on light, brand yellow on dark, as the 5h chart */
.rbar .pace::before, .rbar .pace::after { content: ""; position: absolute; left: -3.5px; border: 4px solid transparent; }
.rbar .pace::before { top: 0; border-top-color: var(--nowc); border-bottom: 0; }
.rbar .pace::after { bottom: 0; border-bottom-color: var(--nowc); border-top: 0; }
@media (prefers-reduced-motion: reduce) { .rbar .f { transition: none; } }
/* Runway on row bars: outlined limit, halftone projection, red cap when it would run out */
.rbar.outlined { background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tone) 70%, var(--line)); }
/* Caching: segmented row (hit | first write | missed | rebuilt), 2px card-surface gaps */
.rbar.segbar { background: var(--card); }
.segbar .segs { position: absolute; inset: 0; display: flex; gap: 2px; }
.segbar .sg { flex: 0 1 0; min-width: 3px; }
.sg.hit { background: color-mix(in srgb, var(--tone) 55%, transparent); }  /* the standard row fill */
.sg.first_write { background: color-mix(in srgb, var(--tone) 16%, transparent); }
.sg.missed.pj { position: relative; top: auto; bottom: auto; overflow: hidden; }  /* missed: halftone squares (app.js), a flex segment, not an absolute overlay */
.sg.rebuilt { background: repeating-linear-gradient(135deg, var(--warn) 0 2px, transparent 2px 4px); box-shadow: inset 0 0 0 1px var(--warn); }
.segbar .r { padding: 0 4px; text-shadow: 1px 0 0 var(--card), -1px 0 0 var(--card), 0 1px 0 var(--card), 0 -1px 0 var(--card); }  /* the app standard (as Quota): 1px card-colour halo, no box */
.split-key { --tone: var(--muted); }
.split-key i.sg { min-width: 0; }
.rbar .pj { position: absolute; top: 0; bottom: 0; }  /* projected: halftone squares (app.js halftone); the diagonal hatch now means "rebuilt" only */
.pj .ht { display: block; } .pj { color: color-mix(in srgb, var(--tone) 55%, transparent); }  /* squares: app.js canvas reads this colour */
.rbar .pj.over::after { content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 2px; --mk: var(--bad); }
/* Quota card: provider header + thinner bars; right text = Now | Est. | Resets columns (widths set on the list in ch) */
.qgrp + .qgrp { margin-top: 8px; }
.qh { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 0 12px 0 0; margin-top: 2px; font-size: var(--fs-small); }
.qh .lbl { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.qh .qcols { font-size: var(--fs-label); color: var(--muted); }
.qcols { display: inline-grid; grid-template-columns: var(--qc0, auto) var(--qc1, auto) var(--qc2, auto); column-gap: 8px; text-align: right; font-variant-numeric: tabular-nums; }
.rbars .r .qcols > .warn { color: var(--warn); } .rbars .r .qcols > .bad { color: var(--bad); } .rbars .r .qcols > .ok { color: var(--muted); }
.qcols > * { justify-self: end; } .qcols small { font-size: var(--fs-label); }
.pace-row { display: flex; align-items: center; gap: 4px; font-size: var(--fs-small); color: var(--muted); margin: 6px 0 2px; }
.pace-row b { color: var(--ink); font-weight: 600; font-size: var(--fs-small); white-space: nowrap; }
.pace-slider { flex: 1; accent-color: var(--brand); height: 24px; margin: 0; }
/* both providers: half Claude, half Codex */
.legend i.sw.lg-used { background: color-mix(in srgb, var(--muted) 60%, transparent); }  /* neutral: the legend explains the shape (solid = used); colour stays the provider */
/* projected key: a mini halftone (CSP img-src allows data:), coloured by a mask so it follows the theme */
.legend:not(.rd-lg) i.sw.lg-proj { width: 18px; border-radius: 0; background: color-mix(in srgb, var(--muted) 80%, transparent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='10'%3E%3Crect x='0.15' y='0.65' width='2.7' height='2.7'/%3E%3Crect x='0.15' y='3.65' width='2.7' height='2.7'/%3E%3Crect x='0.15' y='6.65' width='2.7' height='2.7'/%3E%3Crect x='3.33' y='0.83' width='2.34' height='2.34'/%3E%3Crect x='3.33' y='3.83' width='2.34' height='2.34'/%3E%3Crect x='3.33' y='6.83' width='2.34' height='2.34'/%3E%3Crect x='6.51' y='1.01' width='1.98' height='1.98'/%3E%3Crect x='6.51' y='7.01' width='1.98' height='1.98'/%3E%3Crect x='9.69' y='4.19' width='1.62' height='1.62'/%3E%3Crect x='9.69' y='7.19' width='1.62' height='1.62'/%3E%3Crect x='12.87' y='1.37' width='1.26' height='1.26'/%3E%3Crect x='16.05' y='7.55' width='0.9' height='0.9'/%3E%3C/svg%3E") no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='10'%3E%3Crect x='0.15' y='0.65' width='2.7' height='2.7'/%3E%3Crect x='0.15' y='3.65' width='2.7' height='2.7'/%3E%3Crect x='0.15' y='6.65' width='2.7' height='2.7'/%3E%3Crect x='3.33' y='0.83' width='2.34' height='2.34'/%3E%3Crect x='3.33' y='3.83' width='2.34' height='2.34'/%3E%3Crect x='3.33' y='6.83' width='2.34' height='2.34'/%3E%3Crect x='6.51' y='1.01' width='1.98' height='1.98'/%3E%3Crect x='6.51' y='7.01' width='1.98' height='1.98'/%3E%3Crect x='9.69' y='4.19' width='1.62' height='1.62'/%3E%3Crect x='9.69' y='7.19' width='1.62' height='1.62'/%3E%3Crect x='12.87' y='1.37' width='1.26' height='1.26'/%3E%3Crect x='16.05' y='7.55' width='0.9' height='0.9'/%3E%3C/svg%3E") no-repeat; }
.legend:not(.rd-lg) i.sw.lg-proj.lg-scatter { -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='10'%3E%3Crect x='3.80' y='1.02' width='1.95' height='1.95'/%3E%3Crect x='3.80' y='4.03' width='1.95' height='1.95'/%3E%3Crect x='6.98' y='4.03' width='1.95' height='1.95'/%3E%3Crect x='10.16' y='1.02' width='1.95' height='1.95'/%3E%3Crect x='13.34' y='7.03' width='1.95' height='1.95'/%3E%3Crect x='16.52' y='4.03' width='1.95' height='1.95'/%3E%3Crect x='16.52' y='7.03' width='1.95' height='1.95'/%3E%3C/svg%3E") no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='10'%3E%3Crect x='3.80' y='1.02' width='1.95' height='1.95'/%3E%3Crect x='3.80' y='4.03' width='1.95' height='1.95'/%3E%3Crect x='6.98' y='4.03' width='1.95' height='1.95'/%3E%3Crect x='10.16' y='1.02' width='1.95' height='1.95'/%3E%3Crect x='13.34' y='7.03' width='1.95' height='1.95'/%3E%3Crect x='16.52' y='4.03' width='1.95' height='1.95'/%3E%3Crect x='16.52' y='7.03' width='1.95' height='1.95'/%3E%3C/svg%3E") no-repeat; }  /* missed: even random scatter, like the Savings bar */
.legend i.sw.lg-line { width: 2px; background: var(--ink); }
.legend i.sw.lg-now { width: 1px; background: var(--nowc); position: relative; overflow: visible; margin: 0 7px 0 3px; }  /* 1px line, 7x4 arrows: as the chart's now marker */
.legend i.sw.lg-now::before { content: ""; position: absolute; left: -3px; top: -2px; border: 3.5px solid transparent; border-top-width: 4px; border-top-color: var(--nowc); border-bottom: 0; }
/* Context card, Headroom view: 2px peak tick on the row bar (behind the text, like the other markers); tip line under the rows */
.rbar .pk { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--ink); opacity: .75; z-index: 0; }
.ctx-tip { display: flex; align-items: center; gap: 6px; margin: 8px 0 4px; font-size: var(--fs-small); color: var(--ink); }
.ctx-sub { margin: 0 0 8px; }
/* Provider badges, sparkline */
.pbadge { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 2px; background: var(--tone); color: #fff; font-size: var(--fs-label); font-weight: 800; letter-spacing: 0; flex: none; }
.rbar .lbl { display: inline-flex; align-items: center; gap: 8px; }
.rbar .lbl { max-width: 100%; min-width: 0; } .rbar .lbl .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }  /* long model names end in … instead of a hard cut */  /* clear space round provider logos (brand rule: no crowding) */
.rbar .lbl .os { display: inline-flex; align-items: center; gap: 4px; min-width: 0; color: var(--muted); font-size: var(--fs-small); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }  /* Machines: OS glyph + name */
/* Header switch (headSeg in app.js): packed title, switch (6px gap), tag at the far right; segFit moves the switch to the
   body's first row when they don't fit */
h2.has-seg { display: flex; align-items: center; gap: 6px; }
h2.has-seg > .hseg { margin: 0; } h2.has-seg > .tag { margin-left: auto; } h2.has-seg > .tag:empty { display: none; }
h2.seg-measure > * { width: max-content; flex: none; white-space: nowrap; }
.hseg { display: flex; width: fit-content; max-width: 100%; text-transform: none; letter-spacing: 0; font-weight: 400; }
.hseg button { min-height: 24px; }
.card > h2 + .hseg { margin: 0 auto 8px; }
.plogo { width: 16px; height: 16px; flex: none; color: var(--ink); }  /* marks: own colours; monochrome parts (currentColor) in the theme ink */
.pace-l { white-space: nowrap; } .pace-l b { display: inline-block; min-width: 4.2ch; font-variant-numeric: tabular-nums; }  /* 50%..200%: the slider never shifts */
.rdet .pace-row { gap: 8px; margin: 2px 0 0; }  /* What if, under a Quota row's mini chart: label, then the track to the right edge */
.wi-track { position: relative; flex: 1; display: flex; } .wi-track .pace-slider { flex: 1; }
.wi-track::before { content: ""; position: absolute; left: calc(1px + (100% - 2px) / 3); top: 50%; width: 1px; height: 8px; margin: -4px 0 0 -0.5px; background: var(--muted); pointer-events: none; }  /* 100% on 50%–200% */
.pace-slider:focus { outline: none; } .pace-slider:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
/* Alert tag in the card title row */
h2.h-tag { display: flex; align-items: center; gap: 6px; }
h2.h-tag .tag { margin-left: auto; }
h2.h-tag .tag { text-transform: none; letter-spacing: 0; font-weight: 400; }

/* Free tier (plan 05-01): one-line teaser for Pro content */
.locked { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: var(--fs-small); padding: 4px 0; }
.locked .ico { width: 14px; height: 14px; flex: none; }
.locked .pill.pro, h2 .pill.pro { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; }
h2 .pill.pro .ico { width: 12px; height: 12px; }
.locked-card h2 { margin: 0; }
.locked-desc { color: var(--muted); font-size: var(--fs-small); margin-top: 2px; }
.locked-card h2.h-tag { justify-content: flex-start; } .locked-card h2.h-tag .tag { margin-left: auto; }
.mos { display: inline-flex; align-items: center; gap: 3px; flex: none; }  /* Projects: an OS mark per machine it ran on */
.mos .os .plogo { width: 12px; height: 12px; }
.mdot { width: 10px; height: 10px; border-radius: 2px; display: inline-block; background: var(--muted); }  /* machine with no known OS mark */
/* pace slider: custom track + square thumb (2px radius like other controls); input stays 24px tall for touch */
.pace-slider { -webkit-appearance: none; appearance: none; background: transparent; }
.pace-slider::-webkit-slider-runnable-track { height: 2px; border-radius: 2px; background: linear-gradient(to right, var(--brand) var(--p, 50%), var(--line) 0); }
.pace-slider::-moz-range-track { height: 2px; border-radius: 2px; background: var(--line); } .pace-slider::-moz-range-progress { height: 2px; border-radius: 2px; background: var(--brand); }
.pace-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 2px; height: 12px; margin-top: -5px; border-radius: 1px; background: var(--brand); border: 1px solid var(--brand-edge); box-sizing: border-box; }
.pace-slider::-moz-range-thumb { width: 2px; height: 12px; border-radius: 1px; background: var(--brand); border: 1px solid var(--brand-edge); box-sizing: border-box; }
.legend i.sw.lg-tick { width: 0; background: none; border-left: 2px dotted color-mix(in srgb, var(--ink) 45%, transparent); height: 10px; border-radius: 0; }
.btab { width: 100%; margin-top: 6px; font-variant-numeric: tabular-nums; }
.btab td .lbl { display: inline-flex; align-items: center; gap: 8px; }  /* clear space round provider logos (brand rule: no crowding) */
.btab tr.usual td { color: var(--muted); border-bottom: 0; }
.ap { font-size: .64em; letter-spacing: .02em; }
.ap.am { vertical-align: .38em; line-height: 0; }  /* x-height top level with the digit tops */ .ap.pm { vertical-align: baseline; }
.legend i.sw.lg-band { background: color-mix(in srgb, var(--ptone, var(--s1)) 22%, transparent); }
.chart .likely { stroke: var(--s1); stroke-width: 1.6; stroke-dasharray: 3 3; stroke-linecap: round; }
.btab tr.qfill { background: linear-gradient(90deg, color-mix(in srgb, var(--tone) 24%, transparent) calc(var(--u) - 2px), var(--tone) calc(var(--u) - 2px) var(--u), transparent var(--u)); }
.receipt .muted { font-size: inherit; }

/* Explore polish */
/* s7 red completes the non-provider palette CAT = s6 s3 s4 s5 s7 (validated in that order, light and dark) */
:root { --s7: #e34948; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --s7: #e66767; } }
:root[data-theme="dark"] { --s7: #e66767; }
.s7 { fill: var(--s7); } .legend i.s7 { background: var(--s7); }
/* s8: Antigravity provider hue (blue #537fc4, both themes; owner 2026-11-09) */
:root { --s8: #537fc4; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --s8: #537fc4; } }
:root[data-theme="dark"] { --s8: #537fc4; }
.s8 { fill: var(--s8); } .legend i.s8 { background: var(--s8); } .clock .radar.s8 { stroke: var(--s8); }
/* Provider series (owner 2026-11-09, docs/research/provider-colours-2026-11.md): s0 Codex/OpenAI, s1 Claude/Anthropic clay,
   s8 Antigravity, s9 Ollama slate, s10..s18 the rest. All 13 pass the dataviz CVD and normal-vision checks in canonical order
   (adjacent), light on #fff and dark on #1a1f25; accepted fails: slate chroma, clay/pink brightness in dark. Order and the 6-series cap live in SERIES (app.js). */
:root { --s9: #3e516b; --s10: #0000f2; --s11: #f84fcc; --s12: #9d174d; --s13: #6b85ff; --s14: #65a30d; --s15: #615ced; --s16: #a16207; --s17: #7624f4; --s18: #e54d5e; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --s9: #5c708c; --s10: #2661fe; --s11: #f84fcc; --s12: #c42a68; --s13: #5878fd; --s14: #5f7106; --s15: #615ced; --s16: #b67628; --s17: #7f3aff; --s18: #e0485a; } }
:root[data-theme="dark"] { --s9: #5c708c; --s10: #2661fe; --s11: #f84fcc; --s12: #c42a68; --s13: #5878fd; --s14: #5f7106; --s15: #615ced; --s16: #b67628; --s17: #7f3aff; --s18: #e0485a; }
.s9 { fill: var(--s9); } .legend i.s9 { background: var(--s9); } .clock .radar.s9 { stroke: var(--s9); }
.s10 { fill: var(--s10); } .legend i.s10 { background: var(--s10); } .clock .radar.s10 { stroke: var(--s10); }
.s11 { fill: var(--s11); } .legend i.s11 { background: var(--s11); } .clock .radar.s11 { stroke: var(--s11); }
.s12 { fill: var(--s12); } .legend i.s12 { background: var(--s12); } .clock .radar.s12 { stroke: var(--s12); }
.s13 { fill: var(--s13); } .legend i.s13 { background: var(--s13); } .clock .radar.s13 { stroke: var(--s13); }
.s14 { fill: var(--s14); } .legend i.s14 { background: var(--s14); } .clock .radar.s14 { stroke: var(--s14); }
.s15 { fill: var(--s15); } .legend i.s15 { background: var(--s15); } .clock .radar.s15 { stroke: var(--s15); }
.s16 { fill: var(--s16); } .legend i.s16 { background: var(--s16); } .clock .radar.s16 { stroke: var(--s16); }
.s17 { fill: var(--s17); } .legend i.s17 { background: var(--s17); } .clock .radar.s17 { stroke: var(--s17); }
.s18 { fill: var(--s18); } .legend i.s18 { background: var(--s18); } .clock .radar.s18 { stroke: var(--s18); }
/* 2026-11-11 agents after OmniRoute: s19 Gemini CLI, s20 OpenCode, s21 Amp, s22 Aider, s23 Goose, s24 Grok/xAI. The full 19 in
   canonical order pass the dataviz CVD (>=8) and normal-vision (>=15) checks on adjacent pairs, light and dark
   (docs/research/provider-colours-2026-11.md, "New agents"). Near-twins that never touch in canonical order are listed there. */
/* Dark s14 Z.ai #6fa12a->#5f7106 and s24 Grok #8f588a->#e19dcb (owner 2026-11-11): Gemini/Grok and Aider/Z.ai were dark near-twins (ΔE 4.8). */
:root { --s19: #76399c; --s20: #b85df1; --s21: #38a391; --s22: #227702; --s23: #c0259c; --s24: #b278ac; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --s19: #8557a5; --s20: #b43bf7; --s21: #0d8978; --s22: #3ea61f; --s23: #e00cb5; --s24: #e19dcb; } }
:root[data-theme="dark"] { --s19: #8557a5; --s20: #b43bf7; --s21: #0d8978; --s22: #3ea61f; --s23: #e00cb5; --s24: #e19dcb; }
.s19 { fill: var(--s19); } .legend i.s19 { background: var(--s19); } .clock .radar.s19 { stroke: var(--s19); }
.s20 { fill: var(--s20); } .legend i.s20 { background: var(--s20); } .clock .radar.s20 { stroke: var(--s20); }
.s21 { fill: var(--s21); } .legend i.s21 { background: var(--s21); } .clock .radar.s21 { stroke: var(--s21); }
.s22 { fill: var(--s22); } .legend i.s22 { background: var(--s22); } .clock .radar.s22 { stroke: var(--s22); }
.s23 { fill: var(--s23); } .legend i.s23 { background: var(--s23); } .clock .radar.s23 { stroke: var(--s23); }
.s24 { fill: var(--s24); } .legend i.s24 { background: var(--s24); } .clock .radar.s24 { stroke: var(--s24); }
.legend .plogo { width: 12px; height: 12px; margin-right: 4px; vertical-align: -1px; }  /* legend chip: swatch, then the provider's mark */
/* Model family = a shade of its maker's SERIES colour (explore.js FAM_PROV); one maker's families step in lightness (Opus darkest) */
.mix .grid { stroke: var(--line); }
.fm { fill: var(--fm); } .legend i.fm { background: var(--fm); } .clock .radar.fm { stroke: var(--fm); }
.fm-opus { --fm: color-mix(in oklab, var(--s1) 58%, #000); } .fm-fable { --fm: color-mix(in oklab, var(--s1) 78%, #000); }
.fm-sonnet { --fm: var(--s1); } .fm-haiku { --fm: color-mix(in oklab, var(--s1) 58%, #fff); }
.fm-gemini { --fm: var(--s8); } .fm-hermes { --fm: var(--s10); } .fm-gpt { --fm: var(--s0); } .fm-minimax { --fm: var(--s12); }
.fm-deepseek { --fm: var(--s13); } .fm-glm { --fm: var(--s14); } .fm-qwen { --fm: var(--s15); } .fm-kimi { --fm: var(--s16); } .fm-grok { --fm: var(--s24); }
@media (max-width: 520px) { .clock-legend { grid-template-columns: repeat(2, minmax(0, 1fr)); } }  /* phone: 2 columns so names show in full beside their logos */
.qcredit { padding: 2px 0 0; font-size: var(--fs-label); }
.clock .radar.s3 { stroke: var(--s3); }
.clock text.dl { font-weight: 600; fill: var(--ink); }  /* dial hours: 10px chart text (normLabels sizes .micro) */
.sankey { width: 100%; margin: 4px 0; }  /* inside the 8px card padding */
/* Weekly rhythm Shade: one --heat ramp (opacity from JS); today = ink outline, not a colour cue */
.rhythm .cell, .clock .wedge.shade { fill: var(--heat); }
.rhythm .cell.today, .clock .wedge.today { fill: var(--heat); stroke: var(--ink); stroke-width: 1; }
/* empty heat cells: 1px --line outline, no fill (transparent keeps them tappable); today keeps its ink outline */
.heat .cell.none, .rhythm .cell.none, .clock .wedge.none { fill: transparent; fill-opacity: 1; stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.rhythm .cell.none.today, .clock .wedge.none.today { stroke: var(--ink); }
.legend i.sw.shade { background: var(--heat); }
.legend i.sw.shade-today { background: transparent; box-shadow: inset 0 0 0 1.5px var(--ink); }
/* Day compare: ink text on a tint of the set's colour (>= 4.5:1 in both themes) */
.daychip.a { background: color-mix(in srgb, var(--s6) 24%, var(--card)); border-color: var(--s6); color: var(--ink); }
.daychip.b { background: color-mix(in srgb, var(--s3) 24%, var(--card)); border-color: var(--s3); color: var(--ink); }
.dc .dc-legend { row-gap: 2px; margin: 2px 0 8px; }
.dc .fb-presets { justify-content: center; margin-bottom: 6px; }
/* Agent clock: name and share on one row; split menu at a fixed width so the $/Ŧ toggle never moves */
.clock-legend .lg { grid-template-columns: auto minmax(0, max-content) auto; justify-content: start; }
.clock-legend .lg .sw { grid-row: auto; }
.clock-ctl .t-menu .clock-sel { width: 7.4em; justify-content: space-between; }
.legend i.sw.lg-med { background: var(--muted); }
.trend.cachet .line { stroke: var(--s1); }  /* cache hits are Claude only */
.pricey td:first-child, .pricey th:first-child { white-space: nowrap; width: 1%; padding-right: 10px; }  /* When: as wide as its date, no more (owner 2026-11-10; was 4.6em) */
/* Top turns: a bar behind each row, --w = its Ŧ or $ vs the largest row (set by JS); a light tint so the text stays readable */
.pricey tr { background: linear-gradient(90deg, color-mix(in srgb, var(--tone) 24%, transparent) calc(var(--w, 0%) - 2px), var(--tone) calc(var(--w, 0%) - 2px) var(--w, 0%), transparent var(--w, 0%)); }  /* as .btab tr.qfill */
.rows td .muted { font-size: var(--fs-label); }
.pricey .pill.cold { padding: 0 4px; color: var(--ice); border-color: currentColor; }  /* Top turns: cache expired before this turn; ice blue (owner 2026-11-10) */
.pricey .gapc { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 2px 6px; white-space: nowrap; }  /* cold at the column's left edge, so the tags line up (owner 2026-11-10); the gap stays right; on a narrow phone cold goes above it */
.pricey .gapc > :last-child { margin-left: auto; }
.pricey .ico.cache-st { width: 22px; height: 22px; vertical-align: -5px; }  /* cache state marks (owner 2026-11-10) */
.pricey .ico.cold { fill: var(--ice); } .pricey .ico.warm { fill: var(--warm); } .pricey .ico.hot { fill: var(--hot); }
.pricey td:nth-child(2) { overflow-wrap: normal; }  /* project names never break mid-word */
.pricey tr.far { background: linear-gradient(90deg, color-mix(in srgb, var(--tone) 24%, transparent) var(--w, 0%), transparent var(--w, 0%)); }  /* no end line where it would cross the % */
.rbars .rbar .r { padding: 0 4px; text-shadow: 1px 0 0 var(--card), -1px 0 0 var(--card), 0 1px 0 var(--card), 0 -1px 0 var(--card); }  /* Quota: 1px card-colour halo keeps text readable over the projection without hiding the bar */

/* merged cards: cache hit strip in Savings, records strip in This week, sawtooth line in its machine colour */
.hit-row { margin-top: 12px; }
.hit-row i.sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; vertical-align: -1px; }  /* provider swatch; value text stays ink */
.rec-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 8px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); font-size: var(--fs-label); font-variant-numeric: tabular-nums; }
.rec-strip > span { white-space: nowrap; }
.rec-strip .ico { flex: none; width: 14px; height: 14px; color: var(--muted); }
.rec-strip .muted { font-size: var(--fs-label); }
.saws .line.s0 { stroke: var(--s0); } .saws .line.s1 { stroke: var(--s1); } .saws .line.s2 { stroke: var(--s2); } .saws .line.s3 { stroke: var(--s3); }
.saws .line.s4 { stroke: var(--s4); } .saws .line.s5 { stroke: var(--s5); } .saws .line.s6 { stroke: var(--s6); }
.saws .line.s-other { stroke: var(--muted); }

/* Row bars: tap a row to open its detail (rowPop in app.js) */
.rbar.tap { cursor: pointer; } .rbar.tap:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.rbar.tap[aria-expanded="true"] { box-shadow: inset 0 0 0 1px var(--ink); }
/* Quota headline (explore.js quotaSum): worst state + count, the tightest limit, one muted line per other provider.
   Tone = icon + word, never colour alone. A tapped line flashes its row with the focus ring. */
/* Status card: quota gauges (one per provider, equal size, 2 a row on a phone), machine tiles, then threads at the limit as
   fixed-column rows (a grid of subgrid buttons, so name, % and tag line up). Gauge drawn in a 100x100 viewBox (explore.js gDial). */
.qsum { display: grid; gap: 4px; }
.qsum > .qs-gm { display: contents; }  /* the card: the rows stay .qsum grid items (explore.js moves the wrapper to the masthead) */
.hstat:empty { display: none; }
.g-row, .m-row { display: flex; flex-wrap: wrap; justify-content: center; }  /* every row centred as a block: short rows share the centre line */
.g-row { gap: 8px; margin-bottom: 4px; }  /* explore.js gPack sets the row steps (honeycomb) and the gap to the machines */
.g-row > .g-cell { flex: 0 1 128px; padding: 0; border-radius: 50%; }  /* round focus ring and tap area: packed rows' boxes overlap at the corners */
.m-row { gap: 8px 4px; }
.m-row > .m-cell { flex: 0 0 66px; }
.g-cell, .m-cell { font: inherit; color: inherit; background: none; border: 0; padding: 2px 0; margin: 0; display: grid; justify-items: center; align-content: start; min-width: 0; cursor: pointer; border-radius: 2px; }
.g-cell:focus-visible, .m-cell:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
.g-dial { width: min(128px, 100%); height: auto; aspect-ratio: 1; display: block; }
.g-probe { position: absolute; left: -999px; top: 0; }  /* gFit measures the % here once */
.g-dial > g > path { fill: none; }  /* rings only: the logo watermark is paths too */
.g-trk { stroke: var(--track); }
.g-past { stroke: color-mix(in srgb, var(--brand) var(--gpast), var(--track)); fill: none; }  /* window time gone so far, in brand yellow #fac800 (owner 2026-11-10); 50% on dark, where 35% went olive */
.g-use { stroke: var(--tone); }
.g-pj { stroke: var(--tone); stroke-dasharray: 2 2; }  /* projected: square dots, as the Quota card's halftone */
.g-use.w7, .g-pj.w7 { stroke: color-mix(in srgb, var(--tone) 55%, var(--track)); }  /* 7d: lighter tint, premixed (solid, so nothing under it shows through) */
.g-now { stroke: var(--nowc); stroke-width: 2; transform-origin: 50px 50px; transform-box: view-box; }  /* turns about the dial centre */
.g-hit { transform-origin: 50px 0; transform-box: view-box; }
.g-hit { color: var(--bad); stroke-width: 2.2; } .g-hit circle { fill: var(--card); }
/* logo watermarks (owner 2026-11-10): quota .g-wm .24 light / .30 dark, as v299; ink text with a card halo stays >= 5:1 over it.
   Machine OS marks .28; the solid Windows and Apple marks .2, so they stay a hint behind the name and % yet recognisable. */
.g-wm { opacity: .16; } .m-wm { opacity: .18; } .m-wm:is(.windows, .windows11, .macos) { opacity: .13; }  /* owner 2026-11-10: logos back a bit */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .g-wm { opacity: .2; } }
:root[data-theme="dark"] .g-wm { opacity: .2; }
.g-in text.g-none { fill: var(--muted); }  /* no window running: muted 0% */
.g-in text, .m-in text { font-family: "QS Gauge", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
.g-in text { fill: var(--ink); font-variant-numeric: tabular-nums; stroke: var(--card); stroke-width: 1.2px; paint-order: stroke; stroke-linejoin: round; }
.g-w { font-size: 7px; font-weight: 600; }
.g-big { font-weight: 700; letter-spacing: -.02em; }
.g-ps { font-size: .55em; baseline-shift: .62em; }
.g-r { font-size: 7.5px; }  /* reset times (owner 2026-11-10: bigger) */
.g-chip { fill: var(--tone); } .g-chip.w7 { fill: color-mix(in srgb, var(--tone) 55%, var(--track)); }
.g-tag { color: var(--muted); } .g-tag.ok { color: var(--ok); } .g-tag.warn { color: var(--warn); } .g-tag.bad { color: var(--bad); }
.g-tag path { fill: var(--card); stroke: currentColor; stroke-width: .7px; }
.g-in .g-tag .g-tt { fill: currentColor; stroke: none; font-size: 6px; }
/* problem states solid (needs action), text in the card colour: light warn 9.1:1, bad 5.5:1; dark warn 11.4:1, bad 6.8:1 */
.g-tag:is(.warn, .bad) path { fill: currentColor; }
.g-in .g-out { font-size: 5.6px; font-weight: 600; }  /* run-out time under the top arc, in the tag's colour, no box */
.g-in .g-o1 { font-size: 4.2px; font-weight: 700; letter-spacing: .4px; }  /* "OUT" on the arc above it */
.g-in .g-out.warn { fill: var(--warn); } .g-in .g-out.bad { fill: var(--bad); }
.g-in .g-tag:is(.warn, .bad) .g-tt { fill: var(--card); font-weight: 600; }
.m-cell { width: 100%; }
.m-dial { width: 66px; height: 66px; display: block; }
.m-dial > path { fill: none; stroke-width: 4.5; stroke-linecap: butt; }  /* direct children only: the OS logo is paths too */
.m-in .m-nm, .m-nmp { font-size: 11.5px; font-weight: 600; }  /* size set in explore.js mSize */
.m-in .m-big { font-weight: 700; letter-spacing: -.02em; }  /* size set in explore.js mTile: the quota gauge's % on screen */
.m-in .m-ag { font-size: 10.5px; fill: var(--warn); }
.m-nm2, .m-ag2 { display: none; }
/* gauge text: one layout at every width (owner 2026-11-09: desktop text as big as the phone's); reset times in the tooltip */
.g-wd { display: none; }  /* reset times back in the gauges (owner 2026-11-10) */
.g-w { font-size: 8.5px; }
.g-in .g-tag .g-tt { font-size: 7.73px; }  /* 9.2px on a 119px phone gauge (explore.js G_U) */
.g-in .g-out.g-nw { font-size: 6.8px; font-weight: 700; }
/* Phone (600px and under, owner 2026-11-10): a short Status card. 3 gauges and 5 tiles a row, 2px gaps, 6px card sides (the
   header moves with them). Gauges drop the reset times (tooltip; tap opens the Quota row) and show OUT as one line; tiles show
   only the % inside, name and age under the tile. */
@media (max-width: 600px) {
  section.card:has(#status) { padding: 8px 6px; }
  .g-row { gap: 2px; }
  .g-row > .g-cell { flex: 0 0 calc((100% - 4px) / 3); }  /* 3 a row; a short last row centred */
  .g-dial { width: 100%; }
  .m-row { gap: 2px; }
  .m-row > .m-cell { flex: 0 0 calc((100% - 8px) / 5); min-width: 0; padding: 0; }  /* 5 a row; a short last row centred */
  .m-dial { width: 100%; height: auto; aspect-ratio: 1; transform: scale(1.058); }  /* ring (47.25 of 50 units) fills its 1/5 cell; explore.js sizes from the drawn width */
}
.m-live { stroke: var(--nowc); }
.m-late { stroke: var(--muted); }
.m-rest { stroke-opacity: .45; }  /* the rest of the ring: a tint (light: .28 read grey on a small share) */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .m-rest { stroke-opacity: .28; } }
:root[data-theme="dark"] .m-rest { stroke-opacity: .28; }
.m-late.m-rest { stroke-opacity: .28; stroke-dasharray: 9 7; }  /* late: the share solid, the rest dashed */
.qs-col { display: grid; align-content: start; column-gap: 8px; min-width: 0; }
.qs-t { grid-template-columns: minmax(0, 1fr) auto max-content; margin-top: 10px; }
.qs-h { grid-column: 1 / -1; font-size: var(--fs-label); color: var(--muted); height: 18px; line-height: 18px; }
.qs-row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; height: 28px; min-width: 0;
  font: inherit; font-size: var(--fs-small); color: var(--muted); text-align: left; white-space: nowrap; cursor: pointer; padding: 0; border: 0; background: none; }
.qs-row:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
.qs-row > svg, .qs-row > .pbadge { width: 16px; height: 16px; }
.qs-row b { color: var(--ink); font-weight: 600; }
.qs-n { text-align: right; font-variant-numeric: tabular-nums; }
.qs-name { overflow: hidden; text-overflow: ellipsis; }
.qs-row > .pill { justify-self: stretch; min-width: 76px; text-align: center; padding: 0 6px; line-height: 18px; }  /* one width in every block: stacked on a phone, the tags line up too */
.qs-more { grid-column: 1 / -1; }
.qs-flash { outline: 2px solid var(--focus-c); outline-offset: 1px; box-shadow: var(--focus-halo); }
/* key column fits the widest key (at least 64px) so the values line up */
.rdet { display: grid; grid-template-columns: minmax(64px, max-content) minmax(0, 1fr); column-gap: 8px; font-size: var(--fs-small); }
.rd-r { display: contents; } .rd-k, .rd-v { padding: 2px 0; } .rd-k { color: var(--muted); } .rd-v { color: var(--ink); overflow-wrap: anywhere; }
.rd-v.bad { color: var(--bad); } .rd-v.warn { color: var(--warn); } .rd-v.sub { color: var(--muted); }  /* muted note (5h help: forecast ranges to come) */

/* footer time-format switch */
.foot2 { text-align: center; margin: 0 0 16px; }
.linkbtn { background: none; border: 0; color: var(--muted); font: inherit; font-size: var(--fs-label); min-height: 24px; padding: 0 8px; text-decoration: underline; cursor: pointer; }
/* Row detail as an overlay (menu dropdown motion): floats over the rows, the card keeps its height */
.rpop-box { position: relative; }
.t-dropdown.rpop { left: 0; right: 0; min-width: 0; padding: 8px 10px; border-color: var(--pop-tone, var(--line)); }
.t-dropdown.rpop[data-origin="bottom-left"] { transform-origin: bottom left; }
.rpop:focus { outline: none; }
/* Row detail v2 (mockup): key figures, 48px mini chart, footer lines. Text stays ink/muted; marks take the row tone */
.rbars .qcols { grid-template-columns: var(--qc0, auto) var(--qc1, auto); }
.rdet > .rd-figs, .rdet > .rd-chart, .rdet > .rd-foot, .rdet > .pace-row, .rdet > .bview { grid-column: 1 / -1; }
.rd-figs { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); column-gap: 12px; padding-bottom: 6px; }
.rd-f { display: flex; flex-direction: column; align-items: flex-end; text-align: right; min-width: 0; }
.rd-fh { font-size: var(--fs-label); color: var(--muted); }
.rd-fn { font-size: var(--fs-head); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.2; white-space: nowrap; }
.rd-fn .u { font-size: var(--fs-label); font-weight: 400; color: var(--muted); margin: 0 1px; }
.rd-fn.bad, .rd-fn.bad .u { color: var(--bad); } .rd-fn.warn { color: var(--warn); }
.rd-fs { font-size: var(--fs-label); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.rd-chart { padding: 4px 0 2px; border-top: 1px solid var(--line); }
.rd-mini { display: block; width: 100%; height: 48px; overflow: visible; }
.rd-mini line, .rd-mini polygon, .rd-mini polyline, .rd-mini rect { vector-effect: non-scaling-stroke; }
.rd-mini .base { stroke: var(--line); stroke-width: 1; }
.rd-mini .lim { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; }
.rd-mini .used { fill: color-mix(in srgb, var(--pop-tone, var(--s0)) 32%, transparent); }
.rd-mini .avg { stroke: var(--pop-tone, var(--s0)); stroke-width: 2; }
.rd-mini .proj { stroke: var(--pop-tone, var(--s0)); stroke-width: 1; stroke-dasharray: 3 2; }
.rd-mini .hatch { stroke: color-mix(in srgb, var(--pop-tone, var(--s0)) 45%, transparent); stroke-width: 1.5; }
.rd-mini .now { stroke: var(--ink); stroke-width: 1; }
.rd-mini .out { stroke: var(--bad); stroke-width: 2; }
.rd-mini .day { fill: var(--pop-tone, var(--s0)); }
.rd-ax { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); padding-top: 2px; }
.rd-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 2px 8px; font-size: var(--fs-label); color: var(--muted); padding-top: 2px; }
.rd-lg { margin: 0; gap: 2px 10px; font-size: var(--fs-label); }
.legend i.sw.rd-sw-avg { background: color-mix(in srgb, var(--pop-tone, var(--s0)) 22%, transparent); box-shadow: inset 0 -2px 0 var(--pop-tone, var(--s0)); }
.legend i.sw.rd-sw-out { width: 2px; border-radius: 0; background: var(--bad); }
.rd-mini .ghost { fill: color-mix(in srgb, var(--pop-tone, var(--s0)) 32%, transparent); }
.rd-mini .ghl { stroke: var(--pop-tone, var(--s0)); stroke-opacity: .4; stroke-width: 1; }  /* past windows (5h session Claude detail) */
.rd-mini .fan { fill: var(--pop-tone, var(--s0)); fill-opacity: .24; }
.rd-chart .legend.rd-lg { margin-top: 2px; }
/* row detail mini chart key: marks wear the row's tone (--pop-tone), like the lines they name */
.legend.rd-lg i.sw.lg-dash { background: repeating-linear-gradient(90deg, var(--pop-tone, var(--s0)) 0 4px, transparent 4px 7px); }
.legend.rd-lg i.sw.lg-proj { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--pop-tone, var(--s0)) 60%, transparent) 0 2px, transparent 2px 4px); }
.legend.rd-lg i.sw.lg-fan { background: color-mix(in srgb, var(--pop-tone, var(--s0)) 32%, transparent); }
.legend.rd-lg i.sw.lg-ghost { background: color-mix(in srgb, var(--pop-tone, var(--s0)) 30%, transparent); }
.rd-split { display: flex; gap: 2px; height: 16px; margin: 16px 0; }  /* free Savings: the 4-segment split as one bar, 48px block like the other charts */
.rd-split .sg { flex: 0 1 0; min-width: 3px; border-radius: 2px; }
.legend .lg-x { color: var(--bad); font-weight: inherit; }  /* the run-out mark is red in the legend too */
.legend i.sw.lg-now::after { content: ""; position: absolute; left: -3px; bottom: -2px; border: 3.5px solid transparent; border-bottom-width: 4px; border-bottom-color: var(--nowc); border-top: 0; }  /* matches the now marker: arrows top and bottom */
.rbar .qx { font-size: var(--fs-small); font-weight: inherit; color: var(--bad); }  /* same size as the legend mark */
/* runs-out mark (app.js outSvg): ring + edge-to-edge slash in currentColor, 1em inline */
.xo { width: 1em; height: 1em; vertical-align: -.125em; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: butt; } b.qx, b.lg-x { display: inline-flex; align-items: center; }
.h5 svg.qx { color: var(--bad); }
/* Card help: the title (glyph + name) is a button with a faint ⓘ; the tag stays right-aligned */
.ttl { display: inline-flex; align-items: center; gap: 6px; min-width: 0; cursor: pointer; border-radius: 2px; }
.ttl .hq { width: 12px; height: 12px; color: var(--muted); opacity: .6; }  /* help mark: Phosphor info (Bold) */
.ttl:focus-visible { outline: 2px solid var(--focus-c); outline-offset: 1px; } .ttl[aria-expanded="true"] .hq { opacity: 1; }
.card h2 > .tag { flex: none; }
/* Header help panel: menu dropdown motion, fixed under the ? button */
.t-dropdown.hpanel { position: fixed; left: 8px; min-width: 0; max-width: 420px; margin-left: auto; max-height: calc(100dvh - 72px); overflow-y: auto;
  padding: 10px 12px; font-size: var(--fs-small); color: var(--ink); z-index: 30; }
.hpanel .hp-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.hpanel h2 { margin: 0; } .hpanel p { margin: 6px 0 0; line-height: 1.4; }
.hpanel h3 { margin: 10px 0 2px; font-size: var(--fs-label); text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 600; }
.hpanel .hp-x { font-size: 16px; line-height: 1; }
.hp-sw { display: inline-flex; margin: 0; vertical-align: middle; } .hp-sws { display: inline-flex; gap: 2px; }
.hpanel .lg-x { color: var(--bad); font-weight: inherit; } .hpanel b.warn { color: var(--warn); font-weight: inherit; }
.hpanel:focus { outline: none; } .hpanel .rdet { grid-template-columns: 84px minmax(0, 1fr); }  /* one key column across sections */
html.noscroll, html.noscroll body { overflow: hidden; overscroll-behavior: none; }
.t-dropdown.hpanel { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }  /* swipes scroll the help, not the app */
/* 5h session card: % of each provider's 5h limit on one clock-time chart (line colour = --tone, the provider) */
.chart.h5 { margin: 4px 0 0; overflow: visible; }
.h5 .base { stroke: var(--line); } .h5 .grid { stroke: var(--line); stroke-dasharray: 1 3; }
.h5 .lim { stroke: var(--muted); stroke-dasharray: 3 3; }
.h5 .so { fill: none; stroke: var(--tone); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.h5 .so.avg { stroke-width: 2; stroke-opacity: .85; }  /* one reading only: straight average-pace line */
.h5 .proj { stroke: var(--tone); stroke-width: 2; stroke-dasharray: 4 3; stroke-linecap: round; }
.h5 .fan { fill: var(--tone); fill-opacity: .24; stroke: none; }
.h5 .rtick { stroke: var(--tone); stroke-width: 2; }
.h5 .hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
.h5 .nowm { stroke: var(--nowc); stroke-width: 1; } .h5 .nowa { fill: var(--nowc); }  /* now: radar green on light, brand yellow on dark (owner 2026-11-08) */
/* Threads list and Swim lanes (owner 2026-11-09): every row exactly two lines on one grid. Left block (210px, 156px on a phone) =
   agent logo over the machine's OS mark, line 1 name, line 2 state · project · start, both truncated (full text in the title).
   Threads: turns | min | per turn columns under one muted header, then total over context % and its flag. Lanes: 48h strip, total. */
.rbar.thr, .thr-head { display: grid; grid-template-columns: minmax(0, 1fr) 64px 80px; column-gap: 10px; align-items: center; }
.rbar.thr.free, .thr-head.free { grid-template-columns: minmax(0, 1fr) 48px 80px; }
.thr .c.stk, .thr-head .c.stk { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.3; }  /* stacked values: turns over per turn */
.rbar.thr .c.stk { color: var(--muted); } .rbar.thr .r .tot { color: var(--ink); }  /* hierarchy: session total white, turns grey (owner 2026-11-09) */
.thr-head .c.stk { align-items: center; text-align: center; }  /* headers centred over their stacked values */
.rbar.thr:not(.lane) .c.stk { align-items: center; text-align: center; } .rbar.thr:not(.lane) > .r { text-align: center; align-items: center; justify-content: center; justify-self: center; }  /* values centred under the headers */
.rbar.thr { height: auto; min-height: 0; padding-top: 4px; padding-bottom: 4px; }
.rbar.thr .l { min-width: 0; } .rbar.thr .lbl { display: flex; width: 100%; min-width: 0; }
.thr-head { padding: 0 8px; margin: 2px 0 -2px; font-size: var(--fs-label); color: var(--muted); white-space: nowrap; }
.thr-head .c, .thr .c { text-align: right; font-variant-numeric: tabular-nums; }
.thr .c { position: relative; z-index: 1; }
.thr .tl { flex: 1; min-width: 0; line-height: 1.3; }
.thr .t1, .thr .t2 { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.thr .t2 { font-size: var(--fs-label); color: var(--muted); }
.lane > .l.tap { cursor: pointer; border-radius: 4px; } .lane > .l.tap:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }  /* Swim lanes: the left block opens the lane detail */
.rbar.thr .r { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.3; min-width: 0; max-width: 100%; justify-self: end; }
.thr .tot { font-weight: 600; }
.thr .l2 { font-size: var(--fs-label); color: var(--muted); white-space: nowrap; overflow: hidden; max-width: 100%; }
.thr .l2.tight .fw { display: none; }  /* the flag word only when it fits (explore.js fitFlags); always in the title and aria-label */
.thr .tl, .thr .c, .rbar.thr .r { text-shadow: 1px 0 0 var(--card), -1px 0 0 var(--card), 0 1px 0 var(--card), 0 -1px 0 var(--card); }  /* halo: readable over any fill */
.thr-mark { display: inline-flex; flex-direction: column; align-items: center; gap: 5px; flex: none; }  /* agent logo above the machine's OS mark */
.hmark { display: inline-grid; place-items: center; width: 11px; height: 11px; color: var(--muted); }
.hmark .plogo { width: 11px; height: 11px; }
.hmark.sq::before { content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--muted); opacity: .45; }  /* machine with no known OS */
.hmark.none { visibility: hidden; }
/* Swim lanes on the same grid: left block | 48h strip | total; top row = burn per 15 min stacked by agent */
.rbar.thr.lane, .lane-axis { grid-template-columns: 210px minmax(0, 1fr) 72px; }
.lane-axis { display: grid; column-gap: 10px; padding: 0 8px; font-size: var(--fs-label); color: var(--muted); }
.lane-axis .ticks { display: flex; justify-content: space-between; white-space: nowrap; }
.lane-strip { position: relative; align-self: stretch; margin: -1px 0; background: color-mix(in srgb, var(--muted) 10%, transparent); border-radius: 2px; z-index: 1; }
.lane-strip svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.rbar.burn-row { box-shadow: none; background: none; } .burn-row .lane-strip { background: none; }
.lane-now { position: absolute; top: -4px; bottom: -4px; width: 0; border-left: 1.5px solid var(--nowc); z-index: 2; }
@media (max-width: 600px) {
  .rbar.thr, .thr-head { grid-template-columns: minmax(0, 1fr) 56px 68px; column-gap: 8px; }
  .rbar.thr.free, .thr-head.free { grid-template-columns: minmax(0, 1fr) 44px 68px; }
  .thr .min, .thr-head .min { display: none; }
  .rbar.thr.lane, .lane-axis { grid-template-columns: 156px minmax(0, 1fr) 52px; column-gap: 8px; }
  .lane-axis .ticks span:nth-child(2) { display: none; }
}
/* Live rows (Threads, Machines, Swim lanes; owner 2026-11-09): a static 3px stripe in the now colour on the left edge, and the only
   motion, a soft highlight sweeping the bar fill left to right every 3s (lanes: the coloured cells only), staggered by --i (app.js
   liveRow). The logo stays plain. Reduced motion: no sweep; stripe and state word remain. */
.rbar.live::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--nowc); z-index: 2; pointer-events: none; }
.rbar.live > .f { overflow: hidden; }
.sheen { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(100deg, transparent 0 40%, var(--sheen) 50%, transparent 60% 100%);
  background-size: 300% 100%; background-position: 100% 0; animation: sheen 3s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.6s); }
@keyframes sheen { 0% { background-position: 100% 0; } 60%, 100% { background-position: 0 0; } }
.sheen-r { animation: sheen-x 3s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.6s); }
@keyframes sheen-x { 0% { transform: translateX(0); } 60%, 100% { transform: translateX(var(--sx)); } }  /* the band starts left of the lane's first cell, ends past its last (explore.js cellSheen) */
.sheen-g .e { stop-color: var(--sheen); stop-opacity: 0; } .sheen-g .m { stop-color: var(--sheen); }
/* live machine tile: the same 3s sweep as .sheen, as a short highlight dash travelling round the share arc (pathLength 100) */
.m-dial > .m-sheen { stroke: var(--sheen); stroke-dasharray: 14 200; stroke-dashoffset: 14; animation: m-sheen 3s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.6s); }
@keyframes m-sheen { 0% { stroke-dashoffset: 14; } 60%, 100% { stroke-dashoffset: -100; } }
@media (prefers-reduced-motion: reduce) { .sheen, .sheen-r, .m-sheen { display: none; } }
.thr .thr-full { font-weight: 600; white-space: nowrap; text-shadow: 1px 0 0 var(--card), -1px 0 0 var(--card), 0 1px 0 var(--card), 0 -1px 0 var(--card); }  /* halo: readable over any agent fill */ .thr .thr-full.warn { color: var(--warn); } .thr .thr-full.bad { color: var(--bad); }
.h5 text.qx { fill: var(--bad); font-weight: 600; } .h5 .plogo .pb { opacity: 1; } .h5 .plogo .pbt { fill: #fff; font-size: 22px; font-weight: 800; } .h5 text.dl { font-weight: 600; }
.legend.h5lg { gap: 2px 6px; font-size: var(--fs-label); }  /* one-line key under the 5h chart */
.legend i.sw.lg-dash { height: 2px; border-radius: 0; vertical-align: 3px; background: repeating-linear-gradient(90deg, var(--muted) 0 4px, transparent 4px 7px); }
.legend i.sw.lg-fan { background: color-mix(in srgb, var(--s1) 32%, transparent); }
.btab .lbl i.sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; flex: none; }
.btab .qx { color: var(--bad); font-weight: inherit; }
.btab td.idle { color: var(--muted); } .btab td.warn { color: var(--warn); } .btab td.bad { color: var(--bad); }
/* Daily use: source filter, $ | Ŧ and the cache-reads switch on one wrapping row; cache reads = faint top segment */
/* Daily use source switch: All | provider menu as one segmented control; visible overflow so the menu list shows */
.seg.src-pick { overflow: visible; }
.src-pick .t-menu .clock-sel { height: 22px; border: 0; border-left: 1px solid var(--line); border-radius: 0; background: var(--card); color: var(--muted); }
.src-pick.on .t-menu .clock-sel { background: var(--brand); color: var(--ink-on-brand); } .src-pick.on .t-menu .caret { color: inherit; }
.stack .faint { fill-opacity: .3; } .legend i.faint { opacity: .3; }
/* Tabs (owner-approved 2026-11-05; Insights added 2026-11-07): Quota | Usage | Trends | Threads | Insights. Phone: fixed bottom bar; desktop (900px+): a bar under the header.
   Phone bar, raised mock (owner 2026-11-07): 44px incl. the 1px top border, 5 equal tabs, 28px icons. Inactive = icon only; the active
   tab rises --tabbar-raise above the bar (58px tall, anchored to the bar bottom) with its label under the icon. Every tab is the
   full 58px box; clip-path cuts inactive ones (and their tap area) to the bar, and the brand fill (::before) slides up or down.
   Inactive labels are transparent, not display:none, so they stay in each link's accessible name. */
:root { --tabbar-h: calc(44px + env(safe-area-inset-bottom)); --tabbar-raise: 0px; --tab-t: var(--duration-fast) var(--ease-smooth-out); }
body { padding-bottom: calc(40px + var(--tabbar-h) + var(--tabbar-raise)); }  /* 40px: the footer clears the freshness pill */
nav.tabs { z-index: 15; backdrop-filter: saturate(1.4) blur(8px); -webkit-backdrop-filter: saturate(1.4) blur(8px); }
nav.tabs a { font-family: "Oxanium", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; font-weight: 500; position: relative; display: flex; align-items: center; justify-content: center; box-sizing: border-box; color: var(--muted); text-decoration: none;
  font-size: var(--fs-label); font-weight: 650; white-space: nowrap; -webkit-tap-highlight-color: transparent; }
nav.tabs a[aria-current="page"] { color: var(--ink-on-brand); }
nav.tabs a:focus-visible { outline: 2px solid var(--focus-c); outline-offset: -4px; box-shadow: var(--focus-halo); }
@media (max-width: 899.98px) {
  :root { --tabbar-raise: 18px; }  /* = the updated pill's height (10px text: 12px line + 2px/3px padding + 1px top border) */
  nav.tabs { position: fixed; left: 0; right: 0; bottom: 0; display: grid; grid-template-columns: 1fr 1fr 1.4fr 1fr 1fr; grid-template-rows: 43px; align-items: end;
    box-sizing: border-box; height: var(--tabbar-h); padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    background: color-mix(in srgb, var(--card) 92%, transparent); border-top: 1px solid var(--line); }
  nav.tabs a { display: block; min-width: 0; height: calc(44px + var(--tabbar-raise)); clip-path: inset(calc(var(--tabbar-raise) + 1px) 0 0 0); }  /* end-aligned in a 43px row: overflows upward over the border and the raise */
  nav.tabs a[aria-current="page"] { clip-path: none; }
  /* owner 2026-11-11: one yellow highlight slides under the tabs (like the .seg pill); the tabs themselves change state instantly.
     Per-tab fills that rose and fell flickered on Android Chrome during the cube turn.
     owner 2026-11-11: Quota (middle) is 1.4x the other tabs; app.js placeTabHl sets --tab-x/--tab-w from the active tab. Fallback = Quota. */
  nav.tabs .tab-hl { display: block; position: absolute; z-index: 0; pointer-events: none; top: calc(-1px - var(--tabbar-raise)); height: calc(44px + var(--tabbar-raise));
    left: 0; width: var(--tab-w, calc((100% - env(safe-area-inset-left) - env(safe-area-inset-right)) * 1.4 / 5.4)); border-radius: 2px 2px 0 0; background: var(--brand);
    box-shadow: inset 0 0 0 1px var(--brand-edge), 0 -1px 6px rgb(0 0 0 / .14); transform: translateX(var(--tab-x, calc(env(safe-area-inset-left) + 100% / 0.7)));
    transition: transform var(--tabs-dur) var(--tabs-ease), width var(--tabs-dur) var(--tabs-ease); }
  nav.tabs a .ico { position: absolute; left: calc(50% - 18px); top: 5px; width: 36px; height: 36px; transform: translateY(var(--tabbar-raise)); }
  nav.tabs a > span { position: absolute; left: 0; right: 0; top: 42px; line-height: 14px; text-align: center; opacity: 0; transform: translateY(var(--tabbar-raise)); }
  nav.tabs a[aria-current="page"] .ico, nav.tabs a[aria-current="page"] > span { transform: none; opacity: 1; }
  /* brand bar (owner 2026-11-10): the manifest's #0f2a1a, so it runs into Android's green system bar; light icons, yellow active tab */
  nav.tabs { background: #0f2a1a; border-top: 1px solid color-mix(in srgb, var(--brand) 55%, #0f2a1a); grid-template-rows: 43px; box-shadow: 0 -2px 8px rgb(0 0 0 / .18);  /* yellow top line + lift shadow (owner 2026-11-10) */
    backdrop-filter: none; -webkit-backdrop-filter: none; }
  nav.tabs a { color: #c9d6cd; } nav.tabs a[aria-current="page"] { color: var(--ink-on-brand); }
  nav.tabs a .tdot { box-shadow: 0 0 0 2px #0f2a1a; }
  .readout { bottom: calc(6px + var(--tabbar-h) + var(--tabbar-raise)); }  /* 6px above the raised tab */
}
.tab-hl { display: none; }
.tabp[hidden] { display: none !important; }
.tabp > .card { scroll-margin-top: calc(var(--hdr-h) + env(safe-area-inset-top)); }  /* clears the sticky header */
/* Desktop (owner 2026-11-07): a left rail under the full-width header; the page shifts right by the rail. */
@media (min-width: 900px) {
  :root { --tabbar-h: 0px; --rail-w: 176px; }
  body { padding-left: calc(var(--rail-w) + 16px); }
  .top { max-width: none; margin-left: calc(-8px - var(--rail-w)); margin-right: 0; }  /* header keeps the full width, logo above the rail */
  nav.tabs { position: fixed; top: calc(var(--hdr-h) + env(safe-area-inset-top)); left: 0; bottom: 0; width: var(--rail-w); display: flex; flex-direction: column; gap: 4px;
    padding: 8px max(8px, env(safe-area-inset-left)); overflow-y: auto; backdrop-filter: none; -webkit-backdrop-filter: none; }  /* no fill or divider: the clouds show behind the rail (owner 2026-11-07) */
  nav.tabs a { flex: none; justify-content: flex-start; gap: 10px; height: 44px; padding: 0 10px; border-radius: 2px; font-size: var(--fs-small); font-weight: 500;
    transition: background-color var(--tab-t), color var(--tab-t); }
  nav.tabs a:hover { color: var(--ink); }
  nav.tabs a:not([aria-current="page"]) > span { padding: 0 2px; border-radius: 2px;  /* label scrim, as the header's: keeps the muted text readable */
    background: color-mix(in srgb, var(--bg) 87%, transparent); box-shadow: 0 0 8px 4px color-mix(in srgb, var(--bg) 87%, transparent); }
  nav.tabs a[aria-current="page"] { font-weight: 500; background: var(--brand); box-shadow: inset 0 0 0 1px var(--brand-edge); }
  nav.tabs a .ico { width: 24px; height: 24px; }  /* desktop rail 24px (owner 2026-11-10: 36 too big here; phone stays 36) */
}
@media (min-width: 900px) {
  .tabp > .card { scroll-margin-top: calc(64px + env(safe-area-inset-top)); }  /* clears the sticky header */
}
.details.tabp { margin-top: 0; }
@media (prefers-reduced-motion: reduce) { nav.tabs a, nav.tabs .tab-hl { transition: none; } }
/* Tips card (Insights tab). Dot on the Insights tab icon = a tip not seen yet on this device. */
.tdot { position: absolute; width: 8px; height: 8px; border-radius: 50%; background: var(--bad); box-shadow: 0 0 0 2px var(--card); pointer-events: none; }
.tdot[hidden] { display: none; }
nav.tabs a .tdot { top: calc(4px + var(--tabbar-raise)); left: calc(50% + 10px); }  /* top right of the 36px glyph while the tab is inactive */
@media (min-width: 900px) { nav.tabs a .tdot { top: 8px; left: 28px; } }
.tips-body { margin-top: 6px; }
.tips-body .tip, .tips-body .tipgo { display: block; width: 100%; text-align: left; font: inherit; color: var(--ink); background: none; border: 0; padding: 0; }
.tips-body .tip + .tip { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.tips-body .tip strong { font-size: var(--fs-small); }
.tips-body .sub { margin-top: 4px; line-height: 1.4; }
.tip-cost { margin-top: 4px; font-weight: 600; font-variant-numeric: tabular-nums; }
.tips-body .tip-cost { font-size: var(--fs-small); }
.tip-why { margin-top: 2px; font-size: var(--fs-label); color: var(--muted); font-variant-numeric: tabular-nums; }
.tips-body .locked { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
/* Tools card: a short list of GitHub links, grouped by category */
#tools .tool-cat { margin: 10px 0 2px; font-size: var(--fs-label); font-weight: 600; color: var(--muted); }
#tools .tool-cat:first-child { margin-top: 0; }
#tools .tool { padding: 4px 0; }
#tools .tool a { display: inline-block; min-height: 24px; line-height: 24px; font-size: var(--fs-small); font-weight: 600; color: var(--accent); text-decoration: none; }
#tools .tool a:hover { text-decoration: underline; }
#tools .tool a:focus-visible { outline: 2px solid var(--focus-c); outline-offset: 2px; box-shadow: var(--focus-halo); border-radius: 2px; }
#tools .tool .sub { margin-top: 0; }
#tools .tool-chk { margin-top: 10px; font-size: var(--fs-label); }
/* Log card: one compact line per event, icon | time | host + text */
.log { list-style: none; margin: 0; padding: 0; }
ul.log { display: grid; grid-template-columns: 20px auto auto auto 1fr;  /* 20 = 14px icon + the row's 6px side padding, which a subgrid takes from its edge tracks */ column-gap: 8px; align-items: baseline; font-size: var(--fs-small); }
.log-row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: baseline; padding: 5px 6px; border-radius: 2px; }  /* subgrid: one set of columns, full-width rule */
.log-row:nth-child(even) { background: color-mix(in srgb, var(--line) 70%, var(--card)); }  /* two-tone rows (owner 2026-11-10), from the theme line colour so both themes stripe */
.log-row .ico { width: 14px; height: 14px; align-self: start; margin-top: 2px; color: var(--muted); }
.log-d, .log-t { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.log-t { text-align: right; }
.log-h { font-weight: 600; white-space: nowrap; }
.log-x { min-width: 0; overflow-wrap: anywhere; }
#log-body .locked { margin-top: 4px; }
.tipgo { cursor: pointer; border-radius: 2px; min-height: 24px; }
.tipgo:focus-visible { outline: 2px solid var(--focus-c); outline-offset: 2px; box-shadow: var(--focus-halo); }
.tip-to { display: inline-block; margin-top: 6px; font-size: var(--fs-label); font-weight: 600; color: var(--accent); }
.tip-tool { display: inline-block; margin-top: 6px; min-height: 24px; line-height: 24px; font-size: var(--fs-label); font-weight: 600; color: var(--accent); text-decoration: none; }
.ico.ext { width: 1em; height: 1em; margin-right: 4px; vertical-align: -0.15em; }  /* GitHub / website mark before an external link */
.tip-tool:hover { text-decoration: underline; }
.tip-tool:focus-visible { outline: 2px solid var(--focus-c); outline-offset: 2px; box-shadow: var(--focus-halo); border-radius: 2px; }
.tipgo + .tip-tool { margin-top: 0; }
/* Header buttons (owner review 2026-11-05). Ŧ|$ ? 🔔: hit box = the 24px frame (owner: buttons closer
   together, 8px apart); the frame is ::before, glyph 14px. */
.topr > .iconbtn { position: relative; isolation: isolate; width: 32px; height: 32px; border: 0; background: none; }
.topr > .iconbtn::before { content: ""; position: absolute; inset: 2px; z-index: -1; border: 1px solid var(--line); border-radius: 2px; background: var(--card); }
.topr > .iconbtn[aria-pressed="true"] { background: none; }
.topr > .iconbtn[aria-pressed="true"]::before { background: var(--brand); border-color: var(--brand-edge); }
.topr > .iconbtn svg { width: 18px; height: 18px; }  /* phone: 32px buttons, 18px glyphs (owner 2026-11-10); drawn ~15px = the $ at 18px */
/* Ŧ | $ unit switch: a .seg (sliding pill) with a 44x24 frame in a 28px touch row, 2px side margins so frames stay 8px apart */
.topr > .useg { flex: none; isolation: isolate; height: 32px; margin: 0 2px; border: 0; overflow: visible; }
.useg::before { content: ""; position: absolute; inset: 2px 0; z-index: -1; border: 1px solid var(--line); border-radius: 2px; background: var(--card); }
.useg .t-tabs-pill { top: 2px; bottom: 2px; border-radius: 2px; }
.useg button { width: 26px; height: 32px; padding: 0; font-family: "Oxanium Unit", system-ui, sans-serif; font-size: 16px; font-weight: 400; line-height: 1; border-radius: 2px; color: var(--ink); }  /* owner 2026-11-07: normal weight; 2026-11-11: Oxanium 400, sized so Ŧ / $ sit level with the 18px icons */
.useg button[aria-pressed="true"] { color: var(--ink-on-brand); }
.useg:not(.has-pill) button[aria-pressed="true"] { background: var(--brand); box-shadow: inset 0 0 0 1px var(--brand-edge); }  /* before motion.js adds the pill */
/* Desktop header (owner 2026-11-07): 84px, mark and wordmark 72px (was 68/56, owner 2026-11-08), 32px frames in 36px touch areas, 16-18px glyphs */
@media (min-width: 900px) {
  :root { --hdr-h: 130px; } .top { --wm-n: 72; }  /* 130px (was 104, owner 2026-11-10): masthead gauges at the phone's size */
  .topr > .iconbtn { width: 40px; height: 40px; } .topr > .iconbtn svg { width: 22px; height: 22px; }  /* 40px, 22px glyphs (owner 2026-11-10): ~ the phone's glyph/frame ratio */
  .topr > .useg { height: 40px; } .useg button { width: 32px; height: 40px; font-size: 19px; }
  .hmsg { font-size: 14px; }
  /* Masthead gauges (owner 2026-11-10): the brand fills the rail width, so the row starts at the cards' left edge. Quota
     gauges 119px (as a phone's, so the fixed text sizes match), machine rings 76px, one row, a thin divider between; .hmsg
     keeps the room up to the buttons. */
  .brand { min-width: var(--rail-w); }
  .hstat { display: flex; flex: 0 1 auto; min-width: 0; align-items: center; margin-right: auto; }
  .hstat > .qs-gm { display: flex; align-items: center; gap: 12px; min-width: 0; }
  .hstat .g-row, .hstat .m-row { flex-wrap: nowrap; gap: 4px; margin: 0; }
  .hstat .g-row { flex: none; }  /* quota gauges always whole; machine rings take what is left and scroll sideways, faded at the edge */
  .hstat .m-row { min-width: 0; overflow-x: auto; scrollbar-width: none; justify-content: flex-start; }  /* centred would cut the first ring off */
  .hstat .m-row::-webkit-scrollbar { display: none; }
  .hstat .m-row.m-more { mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); }
  .hstat .g-row > .g-cell { flex: 0 0 119px; margin: 0; } .hstat .g-dial { width: 119px; }
  .hstat .m-row > .m-cell { flex: 0 0 76px; width: 76px; } .hstat .m-dial { width: 76px; height: 76px; }
  .hstat .g-row { order: 0; } .hstat .m-row { order: 2; }
  .hstat > .qs-gm:has(> .g-row):has(> .m-row)::after { content: ""; order: 1; width: 1px; height: calc(var(--hdr-h) * .6); background: var(--line); }
}
.useg button:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); z-index: 2; }
/* Freshness pill (owner 2026-11-06): fixed bottom-right, on the bar, on the side away from the raised tab; muted while fresh, the amber
   warn pill (late or offline) and red error keep their colour and shake. 10px text: owner exception 2026-11-05. */
#fresh { position: fixed; z-index: 14; right: max(8px, env(safe-area-inset-right)); bottom: calc(var(--tabbar-h) + 6px); pointer-events: none; font-size: 10px; line-height: 1.2;
  transition: transform var(--tab-t); }
#fresh.left { transform: translateX(var(--fresh-x, 0px)); }  /* app.js freshSide: the raised tab is under the right-hand spot */
#fresh.swap { animation: fresh-swap var(--tab-t); }
@keyframes fresh-swap { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #fresh { transition: none; } #fresh.swap { animation: none; } }
#fresh > * { display: inline-block; padding: 2px 6px; border: 1px solid var(--line); border-radius: 2px; background: color-mix(in srgb, var(--card) 60%, transparent); color: var(--muted); font-size: inherit; white-space: nowrap; }  /* owner 2026-11-11: 60% card */
#fresh > .pill.warn { color: var(--warn); border-color: currentColor; font-weight: 600; }
#fresh > .err { color: var(--bad); border-color: currentColor; }
#fresh .fl2 { font-weight: 600; }
/* Phone: the pill sits on the bar's top edge, flush with the screen side (the bar's own edge), as tall as the raised tab */
@media (max-width: 899.98px) {
  #fresh { right: env(safe-area-inset-right); bottom: var(--tabbar-h); }
  #fresh > * { padding: 2px 6px 3px; border-width: 1px 0 0 1px; border-radius: 2px 0 0 0; }
  #fresh.left > * { border-width: 1px 1px 0 0; border-radius: 0 2px 0 0; }
}
@media (min-width: 900px) { #fresh { bottom: max(8px, env(safe-area-inset-bottom)); } }
@media (prefers-reduced-motion: reduce) {
  .topr > .iconbtn::before, .topr > .iconbtn svg { transition: none !important; }
}

.qh .qplan { margin-left: 6px; font-weight: 400; color: var(--muted); }  /* Quota: plan name after the provider (e.g. Claude Max) */
.lbl .qest { margin-left: 6px; font-weight: 400; color: var(--muted); }  /* Quota: "est." on a row from the user's own quota figure */

/* Text-clouds page background: clouds.js canvas on every device, coloured by these --cl-* vars.
   Cards, header, tab bar and pill stay opaque over it. */
:root { --cl-speed: 1;  /* drift speed of the clouds.js canvas; 0.5 = half speed */
  --cl-rows: 6;  /* glyph rows in the 52px header; sets the grid (cell 0.8:1), glyph size (5px min) and cloud size. 8 = finer */
  --cl-ink: #7f9187; --cl-gold: #b39a2a; --cl-base: .18; --cl-gain: 1;  /* owner 2026-11-10: the tab bar strength everywhere (was .03 / .5, .04 / .65, .1 / .85) */
  --cl-tab-ink: #f2fbe9; --cl-tab-gold: #fac800; --cl-tab-base: .18; --cl-tab-gain: 1; }  /* phone tab bar strip: cream on #0f2a1a, both themes */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --cl-ink: #a4afb8; --cl-gold: #fac800; --cl-base: .18; --cl-gain: 1; } }  /* was .045 / .8 */
:root[data-theme="dark"] { --cl-ink: #a4afb8; --cl-gold: #fac800; --cl-base: .18; --cl-gain: 1; }
#clouds { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
/* Clouds in the header: clouds.js draws the field's top strip into #clouds-hdr, clipped to the header box. It sits on the
   opaque .top::before base, so cards scrolling under the sticky header never show through; only the clouds do. */
.top > .hclouds { position: absolute; inset: 0; z-index: -1; pointer-events: none; clip-path: inset(0 -100vmax); transform: none !important; transition: none; }
/* Clouds in the phone tab bar: clouds.js draws the field's bottom strip into #clouds-tab, the bar's first child, over its whole
   box incl. the safe-area padding (edge-to-edge: behind Android's buttons). The links paint over it; desktop rail: none. */
#clouds-tab { display: none; }
@media (max-width: 899.98px) { #clouds-tab { display: block; position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } }
@media print { #clouds-tab { display: none; } }
#clouds-hdr { position: fixed; top: 0; left: 0; width: 100%; height: calc(var(--hdr-h) + env(safe-area-inset-top)); pointer-events: none; }
/* Scrims, as the banner's .brand::before: page colour behind the brand, the controls and the alerts note */
.top { --scrim-a: 0%; --scrim-b: 0%; }  /* none (was 87/60): one even letter field top to bottom (owner 2026-11-10); buttons keep their own frames */
.brand, .topr { position: relative; }
.brand::before, .topr::before { content: ""; position: absolute; inset: -8px -100px -8px -24px; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, color-mix(in srgb, var(--bg) var(--scrim-a), transparent) calc(100% - 100px),
    color-mix(in srgb, var(--bg) var(--scrim-b), transparent) calc(100% - 50px), transparent); }
.topr::before { inset: -8px -8px -8px -60px;
  background: linear-gradient(270deg, color-mix(in srgb, var(--bg) var(--scrim-a), transparent) calc(100% - 60px),
    color-mix(in srgb, var(--bg) var(--scrim-b), transparent) calc(100% - 30px), transparent); }
.hmsg:not([hidden]) { background: color-mix(in srgb, var(--bg) 87%, transparent); border-radius: 2px;
  box-shadow: 0 0 10px 6px color-mix(in srgb, var(--bg) 87%, transparent); }
@media print { #clouds, .hclouds { display: none; } }

/* ---- Settings (plan 05-03): the gear opens a full-screen panel with the help panel's motion; one column, max 640px ---- */
.t-dropdown.hpanel.spanel { top: 0 !important; right: 0 !important; left: 0; bottom: 0; max-width: none; max-height: none; height: 100dvh; margin: 0;
  border-radius: 0; border-width: 0; z-index: 40; background: var(--bg);
  padding: calc(10px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
.sp-wrap { max-width: 640px; margin: 0 auto; }
.spanel .hp-top { position: sticky; top: calc(-10px - env(safe-area-inset-top)); z-index: 2; background: var(--bg); padding: 4px 0; }
.spanel .hp-x { width: 32px; height: 32px; }
.spanel h3 { margin: 18px 0 4px; }
.spanel .sub { margin: 2px 0 6px; }
.sp-row { display: grid; grid-template-columns: minmax(96px, 32%) minmax(0, 1fr); gap: 2px 12px; align-items: start; padding: 8px 0; border-bottom: 1px solid var(--line); }
.sp-k { color: var(--ink); font-size: var(--fs-small); padding-top: 4px; }
.sp-v { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.sp-msg { font-size: var(--fs-label); color: var(--muted); margin: 0; }
.sp-msg:empty { display: none; }
.sp-in { font: inherit; font-size: var(--fs-body); min-height: 32px; width: 100%; max-width: 20rem; padding: 4px 8px; border-radius: 2px; border: 1px solid var(--line);
  background: var(--card); color: var(--ink); }
/* on/off switch, not a tick box (owner 2026-11-08): still a checkbox underneath, announced as a switch (role=switch).
   Motion: transitions.dev P27 toggle (owner 2026-11-10), squared to the house 2px radius and 24px control height:
   44x24 track, 22x16 thumb inset 4px, travel 14px, the bounce ease overshoots the end by about 1px. */
.sp-in[type="checkbox"] { appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 44px; min-height: 24px; height: 24px; margin: 0; padding: 0; border-radius: 2px; background: var(--track); box-shadow: inset 0 0 0 1px var(--line); cursor: pointer; transition: background var(--duration-quick); }
.sp-in[type="checkbox"]::before { content: ""; position: absolute; top: 4px; left: 4px; width: 22px; height: 16px; border-radius: 1px; background: var(--muted); transition: transform var(--p27-dur) var(--p27-ease), background var(--duration-quick); }
.sp-in[type="checkbox"]:checked { background: var(--brand); box-shadow: none; }
.sp-in[type="checkbox"]:checked::before { transform: translateX(var(--p27-travel)); background: var(--ink-on-brand); }
@media (prefers-reduced-motion: reduce) { .sp-in[type="checkbox"], .sp-in[type="checkbox"]::before { transition: none; } }
@media (forced-colors: active) { .sp-in[type="checkbox"] { border: 1px solid CanvasText; } .sp-in[type="checkbox"]:checked::before { background: CanvasText; } }
.sp-in[type="number"] { max-width: 9rem; } .sp-in[type="time"] { max-width: 9rem; }
textarea.sp-in { max-width: none; font-family: ui-monospace, monospace; font-size: var(--fs-small); resize: vertical; }
.sp-in:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
.sp-in[aria-invalid="true"] { border-color: var(--bad); } .sp-in[aria-invalid="true"] ~ .sp-msg { color: var(--bad); }
.chip.sp-btn { min-height: 32px; padding: 4px 14px; }
.chip.sp-primary { background: var(--brand); border-color: var(--brand-edge); color: var(--ink-on-brand); font-weight: 600; }
.chip.sp-btn:disabled { opacity: .6; cursor: progress; }
.chip.sp-btn:focus-visible { outline: 2px solid var(--focus-c); outline-offset: var(--focus-off); box-shadow: var(--focus-halo); }
.sp-act { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 4px; }
.sp-note { border: 1px solid var(--line); border-radius: 2px; background: var(--card); padding: 8px 10px; margin: 0 0 8px; font-size: var(--fs-small); }
.sp-pairf { margin-top: 6px; }
.sp-hosts { display: grid; gap: 6px; }
.sp-host { display: grid; grid-template-columns: minmax(48px, max-content) minmax(0, 1fr) auto 24px 24px; align-items: center; gap: 6px; font-size: var(--fs-small); }
.sp-host .sp-in { max-width: none; }
.sp-hn { overflow-wrap: anywhere; } .sp-state { color: var(--muted); font-size: var(--fs-label); display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.sp-host.is-locked .sp-hn, .sp-state.locked { color: var(--muted); }
.sp-mv { position: relative; } .sp-mv::after { content: ""; position: absolute; inset: -10px -4px; }  /* 44px tall hit area on a 24px control */
.sp-mv:disabled { opacity: .35; cursor: default; }
@media (max-width: 420px) {  /* name, state, up, down on one line; the name field under them */
  .sp-host { grid-template-columns: minmax(0, 1fr) auto 24px 24px; row-gap: 2px; padding-bottom: 6px; }
  .sp-host .sp-in { grid-column: 1 / -1; grid-row: 2; } .sp-host .sp-hn, .sp-host .sp-state, .sp-host .sp-mv { grid-row: 1; } }
.sp-devs { display: grid; gap: 6px; }
.sp-dev { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 2px 10px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.sp-dev .sub { grid-column: 1; margin: 0; } .sp-dev .sp-btn { grid-column: 2; grid-row: 1 / span 2; }
.sp-dn { font-size: var(--fs-small); font-weight: 600; }
.sp-pairbox { margin-top: 10px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
/* Away from home (Pro relay, plan 06-01): the join code is typed on another machine, so it wraps and selects whole */
.sp-relcode { margin: 0; max-width: 100%; font-family: ui-monospace, monospace; font-size: var(--fs-small); word-break: break-all; user-select: all; border: 1px solid var(--line); border-radius: 2px; padding: 6px 8px; }
.sp-away h3 { margin: 12px 0 2px; }
.sp-relshow:empty { display: none; }
/* relay origin before pairing (relay.js): one card, no tabs or freshness pill */
.qs-unpaired nav.tabs, .qs-unpaired #fresh, .qs-unpaired #alerts, .qs-unpaired .tabp, .qs-unpaired #label { display: none !important; }
.relay-pair { margin: 12px 16px; }
.sp-qr { width: 200px; height: 200px; background: #fff; padding: 6px; border-radius: 2px; image-rendering: pixelated; }
.sp-code { margin: 0; font-size: var(--fs-display); font-weight: 650; letter-spacing: .18em; font-variant-numeric: tabular-nums; }
.sp-left { font-size: var(--fs-small); color: var(--muted); }
@media (min-width: 900px) { .t-dropdown.hpanel.spanel { padding-top: 16px; } }
/* Over the machine limit: banner on Home, locked machines greyed with a lock in the Machines card */
.limit-banner { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: var(--fs-small); color: var(--ink); border-color: var(--warn); }
.limit-banner .ico { color: var(--warn); }
.limit-banner a, .spanel a { color: var(--accent); font-weight: 600; }
.rbar.host-locked { color: var(--muted); opacity: .7; }
.rbar.host-locked .lbl { display: inline-flex; align-items: center; gap: 6px; }
a.pill.pro { text-decoration: none; cursor: pointer; } a.pill.pro:hover { color: var(--ink); }
a.pill.pro:focus-visible { outline: 2px solid var(--focus-c); outline-offset: 1px; }
/* Settings as cards (owner 2026-11-08): This device, Devices, Hub, Licence (Pro settings under Licence) */
.spanel .sp-card { margin: 12px 0; padding: 10px 12px; }
.spanel .sp-card > h2 { margin: 0 0 6px; }
.spanel .sp-card h3:first-of-type { margin-top: 10px; }
/* thin marks read faint at 16px: a stroke in their own colour thickens the lines by ~0.6px (owner 2026-11-08) */
.plogo.linux path { stroke: currentColor; stroke-width: .6; stroke-linejoin: round; }
/* Orbital page (plan 05-06): the Projects card link (phone and desktop) and the desktop side-rail entry.
   The rail entry is not a tab: hidden below 900px so the phone bar keeps its 5 items. */

.c-read { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; font-size: var(--fs-small); padding: 0 10px; min-height: 26px; }  /* Daily use c_read: tap on, tap off (owner 2026-11-10) */

/* tab switch: the new panel slides 24px in from the side of the tab you tapped and fades in (owner 2026-11-10) */
@keyframes tab-in-r { from { opacity: 0; transform: translateX(24px); } }
@keyframes tab-in-l { from { opacity: 0; transform: translateX(-24px); } }
.tabp.tab-in-r { animation: tab-in-r .2s cubic-bezier(.2, .7, .3, 1); }
.tabp.tab-in-l { animation: tab-in-l .2s cubic-bezier(.2, .7, .3, 1); }
html { overflow-x: clip; }  /* the 24px slide never makes the page scroll sideways */
@media (prefers-reduced-motion: reduce) { .tabp.tab-in-r, .tabp.tab-in-l { animation: none; } }

/* tab switch as a cube turn (View Transitions; owner 2026-11-10). The header and tab bar are their own layers and do not move. */
.top { view-transition-name: qs-top; }
nav.tabs { view-transition-name: qs-tabs; }
html[data-cube] nav.tabs a { transition: none; }  /* owner 2026-11-11: the desktop rail fill snaps during the cube turn; the phone highlight still slides */
::view-transition-group(qs-top), ::view-transition-group(qs-tabs), ::view-transition-old(qs-top), ::view-transition-new(qs-top),
::view-transition-old(qs-tabs), ::view-transition-new(qs-tabs) { animation: none; }
::view-transition-old(qs-top), ::view-transition-old(qs-tabs) { display: none; }
html[data-cube]::view-transition-image-pair(root) { perspective: 1400px; isolation: auto; }
html[data-cube]::view-transition-old(root), html[data-cube]::view-transition-new(root) { mix-blend-mode: normal; backface-visibility: hidden; animation-duration: .22s; animation-timing-function: cubic-bezier(.25, .8, .3, 1);  /* owner 2026-11-11: quicker to respond (.45 -> .3 -> .22s) */ animation-fill-mode: both; }
html[data-cube="r"]::view-transition-old(root) { transform-origin: 100% 50%; animation-name: cube-out-r; }
html[data-cube="r"]::view-transition-new(root) { transform-origin: 0 50%; animation-name: cube-in-r; }
html[data-cube="l"]::view-transition-old(root) { transform-origin: 0 50%; animation-name: cube-out-l; }
html[data-cube="l"]::view-transition-new(root) { transform-origin: 100% 50%; animation-name: cube-in-l; }
@keyframes cube-out-r { to { transform: translateX(-100%) rotateY(-90deg); filter: brightness(.6); } }
@keyframes cube-in-r { from { transform: translateX(100%) rotateY(90deg); filter: brightness(.6); } }
@keyframes cube-out-l { to { transform: translateX(100%) rotateY(90deg); filter: brightness(.6); } }
@keyframes cube-in-l { from { transform: translateX(-100%) rotateY(-90deg); filter: brightness(.6); } }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }
.tabp { touch-action: pan-y; }  /* sideways drags turn the cube (app.js); up and down still scroll */

/* Visualise tab (owner 2026-11-10): one card, the 3D scene, fills the space between the header and the tab bar (app.js orbMount sets its height).
   Without 3D (.off: no WebGL 2) the tab scrolls as any other and the tables show. 3D styles: orbital/orbital.css, loaded with the module. */
body:has(.orb-tab:not([hidden])) #label { display: none; }  /* #fresh shows as on every tab */
html:has(.orb-tab:not([hidden]) .orb-card:not(.off)) { overflow: hidden; }  /* one screen: the page does not scroll; the scene takes the gestures */
body:has(.orb-tab:not([hidden]) .orb-card:not(.off)) { padding-bottom: 0; }
@media (max-width: 519.98px) { .dials .clock-seg { display: grid; grid-template-columns: 1fr 1fr; } }  /* half-width dial column: the line-measure switch as 2 x 2, never cut off */
/* owner 2026-11-11: Weekly rhythm today outlined in brand #fac800 (was ink), Grid and Dial */
.rhythm .cell.today, .rhythm .cell.none.today { stroke: var(--brand); stroke-width: 1; }  /* owner: 1px */
.legend i.sw.shade-today { box-shadow: inset 0 0 0 1px var(--brand); }
.clock .wedge.today, .clock .wedge.none.today { stroke: var(--brand); stroke-width: 1; }
