/* ui.css — the Explorer's parts, defined once (the owner, 2026-10-14: one
   visual language across the pages, with no framework and no dependency).
   Every page in the shell loads this after styles.css; a page's own
   stylesheet lays its page out with these parts and never redefines one
   (explorer/test/ui-parts.test.js). The colour rule holds here as it does
   everywhere: green, amber and red for meaning only (ui-colour.test.js).
   To change a part everywhere, change it here; to add a part, add it here
   with its name in this list and a line in the test.

   The parts:
     .card-head   the band a card opens with: a title at the left, a chip or a note at the far right, a second line
     .chip        a word in a small box: a status (ok, warn, err), the accent for a word that is a label not a verdict, a name from the code
     .ring        a ring drawn by stroke, then its mark: a verdict, a confirmation; spinning while something is checked
     .facts       labelled facts in a grid: the label small and bright, the value a step dimmer, a note under it
     .tagged      a line of text with a chip at its right edge, so the chips of a list line up
     .mark-row    a mark in a gutter beside a block of text */

/* ---- card-head ------------------------------------------------------- */
.card-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; margin: -18px -20px 16px; padding: 12px 20px; background: color-mix(in srgb, var(--accent) 9%, color-mix(in srgb, var(--bg) 90%, #000 10%)); border-bottom: 1px solid var(--border-dim); border-radius: 10px 10px 0 0; }
.card-head h2, .page-article .card-head h2 { margin: 0; padding: 0; border: 0; }
/* A page whose first card is its only card (Verify) puts its h1 in the
   band, set as the band's h2 is, so the page keeps one h1. */
.card-head h1 { margin: 0; padding: 0; border: 0; font-size: 12px; font-weight: 600; letter-spacing: 1.5px; text-transform: uppercase; color: var(--accent); }
.card-head .chip { margin-left: auto; background: var(--bg); }
.card-head .note { margin-left: auto; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-dim); white-space: nowrap; }
.card-head .sub { flex-basis: 100%; order: 3; margin: 0; color: var(--text-dim); font-size: 12px; }
@media (max-width: 600px) { .card-head { margin: -14px -14px 14px; padding: 11px 14px; } }

/* ---- chip ------------------------------------------------------------ */
/* The word centres on its capitals: the chip is an inline block trimmed to
   cap height and baseline where the browser can (text-box; a browser
   without it leaves the word a pixel high, as before), so every chip on
   every page gets the centring by itself, with no inner span (the owner,
   2026-10-14: the check names sat high; the Readout's chips had been
   fixed with a span of their own). The right padding gives back the
   letter-spacing after the last letter. A dot sits at the middle of the
   trimmed line. */
.chip { display: inline-block; line-height: 1; text-box: trim-both cap alphabetic; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); border: 1px solid var(--border); border-radius: 3px; padding: 4px calc(7px - 0.08em) 4px 7px; vertical-align: middle; white-space: nowrap; }
.chip-dot { display: inline-block; vertical-align: middle; width: 6px; height: 6px; margin-right: 5px; border-radius: 50%; background: var(--text-muted); }
.chip.quiet { color: var(--text-muted); }
.chip.accent { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.chip.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 50%, transparent); } .chip.ok .chip-dot { background: var(--ok); }
.chip.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); } .chip.warn .chip-dot { background: var(--warn); }
.chip.err { color: var(--err); border-color: color-mix(in srgb, var(--err) 50%, transparent); } .chip.err .chip-dot { background: var(--err); }
.chip.base { background: var(--bg); }
.chip.raised { background: var(--bg-raised); }
.chip.code { font-family: 'Courier New', Courier, monospace; text-transform: none; letter-spacing: 0; font-size: 11px; padding: 3px 7px; background: var(--bg-raised); }

/* ---- ring ------------------------------------------------------------ */
/* Drawn by stroke: the ring, then the mark, in the status colour (a
   status element, so it carries one); grey with no colour when nothing was
   checked. Spinning: the arc grows from a dot to most of the ring and
   unwinds while the whole turns, over and over, so it is never still; the
   turn is on the drawing element, which every engine rotates alike. Still
   when motion is turned off. A list of rings draws one after another when
   each carries its place in --i. */
.ring { display: inline-block; width: 44px; height: 44px; flex: none; }
.ring svg { width: 100%; height: 100%; overflow: visible; display: block; }
.ring-c { fill: none; stroke: var(--text-muted); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 132; stroke-dashoffset: 0; transform: rotate(-90deg); transform-origin: 50% 50%; }
.mark-path { fill: none; stroke: var(--text-dim); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 40; stroke-dashoffset: 0; }
.ring.ok .ring-c, .ring.ok .mark-path { stroke: var(--ok); }
.ring.warn .ring-c, .ring.warn .mark-path { stroke: var(--warn); }
.ring.err .ring-c, .ring.err .mark-path { stroke: var(--err); }
.ring.sm { width: 15px; height: 15px; vertical-align: -3px; }
.ring.md { width: 18px; height: 18px; vertical-align: -3px; }
.ring.sm .ring-c, .ring.md .ring-c { stroke-width: 4; }
.ring.sm .mark-path, .ring.md .mark-path { stroke-width: 5; }
.ring.spinning svg { animation: ring-spin 1.4s linear infinite; }
.ring.spinning .ring-c { stroke: var(--accent); stroke-dasharray: 1 131; animation: ring-loop 1.5s ease-in-out infinite; }
.ring.spinning.grey .ring-c { stroke: var(--text-muted); }
@keyframes ring-spin { to { transform: rotate(360deg); } }
@keyframes ring-loop { 0% { stroke-dasharray: 1 131; stroke-dashoffset: 0; } 50% { stroke-dasharray: 95 37; stroke-dashoffset: -25; } 100% { stroke-dasharray: 95 37; stroke-dashoffset: -125; } }
.ring.draw .ring-c { animation: ring-draw 0.5s ease-out both; animation-delay: calc(var(--i, 0) * 90ms); }
.ring.draw .mark-path { animation: ring-mark 0.3s ease-out both; animation-delay: calc(var(--i, 0) * 90ms + 0.45s); }
@keyframes ring-draw { from { stroke-dashoffset: 132; } to { stroke-dashoffset: 0; } }
@keyframes ring-mark { from { stroke-dashoffset: 40; } to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .ring.draw .ring-c, .ring.draw .mark-path, .ring.spinning svg, .ring.spinning .ring-c { animation: none; } .ring.spinning .ring-c { stroke-dasharray: 132; } }

/* ---- facts ----------------------------------------------------------- */
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 24px; margin: 10px 0 0; }
.facts .fact { min-width: 0; } .facts .fact.wide { grid-column: 1 / -1; }
.facts dt { font-size: 10px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-hi); margin: 0 0 3px; }   /* a little thicker (the owner, 2026-10-14) */
.facts dd { margin: 0; color: var(--text-mid); font-size: 13px; overflow-wrap: anywhere; }
.facts dd .note { display: block; margin-top: 2px; color: var(--text-dim); font-size: 12px; }
.facts code { white-space: normal; overflow-wrap: anywhere; }
/* On a phone the grid is one column, so each fact is set apart by a rule
   and given air, the way the check rows are (the owner, 2026-10-14). */
@media (max-width: 600px) {
  .facts { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .facts .fact { padding: 12px 0; border-top: 1px solid var(--border-dim); }
  .facts .fact:first-child { border-top: 0; padding-top: 2px; }
  .facts dt { margin-bottom: 5px; }
  .facts dd .note { margin-top: 4px; }
}

/* ---- tagged ---------------------------------------------------------- */
/* The text first, as the thing the eye lands on; the chip after it at its
   natural width, pinned to the right edge so the chips of a list line up;
   a little air between rows; a text's lines balanced so none holds one
   word. Stacked where the row is narrow: always (.stacked, a table cell)
   or on a phone (.stack-narrow). */
.tagged-list { list-style: none; margin: 0; padding: 0; }
.page-article .tagged-list { padding-left: 0; margin: 0; }
.tagged { display: flex; align-items: baseline; gap: 2px 12px; margin: 0 0 8px; }
.tagged .tagged-text { flex: 1 1 auto; min-width: 0; text-wrap: balance; }
.tagged > .chip { flex: none; margin-left: auto; }
.tagged.stacked { flex-direction: column; align-items: flex-start; gap: 4px; margin: 0 0 14px; }
.tagged.stacked > .chip { margin-left: 0; }
@media (max-width: 600px) { .tagged.stack-narrow { flex-direction: column; align-items: flex-start; gap: 4px; margin: 0 0 12px; } .tagged.stack-narrow > .chip { margin-left: 0; } }

/* ---- mark-row -------------------------------------------------------- */
.mark-row { display: grid; grid-template-columns: 22px minmax(0, 1fr); column-gap: 12px; align-items: start; }
.mark-row > .mark { text-align: center; }
