/* The account usage surface (#229): the `.usage-pill` beside the native account <select> in the header's
   auth zone, and the `dialog.usage-sheet` it opens on tap. One file rather than the pill living in badges.css
   and the sheet living in shell.css, because they are two renderings of ONE read, not two features —
   `usageBadge()` in accounts.js computes level/state/stale/blocked/unprovable exactly once, and both the
   pill and the sheet paint off the SAME attributes it publishes. Splitting the file would split that
   guarantee: a colour rule that drifted between two files is precisely the failure a shared derivation exists
   to prevent (the account-select's own option text uses the same `usageBadge()` output for the same reason).

   Class names and attributes here are taken from the COMMITTED accounts.js, not guessed at — in particular
   the number span is `.usage-pill-num` (not `.usage-pill-number`; the testid is `account-usage-pill-number`
   but the class is shorter), and the dialog is `<dialog id="usageSheet" class="usage-sheet">`. */

/* -------------------------------------------------------------------------------------------------------
   THE PILL — `<button class="usage-pill" data-testid="account-usage-pill">` inside #accountSelectorHost,
   BESIDE the native <select>, never a replacement for it: the select is still how the account is CHANGED,
   the pill is how its usage is READ, and this surface already refused once to reimplement the native mobile
   picker (see index.html's own comment on `dialog.usage-sheet`).

   `--tap`, not `--control-h`, for the same reason `.ceilbox` in controls.css uses it over `.field input`'s:
   this sits in a row a thumb reaches for, and it is what OPENS the sheet, so it gets the full 44px HIG floor
   rather than the everyday control height. `font-variant-numeric:tabular-nums` so the percent changing width
   (3 % -> 100 %) never shifts the `<select>` beside it. `:focus-visible` is already handled globally in
   tokens.css for every `button`; nothing is re-declared here. */
.usage-pill {
  display:inline-flex; align-items:center; gap:var(--s-1);
  min-height:var(--tap);
  border:1px solid transparent; border-radius:var(--radius-pill);
  padding:0 var(--s-3);
  font-family:inherit; font-weight:600; font-size:var(--t-meta);
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
  cursor:pointer;
}
/* The number/em-dash span, `.usage-pill-num`, needs no rule of its own: size, weight and tabular figures all
   come from `.usage-pill` above it. */

/* Colour by the RAW-percentage bucket `usageBadge()` computes — never by the server's own `severity`, which
   SLICE-CONTRACT.md forbids from driving colour at all. Three of the four levels reuse the board's own badge
   tokens verbatim (badges.css: `.s-ready`/`.s-run`/`.s-blocked` are the exact same pairs). `crit` is
   deliberately the odd one out — see tokens.css for why it is a solid fill rather than a fifth soft tint. */
.usage-pill[data-usage-level="unknown"] { background:var(--line-soft); color:var(--muted); }
.usage-pill[data-usage-level="ok"]      { background:var(--ready-soft); color:var(--ready); }
.usage-pill[data-usage-level="notice"]  { background:var(--run-soft);   color:var(--run); }
.usage-pill[data-usage-level="warn"]    { background:var(--block-soft); color:var(--block); }
.usage-pill[data-usage-level="crit"]    { background:var(--crit); color:var(--panel); }

/* `data-usage-state="partial"` — a reading missing at least one window, so its maximum is a LOWER BOUND, not
   the truth (per usageBadge(), partial never floors to `ok` either — see SLICE-CONTRACT.md). A partial `warn`
   and a complete `warn` would otherwise paint identically, so partial adds a DASHED border in the level's own
   colour: a line texture rather than a hue, so the marker survives greyscale and colour-blindness exactly the
   way `--crit`'s solid fill does. `crit` is the one level whose OWN colour already IS its background, so a
   `--crit` border on a `--crit` fill would be invisible (the same colour drawn on itself) — it borrows
   `--panel` instead, the one colour already proven in tokens.css to clear AA on that fill, so partial-crit
   still reads as a dashed line and not as nothing. */
.usage-pill[data-usage-state="partial"] { border-style:dashed; }
.usage-pill[data-usage-state="partial"][data-usage-level="unknown"] { border-color:var(--faint); }
.usage-pill[data-usage-state="partial"][data-usage-level="ok"]      { border-color:var(--ready); }
.usage-pill[data-usage-state="partial"][data-usage-level="notice"]  { border-color:var(--run); }
.usage-pill[data-usage-state="partial"][data-usage-level="warn"]    { border-color:var(--block); }
.usage-pill[data-usage-state="partial"][data-usage-level="crit"]    { border-color:var(--panel); }

/* `data-usage-blocked="true"` gets NO rule here, on purpose. `usageBadge()` only ever sets `blocked` when
   `worstFraction >= 1`, which already clears the 90 % crit threshold — a blocked pill is therefore always a
   crit pill by construction (solid fill, `--panel` text), already carrying the loudest treatment this scale
   has. A second rule on top of it would be decoration standing on decoration, not a fact the operator needs
   that isn't already on screen. */

/* The staleness caption, "3 h ago" — rendered only inside an `unknown` pill (never a coloured one; see
   usageBadge()). `--muted` is tuned for legibility on `--panel`/`--bg`, not on a saturated solid fill, so this
   override guards the one level where the ambient pill background stops being a light neutral. Belt and
   braces: `stale` and `crit` cannot co-occur today (staleness is `unknown`-only, crit is a live reading), but
   the rule should not depend on that staying true. */
.usage-pill-age { font-size:var(--t-micro); color:var(--muted); }
.usage-pill[data-usage-level="crit"] .usage-pill-age { color:var(--panel); }

/* The ⚠ marker for a configured ceiling nothing can currently test. `--limbo` is the token this file already
   uses (controls.css `.secret-reveal`) for "needs a second look" rather than "is wrong" — but plain `--limbo`
   text on `--line-soft` (the `unknown`-level pill's own background, since `unprovable` only ever renders
   inside an `unknown` pill) measures 4.357:1 in the light scheme: under the 4.5:1 AA floor by a real margin,
   not a rounding error. `color-mix(in srgb, var(--limbo) 90%, var(--fg))` nudges it toward the scheme's own
   foreground — dark in light mode, light in dark mode — which is exactly the direction that raises contrast
   against `--line-soft` in BOTH schemes at once: measured at ~5.00:1 light and ~8.41:1 dark, both clear. */
.usage-pill-unprovable { color:color-mix(in srgb, var(--limbo) 90%, var(--fg)); }

/* -------------------------------------------------------------------------------------------------------
   THE SHEET — `<dialog id="usageSheet" class="usage-sheet">`, opened by TAP (never hover: the header is read
   on a phone) via `showModal()`. A native dialog rather than the drawer's hand-built `#scrim` + fixed panel,
   for the reason index.html's own comment gives: `showModal()` brings the focus trap, Escape, page inertness
   and `aria-modal` semantics for free. One consequence worth naming because it is easy to miss reading this
   file alone: a dialog shown via `showModal()` is promoted to the browser's own TOP LAYER, which paints above
   every `z-index` on the page regardless of value — so, unlike `#scrim` (z-index:70 in drawer.css) or the
   pinned header/footer (z-index:20 in shell.css), this sheet needs no `z-index` of its own to sit above them. */
dialog.usage-sheet {
  border:0; background:var(--panel); color:var(--fg); box-shadow:var(--lift-high);
  margin:0; padding:var(--s-4);
  /* Pinned to the bottom edge on a phone, so it earns the same home-indicator reservation every other
     edge-pinned surface on this page already carries (shell.css's footer, drawer.css's drawer). */
  padding-bottom:calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
  position:fixed; inset:auto 0 0 0; width:100%;
  border-radius:var(--radius) var(--radius) 0 0;
  max-height:80svh; overflow-y:auto;
}
/* `dialog:not([open]) { display:none }` is a UA rule that an author's NORMAL-weight declaration always beats
   regardless of specificity — so `display:flex` cannot be declared on the bare `dialog.usage-sheet` selector
   above without also showing the dialog while it is closed. It is scoped to `[open]` instead, which only ever
   adds to what the UA already shows. */
dialog.usage-sheet[open] { display:flex; flex-direction:column; gap:var(--s-3); }
dialog.usage-sheet::backdrop { background:var(--scrim); }

/* This page carried NO native <dialog> before #229 — every child accounts.js appends (h2, three kinds of <p>,
   N `.usage-window-row`s, the close <button>) still has the browser's own UA margin, which would double up
   against the `gap` above. Reset once for the whole sheet rather than per element. */
dialog.usage-sheet > * { margin:0; }

.usage-sheet-title { font-size:var(--t-lead); font-weight:650; letter-spacing:-.02em; }

/* From 640px — the SAME step tokens.css already derives for `.fleet`'s own second track, reused rather than a
   third breakpoint invented for one sheet — the bottom sheet becomes a centred panel: `inset:0; margin:auto`
   is the classic fixed-position centring trick once both offsets are set and the box's own size is `auto`,
   capped by `max-width`. */
@media (min-width: 640px) {
  dialog.usage-sheet {
    inset:0; margin:auto; width:auto; max-width:30rem;
    padding-bottom:var(--s-4); /* no longer pinned to the bottom edge, so no safe-area reservation is owed */
    border-radius:var(--radius);
  }
}

.usage-observed, .usage-windows-empty, .usage-ceiling-note {
  font-size:var(--t-meta); color:var(--muted);
}
/* Ceilings configured but nothing live to test them against — the sheet's prose equivalent of the pill's own
   `.usage-pill-unprovable` marker, for the identical underlying fact, so the two never disagree in colour
   language. `--limbo` measures 5.02:1 light / 8.60:1 dark directly on `--panel` (the dialog's own background,
   not the pill's `--line-soft`), both clear of AA — no `color-mix` needed here, unlike the pill's marker. */
.usage-ceiling-note[data-ceiling-provable="false"] { color:var(--limbo); }

/* One row per window PRESENT in the reading (SLICE-CONTRACT.md: `windows[]`, in order received, `[]` when
   none). A flex row rather than a grid/table because the row's own children vary — `.usage-window-pace` and
   `.usage-window-severity` are appended only when there is something to say — and a flex row wraps whatever
   is actually there instead of leaving empty grid cells. The hairline sits BETWEEN rows (`+`, not a per-row
   border) so it never doubles against the sheet's own outer `gap` or trails after the last row into whatever
   follows it (`.usage-ceiling-note`, the close button). */
.usage-window-row {
  display:flex; flex-wrap:wrap; align-items:baseline; gap:var(--s-3);
  padding-block:var(--s-2);
  font-size:var(--t-meta);
}
.usage-window-row + .usage-window-row { border-top:1px solid var(--line-soft); }

.usage-window-percent { font-variant-numeric:tabular-nums; font-weight:600; }

/* `data-window-read="false"` — `fraction: null`: present in the reading but NOT read, never a zero, never
   blank (SLICE-CONTRACT.md). Its percent cell must read as ABSENT rather than as a quiet green "0 %", so it
   takes `--faint` and italic — the same idiom this codebase already uses for "content that is there but not
   really" (drawer.css `.tline.withheld`, `.ev-withheld`), not a new one invented for this file. */
.usage-window-row[data-window-read="false"] .usage-window-percent { color:var(--faint); font-style:italic; }

/* `data-window-dormant="true"` — `resetsAt: null`: a window with NO live period. Dormancy is read off
   `resetsAt`, and NEVER off `fraction === 0` — a window with a set `resetsAt` and `fraction: 0` is confirmed
   margin and "0 %" green is the CORRECT reading for it (SLICE-CONTRACT.md); only the absence of a live period
   makes a reading unconfirmed. Same posture as the row above: `--muted` on the one cell making the claim
   ("no live period — not confirmed margin"), so it does not read with the same confidence as a real reset
   timestamp. */
.usage-window-row[data-window-dormant="true"] .usage-window-reset { color:var(--muted); }

.usage-window-severity { color:var(--muted); }
/* The server's own severity verdict disagreeing with the threshold that coloured the pill IS the reason this
   element exists — resolving the divergence silently in either direction would throw away the only signal
   that our bucket and the server's have drifted apart. `--limbo` again, for the same "needs a second look"
   reason as the ceiling note above; verified at 5.02:1 light / 8.60:1 dark on `--panel`, same as that rule. */
.usage-window-severity[data-severity-disagrees="true"] { color:var(--limbo); font-weight:600; }

.btn.usage-sheet-close { min-height:var(--tap); }
/* Two classes rather than one: `button.btn` in controls.css already carries `min-height:var(--control-h)` at
   equal-or-higher specificity than a bare `.usage-sheet-close` would (type+class beats class alone), so a
   single-class override would only win by SOURCE ORDER — true today because this file loads after
   controls.css in index.html, but fragile against a future reorder. `.btn.usage-sheet-close` (two classes)
   outranks `button.btn` (one type, one class) outright, so the 44px floor holds regardless of link order. */
