/*!
 * evident.css — part of Evident, the Cortex design language.
 * Framework-agnostic core: tokens + primitives + de-scoped components.
 *
 * Do not edit this file directly — it is generated by build.sh from src/.
 * Edit the partials under src/ and re-run ./build.sh.
 * Provenance is the Git commit containing these bytes; consumers record that
 * commit in .evident-version and use it for cache-busting.
 * https://evident.sb.cortex.gigahost.dk/
 */

/* ===== src/tokens.css ===== */
/* ==========================================================================
   Evident — the token layer
   ==========================================================================

   The `--ev-*` custom properties that carry Evident's material language, in
   both themes. These are the single source of numeric truth; components below
   only COMPOSE these, they never invent values.

   Editing anything under src/ means dist/ is now stale: run ./build.sh and
   stage the result in the SAME commit. dist/ is generated but committed —
   consumers vendor it SHA-pinned via sync.sh — so a stale dist/ ships to every
   consumer. The .githooks/pre-commit gate enforces this (cortex-59mbwm2).

   Extracted from a verified, dual-theme production port
   (gigahost/controlcenter/src/css/tokens.css, cortex-vnt3p6m / cortex-1r37qcl /
   cortex-mn5hkp8) rather than re-derived from the study's raw --rank* / --floor*
   names: the CC --ev-* layer is the mature version that has been measured on
   rendered pixels in light AND dark. Historical v16 measurements preserve the
   provenance; the declarations below are authoritative.

   The channels (see README / CLAUDE):
     Rim / lip weight  --evN-{line,lip,wall,rim}  — nesting rank (cuts down)
     Floor luminance   --ev-floor-n{1,2,3}        — nesting depth
     Finish            --ev-sheen-* / oxide        — liveness
     Hue               --ev-accent #2bb3f3         — live / active only

   THEME MODEL — DELIBERATELY DIFFERENT FROM THE CC PORT.
   The CC port keys its dark theme off Bootstrap's [data-bs-theme="dark"]
   attribute, because CC IS a Bootstrap app. Evident's core is framework-
   agnostic, so the token layer keys dark off BOTH [data-ev-theme="dark"] (the
   framework-agnostic selector) AND [data-bs-theme="dark"] (so the SAME file
   Just Works in a Bootstrap consumer with zero markup change). Light uses the
   matching pair as selector aliases on the root list. This is what makes a
   light-scoped part inside a dark bench recompute the material ramp instead of
   inheriting the ancestor's dark custom properties. Each theme still has
   exactly one definition of every value.

   THE CONSUMER CONTRACT — WHICH ATTRIBUTE IS AUTHORITATIVE (cortex-efa3l5n).
   These two attributes are NOT peers, and reading them as peers is what made
   the defect below possible:

     data-ev-theme  is Evident's MATERIAL MODE. It takes exactly `light` or
                    `dark`. It is the authority, and it is the only thing a
                    consumer can rely on.
     data-bs-theme  is honoured ONLY for Bootstrap's own two literals, as a
                    zero-markup convenience for the ordinary single-dark-theme
                    Bootstrap app. It is a convenience ALIAS — not a theme
                    namespace Evident owns, and not a promise about any other
                    value a consumer might put there.

   So a consumer whose dark theme is called anything other than `dark` MUST
   also set data-ev-theme="dark" on the same carrier:

       <html data-bs-theme="very-dark" data-ev-theme="dark">

   Control Center is the worked case: it ships three dark themes (`dark`,
   `darker`, `very-dark`), and before it set the second attribute the whole
   --ev-* layer resolved LIGHT on two of the three while the page ground was
   near-black. Measured on the canonical showcase: data-bs-theme="darker"
   alone gave --ev-bg #c9c9c9 / --ev-ink #1f1f1f, and --ev-accent-text #064466
   measured 1.94:1 against that theme's #070707 ground. Adding the attribute
   resolves the dark register byte-for-byte and takes the same ink to 8.48:1.
   The escape hatch is name-agnostic: `midnight` or `solarized-dark` work
   identically, because the name is precisely what stops mattering.

   Note the adjacent surprise, since it catches people: setting
   data-ev-theme="dark" does NOT make Bootstrap's own [data-bs-theme="dark"]
   rules apply. The consumer keeps owning its framework theming; Evident only
   ever owns the material.

   TWO ALTERNATIVES REJECTED, recorded because both look better than they are:

   1. Match the theme NAME, e.g. [data-bs-theme*="dark"]. This is a guess
      dressed as a rule. It happens to catch `darker` and `very-dark`, it
      SILENTLY catches `dark-blue` and `darkroom` (a light theme named after a
      room), and it SILENTLY misses `midnight` and `night`. One silent-wrong
      case traded for two, with the library's behaviour now depending on a
      consumer's spelling. scripts/check-theme-scope-registers.py pins this
      rejection: it asserts an unrecognised theme name alone still resolves
      LIGHT, so a substring match cannot be introduced without failing.

   2. Fail loudly by withholding tokens — drop :root from the light selector
      so an unknown themed root matches no scope at all and every var(--ev-*)
      goes invalid. Genuinely tempting, since this repo's own tools fail loudly
      on purpose. Rejected because it breaks the documented unset-default root
      contract for every consumer that themes on an attribute Evident has never
      heard of, and because a design library must not paint a diagnostic — or a
      wreck — into a consumer's production page. The loudness belongs in the
      station, where it costs a consumer nothing at runtime.

   Achromatic (Invariant 7): every material value is R = G = B. Colour is
   reserved for ink and indicators.
   ========================================================================== */

:root,
:is([data-ev-theme="light"], [data-bs-theme="light"]) {
    /* The one accent. Hue means "live / active / interactive", nothing else. */
    --ev-accent:     #2bb3f3;
    --ev-accent-fg:  #06232f;   /* dark ink on the lit accent face */

    /* The same accent as a BARE CHANNEL TRIPLE, for consumers whose API takes
       `rgba(<triple>, <alpha>)` rather than a colour. Bootstrap's utilities are
       built that way (`--bs-primary-rgb`, consumed as
       `rgba(var(--bs-primary-rgb), var(--bs-bg-opacity))`), so without this the
       adapter could remap --bs-primary and STILL leave .bg-primary /
       .text-primary / .text-bg-primary painting Bootstrap's #0d6efd.

       It is stated here, beside the hex it decomposes, rather than in the
       adapter — a bare triple in the adapter would be exactly the literal the
       adapter rule forbids. THESE TWO LINES MUST MOVE TOGETHER: nothing checks
       that the triple still matches the hex. (cortex-wp0qzvk) */
    --ev-accent-rgb: 43, 179, 243;   /* = #2bb3f3 */
    /* The same decomposition for --ev-accent-text (below), needed for the same
       reason: Bootstrap resolves `a { color }` through --bs-link-color-RGB, not
       through --bs-link-color, so a link takes the face accent — 1.43:1 on the
       canvas — unless the INK step is available as a triple too. Dark mirrors
       whatever --ev-accent-text resolves to there. (cortex-wp0qzvk) */
    --ev-accent-text-rgb: 6, 68, 102;   /* = #064466 */

    /* The accent as INK, on a neutral ground. A luminance step of the SAME hue
       (199deg vs 201deg — same accent, walked down), never a second hue, so
       Invariant L4's "one flat accent" holds: hue still means exactly one thing.

       It exists because --ev-accent is a FACE value and cannot double as ink on
       a light ground. Measured on the declared hexes: #2bb3f3 is 1.43:1 on
       --ev-bg #c9c9c9, 2.01:1 on --ev-metal-hi #ececec and 1.52:1 on
       --ev-floor-n1 #cfcfcf — the deepest cut, so the darkest face any ink sits
       on, and therefore the binding constraint. Nothing near 4.5:1. Note the
       page canvas got WORSE, not better, when it went to the study's graphite
       bench (2.01 -> 1.43): the bench moved TOWARDS the accent's own luminance.

       1:1 WITH THE v16 STUDY (cortex-8jhd90a): this is the study's --accent-text
       (historical v16 record), whose own comment reads "min 5.00 on any surface
       in this theme". The library simply dropped it during the port and pointed
       the five ink sites at --ev-accent instead; that was the drift, and the
       historical exploration had already made this call. Measured on this ground set: 6.26:1 on
       --ev-bg, 8.77:1 on --ev-metal-hi, 6.65:1 on --ev-floor-n1 — worst 6.26.

       In DARK the accent needs no step and the study sets --accent-text to the
       accent itself (historical v16 record); stated there as var(--ev-accent)
       rather than a repeated literal, because it is a consequence (the accent
       IS legible as ink on a dark ground: 8.13:1 on --ev-bg), not a coincidence.

       This is INK only. Boundaries have their own rung below: their 3:1 floor
       is independent of the 4.5:1 text floor even though the present light
       values coincide. */
    --ev-accent-text: #064466;

    /* The accent as a UI BOUNDARY: focus outlines, rims, borders and inset
       scribes. --ev-accent is a FACE value and misses the 3:1 non-text floor
       on every light surface it borders: 1.43:1 on --ev-bg #c9c9c9, 2.01:1
       on --ev-metal-hi #ececec and 1.52:1 on --ev-floor-n1 #cfcfcf.

       #064466 is the same accent hue walked down in luminance and measures
       6.26:1, 8.77:1 and 6.65:1 on those grounds; it also clears boundaries
       drawn inside accent faces (4.36:1 on --ev-accent and 3.49:1 on
       --ev-accent-press). Keep the boundary name separate from
       --ev-accent-text: the channels have different accessibility floors and
       may diverge even though their present light values coincide.
       (cortex-ne36f8j) */
    --ev-accent-edge: #064466;

    /* Ink — Evident owns neutral ink so evident.css alone (no Bootstrap, no
       consumer palette) still has legible text. A consumer with its own
       palette can point these at its own tokens.

       TWO text rungs, not three. --ev-ink-faint is NON-TEXT (cortex-g2j0rmv).

       It was a third text rung until it was measured. The binding ground is
       --ev-floor-n1 #cfcfcf, the DEEPEST cut and so the darkest face any ink
       ever sits on; #999999 reads 1.83:1 there against a 4.5:1 floor. The
       remedy in the bead as filed — darken it until it passes — does not
       exist: walking the value down, the FIRST light grey to clear 4.5:1 on n1
       is #595959 (4.50), and --ev-ink-dim is #565656 (4.71). The faint rung
       would have to BECOME the dim rung to be legible, i.e. the ladder is
       arithmetically two rungs deep, not three, and always was.

       So the carrier was removed rather than the invariant. Everything that
       used faint ink to say "this text is meta" — placeholder, dropzone hint,
       caption — already said it another way (absent value, position, caps +
       tracking + weight). Faint ink was a SECOND carrier of a meaning already
       carried, which is exactly what rule 2 forbids; that it was also the one
       breaking AA is not a coincidence.

       What the token is still FOR: non-text neutral detail that needs to read
       as recessive without ever being read as prose — a hollow status ring
       (components/identity.css), a resting outline-secondary border
       (adapter-bootstrap.css). Those are UI boundaries at a 3:1 floor, which
       it clears. Do not point a `color:` at it. If a visibly fainter caption
       is wanted later, the route is a LIGHTER GROUND or a fourth rung on a
       lighter face — not a fainter ink on these floors.

       ---- 1:1 WITH THE v16 STUDY (cortex-r3qtun9) ----
       The ink ramp is the study's, verbatim: --ev-ink == study --ink #1f1f1f
       (primary near-black), --ev-ink-dim == study --ink-soft #3d3d3d (the
       secondary rung, AA-verified in the historical table). The library
       had drifted to #1a1a1a / #565656; the verified v16 values were restored. */
    --ev-ink:        #1f1f1f;
    --ev-ink-dim:    #3d3d3d;
    --ev-ink-faint:  #999999;   /* NON-TEXT. See above. */

    /* Page canvas — the stock the whole billet is cut from at page level.
       1:1 WITH THE STUDY: this is the study's --canvas #c9c9c9 (the neutral
       graphite bench), NOT --metal-hi. The library had drifted to #ececec —
       the tone of a raised molded FACE, not the bench — which is exactly the
       "they look completely different, like just the pinstripe bg coloring"
       the founder flagged: the page read near-white and molded cards no longer
       sat proud of it. Reverted to the study's graphite canvas. (cortex-r3qtun9) */
    --ev-bg:         #c9c9c9;

    /* A cut made DIRECTLY into the pinstripe bench is not part of the
       --ev-floor-n1/n2/n3 ladder below a raised slab. It has one floor, held
       below the graphite bench's ACTUAL rendered low point, not merely below
       the #c9 declaration. Pixel sampling includes the fixed atmosphere,
       noise and pinstripe: clear bench pixels reached 188 while #c4 rendered
       at 197, so #b8 supplies the required headroom and still keeps dim ink at
       5.48:1 / accent text at 5.22:1. Descendants of the same bench carve
       inherit this single level; a raised slab resets the composition and
       restores the three-rung ladder. Founder option E,
       cortex-jc83lrz / cortex-c8qr7zn. */
    --ev-bench-floor: #b8b8b8;

    /* Typography pair. IBM Plex Sans everywhere; Mono for genuine machine
       values (ids, metrics, hostnames, readouts) — Invariant L5.
       Sans fallback mirrors the study's proven chain (Inter → the platform UI
       sans → Arial) so the prose stays PROPORTIONAL even where the generic
       `sans-serif`/`system-ui` keyword resolves to a monospace face — the
       gallery's earlier mono-looking type regression was exactly that fallthrough. */
    --ev-font-sans:  'IBM Plex Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --ev-font-mono:  'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

    /* -------------------------------------------------------------------
       Material tones — the stock everything is cut from.
       ------------------------------------------------------------------- */
    --ev-metal:     #e0e0e0;   /* plain land (un-cut face) */
    --ev-metal-hi:  #ececec;   /* raised key face */

    /* Floor luminance = nesting depth. EXACTLY three rungs (Invariant 4).
       The rungs run DARKER with depth: n3 shallowest -> n1 deepest. */
    --ev-floor-n1:  #cfcfcf;   /* deepest carve */
    --ev-floor-n2:  #d4d4d4;   /* cut within a cut */
    --ev-floor-n3:  #d9d9d9;   /* shallowest cut */

    /* Carve shading, by rank. Ornament gets FINER with depth (Invariant 2). */
    --ev-r1-line: inset 0 0 0 1px rgba(28, 28, 28, 0.46);
    --ev-r1-lip:  inset 0 0 6px    rgba(28, 28, 28, 0.42);
    --ev-r1-wall: inset 0 0 10px   rgba(28, 28, 28, 0.20);
    --ev-r1-rim:  0 0 0 1px        rgba(250, 250, 250, 0.88);

    --ev-r2-line: inset 0 0 0 1px rgba(28, 28, 28, 0.26);
    --ev-r2-lip:  inset 0 0 3px    rgba(28, 28, 28, 0.21);
    --ev-r2-wall: inset 0 0 5px    rgba(28, 28, 28, 0.105);
    --ev-r2-rim:  0 0 0 1px        rgba(250, 250, 250, 0.52);

    --ev-r3-line: inset 0 0 0 1px rgba(28, 28, 28, 0.15);
    --ev-r3-lip:  inset 0 0 2px    rgba(28, 28, 28, 0.13);
    --ev-r3-wall: inset 0 0 3px    rgba(28, 28, 28, 0.05);
    --ev-r3-rim:  0 0 0 1px        rgba(250, 250, 250, 0.30);

    /* Theme-INDEPENDENT light-land shading. A few chrome faces are pinned
       opaque white regardless of page theme (e.g. a header user pill), so a
       cut into them must be shaded against a light land even in dark. These
       deliberately have NO dark counterpart. (cortex-9sl5z3t) */
    --ev-lightland-floor-n2: #e8e8e8;
    --ev-lightland-r3-line:  inset 0 0 0 1px rgba(28, 28, 28, 0.15);
    --ev-lightland-r3-lip:   inset 0 0 2px    rgba(28, 28, 28, 0.13);
    --ev-lightland-ink:      #444444;

    /* A pocket cut directly into a RAISED face measures from that ACTUAL face,
       not from the ordinary --ev-metal land. In light, --ev-metal-hi #ececec ->
       #e8e8e8 is one deliberate 4-step rung; the old fallback to --ev-floor-n1
       #cfcfcf dropped 29 steps and read as a disabled grey fill. Dark overrides
       this carrier back to --ev-floor-n1 below (#272727 -> #1e1e1e, a 9-step
       rung), so the already-correct raised-face pocket does not move.

       SUPERSEDED (cortex-pxin6to, corrected by cortex-arivo8b): this carrier
       was first stated as `--ev-raised-white-carve-floor` and scoped narrowly
       to Bootstrap's legacy `.rounded-white`, on the reasoning that the
       framework-neutral .ev-molded / .ev-card slabs own the ordinary n1/n2/n3
       nesting ladder for their direct cuts too. That split was wrong, and it
       shipped as a real defect: a consumer porting to native Evident markup
       (`class="ev-card ev-molded ev-fin-polished"`) got the 236 -> 207 slab
       back, because both native blocks reset the carrier to `initial`. A raised
       face is a raised face; which framework named it cannot change what a cut
       into it looks like. The carrier is therefore the ONE raised-face carve
       floor, and the `-white-` in the old name is gone with the scope that
       justified it. The n1/n2/n3 ladder is not lost — it is what a cut cut into
       a CUT still descends through, and .ev-machined restores it the moment it
       actually holds one (core.css). */
    --ev-raised-carve-floor: var(--ev-lightland-floor-n2);

    /* Molded (raised) shading. `shoulder-lite` is the interior roll-over that
       makes a cast face read domed; contact/ambient are outer falloff rings.
       All zero-offset (Invariant L1 — symmetric axial light). */
    --ev-shoulder-lite: inset 0 0 10px rgba(250, 250, 250, 0.55);
    --ev-shoulder-1:    inset 0 0 2px  rgba(28, 28, 28, 0.055);
    --ev-shoulder-2:    inset 0 0 6px  rgba(28, 28, 28, 0.055);
    --ev-shoulder-3:    inset 0 0 14px rgba(28, 28, 28, 0.045);
    --ev-contact-1:     0 0 3px  rgba(28, 28, 28, 0.30);
    --ev-contact-2:     0 0 4px  rgba(28, 28, 28, 0.36);
    --ev-ambient-1:     0 0 14px rgba(28, 28, 28, 0.14);
    --ev-ambient-2:     0 0 30px rgba(28, 28, 28, 0.20);
    /* Split carriers for the key's size-aware hover falloff. The composite
       shadows above remain stable for every other raised component. */
    --ev-contact-2-blur: 4px;
    --ev-contact-2-ink: rgba(28, 28, 28, 0.36);
    --ev-ambient-1-blur: 14px;
    --ev-ambient-1-ink: rgba(28, 28, 28, 0.14);
    --ev-ambient-2-blur: 30px;
    --ev-ambient-2-ink: rgba(28, 28, 28, 0.20);

    /* RAISED KEY BODY — the chosen keyboard-cap material (cortex-q7rmp1m).
       A key's press face turns through a fine lit arris into a short, darker
       molded sidewall before meeting the host at the contact seam. These are
       intrinsic planes in one cast part, not a stronger cast shadow; each
       concentric layer scales with the five-step key geometry. The centred
       crown is an axial return and stays clear of the rounded silhouette at
       every size: its corner is at hypot(.5/.9, .5/1.6) = .637 of the radial,
       beyond the transparent stop, while the top crest is .312.

       The three planes are SPLIT CARRIERS, exactly like --ev-contact-2-blur /
       --ev-contact-2-ink above, and for a reason that is a property of the
       cascade rather than a style preference. A var() inside a custom
       property is substituted where that property is DECLARED, not where it
       is used. --ev-key-lift-scale is per-key state (it exists only on the
       key element, where the size modifier sets it), so a body layer composed
       HERE would resolve against a scale this scope does not have: it would
       compute guaranteed-invalid and inherit downward already dead, and the
       key re-declaring the scale on itself could not revive it. Every
       box-shadow naming it would then be invalid at computed-value time and
       fall back to `none`, taking the valid contact/ambient layers with it —
       which is precisely what cortex-mz9m49a measured, 76 of 78 keys drawing
       no body at all. So the theme owns the INK (it varies per bench and
       inherits cleanly into any nested theme scope) and the key composes the
       geometry where the scale actually lives. Composing at a theme scope
       would be wrong even if it resolved: a nested [data-ev-theme] carrier
       would bake ITS inherited scale into every key below it. */
    --ev-key-body-arrise-ink: rgba(250, 250, 250, 0.68);
    --ev-key-body-wall-ink:   rgba(28, 28, 28, 0.20);
    --ev-key-body-roll-ink:   rgba(28, 28, 28, 0.09);
    --ev-key-crown:
        radial-gradient(90% 160% at 50% 50%, var(--ev-lum-mid) 0%, transparent 50%);

    /* SEAT CONTACT — the occlusion of a part SEATED INSIDE A CUT, as opposed to
       a part standing proud on an open face. (cortex-cvyhdu3.)

       --ev-contact-* + --ev-ambient-* describe an OPEN-FACE raised part: the
       contact seam at its base plus a broad ambient throw falling off onto the
       surrounding land. A seat has no surrounding land. It sits below the host
       face inside a channel, separated from the channel walls by a few px of
       floor, so there is nowhere for a 14px ambient throw to fall off TO — it
       simply floods the whole visible gap and the channel floor stops reading
       uniform. That is a cast where the geometry cannot produce one, the
       raised-part cousin of drawing an edge where no material was removed.

       So a seat gets contact occlusion ONLY, and tight: a short seam in the
       gap, floor at full value 2px out. This has to be a PER-THEME token rather
       than a reused --ev-contact-1 for the same reason the carve floors are
       bench-relative (cortex-c8qr7zn / founder option E): the read has to match
       across themes, and the two benches have wildly different headroom to
       darken into. Measured on the pinstripe bench, floor -> 1px from the seat:
       light 184 -> 177 (delta 7), dark 8 -> 6 (delta 2). Before this token the
       same absolute cast read as delta 26 over a 14px ramp in light and delta 4
       in dark — a treatment tuned on the dark bench, leaking into the light one
       as a dark tinge around every selected seat. */
    --ev-seat-contact:  0 0 2px  rgba(28, 28, 28, 0.16);

    /* The contact falloff as a RAW COLOUR, for the places a part's shadow must
       be drawn as a gradient rather than a box-shadow — i.e. wherever the part
       is not its own element and cannot carry --ev-contact-*. Same alpha as
       --ev-contact-1 so the two readings agree; a radial gradient is axially
       symmetric by construction, so L1 holds structurally. Introduced for the
       single-element Bootstrap .form-switch adapter (cortex-4t1e6px). */
    --ev-contact-tint:  rgba(28, 28, 28, 0.30);

    /* The swoop — the specular return of a polished, LIVE cast face: the
       molded plane's finish/liveness cue, not a new channel. The former
       "material flow line" reading is superseded because it made the sweep
       decorative. Shadows stay axial; every eligible face shares this angle. */
    --ev-swoop-angle: 118deg;
    --ev-lum-hi:  rgba(250, 250, 250, 0.46);
    --ev-lum-mid: rgba(250, 250, 250, 0.16);
    --ev-lum-lo:  rgba(28, 28, 28, 0.045);

    /* PAGE ENVIRONMENT — the ambient light field and material tooth of the raw
       bench. 1:1 WITH THE v16 STUDY (cortex-r3qtun9): the study's canvas is not
       just the pinstripe — it composes an irregular NOISE tooth (feTurbulence,
       ~180px field, an order of magnitude coarser than the 3px stripe pitch, so
       the two cannot beat) under a broad diagonal CANVAS ATMOSPHERE (pure
       luminance, the environment light). These are the study's --noise-alpha /
       --amb-* , verbatim; the .ev-pinstripe PAGE utility composites them so a
       full-bleed Evident page reads exactly like the study's body. Values are
       per-theme. */
    --ev-amb-hi:      rgba(250, 250, 250, 0.40);
    --ev-amb-lo:      rgba(28, 28, 28, 0.075);
    --ev-noise-alpha: 0.030;

    /* Corner counter-light (fillet). A rim band wrapping 90deg converges into
       ~1.69x the area, so corners read darker at equal per-pixel darkness.
       Sized as a RATIO to lip size, never a constant. */
    --ev-fillet-light:   rgba(250, 250, 250, 0.302);
    --ev-fillet-size:    24px;
    --ev-fillet-light-2: rgba(250, 250, 250, 0.151);
    --ev-fillet-size-2:  12px;
    --ev-fillet-light-3: rgba(250, 250, 250, 0.094);
    --ev-fillet-size-3:  8px;

    --ev-edge-glow: rgba(252, 252, 252, 0.42);
    --ev-cut-edge:  rgba(28, 28, 28, 0.42);
    /* The rail's SEAT FLOOR — a rung DARKER than the channel floor
       (--ev-floor-n1), so the current item reads as a deeper pocket cut into
       the channel's own floor. The swing is deliberately small (well under the
       metal-hi -> n1 step) so it reads as one surface cut twice, not a second
       material. Achromatic in both themes (L4).

       PROMOTED FROM components/rail.css (cortex-wp0qzvk): the Bootstrap adapter
       renders .nav-pills as this same rail, and a component-local custom
       property does not reach a .nav-pills element. Restating the hex in the
       adapter would have put a literal there, which the adapter rule forbids.
       One definition, two consumers — which is what this file is for. */
    --ev-rail-seat: #c4c4c4;

    /* Destructive-action feedback. A destructive control is neutral material
       and neutral ink at rest; wording + the canonical trash glyph carry its
       durable identity. These warm carriers appear only while the user is
       interacting. The burr is coloured LIGHT at the raised arris, never a
       coloured material face. */
    --ev-danger-action-burr: rgba(216, 74, 63, 0.42);
    --ev-danger-action-ink: #8f2018;

    /* Entity-header material. The general shoulder/rank/luminance stacks above
       already match the study exactly; these are the component-specific
       surfaces and colour carriers that have no honest global equivalent. */
    --ev-entity-header-ink-muted: #444444;
    --ev-entity-header-lobe-face: #dadada;
    --ev-entity-header-chamfer-crest: rgba(250, 250, 250, 0.85);
    --ev-entity-header-chamfer-lit: rgba(250, 250, 250, 0.42);
    --ev-entity-header-chamfer-inner: rgba(28, 28, 28, 0.16);
    --ev-entity-header-chamfer-shade: rgba(28, 28, 28, 0.085);
    --ev-entity-header-r2-line-color: rgba(28, 28, 28, 0.26);
    --ev-entity-header-r2-wall-color: rgba(28, 28, 28, 0.105);
    --ev-entity-header-r3-rim-color: rgba(250, 250, 250, 0.30);
    --ev-entity-header-rail-floor: #d7d7d7;
    --ev-entity-header-rail-seat: #c0c0c0;
    --ev-entity-header-rail-seat-low: rgba(28, 28, 28, 0.030);
    --ev-entity-header-rail-seat-high: rgba(250, 250, 250, 0.055);
    --ev-entity-header-danger-burr: var(--ev-danger-action-burr);
    --ev-entity-header-danger-ink: var(--ev-danger-action-ink);

    /* The segmented control's GROOVE SEAM between adjacent segments: two 1px
       achromatic runs a pixel apart — an ink run with a lit companion — reading
       as an inset milled groove, the same physics as the pinstripe grain. Light
       carries the seam mostly by ink over the grey floor.

       PROMOTED FROM components/segmented.css for the same reason as
       --ev-rail-seat above (cortex-wp0qzvk): the adapter draws this seam on a
       Bootstrap .btn-group, and restating the two rgba() values there would put
       colour literals in the adapter, which its own rule forbids.

       A seam beside the live seat remains physically present but recedes to a
       quarter-strength material trace. Keeping that opacity here makes the
       native control and Bootstrap adapter share the same muted state instead
       of encoding the founder-tuned value twice (cortex-t03qgev). */
    --ev-seg-groove-ink:  rgba(28, 28, 28, 0.24);
    --ev-seg-groove-land: rgba(250, 250, 250, 0.42);
    --ev-seg-groove-muted-opacity: 0.25;
    /* Top/bottom inset, so the seam is a short carved detail on the floor
       rather than a full-height rule up to the channel rim. Theme-independent:
       it is geometry, not material. */
    --ev-seg-groove-inset: 5px;
    /* The channel's continuous TOP ARRIS (segmented control). Unlike --ev-cut-edge
       — which shades a hairline against the light grey channel floor only — this
       edge must cross the ACCENT-LIT seat at the SAME darkness (cortex-hnrbqfe).
       A 0.42 line vanishes over the bright accent (a dark wash on a bright face
       barely registers) while reading crisp over the floor, so the rim broke
       exactly over the selected seat. A near-opaque dark line reads as one hard
       cut edge over BOTH surfaces — which is what a cut's own arris is. */
    --ev-seg-arris: rgba(24, 24, 24, 0.86);

    /* Dark material scope aliases — reachable REGARDLESS of page theme, so a
       surface that is dark stock in BOTH themes (product housing: nav, mobile
       menu) can consume them without hardcoding hex. (cortex-e6pvq66) */
    --ev-dark-metal-hi: #272727;
    --ev-dark-floor-n1: #1e1e1e;
    --ev-dark-r1-line:  inset 0 0 0 1px rgba(0, 0, 0, 0.96);
    --ev-dark-r1-lip:   inset 0 0 6px   rgba(0, 0, 0, 0.92);
    --ev-dark-r1-wall:  inset 0 0 10px  rgba(0, 0, 0, 0.66);
    --ev-dark-edge-glow: rgba(245, 245, 245, 0.055);
    --ev-dark-ink:     #f5f5f5;
    --ev-dark-ink-dim: #a3a3a3;

    /* -------------------------------------------------------------------
       SPRUNG SOCKET — the lobe-action material (cortex-czimc0b).
       A lobe key is a distinct rigid part sitting proud of its recessed
       keyplate, then travelling 2px into that seat when pressed. Its material
       follows the surrounding theme: quiet light stock on a light lobe, dark
       stock on a dark lobe. At normal scale one edge and a short contact shadow
       carry the part; extra nested hairlines made the small control visually
       louder than its host.

       Danger is an ink + edge exception for the downstream .ev-confirm
       consumer, never a differently coloured body. See boss.css.
       ------------------------------------------------------------------- */
    --ev-socket-radius: 6px;
    --ev-socket-face: #e2e2e2;
    --ev-socket-body:
        linear-gradient(180deg, #eeeeee 0%, #e2e2e2 58%, #d9d9d9 100%);
    --ev-socket-pressed:
        linear-gradient(180deg, #d5d5d5 0%, #dddddd 100%);
    --ev-socket-ink: var(--ev-ink);
    --ev-socket-ink-dim: var(--ev-ink-dim);
    --ev-socket-top: inset 0 1px 0 rgba(255, 255, 255, 0.72);
    --ev-socket-edge:
        inset 0 0 0 1px rgba(31, 31, 31, 0.24);
    --ev-socket-groove:
        0 1px 0 rgba(255, 255, 255, 0.55);
    --ev-socket-contact: 0 2px 2px -1px rgba(31, 31, 31, 0.28);
    --ev-socket-pressed-depth: inset 0 2px 2px rgba(31, 31, 31, 0.20);
    --ev-socket-danger-ink: #9f2f28;
    --ev-socket-danger-edge:
        inset 0 0 0 1px rgba(159, 47, 40, 0.48);

    /* Scribe lines and persistent state washes ON a machined floor — table
       rules, dividers, selected rows. Ink laid on a floor: same achromatic
       shading ink as the carve stack, nothing else. (cortex-mn5hkp8) */
    --ev-rule-strong: rgba(28, 28, 28, 0.15);
    --ev-rule:        rgba(28, 28, 28, 0.10);
    --ev-wash:        rgba(28, 28, 28, 0.04);

    /* Accent shading — for the primary key ONLY. A lit surface takes DARK ink. */
    --ev-accent-ink:       #06232f;
    --ev-accent-press: #159fe0;
    /* --ev-acc-crown is GONE (cortex-qws8bck). Its only two consumers were the
       segmented seat and the adapter's .btn-group mirror of it, both of which
       dropped the `inset 0 1px 0 0` crown line — an Invariant L1 offset shadow
       that had outlived the darkenings it was added to counter. The lit face of
       an accent part is the --ev-acc-lum-* swoop; there is no separate rim. */
    --ev-acc-lum-hi:   rgba(250, 250, 250, 0.30);
    --ev-acc-lum-mid:  rgba(250, 250, 250, 0.11);
    --ev-acc-lum-lo:   rgba(6, 35, 47, 0.13);
    --ev-acc-shoulder-1: inset 0 0 2px  rgba(6, 35, 47, 0.16);
    --ev-acc-shoulder-2: inset 0 0 7px  rgba(6, 35, 47, 0.13);
    --ev-acc-shoulder-3: inset 0 0 15px rgba(6, 35, 47, 0.10);
    --ev-acc-edge-glow:  rgba(250, 250, 250, 0.34);

    /* Press timing. Instant in, smooth out. */
    --ev-press-in:       60ms;
    --ev-press-in-ease:  cubic-bezier(0.2, 0, 0.4, 1);
    --ev-press-out:      120ms;
    --ev-press-out-ease: ease;

    /* Radius scale — four rungs. */
    --ev-radius-sm: 6px;
    --ev-radius-md: 8px;
    --ev-radius-lg: 12px;
    --ev-radius-pill: 100px;

    /* Entity header geometry. These values are the promoted v16 study
       measurements, now public because consumers compose the component
       directly. The seated action relationship is load-bearing:

           R = lobe radius = action radius = 10px
           h = action height = 30px
           lobe height = rim 9px + dip 31px = 40px
           action inset = (40px - 30px) / 2 = 5px

       Every lobe action is the same rounded socket part. Icon-only removes the
       legend, not the silhouette grammar: its glyph is centred in a 30px square
       with the same 10px corners as an icon-and-text action. The 5px insets
       centre the complete cluster against the WHOLE lobe: vertically that
       includes the upper rim rather than only the pocket below it; horizontally
       the authored lobe span is the cluster width plus two insets. The action
       carrier occupies that complete span, rather than merely naming a
       content-sized box. (cortex-k3ffgmn, cortex-ae3i39q) */
    --ev-entity-header-shell-radius: 28px;
    --ev-entity-header-content-inset: 40px;
    /* The identity plate and the glyph marked into it, at two named steps plus
       the live pair the component actually reads. Each figure is written once:
       the cramped composition restates the plate size as a grid track and the
       lead option restates it again, and the same number in three places is how
       the rail's height silently doubled. The glyph keeps roughly the plate's
       own 0.46 proportion at both steps (21/46, 32/72), so enlarging the plate
       does not also change how much of it the mark fills. */
    --ev-entity-header-mark-size-compact: 46px;
    --ev-entity-header-mark-glyph-compact: 21px;
    --ev-entity-header-mark-size-lead: 72px;
    --ev-entity-header-mark-glyph-lead: 32px;
    --ev-entity-header-mark-size: var(--ev-entity-header-mark-size-compact);
    --ev-entity-header-mark-glyph: var(--ev-entity-header-mark-glyph-compact);
    --ev-entity-header-lobe-radius: 10px;
    --ev-entity-header-rim-width: 9px;
    --ev-entity-header-lobe-dip: 31px;
    --ev-entity-header-lobe-offset: 27px;
    --ev-entity-header-seat-travel: 6px;
    --ev-entity-header-rail-overshoot: 12px;
    --ev-entity-header-action-gap: 3px;
    --ev-entity-header-seat-key-height: 30px;
    --ev-entity-header-seat-key-radius: var(--ev-entity-header-lobe-radius);
    --ev-entity-header-seat-key-padding-start: 9px;
    --ev-entity-header-seat-key-padding-end: 12px;
    --ev-entity-header-seat-key-font-size: 11px;
    --ev-entity-header-action-inset-x: 5px;
    --ev-entity-header-action-inset-y: 5px;
    /* The socket paints below its border box. The resting face therefore
       reads high even though the historical BORDER-BOX figure is 5px/5px.
       The enhancer translates the face in the positive block direction by
       half this measured overhang, within the named bounds. */
    --ev-entity-header-action-overhang-block-end: 2.67px;
    --ev-entity-header-action-shift-min: 0px;
    --ev-entity-header-action-shift-max: var(--ev-entity-header-action-inset-y);

    /* -------------------------------------------------------------------
       GLASS surface tokens — the content-aperture insert material.
       (cortex-t8w48yi.) A transparent PART seated in a machined aperture,
       whose job is to give CONTENT a material home. Every one of these is a
       WHITE / NEUTRAL alpha — NO hue anywhere. They describe the glass PART
       only; all colour comes from the CONTENT behind the glass (Invariant 7,
       achromatic material). See src/components/glass.css.
       ------------------------------------------------------------------- */
    /* the axial specular glint — a soft symmetric white ellipse near the top.
       Alpha only; zero x-offset — a glint on a curved surface, not a light
       (Invariant L1: symmetric axial light). */
    --ev-glass-glint:      rgba(255, 255, 255, 0.55);
    --ev-glass-glint-soft: rgba(255, 255, 255, 0.16);
    /* the bright inner bevel / refraction rim, just inside the glass edge */
    --ev-glass-bevel:      inset 0 0 0 1px rgba(255, 255, 255, 0.55);
    --ev-glass-bevel-soft: inset 0 0 6px   rgba(255, 255, 255, 0.20);
    /* the slight DARK outer contact where the glass part meets the aperture
       wall — the seam of two parts, achromatic (a contact shadow, not a hue) */
    --ev-glass-contact:    inset 0 0 0 1px rgba(20, 20, 20, 0.34);
    --ev-glass-contact-2:  inset 0 0 4px   rgba(20, 20, 20, 0.22);
    /* a hair of neutral darkening so the content reads as UNDER glass (a thin
       tempered-glass tint — grey, never coloured). Was rgba(18,18,20) — a blue
       cast that contradicted the "never coloured" this comment already claimed,
       and broke CLAUDE.md's glass rule ("every --ev-glass-* token is a white /
       neutral ALPHA — no hue anywhere"). Equal-luminance grey. (cortex-yzjllwa) */
    --ev-glass-underscrim: rgba(18, 18, 18, 0.10);
    /* frosted veil — a milky white diffusion laid over the content. Was
       rgba(244,246,248), likewise blue-cast where the comment said "white";
       #f6f6f6 is the same luminance achromatic. (cortex-yzjllwa) */
    --ev-glass-frost:      rgba(246, 246, 246, 0.42);

    /* -------------------------------------------------------------------
       Button (key) size scale — five steps, ratio 1.125 (major second).
       1.125 is the largest ratio that keeps xs above the hit-target floor.
       Height is pinned explicitly (line-height: 1) so the scale holds at the
       ends. Radius is a constant 0.359 of height at every step. (cortex-1r37qcl)

         step   height  font    pad y/x       radius
         xs     31px    10.5    9.5 / 16       11
         sm     35px    12      10.5 / 18      12.5
         md     39px    13.5    12 / 20        14   (default)
         lg     44px    15      13.5 / 22.5    16
         xl     49px    17      15 / 25.5      17.5
       ------------------------------------------------------------------- */
    --ev-btn-height-xs: 1.9375rem;   /* 31px */
    --ev-btn-height-sm: 2.1875rem;   /* 35px */
    --ev-btn-height-md: 2.4375rem;   /* 39px — default */
    --ev-btn-height-lg: 2.75rem;     /* 44px */
    --ev-btn-height-xl: 3.0625rem;   /* 49px */

    --ev-btn-font-xs: 0.65625rem;    /* 10.5px */
    --ev-btn-font-sm: 0.75rem;       /* 12px */
    --ev-btn-font-md: 0.84375rem;    /* 13.5px */
    --ev-btn-font-lg: 0.9375rem;     /* 15px */
    --ev-btn-font-xl: 1.0625rem;     /* 17px */

    --ev-btn-pad-y-xs: 0.59375rem;   /* 9.5px */
    --ev-btn-pad-y-sm: 0.65625rem;   /* 10.5px */
    --ev-btn-pad-y-md: 0.75rem;      /* 12px */
    --ev-btn-pad-y-lg: 0.84375rem;   /* 13.5px */
    --ev-btn-pad-y-xl: 0.9375rem;    /* 15px */

    --ev-btn-pad-x-xs: 1rem;         /* 16px */
    --ev-btn-pad-x-sm: 1.125rem;     /* 18px */
    --ev-btn-pad-x-md: 1.25rem;      /* 20px */
    --ev-btn-pad-x-lg: 1.40625rem;   /* 22.5px */
    --ev-btn-pad-x-xl: 1.59375rem;   /* 25.5px */

    --ev-btn-radius-xs: 0.6875rem;   /* 11px */
    --ev-btn-radius-sm: 0.78125rem;  /* 12.5px */
    --ev-btn-radius-md: 0.875rem;    /* 14px */
    --ev-btn-radius-lg: 1rem;        /* 16px */
    --ev-btn-radius-xl: 1.09375rem;  /* 17.5px */

    /* A control SEATED INSIDE A CUT keeps this much surviving floor between
       its rigid edge and the cut wall. Measured in the rendered entity-header
       rail: the selected detent resolves 3px from the channel on every closed
       side. The lobe's sprung sockets use the same physical relationship
       inside their keyplate cut; the boss's outer 4px land remains a separate
       fabrication layer and must not be collapsed into this inset.
       (cortex-5su0p6l) */
    --ev-seat-inset: 3px;

    /* ------------------------------------------------------------------
       The in-carve label's air.
       ------------------------------------------------------------------
       A label that names the carve it SITS IN needs the SAME air below it as
       above it. The air above is the carve's own top padding, so the two are
       one value, and it is the CARVE that declares it — .ev-carve-label only
       consumes it. Without that, a label reads as the heading of whatever is
       cut BELOW it: the lip progression shipped with 34px of air above each
       rank label and 8px below, which is exactly what the founder reported.

       CONTEXTUAL, not global — this is the point. A magnified demonstration
       slab and a tight readout pocket have different insets and both must hold
       the equality, so each carve sets this to its own padding and the
       relationship, not a magic number, is the invariant. The value below is
       only the fallback for a label in a carve that has not declared one; it
       is the standard 20px control inset. (cortex-4fg3ps6) */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);

    /* Determinate progress is a fixed, shallow cut with one live insert. The
       track owns the machined material; the fill spends the existing accent
       channel only to report the current amount. It is deliberately too small
       for a swoop or other finish treatment: at this scale those marks become
       decoration rather than readable fabrication. Geometry lives beside the
       material carriers so every consumer gets the same compact instrument. */
    --ev-progress-height: 0.5rem;
    --ev-progress-radius: var(--ev-radius-pill);
    --ev-progress-track: var(--ev-lightland-floor-n2);
    --ev-progress-track-line: var(--ev-r3-line);
    --ev-progress-track-lip: var(--ev-r3-lip);
    --ev-progress-track-wall: var(--ev-r3-wall);
    --ev-progress-fill: var(--ev-accent);

    /* Range is the adjustable sibling of determinate progress. Its channel is
       a real rank-3 cut; the accent insert is the selected interval and the
       achromatic cap is the one movable part. The 44px control block is the
       touch target, not depicted material: only the compact track and cap are
       painted inside it. */
    --ev-range-hit-size: 2.75rem;
    --ev-range-track-height: 0.625rem;
    --ev-range-track-radius: var(--ev-radius-pill);
    --ev-range-track: var(--ev-lightland-floor-n2);
    --ev-range-track-line: var(--ev-r3-line);
    --ev-range-track-lip: var(--ev-r3-lip);
    --ev-range-track-wall: var(--ev-r3-wall);
    --ev-range-fill: var(--ev-accent);
    --ev-range-thumb-size: 1.5rem;
    --ev-range-thumb-face: var(--ev-metal-hi);
    --ev-range-thumb-shadow: var(--ev-shoulder-lite), var(--ev-shoulder-1), var(--ev-seat-contact);

    --ev-transition-fast: 0.2s ease;
}

/* ==========================================================================
   Dark theme — the material layer mirrored.
   ==========================================================================
   NOT the light values inverted. In dark the shading ink is near-black at much
   higher alpha (a dark floor has far less headroom to darken into), and the lit
   rim/fillet counter-light drop hard (a bright line on dark material is far
   more conspicuous per unit alpha). Achromatic in both themes. (cortex-vnt3p6m)

   Keyed off BOTH the framework-agnostic [data-ev-theme="dark"] AND Bootstrap's
   [data-bs-theme="dark"] so this one file serves both consumer shapes.

   The first alternative is the AUTHORITY and the second is a convenience alias
   for Bootstrap's own literal — see THE CONSUMER CONTRACT at the top of this
   file. A consumer with a dark theme by any other name sets data-ev-theme
   alongside its own attribute; nothing here matches on the theme's name.

   ANY dark mirror added anywhere in src/ must carry this exact alternation.
   Keying a new register off [data-bs-theme="dark"] alone would silently take
   that ONE register out of the escape hatch — light badges on a dark bench
   while every other register is correct, which is far harder to spot than a
   uniformly wrong theme. scripts/check-theme-scope-registers.py enforces this
   across the built distribution, so it catches a new partial wherever it
   lands rather than only the six files that carry a mirror today. */
:is([data-ev-theme="dark"], [data-bs-theme="dark"]) {
    /* 1:1 WITH THE STUDY (cortex-r3qtun9): ink ramp is the study's dark ramp,
       verbatim — --ev-ink == study --ink #ebebeb, --ev-ink-dim == study
       --ink-soft #b4b4b4. The library had drifted to #e6e6e6 / #9a9a9a. */
    --ev-ink:        #ebebeb;
    --ev-ink-dim:    #b4b4b4;
    /* NON-TEXT — see the light-scope note. Dark is no better as ink: 3.11:1 on
       --ev-metal-hi, which is fine for the UI boundaries it actually draws (a
       hollow status ring, a resting outline-secondary border) and nowhere near
       the 4.5:1 a text rung would need.

       Was #6b7280 rgb(107,114,128) — a blue-cast slate, almost certainly
       inherited from a Tailwind-family palette during the port, and the last
       non-achromatic NEUTRAL in the library (Invariant L4: "every neutral is a
       true grey, R=G=B"). #727272 is the nearest true grey by WCAG relative
       luminance: 0.16827 against the slate's 0.16719, a delta of 0.001. So this
       is a purity fix that changes no contrast outcome — every ratio it
       participates in is unmoved to two decimals. (cortex-yzjllwa) */
    --ev-ink-faint:  #727272;
    /* 1:1 WITH THE STUDY: the study's --canvas #0e0e0e (neutral tar bench), a
       true achromatic near-black. The library had drifted to #1a1d21 — a
       BLUISH near-black that broke the achromatic invariant (R≠G≠B) and read
       cooler than the study's bench. Reverted to the study's canvas. */
    --ev-bg:         #0e0e0e;
    /* Direct bench carve, dark mirror — PER-THEME DIVERGENCE FROM LIGHT.
       In light the bench (#c9c9c9) has ample headroom to darken into, so the
       direct carve is a genuinely-darker floor (#b8b8b8 < bench) and reads as a
       real cut — option E as designed. In dark the bench is near-black #0e0e0e
       and there is NO headroom below it: a "true" darker carve (#080808) is
       visually black, collapsing every direct-bench element — .ev-machined·
       recessed / --shallow / +pinstripe--carve, dropzone, identity chip, entity
       token, the segmented channel — into an unreadable near-black slab. The
       dark ladder itself already resolves this tension by rendering recessed
       floors as LIFTED grey above the bench (n1 #1e1e1e, n2 #222222, n3 #262626
       all > #0e0e0e), so a direct bench carve joins the ladder at n2 — its
       depth carried by the near-black wall + lit arris, not by a floor darker
       than the ground. This restores the pre-E dark look the founder confirmed
       reads better; the :has(.ev-pocket) land case (core.css) and this now
       agree at n2, with nested pockets stepping to n1. (cortex-a2ca9mx,
       relates cortex-jc83lrz / cortex-c8qr7zn option E). */
    --ev-bench-floor: #222222;
    --ev-accent-fg:  #06232f;
    /* 1:1 WITH THE HISTORICAL V16 RECORD: in dark the accent needs no
       luminance step to be legible as ink, so --accent-text IS the accent —
       8.13:1 on --ev-bg #0e0e0e, 6.29:1 on --ev-metal-hi, 7.02:1 on
       --ev-floor-n1. Stated as the var, not a repeated #2bb3f3 literal, so the
       identity survives a future accent change. Computed value is the study's
       exactly. See the light-scope note for why the light theme needs a step. */
    --ev-accent-text: var(--ev-accent);
    /* The ink triple collapses with the ink itself — same identity, stated as
       the var so it cannot drift from the line above. (cortex-wp0qzvk) */
    --ev-accent-text-rgb: var(--ev-accent-rgb);
    /* Dark surfaces already give the face accent 6.29–8.13:1, so the boundary
       rung collapses back to the one accent rather than becoming a dark line. */
    --ev-accent-edge: var(--ev-accent);

    --ev-metal:     #1d1d1d;
    --ev-metal-hi:  var(--ev-dark-metal-hi);

    --ev-floor-n1:  var(--ev-dark-floor-n1);
    --ev-floor-n2:  #222222;
    --ev-floor-n3:  #262626;
    /* Dark already reads a raised-face cut correctly on the ordinary deepest
       rung: --ev-metal-hi #272727 -> --ev-floor-n1 #1e1e1e is 9 steps, a
       shallow cut rather than the 29-step slab the same pair produces in light.
       So dark keeps n1 and only light needs the light-land rung. Changing this
       line would move a face the founder has already accepted. */
    --ev-raised-carve-floor: var(--ev-floor-n1);

    /* Dark stock keeps the same compact geometry and live insert. Only the
       machined track material moves onto the dark ladder; the rank shadows
       above already mirror through their theme-scoped tokens. */
    --ev-progress-track: var(--ev-floor-n2);
    --ev-range-track: var(--ev-floor-n2);

    --ev-r1-line: var(--ev-dark-r1-line);
    --ev-r1-lip:  var(--ev-dark-r1-lip);
    --ev-r1-wall: var(--ev-dark-r1-wall);
    --ev-r1-rim:  0 0 0 1px        rgba(245, 245, 245, 0.22);

    --ev-r2-line: inset 0 0 0 1px rgba(0, 0, 0, 0.70);
    --ev-r2-lip:  inset 0 0 3px    rgba(0, 0, 0, 0.62);
    --ev-r2-wall: inset 0 0 5px    rgba(0, 0, 0, 0.38);
    --ev-r2-rim:  0 0 0 1px        rgba(245, 245, 245, 0.115);

    --ev-r3-line: inset 0 0 0 1px rgba(0, 0, 0, 0.45);
    --ev-r3-lip:  inset 0 0 2px    rgba(0, 0, 0, 0.40);
    --ev-r3-wall: inset 0 0 3px    rgba(0, 0, 0, 0.20);
    --ev-r3-rim:  0 0 0 1px        rgba(245, 245, 245, 0.06);

    --ev-shoulder-lite: inset 0 0 12px rgba(245, 245, 245, 0.052);
    --ev-shoulder-1:    inset 0 0 2px  rgba(0, 0, 0, 0.32);
    --ev-shoulder-2:    inset 0 0 7px  rgba(0, 0, 0, 0.26);
    --ev-shoulder-3:    inset 0 0 16px rgba(0, 0, 0, 0.20);
    --ev-contact-1:     0 0 3px  rgba(0, 0, 0, 0.85);
    --ev-contact-2:     0 0 5px  rgba(0, 0, 0, 0.90);
    --ev-ambient-1:     0 0 16px rgba(0, 0, 0, 0.55);
    --ev-ambient-2:     0 0 34px rgba(0, 0, 0, 0.72);
    --ev-contact-2-blur: 5px;
    --ev-contact-2-ink: rgba(0, 0, 0, 0.90);
    --ev-ambient-1-blur: 16px;
    --ev-ambient-1-ink: rgba(0, 0, 0, 0.55);
    --ev-ambient-2-blur: 34px;
    --ev-ambient-2-ink: rgba(0, 0, 0, 0.72);
    --ev-key-body-arrise-ink: rgba(245, 245, 245, 0.16);
    --ev-key-body-wall-ink:   rgba(0, 0, 0, 0.76);
    --ev-key-body-roll-ink:   rgba(0, 0, 0, 0.30);
    --ev-key-crown:
        radial-gradient(90% 160% at 50% 50%, var(--ev-lum-mid) 0%, transparent 50%);
    /* Dark stock returns only on the dark bench. */
    --ev-socket-face: #343434;
    --ev-socket-body:
        linear-gradient(180deg, #3d3d3d 0%, #343434 48%, #2b2b2b 100%);
    --ev-socket-pressed:
        linear-gradient(180deg, #292929 0%, #303030 100%);
    --ev-socket-ink: #f1f1f1;
    --ev-socket-ink-dim: #d2d2d2;
    --ev-socket-top: inset 0 1px 0 rgba(255, 255, 255, 0.56);
    --ev-socket-edge:
        inset 0 0 0 1px rgba(255, 255, 255, 0.24),
        inset 1px 0 0 rgba(255, 255, 255, 0.10),
        inset -1px 0 0 rgba(0, 0, 0, 0.52);
    --ev-socket-groove:
        0 1px 0 rgba(255, 255, 255, 0.12),
        0 2px 0 rgba(0, 0, 0, 0.82);
    --ev-socket-contact: 0 3px 0 -1px rgba(0, 0, 0, 0.82);
    --ev-entity-header-action-overhang-block-end: 2px;
    --ev-socket-pressed-depth: inset 0 2px 2px rgba(0, 0, 0, 0.58);
    --ev-socket-danger-ink: #ffb7ae;
    --ev-socket-danger-edge:
        inset 0 0 0 1px rgba(255, 126, 112, 0.68);
    /* Seat contact on the tar bench: the same tight seam, at the near-black
       occlusion alpha the dark stack uses everywhere. There is almost no
       headroom below --ev-bench-floor #080808, so this reads as delta ~2 — and
       that near-nil read IS the reference the light value above was dialled to
       match, because the dark seat is the one the founder signed off on. */
    --ev-seat-contact:  0 0 2px  rgba(0, 0, 0, 0.85);
    --ev-contact-tint:  rgba(0, 0, 0, 0.85);

    --ev-lum-hi:  rgba(245, 245, 245, 0.055);
    --ev-lum-mid: rgba(245, 245, 245, 0.020);
    --ev-lum-lo:  rgba(0, 0, 0, 0.20);

    /* PAGE ENVIRONMENT, dark — 1:1 with the study. On a dark bench the tooth is
       carried by LIGHT (a faint scattered sheen, not speckled black) and the
       canvas atmosphere reads as an oil sheen. Study --amb-* / --noise-alpha,
       verbatim. */
    --ev-amb-hi:      rgba(245, 245, 245, 0.050);
    --ev-amb-lo:      rgba(0, 0, 0, 0.30);
    --ev-noise-alpha: 0.026;

    /* Dark corner counter-light — re-measured (cortex-87trzv7). The prior 0.129
       was calibrated on the OUTER (rank-1) carve in light and carried into dark
       at ~0.43x; on a dark floor that has almost no headroom to darken into, a
       white patch that alpha lifts the corner APEX ABOVE the mid-edge (measured:
       corner-diagonal lum 40 vs mid-edge 31 on the FABRICATION PLANES machined
       swatch), i.e. a bright corner where a fillet should read as the DARKEST
       point of the face. Per Invariant 5 the counter-light is a RATIO to lip
       size, never a constant: the geometry (24px, matching the light fillet and
       the theme-independent lip blur) is unchanged; only the ALPHA drops to
       ~0.35x of the old value so the lifted apex lands AT or BELOW the mid-edge
       (re-measured: apex 27, mid-edge 29-31 — corner no longer exceeds edge).
       The -2/-3 rungs (the delicate nested lips) drop proportionally on the same
       ratio, so a nested cut's fillet never overshoots either. */
    --ev-fillet-light:   rgba(245, 245, 245, 0.045);
    --ev-fillet-size:    24px;
    --ev-fillet-light-2: rgba(245, 245, 245, 0.023);
    --ev-fillet-size-2:  12px;
    --ev-fillet-light-3: rgba(245, 245, 245, 0.014);
    --ev-fillet-size-3:  8px;

    --ev-edge-glow: var(--ev-dark-edge-glow);
    --ev-cut-edge:  rgba(0, 0, 0, 0.92);
    /* Rail seat, dark. NOT the light value inverted: in dark the channel floor
       is #1e1e1e and the seat must descend BELOW it into near-black at the same
       small swing the study measured (light channel->seat ~19 units; dark ~11,
       because dark floors have far less headroom to darken into). */
    --ev-rail-seat: #131313;
    --ev-entity-header-ink-muted: #adadad;
    --ev-entity-header-lobe-face: #191919;
    --ev-entity-header-chamfer-crest: rgba(245, 245, 245, 0.16);
    --ev-entity-header-chamfer-lit: rgba(245, 245, 245, 0.070);
    --ev-entity-header-chamfer-inner: rgba(0, 0, 0, 0.75);
    --ev-entity-header-chamfer-shade: rgba(0, 0, 0, 0.34);
    --ev-entity-header-r2-line-color: rgba(0, 0, 0, 0.70);
    --ev-entity-header-r2-wall-color: rgba(0, 0, 0, 0.38);
    --ev-entity-header-r3-rim-color: rgba(245, 245, 245, 0.06);
    --ev-entity-header-rail-floor: #191919;
    --ev-entity-header-rail-seat: #131313;
    --ev-entity-header-rail-seat-low: rgba(0, 0, 0, 0.22);
    --ev-entity-header-rail-seat-high: rgba(245, 245, 245, 0.030);
    --ev-danger-action-burr: rgba(242, 104, 92, 0.40);
    --ev-danger-action-ink: #ff8d81;
    --ev-entity-header-danger-burr: var(--ev-danger-action-burr);
    --ev-entity-header-danger-ink: var(--ev-danger-action-ink);
    /* Dark theme: the arris crosses the accent seat as a near-black cut line, the
       same hard edge it draws over the near-black channel floor (cortex-hnrbqfe). */
    --ev-seg-arris: rgba(0, 0, 0, 0.92);

    /* Groove seam, dark: the pair inverts to a near-black run with an almost
       invisible lit thread — a near-black floor has no room left to darken
       into, so the seam is carried mostly by the scattered light companion.
       Same inversion the pinstripe grain makes. */
    --ev-seg-groove-ink:  rgba(0, 0, 0, 0.55);
    --ev-seg-groove-land: rgba(245, 245, 245, 0.05);

    --ev-rule-strong: rgba(245, 245, 245, 0.14);
    --ev-rule:        rgba(245, 245, 245, 0.09);
    --ev-wash:        rgba(245, 245, 245, 0.05);

    /* No --ev-acc-crown here either — see the light block (cortex-qws8bck). */
    --ev-acc-lum-hi:  rgba(250, 250, 250, 0.22);
    --ev-acc-lum-mid: rgba(250, 250, 250, 0.08);
    --ev-acc-lum-lo:  rgba(6, 35, 47, 0.16);
    --ev-acc-shoulder-1: inset 0 0 2px  rgba(6, 35, 47, 0.34);
    --ev-acc-shoulder-2: inset 0 0 7px  rgba(6, 35, 47, 0.26);
    --ev-acc-shoulder-3: inset 0 0 15px rgba(6, 35, 47, 0.18);
    --ev-acc-edge-glow:  rgba(250, 250, 250, 0.20);

    /* GLASS in dark. Under the dark-theme luminance ceiling the glint and bevel
       DROP hard (a bright line on dark material is far more conspicuous per unit
       alpha — same reasoning as the carve stack), and the outer contact goes
       near-black. Still achromatic; still white/black alphas only. */
    --ev-glass-glint:      rgba(255, 255, 255, 0.30);
    --ev-glass-glint-soft: rgba(255, 255, 255, 0.07);
    --ev-glass-bevel:      inset 0 0 0 1px rgba(255, 255, 255, 0.22);
    --ev-glass-bevel-soft: inset 0 0 7px   rgba(255, 255, 255, 0.08);
    --ev-glass-contact:    inset 0 0 0 1px rgba(0, 0, 0, 0.85);
    --ev-glass-contact-2:  inset 0 0 5px   rgba(0, 0, 0, 0.55);
    --ev-glass-underscrim: rgba(0, 0, 0, 0.28);
    /* dark-scope frost — was rgba(228,232,236), the same blue cast as the light
       scope; equal-luminance grey. (cortex-yzjllwa) */
    --ev-glass-frost:      rgba(231, 231, 231, 0.10);
}

/* ===== src/core.css ===== */
/* ==========================================================================
   Evident — core primitives (the two fabrication planes)
   ==========================================================================

   Framework-agnostic, de-scoped public classes for Evident's own vocabulary.
   These are the EXTRACT + DE-SCOPE of the treatments that live under CC's
   `.rounded-white` (molded) and `.rounded-light` (machined) scope selectors —
   lifted out into standalone `.ev-*` classes so greenfield markup (the Cortex
   dashboard, new CC surfaces) can use them without the scope wrapper.

   Two fabrication planes, and nothing between them:
     MOLDED   (.ev-molded)   — cast. No cut edge; the shoulder rolls over.
                               Outer falloff. Reads RAISED. Interactive.
     MACHINED (.ev-machined) — tool-cut. A real cut edge with lip, floor, and
                               INSET shadow. Reads RECESSED. Information display.

   An element must never carry both an inset and an outer *depth* shadow: that
   claims to be cast and cut at once. The one legal outer shadow on a machined
   surface is --evN-rim, which is a lit burr, not depth.
   ========================================================================== */

/* --------------------------------------------------------------------------
   .ev-molded — the cast/raised plane (the float). (from .rounded-white)
   Opaque material, not glass. The rim carries the separation, not a blur.
   -------------------------------------------------------------------------- */
.ev-molded {
    /* A cut made directly into this cast face measures from THIS face, so the
       slab publishes its own carve floor rather than letting the page bench's
       floor inherit through OR falling back to the ordinary n1/n2/n3 ladder.
       The ladder is what a cut inside a CUT descends through; a first cut into
       raised stock is one contextual rung down from --ev-metal-hi.

       This replaces `--ev-direct-carve-floor: initial`. That reset was the
       reason the native composition still rendered light #ececec -> #cfcfcf, a
       29-step drop that reads as a filled slab, while the Bootstrap adapter's
       .rounded-white — the same physical face, differently named — had already
       been corrected to the 4-step rung. Both now resolve through the single
       --ev-raised-carve-floor token, so neither host can drift from the other
       and a consumer needs no local override to get the shipped face.
       (cortex-arivo8b; the narrow-scope reasoning it corrects is preserved in
       tokens.css.) */
    --ev-direct-carve-floor: var(--ev-raised-carve-floor);
    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    border: 0;
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
    transition: var(--ev-transition-fast);
}

/* A full-plane link lifts on hover; a plain plane does not. */
.ev-molded--float:hover {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2);
    transition: none;
}

/* The swoop — the specular return of a polished, LIVE cast face. It is the
   molded plane's finish/liveness cue, not a new channel: swoop present iff the
   face is live and faceplate-sized. The former independent modifier licensed
   decorative swoops on inert cards, so finish now owns the treatment. Author
   .ev-fin-polished on a faceplate-sized .ev-molded; machined and small parts
   never match this selector. Shadows remain axial, and the shared direction
   stays fixed. */
.ev-molded.ev-fin-polished:not(.ev-fin-oxidized) {
    position: relative;
    overflow: hidden;
}
.ev-molded.ev-fin-polished:not(.ev-fin-oxidized)::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(
        var(--ev-swoop-angle),
        var(--ev-lum-hi) 0%,
        var(--ev-lum-mid) 34%,
        transparent 60%,
        var(--ev-lum-lo) 100%);
}

/* --------------------------------------------------------------------------
   .ev-machined — THE machined surface primitive. Evident rank-1 carve.
   (from .rounded-light) A machined panel is itself a cut, so its floor follows
   whatever face it was cut into: directly on .ev-pinstripe, founder option E
   uses the inherited single --ev-bench-floor, and a bench carve plus everything
   cut inside it stay at that one legal level. Cut into raised stock it takes
   that face's --ev-raised-carve-floor by the same rule — one contextual rung
   under --ev-metal-hi, not the ladder (cortex-arivo8b changed this; the note
   used to say a raised slab always gave n2, which has been true only of the
   HOLDS-a-pocket case below since the raised hosts began publishing a floor).
   The ladder — n2 panel over n1 pocket — is what a panel gets the moment it
   actually holds a cut, which is the rule immediately below. The panel keeps
   rank-1 SHADING (heavy 6px lip) regardless, and that shading, not a drop in
   tone, is what carries the cut on a shallow floor.
   (cortex-vnt3p6m, cortex-c8qr7zn, cortex-arivo8b)
   -------------------------------------------------------------------------- */
.ev-machined {
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n2));
    color: var(--ev-ink);
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
    position: relative;
}

/* A machined panel that HOLDS a pocket is a LAND (a slab of stock cut into),
   not a single-level direct carve. Reset the host's floor override so the panel
   takes the n2 machined floor and the pocket inside descends to n1 — a visible
   depth step — instead of both collapsing to the host's one level: the
   near-black bench floor on the bench, or the shallow contextual rung on a
   raised card. This is the ladder, applied automatically when a cut is actually
   present. A bare .ev-machined with nothing cut into it stays a direct carve
   and follows its host. (cortex-a2ca9mx, cortex-arivo8b) */
.ev-machined:has(.ev-pocket) {
    --ev-direct-carve-floor: initial;
}

/* Rank modifiers — a shallower carve steps the shading finer (Invariant 2).
   The default .ev-machined is rank-1 (deep); --shallow/--medium override. */
.ev-machined--medium {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
}
.ev-machined--shallow {
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}
.ev-machined--deep {
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
}

/* Corner counter-light (fillet). A rim band wrapping 90deg converges two
   edge-bands into ~1.69x the area, so corners read darker than straight runs
   at identical per-pixel darkness.

   Invariant 5 — the counter-light is a RATIO to the LIP, never a constant. The
   default (rank-1, deep) carve reads its fillet from --ev-fillet-{light,size};
   the finer ranks step the fillet down to the -2 / -3 rungs in lockstep with
   their finer lip, via the local --ev-fillet-l / --ev-fillet-s indirection. A
   single constant calibrated on the deep carve OVERSHOOTS on the delicate lips
   — the corner then reads BRIGHTER than the mid-edge (a bright corner patch),
   most conspicuously in dark where a white patch sits on near-black stock
   (cortex-87trzv7, relates cortex-c8qr7zn). The -2/-3 tokens already exist per
   theme, so both themes get the ratio; no light-theme VALUE changes here. */
.ev-machined {
    --ev-fillet-l: var(--ev-fillet-light);
    --ev-fillet-s: var(--ev-fillet-size);
}
.ev-machined--medium {
    --ev-fillet-l: var(--ev-fillet-light-2);
    --ev-fillet-s: var(--ev-fillet-size-2);
}
.ev-machined--shallow {
    --ev-fillet-l: var(--ev-fillet-light-3);
    --ev-fillet-s: var(--ev-fillet-size-3);
}
.ev-machined::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 0% 0%,
            var(--ev-fillet-l), transparent 72%),
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 100% 0%,
            var(--ev-fillet-l), transparent 72%),
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 0% 100%,
            var(--ev-fillet-l), transparent 72%),
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 100% 100%,
            var(--ev-fillet-l), transparent 72%);
}

/* The floor's own curvature — a shallow centre sheen falling off to the walls.
   A milled floor is not perfectly flat. This is NOT a grain texture: finish is
   a channel that already means liveness, so a grain would be a third state. */
.ev-machined::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(125% 125% at 50% 50%,
            var(--ev-lum-mid) 0%,
            transparent      52%,
            transparent      80%,
            var(--ev-lum-lo) 100%);
}

/* Both pseudo-elements are decoration and must sit under the content. */
.ev-machined > * {
    position: relative;
    z-index: 1;
}

/* Flat glyphs on a carve — Invariant L3. Ink is ink; it has no material and
   casts nothing. No embossed/debossed/shadowed headings, ever. */
.ev-machined :is(h1, h2, h3, h4, h5, h6) {
    text-shadow: none;
    color: var(--ev-ink);
}

/* --------------------------------------------------------------------------
   Finish channel — liveness. Polished = live/editable, oxidized = inert/RO.
   The one channel that carries liveness; never encode it on floor luminance.
   -------------------------------------------------------------------------- */
.ev-fin-polished {
    filter: none;
    opacity: 1;
}
.ev-fin-oxidized {
    /* A read-only face reads dulled — a thin achromatic veil, no colour. */
    filter: saturate(0.9) brightness(0.98);
    opacity: 0.86;
}

/* ===== src/typography.css ===== */
/* ==========================================================================
   Evident — the type system
   ==========================================================================

   Typography is a first-class part of the design language, not an afterthought
   layered on top of the material work. This partial CODIFIES the type decisions
   that were already implicit in the readout, the keys, and the study's canvas
   text, and states them as the single source of numeric truth for text — the
   same way tokens.css is the source of truth for the material channels.

   Founder feedback (2026-07-27, cortex-9kzmfzu): "Typography is also in scope of
   the design system." So it is declared here.

   ------------------------------------------------------------------------------
   THE TWO RULES, APPLIED TO TYPE
   ------------------------------------------------------------------------------
   Evident's two rules govern type exactly as they govern surfaces:

   1. Nothing is depicted that is not there.
        Type is FLAT INK. There is no text-shadow, no emboss, no deboss, no
        engraving, no bevel on a glyph — ever (Invariant L3). A shadow on text
        would depict an occlusion event that did not happen: ink lies flat on
        the surface it is printed on; it does not float above it. Emboss/deboss
        is for SHAPES (the material planes), never for glyphs. A raised or
        recessed *plate* may carry flat ink; the ink itself stays flat.

   2. Every visual channel carries exactly one meaning.
        On type the live channels are SIZE (rank in the reading order), WEIGHT
        (emphasis), and FAMILY (sans = prose, mono = machine value). HUE on text
        carries exactly one meaning and only one: the single accent, used only
        for a genuinely live/active/interactive value (a link, a live readout
        value). Resting body text is never accent-hued. Colour is otherwise
        spent only on the ink ladder, which is a LUMINANCE ramp (achromatic,
        R=G=B via the ink tokens), i.e. prominence, not a second hue. As TEXT
        the ladder is two rungs — --ev-ink and --ev-ink-dim. --ev-ink-faint is
        a non-text token; a third text rung cannot clear AA on Evident's floors
        (cortex-g2j0rmv, reasoned in full in tokens.css).

   ------------------------------------------------------------------------------
   THE FAMILIES
   ------------------------------------------------------------------------------
   Exactly two, both already in the token layer (tokens.css) and already in play
   in the readout and the keys — this partial does not introduce a new typeface,
   it codifies the pair:

     --ev-font-sans   IBM Plex Sans   — ALL prose, labels, headings, UI text.
     --ev-font-mono   IBM Plex Mono   — RESERVED for genuine machine values:
                                        ids, metrics, hostnames, readouts,
                                        numerals in a technical readout, code.

   Mono is EARNED, not decorative (Invariant L5). Reaching for mono to look
   "technical" on prose is the same failure as hue-for-decoration: it makes the
   family channel mean two things. If it is not a machine value, it is sans.

   ------------------------------------------------------------------------------
   THE SCALE
   ------------------------------------------------------------------------------
   A small, deliberate set — seven steps — on a MINOR-THIRD ratio (1.2) above the
   body, matching the study's own canvas text (body ~15.5px, headings ~19-23px)
   rather than re-deriving a fresh scale. Small text steps DOWN from body on the
   same ratio. Sizes are rem so a consumer's root font-size governs; the px in
   the comment is at the 16px browser default.

     token                 rem        px      role
     --ev-text-display     2.1875rem  35px    one hero line per view, at most
     --ev-text-h1          1.75rem    28px    page / section title
     --ev-text-h2          1.375rem   22px    major heading
     --ev-text-h3          1.125rem   18px    sub-heading
     --ev-text-body        0.96875rem 15.5px  the sanctioned canvas body size
     --ev-text-small       0.8125rem  13px    dense UI text, secondary labels
     --ev-text-caption     0.6875rem  11px    the floor: captions, meta, chips

   The ratio between display and body is compressed relative to a strict 1.2^n
   because a screen hero rarely needs to shout as loud as print; the steps below
   body hold the ratio exactly so dense UI stays even.

   ------------------------------------------------------------------------------
   WEIGHTS
   ------------------------------------------------------------------------------
   Three IBM Plex weights, no more. A fourth weight is a channel splitting in two.

     --ev-weight-regular   400   body, readout values, running prose
     --ev-weight-medium    500   labels, small emphasis, table headers
     --ev-weight-semibold  600   headings, the one strong word in a line

   Bold-800 and light-300 are deliberately absent: 400/500/600 already carry
   the three levels of emphasis the reading order needs, and each extra weight
   is one more thing the eye must learn to tell apart at a glance.

   ------------------------------------------------------------------------------
   LINE-HEIGHT
   ------------------------------------------------------------------------------
   Three, mapped to purpose, not to size:

     --ev-leading-tight    1.15   display / headings (large type needs less air)
     --ev-leading-snug     1.3    UI blocks, labels, table cells
     --ev-leading-body     1.55   running prose (the study's canvas body value)

   ------------------------------------------------------------------------------
   LETTER-SPACING
   ------------------------------------------------------------------------------
   Type is set at its designed spacing (0) almost everywhere. Three deliberate
   exceptions, each earning its tracking:

     --ev-tracking-tight    -0.01em  large display/headings, where default
                                     tracking looks loose at size
     --ev-tracking-caps      0.04em  caption / chip labels — caps need air to
                                     stay readable
     --ev-tracking-eyebrow   0.10em  the OPEN kicker: the .ev-eyebrow "upperspace"
                                     section label, deliberately more generous
                                     than the caption (the study's .nest-cap)

   All-caps is itself rationed: it is a caption-level affordance (eyebrows, chip
   labels), never a heading treatment — a shouting heading is a size decision,
   not a caps decision. The caption (.ev-caption, 0.04em, faint) and the eyebrow
   (.ev-eyebrow, 0.10em, muted) are the two sanctioned all-caps roles.
   ========================================================================== */

:root {
    /* Family aliases live in tokens.css (--ev-font-sans / --ev-font-mono) and
       are consumed here; they are NOT redeclared, to keep one definition. */

    /* Size scale — seven steps, minor third (1.2) below the body. */
    --ev-text-display: 2.1875rem;    /* 35px  */
    --ev-text-h1:      1.75rem;      /* 28px  */
    --ev-text-h2:      1.375rem;     /* 22px  */
    --ev-text-h3:      1.125rem;     /* 18px  */
    --ev-text-body:    0.96875rem;   /* 15.5px — the sanctioned canvas body size */
    --ev-text-small:   0.8125rem;    /* 13px  */
    --ev-text-caption: 0.6875rem;    /* 11px  */

    /* Weights — three, no more. */
    --ev-weight-regular:  400;
    --ev-weight-medium:   500;
    --ev-weight-semibold: 600;

    /* Line-height — by purpose. */
    --ev-leading-tight: 1.15;
    --ev-leading-snug:  1.3;
    --ev-leading-body:  1.55;

    /* Letter-spacing — 0 by default; three earned exceptions. */
    --ev-tracking-tight:   -0.01em;
    --ev-tracking-caps:     0.04em;
    /* The eyebrow's generous tracking — deliberately MORE OPEN than the caption
       (0.04em). An eyebrow is a spaced-out kicker label above a heading; the wide
       tracking is what gives it the "upperspace" feel from the study's .nest-cap
       treatment. Rationed to the eyebrow only (cortex-x738nj7). */
    --ev-tracking-eyebrow:  0.10em;
}

/* ==========================================================================
   Type classes — the small set of ready-made roles.
   ==========================================================================

   Utility classes that COMPOSE the tokens above (never inventing values), so
   greenfield markup can reach for a role by name. All share the sans family and
   flat ink; each states its size / weight / leading. .ev-mono is the one that
   swaps family, and only for genuine machine values.

   Every class sets `color: var(--ev-ink)` explicitly so a fragment rendered
   outside a themed body still gets legible flat ink. FLAT: none of these carry
   a text-shadow, by rule (Invariant L3). */

.ev-display,
.ev-h1, .ev-h2, .ev-h3,
.ev-body, .ev-small, .ev-caption, .ev-eyebrow, .ev-carve-label, .ev-aux,
.ev-mono {
    font-family: var(--ev-font-sans);
    color: var(--ev-ink);
    text-shadow: none;   /* explicit: type is flat ink, never embossed (L3). */
    margin: 0;
}

.ev-display {
    font-size: var(--ev-text-display);
    font-weight: var(--ev-weight-semibold);
    line-height: var(--ev-leading-tight);
    letter-spacing: var(--ev-tracking-tight);
}

.ev-h1 {
    font-size: var(--ev-text-h1);
    font-weight: var(--ev-weight-semibold);
    line-height: var(--ev-leading-tight);
    letter-spacing: var(--ev-tracking-tight);
}

.ev-h2 {
    font-size: var(--ev-text-h2);
    font-weight: var(--ev-weight-semibold);
    line-height: var(--ev-leading-snug);
    letter-spacing: var(--ev-tracking-tight);
}

.ev-h3 {
    font-size: var(--ev-text-h3);
    font-weight: var(--ev-weight-semibold);
    line-height: var(--ev-leading-snug);
}

.ev-body {
    font-size: var(--ev-text-body);
    font-weight: var(--ev-weight-regular);
    line-height: var(--ev-leading-body);
}

.ev-small {
    font-size: var(--ev-text-small);
    font-weight: var(--ev-weight-medium);
    line-height: var(--ev-leading-snug);
    color: var(--ev-ink-dim);   /* secondary text steps down the ink ladder. */
}

/* Caption / eyebrow — the one sanctioned all-caps affordance. Caps EARN the
   caps tracking. The ink sits at the DIM rung, not a fainter one: caps +
   tracking + semibold at 11px already say "meta, not content", so dropping the
   ink as well was a second carrier of a meaning already carried — the thing
   rule 2 forbids — and it was the carrier that failed AA (1.83:1 on
   --ev-floor-n1). The caption is still distinguishable from body: it differs in
   case, tracking, weight and size. (cortex-g2j0rmv; ladder note in tokens.css.) */
.ev-caption {
    font-size: var(--ev-text-caption);
    font-weight: var(--ev-weight-semibold);
    line-height: var(--ev-leading-snug);
    letter-spacing: var(--ev-tracking-caps);
    text-transform: uppercase;
    color: var(--ev-ink-dim);
}

/* Eyebrow — the "upperspace" kicker. The study's .nest-cap treatment, promoted
   to a first-class Evident type role (cortex-x738nj7). A generously-tracked
   all-caps label that sits ABOVE a heading as a section kicker. It is a SIBLING
   of the caption, not a replacement: both are the sanctioned all-caps affordance,
   and the eyebrow is the OPEN one (0.10em vs the caption's 0.04em). Both now sit
   at the muted ink rung — the eyebrow used to be one step brighter than the
   caption, but that separation rode on --ev-ink-faint, which is no longer a text
   rung (cortex-g2j0rmv). TRACKING is what tells these two apart, and it always
   did the clearer job: an open kicker labels a section, a tight caption annotates
   the thing beside it. Flat ink, no shadow (L3). */
.ev-eyebrow,
.ev-carve-label {
    font-size: 11px;
    font-weight: var(--ev-weight-semibold);
    line-height: var(--ev-leading-snug);
    letter-spacing: var(--ev-tracking-eyebrow);
    text-transform: uppercase;
    color: var(--ev-ink-dim);   /* the muted-ink rung — a structural label. */
}

/* IN-CARVE LABEL — the eyebrow's twin for a label that names the carve it SITS
   IN, rather than the thing that follows it. One class across the lip
   progression, the readout well and the baseplate, which is what makes the
   three read as one language (founder review 2026-07-28, cortex-4fg3ps6).

   THE DEFECT IT FIXES IS ARITHMETIC, NOT TASTE. The lip progression shipped
   with 34px of air above each rank label (the carve's padding) and 8px below
   it (the label's own margin). 34 ≠ 8, so every label sat against the sub-carve
   underneath and read as ITS heading — "RANK 1" appeared to title the rank-2
   pocket rather than to name the rank-1 carve it was actually inside. Equal air
   on both sides is what makes a label belong to its own carve.

   The founder's word was "CENTER", and the same sentence defines what it means:
   "equal distance above the text and to the upper edge of the sub-carve below
   it". That is VERTICAL centring — the label centred in the band between its
   carve's top edge and the next cut. It is deliberately not horizontal: the
   well's title spans a left-aligned key/value grid and the baseplate's caption
   row ends in a right-landing .ev-aux, so a centred line would fight the
   composition in two of the three places it has to live. Naming that here so it
   reads as a decision, not an omission.

   :not(:last-child) because a label that is the ONLY thing in its carve already
   has the carve's own bottom padding under it; adding the gap on top would
   double the air below and unbalance it the other way. (The zero base margin
   comes from the shared type rule above, so only the gap is declared here.) */
.ev-carve-label:not(:last-child) {
    margin-bottom: var(--ev-carve-label-gap);
}

/* AUXILIARY TEXT — a short companion to a heading or a label: subordinate in
   the reading order, not subordinate in truth. A count, an id, a qualifier, a
   status figure ("3 variants", "fra-01", "read, not learned").

   It is a ROLE, not a POSITION (founder ruling, cortex-l6wn803). The name says
   WHAT IT IS; "secondary" would name a rank and "subtext" a position, both of
   which were explicitly rejected. Alignment is therefore NOT part of this rule —
   where an aux LANDS is the host component's business, expressed as a context
   rule beside that component (see .ev-baseplate__cap in baseplate.css).

   It replaces .ev-eyebrow__val, which was scoped as a BEM element of the eyebrow
   and mono by default. Both were wrong: the companion appears beside headings
   and captions too, not only eyebrows, and most of its call sites are prose
   ("the entity header", "no modals, no toasts") where mono was decoration, which
   Invariant L5 forbids. Mono is now EARNED via --mono. (Removed cleanly, no
   alias, per cortex-qairdc1; row in docs/removed-names.tsv.)

   Sits at the caption step (11px) so it matches the eyebrow it most often sits
   beside — a companion that outsized its own label would invert the hierarchy
   the role exists to express. Medium weight and normal tracking against the
   eyebrow's semibold + 0.10em: the two are told apart by CASE and TRACKING, the
   carriers that already do that job, not by a second colour rung. Ink sits at
   the dim rung — 7.33:1 on --ev-floor-n2, 6.97:1 on the deepest --ev-floor-n1,
   7.67:1 / 8.04:1 dark (historical v16 contrast audit). */
.ev-aux {
    font-family: var(--ev-font-sans);
    font-size: var(--ev-text-caption);
    font-weight: var(--ev-weight-medium);
    line-height: var(--ev-leading-snug);
    letter-spacing: normal;
    text-transform: none;
    color: var(--ev-ink-dim);
}

/* Mono is EARNED (L5): opt in only for a GENUINE machine value — a node id, a
   measurement, a count. Not for prose that happens to be short. The tracking is
   the readout's, because mono figures otherwise touch. */
.ev-aux--mono {
    font-family: var(--ev-font-mono);
    font-weight: var(--ev-weight-regular);
    letter-spacing: 0.03em;
    font-variant-numeric: tabular-nums;
}

/* Mono — the family swap, for GENUINE machine values only (L5). Inherits size
   from context so it aligns with the sans it sits beside; use .ev-body etc. for
   size, .ev-mono for family. The tiny positive tracking matches the readout,
   where mono figures otherwise touch. */
.ev-mono {
    font-family: var(--ev-font-mono);
    font-weight: var(--ev-weight-regular);
    letter-spacing: 0.01em;
    font-variant-numeric: tabular-nums;   /* numerals align in columns. */
}

/* An accent text value — hue as INK, the ONE allowed use of colour on type:
   a genuinely live / active / interactive value (a link, a live readout digit).
   Never on resting prose. Composable onto any of the classes above.

   Takes --ev-accent-text, NOT --ev-accent: the accent is a FACE value and is
   illegible as ink on a light ground (1.43:1 on the canvas). --ev-accent-text
   is the same hue walked down a luminance step, worst measured 6.26:1 in light;
   in dark it resolves back to the accent itself. See tokens.css. (cortex-8jhd90a) */
.ev-ink-accent { color: var(--ev-accent-text); }

/* THE TEXT LINK — one interactive object, one uninterrupted live channel.

   Accent ink is a RESTING property of a text link, not a hover effect. Hue
   therefore says exactly one thing: "this whole run is interactive". Pointer
   or keyboard arrival uses a second channel, the underline, while keyboard
   focus also receives a boundary that cannot be mistaken for hover. This is
   the general rule for linked domain names, ids and prose destinations; it is
   not a Control Center exception.

   The whole anchor takes --ev-accent-text. Never colour only the machine-value
   span inside a longer link: that draws a boundary inside an object that has
   none and turns hue into emphasis. Internal hierarchy may use the family
   channel (.ev-mono for the genuine machine value, sans for its gloss), but
   every child inherits the same ink. Do not put .ev-ink-dim, semantic ink or
   another colour carrier inside .ev-link.

   --ev-accent is deliberately absent: it is the lit FACE value and measures
   only 1.43:1 on the light canvas. --ev-accent-text is the AA-safe ink value
   (worst public light ground 6.26:1); --ev-accent-edge is the independently
   named focus/boundary carrier. The identical hue does not merge their
   meanings because ink and geometry are different visual channels. */
.ev-link {
    color: var(--ev-accent-text);
    text-decoration-line: underline;
    text-decoration-color: transparent;
    text-decoration-thickness: 0.08em;
    text-underline-offset: 0.16em;
}

.ev-link :where(*) {
    color: inherit;
}

.ev-link:is(:hover, :focus-visible) {
    text-decoration-color: currentColor;
}

.ev-link:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
    border-radius: 2px;
}

/* The ink ladder as explicit text utilities, for prominence (a luminance ramp,
   not a second hue). TWO rungs, because the ladder is two rungs deep as text —
   there is deliberately no .ev-ink-faint. It existed, and it was a footgun: a
   colour utility a consumer could put on any text, that failed AA on every
   ground Evident defines (1.83:1 on --ev-floor-n1). Removed rather than
   darkened, because the only passing value for it IS --ev-ink-dim
   (cortex-g2j0rmv — see the ink-ladder note in tokens.css). */
.ev-ink-dim   { color: var(--ev-ink-dim); }

/* ===== src/components/keys.css ===== */
/* ==========================================================================
   Evident component — keys (buttons)
   ==========================================================================

   Public de-scoped button vocabulary. BEM `--` modifiers under the `ev-`
   namespace so these NEVER collide with Bootstrap's own `.btn-primary` /
   `.btn-lg` / `.btn-sm` (the exact collision cortex-q29li00 measured).

     .ev-key                 the default key (md)
     .ev-key--xs/sm/md/lg/xl the five-step size scale (ratio 1.125)
     .ev-key--primary        the lit accent key (dark ink, Invariant 7)
     .ev-key--danger         neutral-at-rest destructive key
     .ev-key__glyph          canonical action glyph slot
     .ev-key__label          durable action wording

   A key is a RAISED cast part (molded), so it sits on the molded outer
   falloff, never on a rim. Size is ORTHOGONAL to variant: a size modifier sets
   only geometry, a variant sets only colour, and they compose.

   Study source: "Keys, one material two colours". Verified treatment ported
   from CC's .btn / .btn-primary / .rounded-white .btn rules. (cortex-1r37qcl,
   cortex-mn5hkp8)

   DANGER MARKUP CONTRACT
   ----------------------
   Every .ev-key--danger has a specific accessible name. Where space permits,
   pair the standard trash glyph (the 20x20 path shown in the showcase,
   aria-hidden="true") with explicit destructive wording in .ev-key__label.
   Icon-only use is the compact exception and MUST put that wording in an
   aria-label on the control. Colour never carries destructive identity by
   itself: the glyph and accessible wording remain present on touch/non-hover
   devices while warm ink and burr are interaction feedback only.
   ========================================================================== */

.ev-key {
    --ev-direct-carve-floor: initial;
    --ev-key-lift-scale: 1;
    /* The cast body, composed HERE and not in the token file, because a var()
       inside a custom property resolves where it is DECLARED. --ev-key-lift-scale
       is per-key state, so these three layers can only be built on the key
       itself; built at :root they compute guaranteed-invalid and every
       box-shadow naming them collapses to `none` (cortex-mz9m49a). A size
       modifier re-declares the scale on this same element, so its computed
       value — not the md default above — is what these substitute. */
    --ev-key-body-arrise:
        inset 0 0 0 calc(1px * var(--ev-key-lift-scale)) var(--ev-key-body-arrise-ink);
    --ev-key-body-wall:
        inset 0 0 calc(3px * var(--ev-key-lift-scale)) var(--ev-key-body-wall-ink);
    --ev-key-body-roll:
        inset 0 0 calc(9px * var(--ev-key-lift-scale)) var(--ev-key-body-roll-ink);
    /* geometry — md default */
    height: var(--ev-btn-height-md);
    padding: var(--ev-btn-pad-y-md) var(--ev-btn-pad-x-md);
    font: 600 var(--ev-btn-font-md)/1 var(--ev-font-sans);
    border-radius: var(--ev-btn-radius-md);
    /* raised cast key on land */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    border: 0;
    background-color: var(--ev-metal-hi);
    background-image: var(--ev-key-crown);
    color: var(--ev-ink);
    cursor: pointer;
    user-select: none;
    text-decoration: none;
    transition: var(--ev-transition-fast);
    box-shadow:
        var(--ev-key-body-arrise),
        var(--ev-key-body-wall),
        var(--ev-key-body-roll),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

/* HOST-ELEMENT NEUTRALITY — the hover half. A key is a PART, and which element
   hosts it is a semantic choice: `.ev-notice__action` ships the same key as an
   <a> for the way onward and a <button> for the mutation. Why a key must not
   underline AT ALL — its legend is a laser mark that removes no material (L3),
   and the underline channel already belongs to `.ev-link` — is argued once at
   `.ev-entity-header__action` in entity-header.css and is not repeated here.

   THE DECLARATION ABOVE IS NOT SUFFICIENT ON ITS OWN, which is the part a later
   reader will be tempted to simplify away. It is (0,1,0): enough for the resting
   form a modern reboot states on the element — Bootstrap 5's
   `a { text-decoration: underline }` is (0,0,1) — but a reboot that states the
   underline per state instead, `a:hover { text-decoration: underline }` at
   (0,1,1), outranks it, and no state rule below names the property. Under such a
   consumer an anchor-hosted key is clean at rest and sprouts an underline on
   arrival: the same defect the entity-header action carried, one degree harder
   to catch, because it exists only while the pointer is on it. Enumerating the
   states inside `:is()` takes the specificity of its most specific argument, so
   each arm is (0,2,0) and clears both reboot shapes without `!important`.

   THE ONE COMPOSITION THIS MUST NOT SILENCE is `.ev-notice__action--auxiliary`,
   a key that legitimately OWNS the underline channel: it is the same step marked
   INTO the face rather than cast onto it, so the mark is what carries its lower
   emphasis. `:link` matches a resting anchor, so this rule reaches that key in
   every state, not just on hover — notice.css therefore restates the ownership
   at (0,3,0) rather than leaving it to which partial the build concatenated
   last. A future composition that wants the same channel states its ownership
   there, in its own partial, at (0,3,0); it does not weaken this rule to make
   room. (cortex-wkljlpn) */
.ev-key:is(
    :link,
    :visited,
    :hover,
    :focus,
    :focus-visible,
    :active,
    :disabled,
    [aria-disabled="true"]
) {
    text-decoration: none;
}

/* The cap body and its lift are geometry: arris, wall, roll, contact and
   ambient falloff all step with the key at the same 1.125 ratio. The first
   three layers define the part itself, so same-token key and host remain
   distinct even with the outer falloff removed. Every layer is concentric —
   L1 forbids a directional light. */
.ev-key:not(:disabled):not(.ev-key--disabled):hover {
    transition: none;
    box-shadow:
        var(--ev-key-body-arrise),
        var(--ev-key-body-wall),
        var(--ev-key-body-roll),
        0 0 calc(var(--ev-contact-2-blur) * var(--ev-key-lift-scale))
            var(--ev-contact-2-ink),
        0 0 calc(var(--ev-ambient-2-blur) * var(--ev-key-lift-scale))
            var(--ev-ambient-2-ink);
}

/* A press is a real geometric event: the key travels DOWN into the panel it
   sits on, so the outer depth shadow is dropped and replaced with the cut
   stack. No translateY — that would depict a downward light on an axial face. */
.ev-key:active {
    background-image: none;
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

.ev-key:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

.ev-key:disabled,
.ev-key.ev-key--disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.ev-key__glyph {
    display: block;
    inline-size: 1.1em;
    block-size: 1.1em;
    flex: 0 0 auto;
}

/* ---- size scale — five steps, ratio 1.125 --------------------------------- */
.ev-key--xs {
    --ev-key-lift-scale: 0.7901234568; /* 1.125^-2 = 64/81 */
    height: var(--ev-btn-height-xs);
    padding: var(--ev-btn-pad-y-xs) var(--ev-btn-pad-x-xs);
    font-size: var(--ev-btn-font-xs);
    border-radius: var(--ev-btn-radius-xs);
}
.ev-key--sm {
    --ev-key-lift-scale: 0.8888888889; /* 1.125^-1 = 8/9 */
    height: var(--ev-btn-height-sm);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    font-size: var(--ev-btn-font-sm);
    border-radius: var(--ev-btn-radius-sm);
}
.ev-key--md {
    --ev-key-lift-scale: 1;
    height: var(--ev-btn-height-md);
    padding: var(--ev-btn-pad-y-md) var(--ev-btn-pad-x-md);
    font-size: var(--ev-btn-font-md);
    border-radius: var(--ev-btn-radius-md);
}
.ev-key--lg {
    --ev-key-lift-scale: 1.125; /* 9/8 */
    height: var(--ev-btn-height-lg);
    padding: var(--ev-btn-pad-y-lg) var(--ev-btn-pad-x-lg);
    font-size: var(--ev-btn-font-lg);
    border-radius: var(--ev-btn-radius-lg);
}
.ev-key--xl {
    --ev-key-lift-scale: 1.265625; /* 1.125^2 = 81/64 */
    height: var(--ev-btn-height-xl);
    padding: var(--ev-btn-pad-y-xl) var(--ev-btn-pad-x-xl);
    font-size: var(--ev-btn-font-xl);
    border-radius: var(--ev-btn-radius-xl);
}

/* ---- .ev-key--primary — THE lit accent key ------------------------------- */
/* A lit surface reads bright and takes DARK ink (--ev-accent-ink). White ink
   would imply the metal itself is blue. Depth is carried by blurred stacks
   with NO line in them — no 1px edge ring (the rim trap wearing `inset`).
   Hover stays lit and steps the falloff (liveness is finish, not geometry);
   press travels down to --ev-accent-press and takes the cut stack.
   (cortex-mn5hkp8) */
.ev-key--primary {
    background-color: var(--ev-accent);
    color: var(--ev-accent-ink);
    font-weight: 500;
    box-shadow:
        var(--ev-key-body-arrise),
        var(--ev-key-body-wall),
        var(--ev-key-body-roll),
        var(--ev-acc-shoulder-1),
        var(--ev-acc-shoulder-2),
        var(--ev-contact-1);
}

.ev-key--primary:not(:disabled):not(.ev-key--disabled):hover {
    box-shadow:
        var(--ev-key-body-arrise),
        var(--ev-key-body-wall),
        var(--ev-key-body-roll),
        var(--ev-acc-shoulder-1),
        var(--ev-acc-shoulder-2),
        0 0 calc(var(--ev-contact-2-blur) * var(--ev-key-lift-scale))
            var(--ev-contact-2-ink),
        0 0 calc(var(--ev-ambient-1-blur) * var(--ev-key-lift-scale))
            var(--ev-ambient-1-ink);
}

.ev-key--primary:active {
    background: var(--ev-accent-press);
    color: var(--ev-accent-ink);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

/* ---- .ev-key--danger — neutral stock, destructive interaction feedback --- */
/* Wording + the canonical trash glyph carry the durable meaning. At rest this
   is byte-for-byte the default key's neutral material/ink doctrine. Hover and
   keyboard focus warm only ink and the light caught by the raised arris; the
   stock stays achromatic. Press keeps warm ink but loses the burr because a
   key travelling into the panel has no raised arris left to catch light. */
.ev-key--danger {
    background-color: var(--ev-metal-hi);
    color: var(--ev-ink);
}

.ev-key--danger:not(:disabled):not(.ev-key--disabled):is(:hover, :focus-visible) {
    color: var(--ev-danger-action-ink);
    box-shadow:
        var(--ev-key-body-arrise),
        var(--ev-key-body-wall),
        var(--ev-key-body-roll),
        0 0 calc(var(--ev-contact-2-blur) * var(--ev-key-lift-scale))
            var(--ev-contact-2-ink),
        0 0 calc(var(--ev-ambient-2-blur) * var(--ev-key-lift-scale))
            var(--ev-ambient-2-ink),
        0 0 0 1px var(--ev-danger-action-burr);
}

.ev-key--danger:focus-visible {
    outline-color: var(--ev-danger-action-ink);
}

.ev-key--danger:not(:disabled):not(.ev-key--disabled):active {
    background: var(--ev-metal-hi);
    color: var(--ev-danger-action-ink);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

.ev-key--danger:disabled,
.ev-key--danger.ev-key--disabled {
    background: var(--ev-metal-hi);
    color: var(--ev-ink);
}

/* ---- .ev-key--ghost — text-only key, no material ------------------------- */
/* A link-like key: no cast face, so no falloff. Ink + accent on hover only. */
.ev-key--ghost {
    background-color: transparent;
    background-image: none;
    color: var(--ev-ink-dim);
    box-shadow: none;
    font-weight: 500;
}
.ev-key--ghost:not(:disabled):not(.ev-key--disabled):hover {
    background: transparent;
    /* Ink on the bare ground the ghost key sits on, so it takes --ev-accent-text
       (the accent a luminance step down), not the face-value --ev-accent, which
       is 1.43:1 there in light. Dark resolves it back. (cortex-8jhd90a) */
    color: var(--ev-accent-text);
    box-shadow: none;
}
.ev-key--ghost:active {
    box-shadow: none;
}

/* ---- keys INSIDE a machined carve — detents, not raised keys ------------- */
/* Under the nesting invariant a raised block may not sit inside a cut. Where a
   key genuinely lives on a machined floor it renders as a DETENT cut one rung
   below the panel (n1), rank-2 shading, never as a raised key. */
.ev-machined .ev-key:not(.ev-key--ghost):not(.ev-key--primary):not(.ev-key--danger) {
    background: var(--ev-floor-n1);
    background-image: none;
    color: var(--ev-ink);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}
.ev-machined .ev-key:not(.ev-key--ghost):not(.ev-key--primary):not(.ev-key--danger):not(:disabled):not(.ev-key--disabled):hover {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}
.ev-machined .ev-key:not(.ev-key--ghost):not(.ev-key--primary):not(.ev-key--danger):active {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
}

/* ===== src/components/cards.css ===== */
/* ==========================================================================
   Evident component — cards (molded planes)
   ==========================================================================

   A card is the molded plane used as a container: a cast, raised billet the
   content sits on. De-scoped from CC's `.card.rounded-white`. It composes the
   .ev-molded primitive plus card-shaped padding and slots.

     .ev-card                 the molded card plane
     .ev-card--clickable      a full-card link that lifts on hover
     .ev-card__header/body/footer   the three slots
   ========================================================================== */

.ev-card {
    /* inherit the molded plane treatment — including the raised face's own
       carve floor. .ev-card restates the molded paint rather than requiring
       .ev-molded, so it must restate this too; both point at the one
       --ev-raised-carve-floor token, which is what makes the ownership
       question moot. `class="ev-card ev-molded"` (the shipped Control Center
       login composition) therefore resolves to the same floor whichever block
       the cascade lands on, and `class="ev-card"` alone resolves to it as well.
       See core.css .ev-molded for why the former `initial` was wrong.
       (cortex-arivo8b) */
    --ev-direct-carve-floor: var(--ev-raised-carve-floor);
    /* HOST-ELEMENT NEUTRALITY — the appearance half. A card is a PART, and a
       card claims ONE drawing whichever element carries it: the whole plane is
       a single click target, and that target is a destination on some pages
       (an <a>) and a choice on others — pick a plan, pick a saved card — which
       is a <button>. That choice is semantic, never an appearance one, so a
       consumer who emits the honest element must not get a different card for
       it.

       These four undo exactly what the user agent decides for a <button> and
       nothing else. Measured on the paired bench before they were written, the
       button host diverged from its anchor twin on: `appearance` (auto), `font`
       (13.3333px Arial rather than the inherited page face), `padding` (1px
       block / 6px inline), and `text-align` (center). Every other difference in
       that reading — width, inline-size, the two origins — was a sub-pixel
       consequence of those, and resolved with them.

       Each declaration is `inherit` or the initial value, so on a <div> or an
       <a> host they are all no-ops: this only ever REMOVES a decision the
       button host made. That is also why the fix belongs here rather than in a
       `data-ev-host-parity-omit` on the bench — an omission would tell the
       station to stop asking the question, and the divergence is the defect,
       not an exception to it. (cortex-fjn50nt) */
    appearance: none;
    -webkit-appearance: none;
    font: inherit;
    text-align: inherit;
    padding: 0;
    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    border: 0;
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
    transition: var(--ev-transition-fast);
    display: flex;
    flex-direction: column;
}

/* Cards do not lift by default — hover elevation is only for full-card links. */
.ev-card--clickable {
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}
.ev-card--clickable:hover {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2);
    transition: none;
}

/* HOST-ELEMENT NEUTRALITY — the ink half. One of this modifier's two honest
   hosts is an <a>, so the declaration above is exposed to whatever the
   consumer's link reboot says. That declaration is (0,1,0): enough for the
   resting form, `a { text-decoration: underline }` at (0,0,1), but outranked by
   the per-state form older and hand-rolled resets ship, `a:hover { … }` at
   (0,1,1) — and the hover rule above moves only the shoulder. So under such a
   consumer the card lifts correctly and rules a groove under its own text on the
   way up: a cut no cutter made (rule 1), and the underline channel belongs to
   `.ev-link` besides (rule 2, docs/interactive-ink.md). A card already says
   "arrived" by rising.
   Each `:is()` arm is (0,2,0), which clears both reboot shapes without
   `!important`.

   This normalizes THE CARD, not its contents: text-decoration propagates to
   in-flow descendants but never overrides a descendant's own declaration, so an
   `.ev-link` inside a clickable card keeps its mark.

   `:disabled` is in the list because the other honest host is a <button>, which
   is the only one of the two that can carry the native inert state; an anchor
   matches `[aria-disabled="true"]` instead, so the pair needs both arms to be
   covered in the same states. (cortex-wkljlpn, cortex-fjn50nt) */
.ev-card--clickable:is(
    :link,
    :visited,
    :hover,
    :focus,
    :focus-visible,
    :active,
    :disabled,
    [aria-disabled="true"]
) {
    text-decoration: none;
}

.ev-card__header {
    padding: var(--ev-btn-pad-x-md) var(--ev-btn-pad-x-lg);
    font-weight: 600;
    color: var(--ev-ink);
    /* Slot boundaries describe the card's persistent structure, not a row in
       a repeating field. Use the strong scribe so that structure survives the
       dark metal face as clearly as it does in light. (cortex-lw1zonj) */
    border-bottom: 1px solid var(--ev-rule-strong);
}

.ev-card__body {
    padding: var(--ev-btn-pad-x-lg);
    flex: 1 1 auto;
}

.ev-card__footer {
    padding: var(--ev-btn-pad-x-md) var(--ev-btn-pad-x-lg);
    border-top: 1px solid var(--ev-rule-strong);
}

/* Flat glyphs on the card face — Invariant L3. */
.ev-card :is(h1, h2, h3, h4, h5, h6) {
    text-shadow: none;
}

/* ===== src/components/notice.css ===== */
/* ==========================================================================
   Evident component — notice (inline state message)
   ========================================================================== */
/* A notice reports state in flow. It may be the neutral account-attention row
   or one of four semantic billets:

     .ev-notice                         inert raised host
     .ev-notice--danger|warning|info|success
                                        semantic material face
     .ev-notice--dismissible            opt-in dismiss-control spacing
     .ev-notice__indicator              optional aria-hidden badge lamp
     .ev-notice__copy                   heading/body column
     .ev-notice__title                  short heading
     .ev-notice__body                   explanatory body
     .ev-notice__action                 optional composed key
     .ev-notice__action--auxiliary      the same action marked into the face
     .ev-notice__actions                the action land, for one or two actions
     .ev-notice__dismiss                optional native dismiss button

   A semantic modifier moves hue from indicator scale onto the whole molded
   face. Its matching -fg token owns ordinary type, links, auxiliary actions
   and the dismiss key, so every interactive mark remains readable on that face
   in both themes. Links keep one ink across their whole hit area; underline
   appears only on hover/focus, in keeping with the one-link-one-object
   doctrine.

   The host is never a link and never lifts. Only its descendants promise a
   click. Confirmation is not a notice mode: .ev-confirm asks for a decision at
   the referent, while .ev-notice only reports state and possible next steps.

   One notice owns no surrounding layout. Consecutive sibling notices form a
   stack, so the later face introduces one medium register of separation. This
   keeps mixed raw/component renderers legible without adding trailing space to
   an isolated notice; consumer spacing utilities may still override the margin.
   ========================================================================== */

.ev-notice {
    --ev-notice-face: var(--ev-metal-hi);
    --ev-notice-ink: var(--ev-ink);
    --ev-notice-body-ink: var(--ev-ink-dim);
    --ev-notice-interactive-ink: var(--ev-accent-text);
    --ev-direct-carve-floor: var(--ev-raised-carve-floor);

    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "indicator copy action dismiss";
    align-items: center;
    gap: var(--ev-space-md, 1rem);
    padding: var(--ev-btn-pad-x-lg);
    color: var(--ev-notice-ink);
    background: var(--ev-notice-face);
    border: 0;
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

.ev-notice + .ev-notice {
    margin-block-start: var(--ev-space-md, 1rem);
}

.ev-notice--danger {
    --ev-notice-face: var(--ev-danger);
    --ev-notice-ink: var(--ev-danger-fg);
    --ev-notice-body-ink: var(--ev-danger-fg);
    --ev-notice-interactive-ink: var(--ev-danger-fg);
}

.ev-notice--success {
    --ev-notice-face: var(--ev-success);
    --ev-notice-ink: var(--ev-success-fg);
    --ev-notice-body-ink: var(--ev-success-fg);
    --ev-notice-interactive-ink: var(--ev-success-fg);
}

.ev-notice--warning {
    --ev-notice-face: var(--ev-warning);
    --ev-notice-ink: var(--ev-warning-fg);
    --ev-notice-body-ink: var(--ev-warning-fg);
    --ev-notice-interactive-ink: var(--ev-warning-fg);
}

.ev-notice--info {
    --ev-notice-face: var(--ev-info);
    --ev-notice-ink: var(--ev-info-fg);
    --ev-notice-body-ink: var(--ev-info-fg);
    --ev-notice-interactive-ink: var(--ev-info-fg);
}

/* A later bare typography rule must not break the semantic face/ink pair. A
   later component class still wins and therefore accepts its own contrast. */
:is(
    .ev-notice--danger,
    .ev-notice--success,
    .ev-notice--warning,
    .ev-notice--info
) :where(p, small, h1, h2, h3, h4, h5, h6) {
    color: inherit;
}

.ev-notice--dismissible {
    padding-inline-end: calc(var(--ev-btn-pad-x-lg) * 0.7);
}

.ev-notice__indicator {
    grid-area: indicator;
    flex: 0 0 auto;
}

.ev-notice__copy {
    grid-area: copy;
    min-width: 0;
    max-width: 62ch;
    color: var(--ev-notice-body-ink);
}

.ev-notice__title {
    margin: 0 0 0.25rem;
    color: var(--ev-notice-ink);
    font: 600 var(--ev-text-body, 1rem)/1.3 var(--ev-font-sans);
    text-shadow: none;
}

.ev-notice__body {
    margin: 0;
    color: inherit;
    font: 400 var(--ev-text-body, 1rem)/1.45 var(--ev-font-sans);
    overflow-wrap: anywhere;
}

.ev-notice__copy :where(a) {
    color: var(--ev-notice-interactive-ink);
    font-weight: 650;
    text-decoration-line: underline;
    text-decoration-color: transparent;
    text-decoration-thickness: 0.08em;
    text-underline-offset: 0.16em;
}

.ev-notice__copy :where(a:hover, a:focus-visible) {
    text-decoration-color: currentColor;
}

.ev-notice__copy :where(a:focus-visible) {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.ev-notice__action {
    grid-area: action;
    justify-self: end;
    white-space: nowrap;
}

/* ---- .ev-notice__actions — the action land ------------------------------- */
/* A single action may still sit directly in the area; the land exists so a
   notice can carry a second one without a second stacking rule. It is a
   layout container, not a part: it draws no face, edge or shadow, so it adds
   no material to the notice and the nesting invariant never comes into play.
   Two is the cap. A notice reports state and offers the way back or forward
   from it; a third choice is a decision, and a decision belongs to the
   referent, not to the report. */
.ev-notice__actions {
    grid-area: action;
    justify-self: end;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--ev-space-sm, 0.5rem);
    min-width: 0;
}

/* ---- .ev-notice__action--auxiliary — the action marked into the face ----- */
/* Undo is the canonical case: the way back from what the notice just
   reported. It has to belong to the notice, stay findable, and never read as
   the page's commit — so emphasis moves to MATERIAL, not to size. The raised
   .ev-notice__action is a cast part fastened ONTO the face; the auxiliary is
   the same size step marked INTO it. Two emphases, one channel, and the pair
   remains comparable because nothing else about them differs.

   Nothing is depicted that is not there, so a marked action has no cast face,
   no falloff and no press travel: ink removes no material, so there is no
   part to travel and nothing for it to travel into. What it does have is the
   key's real hit target and native control semantics — it is quiet, not
   decorative.

   Its whole label carries --ev-notice-interactive-ink, which is the ink the
   notice already gives its on-face links. That is the entire reason it reads
   as part of the notice, and it is also why it never overwrites semantic ink
   with interaction blue: on a tone the ink IS that tone's verified -fg, and
   on the neutral face it resolves to the accent text the copy links use.
   Underline and the focus boundary arrive together on hover and
   :focus-visible and cover the whole control, never a fragment of it.

   Padding on a raised key is clearance from the key's own wall. A marked
   action has no wall, so it keeps only the land's own rhythm; and its height
   becomes a MINIMUM, so a long localized label wraps and grows the control
   instead of being clipped by a fixed cap height. A wrapped label also reads
   from the start rather than centred: a cast key centres its legend within its
   own body, but a mark has no body to centre in — it continues the line of the
   copy it belongs to, and Danish and German labels are where that shows.

   .ev-key--primary and .ev-key--danger are not legal in a notice at all. The
   page's one lit commit face belongs at the form's action boundary, and an
   irreversible action belongs to .ev-confirm at the referent it destroys.
   An auxiliary action that is no longer available is REMOVED, not disabled:
   the notice reports state, so when the way back expires the report changes. */
.ev-notice__action--auxiliary {
    height: auto;
    min-height: var(--ev-btn-height-sm);
    padding-inline: var(--ev-space-sm, 0.5rem);
    background-color: transparent;
    background-image: none;
    box-shadow: none;
    color: var(--ev-notice-interactive-ink);
    font-weight: 650;
    white-space: normal;
    justify-content: flex-start;
    text-align: start;
    text-decoration-line: underline;
    text-decoration-color: transparent;
    text-decoration-thickness: 0.08em;
    text-underline-offset: 0.16em;
}

/* THE MARKED ACTION OWNS THE UNDERLINE CHANNEL, and must say so loudly enough to
   survive the key it composes. `.ev-key` normalizes text-decoration through the
   whole link-state list at (0,2,0) (keys.css), because an anchor-hosted key must
   not sprout a groove under a consumer's per-state link reboot. The declaration
   above is (0,1,0) and `:link` matches an anchor at rest, so on the honest <a>
   host that guard would erase the very mark that separates a marked action from
   a cast one — and would do it silently, since the button host, matching none of
   those states at rest, would keep its underline and the pair would disagree.

   Naming `.ev-key` beside the modifier and repeating the state list makes each
   arm (0,3,0), which OUTRANKS the guard in every state rather than tying it and
   depending on which partial the build concatenated last. The colour and
   thickness are restated with the line because `text-decoration` is a shorthand:
   the guard's `none` resets colour to currentColor and thickness to auto, so a
   rule that restated only the line would reveal this action's mark at rest.
   `text-underline-offset` is not part of the shorthand and is left above.
   The hover rule below is (0,4,0) and still wins over this. (cortex-wkljlpn) */
.ev-notice__action--auxiliary.ev-key:is(
    :link,
    :visited,
    :hover,
    :focus,
    :focus-visible,
    :active
) {
    text-decoration-line: underline;
    text-decoration-color: transparent;
    text-decoration-thickness: 0.08em;
}

/* Equal specificity to .ev-key's own hover, and this partial is concatenated
   after keys.css, so the marked action keeps the face's ink instead of waking
   to accent. Stated here rather than relied upon silently: the guard asserts
   the build order that makes it true. */
.ev-notice__action--auxiliary:not(:disabled):not(.ev-key--disabled):is(:hover, :focus-visible) {
    background: transparent;
    box-shadow: none;
    color: var(--ev-notice-interactive-ink);
    text-decoration-color: currentColor;
}

.ev-notice__action--auxiliary:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.ev-notice__action--auxiliary:active {
    background: transparent;
    box-shadow: none;
}

.ev-notice__dismiss {
    grid-area: dismiss;
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    padding: 0;
    border: 0;
    border-radius: var(--ev-btn-radius-xs);
    color: var(--ev-notice-interactive-ink);
    background: transparent;
    box-shadow: none;
    font: 650 1.25rem/1 var(--ev-font-sans);
    cursor: pointer;
}

.ev-notice__dismiss:hover {
    box-shadow: inset 0 0 0 1px currentColor;
}

.ev-notice__dismiss:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.ev-notice__dismiss:active {
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

@media (max-width: 35.998rem) {
    /* The stacked action row starts at the COPY column, not at the notice's
       own edge. While the only action was a key stretched across the whole
       row, an edge-to-edge row read as deliberate; a marked action is the
       width of its own label, so starting it left of the copy it belongs to
       reads as a misalignment rather than as a second row of the same block.
       Indenting the row also aligns a stretched cast key with the message
       above it, which is what the eye was already expecting. */
    .ev-notice {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "indicator copy dismiss"
            "indicator action action";
        align-items: start;
    }

    .ev-notice__action {
        justify-self: stretch;
        width: 100%;
        white-space: normal;
    }

    .ev-notice__actions {
        justify-self: stretch;
        justify-content: flex-start;
    }

    /* A cast key stretches to the stacked row because a wide key is still a
       key with a visible body. A marked action must not: stretching a
       face-less control to the row width sets its label adrift in the middle
       of an invisible hit area, and the reader loses where the control is. It
       stays the width of its own mark, at the start of the row, so it
       continues the copy's reading order. */
    .ev-notice__action--auxiliary {
        justify-self: start;
        width: auto;
    }
}

/* ===== src/components/progress.css ===== */
/* ==========================================================================
   Evident component — determinate progress
   ========================================================================== */
/* Progress is status at the locus of work, not an overlay. The native
   <progress> element remains the single value authority:

     <label for="upload-progress">Upload</label>
     <progress class="ev-progress" id="upload-progress"
               value="42" max="100">42%</progress>

   Omit role, aria-valuemin, aria-valuenow and aria-valuemax: native value/max
   already expose that range, and duplicating it creates two states that can
   drift. Give every instance a visible associated <label>, or an explicit
   accessible name when no visible label is possible. aria-valuetext is legal
   only when the numeric fraction needs a domain phrase such as password
   strength; it supplements rather than replaces value/max.

   This primitive is determinate only: author both value and a positive max,
   with 0 <= value <= max. The implicit minimum is the native zero. Its fixed
   track is a shallow machined cut and the accent insert is the live/current
   amount. The insert advances by snapping to the new native value. There is no
   transition, stripe or pulse to remove under reduced motion, so the meaning
   and the update are identical in every motion mode.
   ========================================================================== */

.ev-progress {
    appearance: none;
    display: block;
    inline-size: 100%;
    block-size: var(--ev-progress-height);
    overflow: hidden;
    border: 0;
    border-radius: var(--ev-progress-radius);
    color: var(--ev-progress-fill);
    background-color: var(--ev-progress-track);
    box-shadow:
        var(--ev-progress-track-line),
        var(--ev-progress-track-lip),
        var(--ev-progress-track-wall);
    vertical-align: middle;
}

/* Chromium/WebKit expose both planes. Keep the track transparent so the host
   element's complete cut remains the one material source. */
.ev-progress::-webkit-progress-bar {
    border-radius: inherit;
    background-color: transparent;
    box-shadow: none;
}

.ev-progress::-webkit-progress-value {
    border-radius: inherit;
    background-color: var(--ev-progress-fill);
}

/* Firefox exposes the value part and paints the element itself as the track. */
.ev-progress::-moz-progress-bar {
    border-radius: inherit;
    background-color: var(--ev-progress-fill);
}

/* In forced colours, return paint authority to the platform while preserving
   the same native semantics and compact geometry. */
@media (forced-colors: active) {
    .ev-progress {
        appearance: auto;
        forced-color-adjust: auto;
    }
}

/* ===== src/components/range.css ===== */
/* ==========================================================================
   Evident component — native adjustable range
   ========================================================================== */
/* A range chooses a quantity; progress only reports one. Keep that distinction
   semantic and physical: the native input owns min/max/step/value, keyboard,
   touch, validation and form submission. Evident paints its real parts only:

     TRACK  — a shallow machined channel.
     FILL   — the live interval from minimum to the current value.
     THUMB  — an achromatic cap seated on, and travelling along, that channel.

   The optional evident-range.js asset derives --ev-range-position and mirrors
   the native value into an associated output. Without it the native control is
   still complete and usable; only the authored initial fill/value text remains
   static. No pointer or key event is intercepted, so platform behavior stays
   authoritative. There is no authored transition: drag, key and reduced-motion
   modes all expose the same immediate state.
   ========================================================================== */

.ev-range {
    display: grid;
    gap: 0.5rem;
    inline-size: 100%;
    color: var(--ev-ink);
}

.ev-range__header,
.ev-range__scale {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.ev-range__label {
    color: var(--ev-ink);
    font-weight: 650;
}

.ev-range__value {
    color: var(--ev-ink-dim);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ev-range__input {
    --ev-range-position: 0%;
    appearance: none;
    display: block;
    inline-size: 100%;
    block-size: var(--ev-range-hit-size);
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--ev-range-track-radius);
    color: var(--ev-range-fill);
    background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    touch-action: pan-y;
}

.ev-range__input:focus {
    outline: none;
}

.ev-range__input:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

/* Chromium/WebKit expose one complete track. The gradient is not a depicted
   light or finish: its hard stop separates the live insert from unselected
   channel floor. The inset stack belongs to the channel as a whole. */
.ev-range__input::-webkit-slider-runnable-track {
    block-size: var(--ev-range-track-height);
    border: 0;
    border-radius: var(--ev-range-track-radius);
    background:
        linear-gradient(to right,
            var(--ev-range-fill) 0 var(--ev-range-position),
            var(--ev-range-track) var(--ev-range-position) 100%);
    box-shadow:
        var(--ev-range-track-line),
        var(--ev-range-track-lip),
        var(--ev-range-track-wall);
}

.ev-range__input::-webkit-slider-thumb {
    appearance: none;
    inline-size: var(--ev-range-thumb-size);
    block-size: var(--ev-range-thumb-size);
    margin-block-start: calc((var(--ev-range-track-height) - var(--ev-range-thumb-size)) / 2);
    border: 0;
    border-radius: 50%;
    background: var(--ev-range-thumb-face);
    box-shadow: var(--ev-range-thumb-shadow);
}

/* Firefox splits the channel into track and progress parts, so it can consume
   the same native value without the derived percentage custom property. */
.ev-range__input::-moz-range-track,
.ev-range__input::-moz-range-progress {
    block-size: var(--ev-range-track-height);
    border: 0;
    border-radius: var(--ev-range-track-radius);
    box-shadow:
        var(--ev-range-track-line),
        var(--ev-range-track-lip),
        var(--ev-range-track-wall);
}

.ev-range__input::-moz-range-track {
    background: var(--ev-range-track);
}

.ev-range__input::-moz-range-progress {
    background: var(--ev-range-fill);
}

.ev-range__input::-moz-range-thumb {
    inline-size: var(--ev-range-thumb-size);
    block-size: var(--ev-range-thumb-size);
    border: 0;
    border-radius: 50%;
    background: var(--ev-range-thumb-face);
    box-shadow: var(--ev-range-thumb-shadow);
}

.ev-range__scale {
    color: var(--ev-ink-faint);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

.ev-range__hint {
    margin: 0;
    color: var(--ev-ink-dim);
}

.ev-range__input:disabled {
    cursor: not-allowed;
    filter: saturate(0);
    opacity: 0.55;
}

.ev-range__input:disabled ~ .ev-range__scale {
    opacity: 0.6;
}

@media (forced-colors: active) {
    .ev-range__input {
        appearance: auto;
        forced-color-adjust: auto;
    }
}

/* ===== src/components/pockets.css ===== */
/* ==========================================================================
   Evident component — pockets (form controls)
   ==========================================================================

   "One pocket, four finishes." A form control is a small cut into the face it
   sits on — a pocket. Subtractive is unconstrained (a cut is legal at any
   depth), so a pocket needs no re-classification; it just carves one rung
   below its host. De-scoped from CC's `.rounded-light .form-control` etc.

     .ev-pocket            text input / select / textarea (the pocket)
     .ev-pocket--check     a checkbox/radio pocket
     .ev-pocket:checked    accent fill = indicator, not a material face
     [aria-invalid="true"] native invalid state; no modifier class
     :required             native required state; label marker is derived
     .ev-field             canonical label/control/helper rhythm
     .ev-field__label      form label register
     .ev-field__help       optional helper/error register
   ========================================================================== */

.ev-pocket {
    display: block;
    width: 100%;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    color: var(--ev-ink);
    border: 0;
    border-radius: var(--ev-radius-sm);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    font: 400 0.9375rem/1.4 var(--ev-font-sans);
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
    transition: var(--ev-transition-fast);
}

/* Placeholder ink is the DIM rung, not the faint one. The rung is chosen
   against the pocket's WORST ground, which is --ev-floor-n1 — the deepest cut
   and the darkest ground in the language, where faint ink measures 1.83:1
   (cortex-g2j0rmv — see the ink-ladder note in tokens.css). That remains the
   floor whenever the pocket is cut into a cut; a pocket cut straight into a
   raised face now lands on the lighter --ev-raised-carve-floor instead
   (cortex-arivo8b), which only widens the margin. Nothing is lost: a
   placeholder already reads as provisional because there is no value, not
   because the ink is weak. */
.ev-pocket::placeholder {
    color: var(--ev-ink-dim);
}

/* Placeholder copy is guidance for an idle field, not content to compete with
   the user's insertion point. Focus removes it visually while the accessible
   name remains on the label / aria-label; an empty field shows it again on
   blur. This is the standing interaction rule for every Evident-owned input. */
.ev-pocket:focus::placeholder {
    color: transparent;
}

/* Focus is a finish event, not a geometry event: the pocket's lip sharpens
   (steps up a rank) rather than the floor moving or a coloured ring appearing.
   The accent shows as a thin lit edge — an indicator on the lip, not a bloom. */
.ev-pocket:focus {
    outline: none;
    color: var(--ev-accent-text);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

/* Validation is a semantic indicator on the existing lip, never a new depth.
   The floor and the complete rank-2 carve stay byte-for-byte identical to
   rest. `aria-invalid` is both the accessible state and the only public hook:
   there is no parallel `.ev-pocket--invalid` API for authors to synchronize. */
.ev-pocket[aria-invalid="true"] {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink);
}

/* Focus and invalid are simultaneous facts. The danger hairline remains at
   the aperture; the accent occupies the adjacent pixel while focus still
   sharpens r2 -> r1. Two flat inset scribes, zero halo and zero bloom. */
.ev-pocket[aria-invalid="true"]:focus {
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink),
        inset 0 0 0 2px var(--ev-accent-edge);
}

/* The canonical helper register carries the error in semantic ink and is
   connected to the control with aria-describedby in markup. */
.ev-pocket[aria-invalid="true"] + .ev-small {
    color: var(--ev-danger-action-ink);
}

/* The field wrapper makes typography and spacing a component concern. A
   consumer supplies semantic label/control/help elements and never hand-tunes
   the distance between them. */
.ev-field {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
    min-width: 0;
}

.ev-field + .ev-field {
    margin-block-start: 1rem;
}

.ev-field__label {
    display: block;
    margin: 0;
    color: var(--ev-ink-dim);
    font: var(--ev-weight-semibold) var(--ev-text-caption) / var(--ev-leading-snug) var(--ev-font-sans);
    letter-spacing: var(--ev-tracking-caps);
    text-transform: uppercase;
}

.ev-field__help {
    display: block;
    min-height: 0;
    margin: 0.125rem 0 0;
    color: var(--ev-ink-dim);
    font: var(--ev-weight-regular) var(--ev-text-small) / var(--ev-leading-snug) var(--ev-font-sans);
}

.ev-field__help:empty { display: none; }

.ev-form-heading {
    display: block;
    margin: 0 0 1rem;
    color: var(--ev-ink);
    font: var(--ev-weight-semibold) var(--ev-text-small) / var(--ev-leading-snug) var(--ev-font-sans);
    letter-spacing: var(--ev-tracking-caps);
    text-transform: uppercase;
}

.ev-field:has(.ev-pocket[aria-invalid="true"]) .ev-field__help {
    color: var(--ev-danger-action-ink);
}

/* Required belongs to the LABEL register, not the helper/error register, but
   a visible marker is useful only when it discriminates. Native `required`
   remains the accessible fact in every form. Its visual echo appears only in
   a form/fieldset containing both a required and an optional captioned field;
   single-field and all-required groups spend no marker. The predicates cover
   direct pockets, measured carriers, and native select wrappers. */
:is(form, fieldset):has(
    .ev-field__label + :is(input, select, textarea).ev-pocket:required,
    .ev-field__label + .ev-pocket :is(input, select, textarea):required,
    .ev-field__label + .ev-select :is(input, select, textarea).ev-pocket:required
):has(
    .ev-field__label + :is(input, select, textarea).ev-pocket:not(:required),
    .ev-field__label + .ev-pocket :is(input, select, textarea):not(:required),
    .ev-field__label + .ev-select :is(input, select, textarea).ev-pocket:not(:required)
) .ev-field__label:has(
    + :is(input, select, textarea).ev-pocket:required,
    + .ev-pocket :is(input, select, textarea):required,
    + .ev-select :is(input, select, textarea).ev-pocket:required
)::after {
    content: " · required";
    margin-inline-start: 0.2em;
    color: var(--ev-ink-dim);
    font-weight: 500;
    letter-spacing: 0.04em;
}

.ev-pocket:disabled,
.ev-pocket[readonly] {
    /* oxidized finish = inert */
    opacity: 0.86;
    filter: saturate(0.9) brightness(0.99);
}

/* Checkbox / radio pocket. */
.ev-pocket--check {
    width: 1.15em;
    height: 1.15em;
    padding: 0;
    border-radius: var(--ev-radius-sm);
    vertical-align: text-bottom;
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    /* Reserve an inner polish line so hover can acknowledge the pointer
       without changing the pocket's depth or moving its geometry. */
    outline: 1px solid transparent;
    outline-offset: -2px;
}
.ev-pocket--check:not(:disabled):hover {
    outline-color: var(--ev-edge-glow);
}
.ev-pocket--check.ev-pocket--radio {
    border-radius: 50%;
}
/* Checked = the accent as an INDICATOR (colour is legal as an indicator),
   never as a material face. */
.ev-pocket--check:checked {
    background-color: var(--ev-accent);
    box-shadow:
        var(--ev-r3-line),
        inset 0 0 0 2px var(--ev-floor-n1);
}

/* ===== src/components/descriptive-choice.css ===== */
/* ==========================================================================
   Evident component — descriptive single-choice group
   ==========================================================================

   A finite choice group is a set of labelled, native radio controls seated in
   equal molded option plates. The fieldset, legend and radios are the complete
   control: there is no replacement face and no script-owned selection state.
   A consumer can submit the same name/value pair with CSS unavailable, and the
   browser keeps its native arrow-key traversal because the radios remain one
   ordinary named group.

     .ev-descriptive-choice                 fieldset / group
     .ev-descriptive-choice__legend         accessible visible legend
     .ev-descriptive-choice__options        responsive option grid
     .ev-descriptive-choice__option         one whole-label hit target
     .ev-descriptive-choice__input          visually hidden native radio
     .ev-descriptive-choice__indicator      full-width carved selection strip
     .ev-descriptive-choice__content        option copy register
     .ev-descriptive-choice__heading        icon + title register
     .ev-descriptive-choice__icon           optional semantic glyph carrier
     .ev-descriptive-choice__title          option title
     .ev-descriptive-choice__description    required explanation
     .ev-descriptive-choice__detail         optional supporting detail
     .ev-descriptive-choice__status         checked-state copy

   Selected is :checked. Disabled is the native disabled attribute (or a
   disabled fieldset). The native radio is the only selection source of truth:
   CSS moves the status, title accent and indicator together when it changes.
   ========================================================================== */

.ev-descriptive-choice {
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    color: var(--ev-ink);
}

.ev-descriptive-choice__legend {
    width: 100%;
    margin: 0 0 1rem;
    padding: 0;
    font: var(--ev-weight-semibold) var(--ev-text-h2) / var(--ev-leading-tight) var(--ev-font-sans);
    letter-spacing: var(--ev-tracking-tight);
    color: var(--ev-ink);
    text-shadow: none;
}

.ev-descriptive-choice__options {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: 1rem;
    min-width: 0;
}

/* The option is one legal raised host and one label target. The radio pocket
   is a cut into that host; the rest is flat ink. Nothing inside is a second
   pointer target, so hover honestly means the whole plate is clickable. */
.ev-descriptive-choice__option {
    --ev-direct-carve-floor: var(--ev-raised-carve-floor);
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 0.875rem;
    min-width: 0;
    min-height: 100%;
    padding: 1rem;
    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    border: 0;
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
    cursor: pointer;
    transition: var(--ev-transition-fast);
}

.ev-descriptive-choice__option:not(:has(> .ev-descriptive-choice__input:disabled)):hover {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2);
    transition: none;
}

/* Hover and selection are simultaneous facts. Repeat the accent hairline in
   the combined state so a pointer cannot erase the chosen option's rim. */
.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:checked):hover {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2),
        inset 0 0 0 1px var(--ev-accent-edge);
}

/* Focus and selection occupy adjacent flat edges on the existing part. There
   is no glow and no layout motion; the native radio still carries the state. */
.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:checked) {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:focus-visible) {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 3px;
}

.ev-descriptive-choice__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.ev-descriptive-choice__content {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    min-width: 0;
    min-height: 100%;
}

/* A long LED strip is easier to scan than a radio dot and uses the same
   content width on every option. The slot is always physically present; the
   selected option energizes the insert without changing geometry. */
.ev-descriptive-choice__indicator {
    order: 10;
    display: block;
    inline-size: 100%;
    block-size: 0.42rem;
    margin-block-start: auto;
    border-radius: calc(var(--ev-radius-sm) - 2px);
    background: var(--ev-floor-n2);
    box-shadow: var(--ev-r3-line), var(--ev-r3-lip), var(--ev-r3-wall);
    transition: background-color var(--ev-transition-fast), color var(--ev-transition-fast);
}

.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:checked)
    .ev-descriptive-choice__indicator {
    background: var(--ev-accent);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-descriptive-choice__heading {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-width: 0;
}

.ev-descriptive-choice__icon {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    color: var(--ev-ink-dim);
}

.ev-descriptive-choice__icon > :is(svg, img) {
    display: block;
    width: 100%;
    height: 100%;
}

.ev-descriptive-choice__title {
    min-width: 0;
    font: var(--ev-weight-semibold) var(--ev-text-h3) / var(--ev-leading-snug) var(--ev-font-sans);
    color: var(--ev-ink);
    overflow-wrap: anywhere;
    text-shadow: none;
}

/* Accent ink is the selected option's semantic finish. It repeats the lit
   strip's meaning on copy and an optional glyph without painting a new face. */
.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:checked)
    :is(.ev-descriptive-choice__title, .ev-descriptive-choice__icon) {
    color: var(--ev-accent-text);
}

.ev-descriptive-choice__description {
    font: var(--ev-weight-regular) var(--ev-text-body) / var(--ev-leading-body) var(--ev-font-sans);
    color: var(--ev-ink);
    text-shadow: none;
}

.ev-descriptive-choice__detail {
    font: var(--ev-weight-regular) var(--ev-text-small) / var(--ev-leading-snug) var(--ev-font-sans);
    color: var(--ev-ink-dim);
    text-shadow: none;
}

/* Every option carries the same static phrase, but only :checked reveals it.
   The browser therefore moves truthful copy for click and arrow-key changes
   without a script or a renderer-maintained modifier class. */
.ev-descriptive-choice__status {
    display: none;
    align-self: flex-start;
    margin-top: auto;
    padding: 0.2rem 0.5rem;
    background: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
    color: var(--ev-ink);
    border: 1px solid var(--ev-rule-strong);
    border-radius: 999px;
    font: var(--ev-weight-medium) var(--ev-text-caption) / var(--ev-leading-snug) var(--ev-font-sans);
    letter-spacing: var(--ev-tracking-caps);
    text-transform: uppercase;
    text-shadow: none;
}

.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:checked)
    .ev-descriptive-choice__status {
    display: inline-block;
}

.ev-descriptive-choice__option:has(> .ev-descriptive-choice__input:disabled),
.ev-descriptive-choice:disabled .ev-descriptive-choice__option {
    cursor: not-allowed;
    opacity: 0.72;
    filter: saturate(0.9) brightness(0.99);
}

@media (max-width: 40rem) {
    .ev-descriptive-choice__options {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.75rem;
    }

    .ev-descriptive-choice__option {
        gap: 0.75rem;
        padding: 0.875rem;
    }
}

/* ===== src/components/select.css ===== */
/* ==========================================================================
   Evident component — select
   ==========================================================================

   A native select is still a pocket. The browser's platform arrow, however,
   belongs to a different material language and varies by engine. .ev-select
   removes that foreign fitting and etches one disclosure mark into the same
   cut floor. The mark is generated by the wrapper, so authors cannot forget
   it or accidentally submit a second control.

     .ev-select             positioned pocket carrier + disclosure mark
     .ev-select__control    native select; composes .ev-pocket
   ========================================================================== */

.ev-select {
    position: relative;
    display: block;
    width: 100%;
}

.ev-select__control {
    appearance: none;
    -webkit-appearance: none;
    padding-inline-end: calc(var(--ev-btn-pad-x-sm) * 2 + 0.75em);
    cursor: pointer;
}

/* One etched chevron on the pocket floor. It is an affordance, not another
   key: no enclosing face, rim or separate hit target. The select remains the
   only interactive and submitted element. */
.ev-select::after {
    content: "";
    position: absolute;
    pointer-events: none;
    width: 0.48em;
    height: 0.48em;
    inset-inline-end: var(--ev-btn-pad-x-sm);
    inset-block-start: 50%;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    color: var(--ev-ink-dim);
    transform: translateY(-72%) rotate(45deg);
    transition: color var(--ev-transition-fast);
}

.ev-select:hover::after {
    color: var(--ev-ink);
}

.ev-select:focus-within::after {
    color: var(--ev-accent-text);
}

/* The closed value and its disclosure mark are one live affordance. When the
   chevron lights, the value follows it instead of leaving half the control in
   the resting finish. Use the accessible ink step in light theme; it resolves
   to the face accent in dark theme. */
.ev-select:focus-within .ev-select__control {
    color: var(--ev-accent-text);
}

.ev-select:has(.ev-select__control:disabled)::after {
    color: var(--ev-ink-dim);
    opacity: 0.48;
}

.ev-select:has(.ev-select__control:disabled) {
    opacity: 0.58;
}

.ev-select__control:disabled {
    color: var(--ev-ink-dim);
    cursor: not-allowed;
}

.ev-select__control option {
    background-color: var(--ev-floor-n1);
    color: var(--ev-ink);
}

/* ===== src/components/select-action.css ===== */
/* ==========================================================================
   Evident component — select + adjacent action
   ==========================================================================

   A native choice and its adjacent action may belong to one task without
   becoming one control. The select remains a cut chamber; the ordinary
   .ev-key remains a raised, independently labelled and focusable action.

     .ev-select-action             labelled compound root
     .ev-select-action__label      visible label for the native select
     .ev-select-action__row        choice/action geometry carrier
     .ev-select-action__select     existing .ev-select wrapper
     .ev-select-action__action     existing .ev-key action
     .ev-select-action--joined     close-coupled two-chamber arrangement

   This differs from .ev-fixed-suffix: its suffix is inert and therefore
   shares ONE cut with its input. Here both children are genuine controls.
   Joined geometry communicates belonging through one outer radius and two
   smaller, facing radii separated by a narrow contact land. It never erases
   either chamber or either control's own focus boundary.
   ========================================================================== */

.ev-select-action {
    --ev-select-action-height: var(--ev-btn-height-md);
    --ev-select-action-gap: 0.625rem;
    display: grid;
    gap: 0.5rem;
    width: 100%;
    min-width: 0;
    container-type: inline-size;
}

.ev-select-action__label { display: block; }

.ev-select-action__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    gap: var(--ev-select-action-gap);
    min-width: 0;
}

.ev-select-action__select { min-width: 0; }

.ev-select-action__select .ev-select__control,
.ev-select-action__action.ev-key {
    height: var(--ev-select-action-height);
}

.ev-select-action__select .ev-select__control {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Two pixels of visible host land is an honest seam: the select's cut does
   not flow under the raised key, and the key does not masquerade as part of
   the select disclosure. Matching outer/inner radii fix the mismatched caps
   while preserving two readable parts. */
.ev-select-action--joined { --ev-select-action-gap: 2px; }

.ev-select-action--joined .ev-select-action__select .ev-select__control {
    border-start-start-radius: var(--ev-btn-radius-md);
    border-end-start-radius: var(--ev-btn-radius-md);
    border-start-end-radius: var(--ev-radius-sm);
    border-end-end-radius: var(--ev-radius-sm);
}

.ev-select-action--joined .ev-select-action__action.ev-key {
    border-start-start-radius: var(--ev-radius-sm);
    border-end-start-radius: var(--ev-radius-sm);
    border-start-end-radius: var(--ev-btn-radius-md);
    border-end-end-radius: var(--ev-btn-radius-md);
}

@media (max-width: 420px) {
    .ev-select-action__row { grid-template-columns: minmax(0, 1fr); }
    .ev-select-action__action.ev-key { width: 100%; }
    .ev-select-action--joined .ev-select-action__row { gap: 0.5rem; }
    .ev-select-action--joined :is(.ev-select-action__select .ev-select__control, .ev-select-action__action.ev-key) {
        border-radius: var(--ev-btn-radius-md);
    }
}

@container (max-width: 420px) {
    .ev-select-action__row { grid-template-columns: minmax(0, 1fr); }
    .ev-select-action__action.ev-key { width: 100%; }
    .ev-select-action--joined .ev-select-action__row { gap: 0.5rem; }
    .ev-select-action--joined :is(.ev-select-action__select .ev-select__control, .ev-select-action__action.ev-key) {
        border-radius: var(--ev-btn-radius-md);
    }
}

/* ===== src/components/selector.css ===== */
/* ==========================================================================
   Evident component — selector
   ==========================================================================

   A selector progressively enhances a native <select> when a choice set needs
   search or richer option rows. The native control ships VISIBLE and usable;
   enhancement code hides it only after it can reveal the complete replacement.
   The replacement therefore starts with both material parts carrying `hidden`:

   .ev-selector
   ├── .ev-selector__affix          optional semantic glyph, one pocket
   ├── .ev-selector__control        closed pocket face
     └── .ev-selector__popover        non-modal lifted choice plate
         ├── .ev-selector__search     revealed past the behaviour threshold
         └── .ev-selector__list
             └── .ev-selector__option (+ --active)

   The standalone menu is the same plate with the same two inner parts, in the
   same order, and no selector behaviour behind it:

   .ev-menu-panel
   ├── .ev-menu-panel__search       optional; always the first flow child
   └── .ev-menu-panel__list         optional; bounds and scrolls a long menu
       └── .ev-menu-panel__item     (also legal as a direct child of the panel)

   MATERIAL:
   - The closed control is the same pocket as .ev-select: same cut floor,
     padding, type, lip stack and one etched disclosure mark. Enhancement must
     not announce itself while the list is closed.
   - The popover is the interactive-scale sibling of .ev-tooltip. Choices have
     been ADDED above the bench, so the panel is one molded plate, never a cut
     and never a modal. Its shadows remain axial: every offset is zero.
     .ev-menu-panel is this same part without selector positioning or behavior;
     it is the standalone owner for ordinary menus, never a second material.
   - Opening is an elevation event. The plate transitions from the lower axial
     shadow stack to its resting lifted stack; it never scales like inflating
     metal. With the library motion gate stripped, the final elevation remains.

   STATE CHANNELS:
   - --active is the live keyboard/pointer row and uses accented row ink plus
     relief: it says where the next commit would land.
   - aria-selected / aria-current is the stored value or destination, a
     different fact. It uses weight plus a check-shaped end mark, so the fact
     survives without colour; the check borrows accent because the selected
     value is the currently active one, never merely decorated stock.
   ========================================================================== */

.ev-selector {
    position: relative;
    display: block;
    width: 100%;
}

/* A semantic glyph may identify the kind of value being selected, but it is
   not a second control and therefore gets no chamber, border or hit target.
   Keep it as a direct child of .ev-selector, outside both value carriers: the
   native select remains complete without JavaScript, while enhancement may
   replace the closed face's text without deleting the glyph. The control's
   accessible name carries the meaning; the repeated pictogram is decorative
   and authors mark this slot aria-hidden="true". */
.ev-selector__affix {
    position: absolute;
    z-index: 1;
    display: grid;
    place-items: center;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    inset-inline-start: var(--ev-btn-pad-x-sm);
    inset-block-start: 50%;
    color: var(--ev-ink-dim);
    pointer-events: none;
    transform: translateY(-50%);
    transition: color var(--ev-transition-fast);
}

.ev-selector__affix > .ev-entity-glyph {
    inline-size: 1.125rem;
    block-size: 1.125rem;
}

/* The same inset serves the native baseline and the enhanced closed face.
   Nothing moves when behavior swaps one for the other, and the end padding
   remains independently reserved for the etched disclosure affordance. */
.ev-selector:has(> .ev-selector__affix) > select,
.ev-selector:has(> .ev-selector__affix) > .ev-selector__control {
    padding-inline-start: calc(
        var(--ev-btn-pad-x-sm) + 1.25rem + 0.625rem
    );
}

.ev-selector:has(> select:not([hidden]):focus) > .ev-selector__affix,
.ev-selector:has(> .ev-selector__control:focus-visible) > .ev-selector__affix,
.ev-selector:has(> .ev-selector__control[aria-expanded="true"]) > .ev-selector__affix {
    color: var(--ev-accent-text);
}

.ev-selector:has(> select:disabled) > .ev-selector__affix,
.ev-selector:has(> .ev-selector__control:disabled) > .ev-selector__affix {
    color: var(--ev-ink-dim);
    opacity: 0.48;
}

/* Before enhancement the native select is the only face. Give that direct
   child the same etched disclosure mark without introducing a wrapper that
   would violate the selector's fixed server-owned nesting. Once behavior hides
   the select, this mark disappears and the replacement control owns its own. */
.ev-selector:has(> select:not([hidden]))::after {
    content: "";
    position: absolute;
    pointer-events: none;
    width: 0.48em;
    height: 0.48em;
    inset-inline-end: var(--ev-btn-pad-x-sm);
    inset-block-start: 50%;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    color: var(--ev-ink-dim);
    transform: translateY(-72%) rotate(45deg);
    transition: color var(--ev-transition-fast);
}

.ev-selector:has(> select:not([hidden]):focus)::after {
    color: var(--ev-accent-text);
}

.ev-selector__control {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    min-height: calc(1.4em + var(--ev-btn-pad-y-sm) * 2);
    padding: var(--ev-btn-pad-y-sm)
        calc(var(--ev-btn-pad-x-sm) * 2 + 0.75em)
        var(--ev-btn-pad-y-sm)
        var(--ev-btn-pad-x-sm);

    appearance: none;
    -webkit-appearance: none;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    color: var(--ev-ink);
    border: 0;
    border-radius: var(--ev-radius-sm);
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);

    font: 400 0.9375rem/1.4 var(--ev-font-sans);
    text-align: start;
    cursor: pointer;
    transition: var(--ev-transition-fast);
}

/* Author-level component display declarations outrank the user-agent [hidden]
   rule. Restate the enhancement boundary here so the replacement, search and
   filtered rows really stay absent when their server/behavior state says so. */
.ev-selector [hidden] {
    display: none;
}

/* The disclosure mark is etched into the pocket face, exactly as on the
   native .ev-select. It has no enclosing face and no separate hit target. */
.ev-selector__control::after {
    content: "";
    position: absolute;
    pointer-events: none;
    width: 0.48em;
    height: 0.48em;
    inset-inline-end: var(--ev-btn-pad-x-sm);
    inset-block-start: 50%;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    color: var(--ev-ink-dim);
    transform: translateY(-72%) rotate(45deg);
    transition: color var(--ev-transition-fast);
}

.ev-selector__control:is(:hover, :focus-visible)::after,
.ev-selector__control[aria-expanded="true"]::after {
    color: var(--ev-accent-text);
}

.ev-selector__control:focus-visible,
.ev-selector__control[aria-expanded="true"] {
    outline: none;
    color: var(--ev-accent-text);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-selector__popover,
.ev-menu-panel {
    /* Search-glyph metrics belong to the plate that carries the mark, and both
       plates carry the same 0.5rem land, so they are stated once here rather
       than twice with the same numbers. */
    --ev-selector-search-glyph-size: 0.875rem;
    --ev-selector-search-glyph-inset: var(--ev-btn-pad-x-sm);

    padding: 0.5rem;

    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    border: 1px solid var(--ev-rule);
    border-radius: var(--ev-radius-sm);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2);

    opacity: 1;
    transition:
        opacity 0.12s ease,
        box-shadow 0.12s ease;
}

/* The plate stays pinned to the pocket that opened it, and that is a
   containment decision, not an oversight about width.

   It was tried the other way for cortex-cspr23y: content width with a floor
   and a viewport-aware cap, the shape `.ev-breadcrumb__switcher` and
   `.ev-menu-panel` both already use. It reads better wherever it fits — a
   150px filter pocket opened a 416px plate and twelve wrapped Nete role
   labels stopped wrapping. It does not fit generally, and the measurements
   are the reason it is not here:

     control at x=46 of 1280   plate 416px wide, right edge 1538 — 258px
                               outside the viewport
     control at x=46 of 375    plate 343px (the cap itself), right edge 389 —
                               14px outside

   A cap bounds a plate's WIDTH; nothing in it bounds the plate's POSITION. An
   absolutely positioned box anchored at its start edge grows one way only, so
   the room it actually has is `viewport - its own offset`, and that offset is
   the one quantity CSS cannot read here. `calc(100vw - 2rem)` silently assumes
   the plate begins at the page gutter. Anchoring at the end edge instead just
   moves the overflow to the other side; a narrow-viewport media query fixes
   only the 375px row of that table and leaves the 258px one. The breadcrumb
   can size to content because it OWNS its item layout and re-lays that row out
   at ≤520px; `.ev-menu-panel` can because it states no position at all and
   makes its trigger place it. This plate owns its placement and its consumer
   owns where the pocket sits, which is exactly the combination that has no
   safe content width until anchor positioning is baseline.

   The legibility half of that bead is fixed where it belongs and where it is
   width-independent — see `flex-shrink` on the option row below. A wrapped
   label here is tall, not broken. Widening the plate remains desirable and is
   tracked as its own change, needing an opt-in the consumer can only give
   because it knows where its pocket sits. */
.ev-selector__popover {
    position: absolute;
    z-index: 110;
    inset-block-start: calc(100% + 0.5rem);
    inset-inline: 0;
    width: 100%;
}

/* The menu panel owns only the open part. Placement belongs to its trigger
   context, so the component works as an anchored dropdown or a standalone
   menu without pretending every menu opens in the same direction. No
   overflow clip participates in the material: its zero-offset cast may
   occlude any surface below it.

   The clip a long menu needs lives one part inward, on .ev-menu-panel__list —
   the same division the popover already makes with .ev-selector__list. The
   plate keeps its lift, and lift under L1 is a symmetric ring of zero-offset
   shadow that is painted OUTSIDE this box; a clip here would cut that ring
   off at the plate's own edge and depict a raised part whose cast stops where
   the part stops, which no raised part does. The list inside carries no
   shadow of its own, so bounding it removes nothing that was drawn. A panel
   with no list part is unchanged and still grows to its content. */
.ev-menu-panel {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 12rem;
    width: max-content;
    max-width: min(24rem, 100%);
}

.ev-menu-panel[hidden] {
    display: none;
}

/* A plate that carries its own etched mark must be the frame that mark is
   measured from. A panel without a search still states no position at all, so
   its trigger context keeps placing it; the anchored consumers state
   `position: absolute` themselves and are unaffected either way. */
.ev-menu-panel:has(> .ev-menu-panel__search:not([hidden])) {
    position: relative;
}

/* A newly exposed plate begins nearer the bench and rises by shadow depth.
   There is intentionally no scale or directional translation. */
@starting-style {
    .ev-selector__popover:not([hidden]),
    .ev-menu-panel:not([hidden]) {
        opacity: 0;
        box-shadow:
            var(--ev-shoulder-lite),
            var(--ev-shoulder-1),
            var(--ev-contact-1),
            var(--ev-ambient-1);
    }
}

/* One search field, stated once for both plates that can hold one. The panel
   variant exists so a menu long enough to need a bounded list can also be
   narrowed by name; it is the selector's field, not a second instrument. */
.ev-selector__search,
.ev-menu-panel__search {
    width: 100%;
    padding-inline-start: calc(
        var(--ev-selector-search-glyph-inset) +
        var(--ev-selector-search-glyph-size) +
        0.25rem
    );
}

.ev-selector__search {
    margin: 0 0 0.5rem;
}

/* The panel is a flex column and its own 0.125rem row gap already stands
   between the field and the list, so the field states only the remainder —
   the separation measures the same 0.5rem as inside the popover. */
.ev-menu-panel__search {
    margin: 0 0 0.375rem;
}

/* Search is one pocket with one etched utility mark. The mark is drawn on the
   plate rather than supplied by the browser, so it follows Evident ink in
   every engine and cannot drift into a second icon family. It shares the
   field's state channel: neutral at rest, accent while the input is focused.

   One mark, one rule, both plates: the geometry below reads the field as the
   plate's FIRST flow child and measures in from the shared 0.5rem land, which
   is why the field precedes the list in a menu panel exactly as it does in a
   popover. A second glyph rule for the panel would be a second copy of the
   same etching, free to drift. */
.ev-selector__popover:has(> .ev-selector__search:not([hidden]))::before,
.ev-menu-panel:has(> .ev-menu-panel__search:not([hidden]))::before {
    content: "";
    position: absolute;
    z-index: 1;
    inline-size: var(--ev-selector-search-glyph-size);
    block-size: var(--ev-selector-search-glyph-size);
    inset-inline-start: calc(0.5rem + var(--ev-selector-search-glyph-inset) + 1px);
    inset-block-start: calc(0.5rem + (1.4em + var(--ev-btn-pad-y-sm) * 2) / 2);
    background-color: var(--ev-ink-dim);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='6.5' cy='6.5' r='4.5' fill='none' stroke='black' stroke-width='1.75'/%3E%3Cpath d='M10 10l4 4' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='6.5' cy='6.5' r='4.5' fill='none' stroke='black' stroke-width='1.75'/%3E%3Cpath d='M10 10l4 4' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    pointer-events: none;
    transform: translateY(-50%);
    transition: background-color var(--ev-transition-fast);
}

.ev-selector__popover:has(> .ev-selector__search:focus)::before,
.ev-menu-panel:has(> .ev-menu-panel__search:focus)::before {
    background-color: var(--ev-accent-text);
}

/* The bounded, scrolling inner region of both plates. It is the ONLY part in
   this file that clips, and it may: it is a flat region of the plate's own
   face with no shadow and no edge of its own, so nothing drawn is cut off.
   The 0.125rem padding is that permission's price — the row relief on hover
   and focus is painted outside each row's box, and the scroll box would clip
   it flush against the first and last row without this land.

   Because it clips, it must SAY it clips. A bound with no cue ends the last
   visible row whole on clean plate and draws a list that has stopped, when the
   material actually continues — rule 1 read in the other direction: the cut
   this box makes through its own content is a real event, left undepicted.
   Bounding the list made the far rows reachable; the cue is what makes them
   discoverable, and the two are not the same fix. Control Center's breadcrumb
   held 32 domains and hid 24 of them below the fold (cortex-ql49f1i).

   `thin` is the house width already stated by the rail track, the pagination
   channel and the entity-header rail. The track is transparent because a
   painted track would be a groove, and nothing was milled here — the list
   draws no edge on any of its four sides and must keep drawing none. The thumb
   is a flat tonal mark with no relief, which is what ink IS in this language
   (L3, laser mark), so it depicts no fabrication that did not happen. It takes
   the FAINT rung specifically: --ev-ink and --ev-ink-dim are the two TEXT
   rungs, and this mark carries no words. Faint is the library's declared
   carrier for exactly this case — non-text neutral detail that must read as
   recessive — beside the hollow status ring and the resting outline-secondary
   border. A text rung here would lend the option rows' own ink hierarchy to a
   part that is not prose (rule 2), and at light #3d3d3d it would out-weigh the
   rows it is only describing. */
.ev-selector__list,
.ev-menu-panel__list {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    max-height: min(18rem, 50vh);
    margin: 0;
    padding: 0.125rem;
    overflow-y: auto;
    list-style: none;
    scrollbar-width: thin;
    scrollbar-color: var(--ev-ink-faint) transparent;
}

.ev-selector__option,
.ev-menu-panel__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    min-width: 0;
    min-height: var(--ev-btn-height-sm);
    padding: 0.4375rem 2rem 0.4375rem 0.75rem;

    background: transparent;
    color: var(--ev-ink);
    border: 0;
    border-radius: var(--ev-radius-sm);

    /* A row is a part, and a part is as tall as what is in it. The list above
       is a height-capped flex column, so a row left at the default
       `flex-shrink: 1` is compressed to its `min-height` when the column runs
       past that cap — the box shrinks and the ink does not, so a wrapped label
       paints straight out of the row and across its neighbour. Three of the
       twelve rows below reproduced it: 35px of box holding 45px of ink, and
       "Shared hosting web node" over "Database cluster member" reading as
       `Dodabase` (cortex-cspr23y).
       Nothing removed material from those rows, so nothing may draw them
       shorter than their content — the sentence below this one has always said
       the row may grow downward, and this is the declaration that lets it. The
       overflow belongs one part outward: the list is the only box here that
       clips, it says so, and it already carries the max-height, the scroll and
       the cue that the material continues. Rows keep their height; the list
       scrolls. */
    flex-shrink: 0;

    font: 400 var(--ev-btn-font-md)/1.35 var(--ev-font-sans);
    /* Rows carry consumer data, including dotted machine identifiers with no
       author-controlled break opportunity. Keep that ink inside the plate;
       the row may grow downward, but never widen its scroll geometry beyond
       the panel that physically contains it. */
    overflow-wrap: anywhere;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}

/* Stored selection/current location is persistent. Weight plus a check-shaped
   end mark makes it legible without colour; accent on that mark is lawful
   because hue already means active/current/interactive in Evident. Keep the
   row ink neutral so stored selection does not collapse into the transient
   keyboard/pointer highlight below. */
.ev-selector__option:is(
    [aria-current]:not([aria-current="false"]),
    [aria-selected="true"]
),
.ev-menu-panel__item:is(
    [aria-current]:not([aria-current="false"]),
    [aria-selected="true"],
    .ev-menu-panel__item--current
) {
    font-weight: 600;
}

.ev-selector__option:is(
    [aria-current]:not([aria-current="false"]),
    [aria-selected="true"]
)::after,
.ev-menu-panel__item:is(
    [aria-current]:not([aria-current="false"]),
    [aria-selected="true"],
    .ev-menu-panel__item--current
)::after {
    content: "";
    position: absolute;
    inset-inline-end: 0.75rem;
    inset-block-start: 50%;
    width: 0.5rem;
    height: 0.3rem;
    border-inline-end: 2px solid var(--ev-accent-text);
    border-block-end: 2px solid var(--ev-accent-text);
    transform: translateY(-60%) rotate(45deg);
}

/* Live keyboard/pointer highlight: accent has exactly this one meaning inside
   the row itself. The selected check remains visible when the facts overlap,
   so keyboard traversal never makes the stored value ambiguous. */
.ev-selector__option--active,
.ev-menu-panel__item:is(
    :hover,
    :focus-visible,
    .ev-menu-panel__item--active
) {
    background: var(--ev-floor-n1);
    color: var(--ev-accent-text);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-r3-rim);
}

.ev-selector__option:focus-visible,
.ev-menu-panel__item:focus-visible {
    outline: none;
}

.ev-selector__control:disabled,
.ev-selector__option:disabled,
.ev-menu-panel__item:is(:disabled, [aria-disabled="true"]) {
    color: var(--ev-ink-dim);
    cursor: not-allowed;
    opacity: 0.58;
}

/* ===== src/components/breadcrumb.css ===== */
/* ==========================================================================
   Evident opinionated component — breadcrumb
   ==========================================================================

   A breadcrumb is a path, not a toolbar. Every segment therefore has one
   action only:

     .ev-breadcrumb
     └── .ev-breadcrumb__list
         └── .ev-breadcrumb__item
             ├── .ev-breadcrumb__link
             ├── .ev-breadcrumb__current
             ├── .ev-breadcrumb__dropdown
             └── .ev-breadcrumb__switcher

   LINK / CURRENT are ordinary wayfinding. DROPDOWN is a generic menu segment.
   SWITCHER is deliberately legal only as the current, leaf segment: its one
   action is switching the entity. An ancestor entity remains one plain link.
   This is the leaf-only resolution of the navigate-versus-switch ambiguity;
   no split hit target and no "go to entity" row are part of the vocabulary.

   The switcher reuses .ev-selector__popover, __list and __option. Breadcrumb
   CSS owns only anchoring and path semantics; it does not invent a second
   lifted plate. Every sibling option is an <a href>, so a server can compute
   the current-view URL (and canonical-page fallback) without client routing.

   Separators are CSS-generated punctuation and absent from the accessibility
   tree. The list contains no separator markup.
   ========================================================================== */

.ev-breadcrumb {
    min-width: 0;
    color: var(--ev-ink-dim);
    font: 500 0.875rem/1.4 var(--ev-font-sans);
}

.ev-breadcrumb__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ev-breadcrumb__item {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}

/* A separator describes the relationship between adjacent path segments. It
   is punctuation, not another object, so it is generated rather than emitted
   as a list item or spoken by assistive technology. */
.ev-breadcrumb__item + .ev-breadcrumb__item::before {
    content: "/";
    margin-inline: 0.3rem 0.55rem;
    color: var(--ev-rule-strong);
    font-weight: 400;
}

.ev-breadcrumb__link,
.ev-breadcrumb__current,
.ev-breadcrumb__trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    min-height: 1.75rem;
    padding: 0.2rem 0.35rem;
    border-radius: var(--ev-radius-sm);
    color: inherit;
    text-decoration: none;
}

.ev-breadcrumb__link {
    color: var(--ev-ink);
}

.ev-breadcrumb__link:hover {
    color: var(--ev-accent-text);
    text-decoration: underline;
    text-underline-offset: 0.18em;
}

.ev-breadcrumb__link:focus-visible,
.ev-breadcrumb__trigger:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 1px;
    color: var(--ev-accent-text);
}

.ev-breadcrumb__current {
    color: var(--ev-ink-dim);
    font-weight: 600;
}

/* Entity identity remains visible without turning the trail into a row of
   badges. The inline token is already the quietest canonical silhouette; the
   breadcrumb supplies no extra plate, border, tint or elevation around it. */
.ev-breadcrumb :is(
    .ev-breadcrumb__link,
    .ev-breadcrumb__current,
    .ev-breadcrumb__trigger
) > .ev-entity-token {
    flex: 0 1 auto;
    max-width: min(24rem, 55vw);
}

.ev-breadcrumb .ev-entity-token__name {
    overflow: hidden;
    text-overflow: ellipsis;
}

.ev-breadcrumb__dropdown,
.ev-breadcrumb__switcher {
    position: relative;
}

.ev-breadcrumb__trigger {
    position: relative;
    padding-inline-end: 1.35rem;
    list-style: none;
    cursor: pointer;
}

.ev-breadcrumb__trigger::-webkit-details-marker {
    display: none;
}

/* The disclosure mark belongs to the one whole dropdown segment. It is etched
   punctuation, never a separate button or split hit target. */
.ev-breadcrumb__trigger::after {
    content: "";
    position: absolute;
    inset-inline-end: 0.35rem;
    inset-block-start: 50%;
    width: 0.38em;
    height: 0.38em;
    border-inline-end: 1.5px solid currentColor;
    border-block-end: 1.5px solid currentColor;
    color: var(--ev-ink-dim);
    transform: translateY(-72%) rotate(45deg);
}

.ev-breadcrumb__dropdown[open] > .ev-breadcrumb__trigger,
.ev-breadcrumb__switcher[open] > .ev-breadcrumb__trigger {
    color: var(--ev-accent-text);
}

.ev-breadcrumb__dropdown[open] > .ev-breadcrumb__trigger::after,
.ev-breadcrumb__switcher[open] > .ev-breadcrumb__trigger::after {
    transform: translateY(-28%) rotate(225deg);
}

/* Placement belongs to the breadcrumb. The raised material remains the
   selector/menu material itself. A searchable menu states `position: relative`
   so its etched search mark has a frame; repeat that relational condition here
   so the breadcrumb-owned absolute placement wins by source order without
   changing the placement contract of searchable panels elsewhere. */
.ev-breadcrumb__dropdown > .ev-menu-panel,
.ev-breadcrumb__switcher > .ev-selector__popover {
    position: absolute;
    z-index: 110;
    inset-block-start: calc(100% + 0.35rem);
    inset-inline-start: 0;
    min-width: min(22rem, calc(100vw - 2rem));
}

.ev-breadcrumb__dropdown > .ev-menu-panel:has(> .ev-menu-panel__search:not([hidden])) {
    position: absolute;
}

.ev-breadcrumb__switcher > .ev-selector__popover {
    width: max-content;
    max-width: min(26rem, calc(100vw - 2rem));
}

.ev-breadcrumb__switcher .ev-selector__list {
    min-width: 17rem;
}

/* Link rows keep selector geometry but use navigation semantics: aria-current
   is the stored entity, while selector listbox buttons use aria-selected.
   selector.css owns the shared persistent check; this file owns only the
   breadcrumb link's pointer/focus interaction. */
.ev-breadcrumb__switcher a.ev-selector__option:is(:hover, :focus-visible) {
    outline: none;
    color: var(--ev-accent-text);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-r3-rim);
}

.ev-breadcrumb__group + .ev-breadcrumb__group {
    display: block;
    margin-top: 0.4rem;
    padding-top: 0.45rem;
    border-top: 1px solid var(--ev-rule);
}

.ev-breadcrumb__group-label {
    display: block;
    padding: 0.25rem 0.75rem 0.35rem;
    color: var(--ev-ink-dim);
    font: 600 0.6875rem/1.2 var(--ev-font-sans);
    letter-spacing: 0.055em;
    text-transform: uppercase;
}

@media (max-width: 520px) {
    .ev-breadcrumb__item {
        position: relative;
    }

    /* Put an opening segment at the start of its own row. That full row, not
       the trigger after its generated separator, is the plate's containing
       block: a viewport-sized max-width spent from an offset trigger still
       falls off the far edge. The row already knows the real content gutter,
       so bounding the plate to it needs neither a guessed offset nor JS. */
    .ev-breadcrumb__item:has(
        > .ev-breadcrumb__dropdown,
        > .ev-breadcrumb__switcher
    ) {
        flex-basis: 100%;
    }

    .ev-breadcrumb__item > :is(
        .ev-breadcrumb__dropdown,
        .ev-breadcrumb__switcher
    ) {
        position: static;
    }

    .ev-breadcrumb__dropdown > .ev-menu-panel,
    .ev-breadcrumb__switcher > .ev-selector__popover {
        inset-inline-start: 0;
        inset-inline-end: auto;
        min-width: min(17rem, 100%);
        max-width: 100%;
    }

    .ev-breadcrumb__switcher .ev-selector__list {
        min-width: 0;
    }
}

/* ===== src/components/measure.css ===== */
/* ==========================================================================
   Evident component — measure
   ==========================================================================

   A measured value and its fixed unit are one instrument, not an input beside
   a second control. .ev-measure seats both in ONE .ev-pocket: the editable
   value occupies the clear opening and the inert unit is engraved beside it
   on the same floor. The unit is a legend, not a second field-shaped cell.

     .ev-measure          shared pocket geometry; composes .ev-pocket
     .ev-measure__input   the only focusable and submitted control
     .ev-measure__unit    fixed calibration legend; never an action

   Keep the unit in the DOM and connect it with aria-describedby when the
   visible field label does not already name the unit. Do not put buttons,
   selects or a second input in the calibration cell.
   ========================================================================== */

.ev-measure {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    width: 100%;
    padding: 0;
    overflow: hidden;
}

.ev-measure__input {
    min-width: 0;
    width: 100%;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ev-ink);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    font: inherit;
    text-align: end;
}

.ev-measure__unit {
    position: relative;
    display: flex;
    align-items: center;
    align-self: center;
    min-height: 1.5rem;
    margin-inline-end: 0.625rem;
    padding-inline-start: 0.75rem;
    color: var(--ev-ink-dim);
    opacity: 0.78;
    font: 600 0.75rem/1 var(--ev-font-mono);
    letter-spacing: 0.035em;
    white-space: nowrap;
    user-select: none;
}

/* A short datum tick relates the legend to the reading without drawing a
   full-height terminal chamber that could be mistaken for another input. */
.ev-measure__unit::before {
    content: "";
    position: absolute;
    inset-block: 0.25rem;
    inset-inline-start: 0;
    inline-size: 1px;
    background: var(--ev-ink-faint);
    opacity: 0.72;
}

/* Focus belongs to the one instrument. The input stays the focus target while
   the shared pocket lip carries the visible state. */
.ev-measure:focus-within {
    outline: none;
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-measure:focus-within .ev-measure__input {
    color: var(--ev-accent-text);
}

.ev-measure:focus-within .ev-measure__unit {
    color: color-mix(in srgb, var(--ev-accent-text) 68%, var(--ev-ink-dim));
}

.ev-measure:focus-within .ev-measure__unit::before {
    background: color-mix(in srgb, var(--ev-accent-edge) 48%, var(--ev-ink-faint));
}

.ev-measure:has(.ev-measure__input:disabled),
.ev-measure:has(.ev-measure__input[readonly]) {
    opacity: 0.86;
    filter: saturate(0.9) brightness(0.99);
}

.ev-measure__input:disabled {
    cursor: default;
}

/* ===== src/components/fixed-prefix.css ===== */
/* ==========================================================================
   Evident component — fixed prefix
   ==========================================================================

   One fixed textual prefix and one editable value form one labelled input
   instrument. The prefix is visible context, not a submitted field, unit, or
   focus target. An optional ordinary .ev-key sits beside the field.

     .ev-fixed-prefix              labelled component root
     .ev-fixed-prefix__label       the one accessible label
     .ev-fixed-prefix__row         field/action geometry carrier
     .ev-fixed-prefix__instrument  shared .ev-pocket
     .ev-fixed-prefix__prefix      inert visible text; aria-hidden
     .ev-fixed-prefix__input       the only editable/submitted field
     .ev-fixed-prefix__action      optional ordinary .ev-key
     .ev-fixed-prefix__error       server-error/helper hook

   This is not .ev-measure: a prefix is part of a value's spelling, not a unit
   calibrating a reading. It is not .ev-dns-hostname: there is no fixed zone,
   root state, hidden full value, or synchronization behavior. The server
   receives exactly the native input.
   ========================================================================== */

.ev-fixed-prefix {
    --ev-fixed-prefix-height: var(--ev-btn-height-md);
    --ev-fixed-prefix-gap: 0.625rem;
    display: grid;
    gap: 6px;
    width: 100%;
    min-width: 0;
    container-type: inline-size;
}

.ev-fixed-prefix__label { display: block; }

.ev-fixed-prefix__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    gap: var(--ev-fixed-prefix-gap);
    min-width: 0;
}

.ev-fixed-prefix__instrument.ev-pocket {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: stretch;
    height: var(--ev-fixed-prefix-height);
    min-width: 0;
    padding: 0;
    overflow: hidden;
}

.ev-fixed-prefix__prefix {
    display: flex;
    align-items: center;
    margin-block: 0.35rem;
    padding-inline: var(--ev-btn-pad-x-sm) 0.75rem;
    border-inline-end: 1px solid color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    color: var(--ev-ink-dim);
    font: 600 0.8125rem/1 var(--ev-font-mono);
    white-space: nowrap;
    user-select: none;
    transition: var(--ev-transition-fast);
}

.ev-fixed-prefix__input {
    display: block;
    width: 100%;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ev-ink);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    font: 400 0.9375rem/1.4 var(--ev-font-sans);
}

.ev-fixed-prefix__action.ev-key { height: var(--ev-fixed-prefix-height); }

/* Focus belongs to the one native input; its shared carrier displays the
   state while the inert prefix changes ink as part of the same instrument. */
.ev-fixed-prefix__instrument:focus-within {
    outline: none;
    box-shadow:
        var(--ev-r1-line), var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-fixed-prefix__instrument:focus-within .ev-fixed-prefix__input {
    color: var(--ev-accent-text);
}

.ev-fixed-prefix__instrument:focus-within .ev-fixed-prefix__prefix {
    border-inline-end-color: color-mix(in srgb, var(--ev-accent-edge) 48%, var(--ev-ink-faint));
    color: color-mix(in srgb, var(--ev-accent-text) 68%, var(--ev-ink-dim));
}

/* Native required remains the fact. Generated words are only its visual echo,
   derived from structure so templates cannot desynchronise it. */
.ev-fixed-prefix__label:has(+ .ev-fixed-prefix__row .ev-fixed-prefix__input:required)::after {
    content: " · required";
    margin-inline-start: 0.2em;
    color: var(--ev-ink-dim);
    font-weight: 500;
    letter-spacing: 0.04em;
}

/* aria-invalid is the server-error hook. :user-invalid supplies the native
   validation path without painting an untouched required field as erroneous. */
.ev-fixed-prefix:has(.ev-fixed-prefix__input[aria-invalid="true"], .ev-fixed-prefix__input:user-invalid) .ev-fixed-prefix__instrument {
    box-shadow:
        var(--ev-r2-line), var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink);
}

.ev-fixed-prefix:has(.ev-fixed-prefix__input[aria-invalid="true"], .ev-fixed-prefix__input:user-invalid) .ev-fixed-prefix__instrument:focus-within {
    box-shadow:
        var(--ev-r1-line), var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink),
        inset 0 0 0 2px var(--ev-accent-edge);
}

.ev-fixed-prefix__error {
    margin: 0;
    color: var(--ev-danger-action-ink);
    font: 400 0.75rem/1.35 var(--ev-font-sans);
}

.ev-fixed-prefix__error:empty { display: none; }

.ev-fixed-prefix:has(.ev-fixed-prefix__input:disabled, .ev-fixed-prefix__input[readonly]) .ev-fixed-prefix__instrument {
    opacity: 0.86;
    filter: saturate(0.9) brightness(0.99);
}

.ev-fixed-prefix__input:disabled { cursor: default; }

@media (max-width: 420px) {
    .ev-fixed-prefix__row { grid-template-columns: minmax(0, 1fr); }
    .ev-fixed-prefix__action.ev-key { width: 100%; }
}

/* A component can be narrow inside a wide page (table cell, card column), so
   viewport containment alone is insufficient. The carrier is its own inline
   query container; this is the same stack, triggered by the space it owns. */
@container (max-width: 420px) {
    .ev-fixed-prefix__row { grid-template-columns: minmax(0, 1fr); }
    .ev-fixed-prefix__action.ev-key { width: 100%; }
}

/* ===== src/components/fixed-suffix.css ===== */
/* ==========================================================================
   Evident component — fixed suffix
   ==========================================================================

   One editable value and one fixed textual suffix form one labelled input
   instrument. The suffix is visible context, not a submitted field, unit, or
   focus target. An optional ordinary .ev-key sits beside the field.

     .ev-fixed-suffix              labelled component root
     .ev-fixed-suffix__label       the one accessible label
     .ev-fixed-suffix__row         field/action geometry carrier
     .ev-fixed-suffix__instrument  shared .ev-pocket
     .ev-fixed-suffix__input       the only editable/submitted field
     .ev-fixed-suffix__suffix      inert visible text; aria-hidden
     .ev-fixed-suffix__action      optional ordinary .ev-key
     .ev-fixed-suffix__error       server-error/helper hook

   The input and suffix occupy ONE cut. The short internal separator is a
   datum between spelling parts, not the wall of a second chamber: the carrier
   alone owns floor, rim, focus, invalid and inert state. This is not
   .ev-measure: a suffix such as @example.dk is part of a value's spelling,
   not a unit calibrating a reading. The server receives exactly the native
   input. Templates name the complete value in the label; consumers may add
   visually-hidden wording inside that label when their visible copy is short.
   ========================================================================== */

.ev-fixed-suffix {
    --ev-fixed-suffix-height: var(--ev-btn-height-md);
    --ev-fixed-suffix-gap: 0.625rem;
    display: grid;
    gap: 6px;
    width: 100%;
    min-width: 0;
    container-type: inline-size;
}

.ev-fixed-suffix__label { display: block; }

.ev-fixed-suffix__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    gap: var(--ev-fixed-suffix-gap);
    min-width: 0;
}

.ev-fixed-suffix__instrument.ev-pocket {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    height: var(--ev-fixed-suffix-height);
    min-width: 0;
    padding: 0;
    overflow: hidden;
}

.ev-fixed-suffix__input {
    display: block;
    width: 100%;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ev-ink);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    font: 400 0.9375rem/1.4 var(--ev-font-sans);
}

.ev-fixed-suffix__suffix {
    display: flex;
    align-items: center;
    margin-block: 0.35rem;
    padding-inline: 0.75rem var(--ev-btn-pad-x-sm);
    border-inline-start: 1px solid color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    color: var(--ev-ink-dim);
    font: 600 0.8125rem/1 var(--ev-font-mono);
    white-space: nowrap;
    user-select: none;
    transition: var(--ev-transition-fast);
}

.ev-fixed-suffix__action.ev-key { height: var(--ev-fixed-suffix-height); }

/* Focus belongs to the one native input; its shared carrier displays the
   state while the inert suffix changes ink as part of the same instrument. */
.ev-fixed-suffix__instrument:focus-within {
    outline: none;
    box-shadow:
        var(--ev-r1-line), var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-fixed-suffix__instrument:focus-within .ev-fixed-suffix__input {
    color: var(--ev-accent-text);
}

.ev-fixed-suffix__instrument:focus-within .ev-fixed-suffix__suffix {
    border-inline-start-color: color-mix(in srgb, var(--ev-accent-edge) 48%, var(--ev-ink-faint));
    color: color-mix(in srgb, var(--ev-accent-text) 68%, var(--ev-ink-dim));
}

.ev-fixed-suffix__label:has(+ .ev-fixed-suffix__row .ev-fixed-suffix__input:required)::after {
    content: " · required";
    margin-inline-start: 0.2em;
    color: var(--ev-ink-dim);
    font-weight: 500;
    letter-spacing: 0.04em;
}

.ev-fixed-suffix:has(.ev-fixed-suffix__input[aria-invalid="true"], .ev-fixed-suffix__input:user-invalid) .ev-fixed-suffix__instrument {
    box-shadow:
        var(--ev-r2-line), var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink);
}

.ev-fixed-suffix:has(.ev-fixed-suffix__input[aria-invalid="true"], .ev-fixed-suffix__input:user-invalid) .ev-fixed-suffix__instrument:focus-within {
    box-shadow:
        var(--ev-r1-line), var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink),
        inset 0 0 0 2px var(--ev-accent-edge);
}

.ev-fixed-suffix__error {
    margin: 0;
    color: var(--ev-danger-action-ink);
    font: 400 0.75rem/1.35 var(--ev-font-sans);
}

.ev-fixed-suffix__error:empty { display: none; }

.ev-fixed-suffix:has(.ev-fixed-suffix__input:disabled, .ev-fixed-suffix__input[readonly]) .ev-fixed-suffix__instrument {
    opacity: 0.86;
    filter: saturate(0.9) brightness(0.99);
}

.ev-fixed-suffix__input:disabled { cursor: default; }

@media (max-width: 420px) {
    .ev-fixed-suffix__row { grid-template-columns: minmax(0, 1fr); }
    .ev-fixed-suffix__action.ev-key { width: 100%; }
}

@container (max-width: 420px) {
    .ev-fixed-suffix__row { grid-template-columns: minmax(0, 1fr); }
    .ev-fixed-suffix__action.ev-key { width: 100%; }
}

/* ===== src/components/input-selector.css ===== */
/* ==========================================================================
   Evident component — input selector
   ==========================================================================

   One editable text part and one bounded native choice form a compound value
   inside ONE outer pocket. Unlike .ev-measure, this instrument honestly
   contains TWO controls: the appended selector therefore owns a visibly
   distinct seat and its own focus finish instead of borrowing a whole-pocket
   ring that would lie about which control is live. Engrave words, not
   punctuation: `@` belongs to the selector's visible suffix token, while its
   submitted value remains the bare domain.

     .ev-input-selector              labelled fieldset root
     .ev-input-selector__label       compound-value legend
     .ev-input-selector__instrument  one outer .ev-pocket
     .ev-input-selector__input       editable/submitted text part
     .ev-input-selector__choice      bounded selector seat
     .ev-input-selector__select      native submitted selector
     .ev-input-selector__fixed       n=1 auto-adopted visible value

   Cardinality is server-owned: n>1 renders the native select; n=1 renders
   __fixed plus a hidden submitted value; n=0 omits the instrument and renders
   an unavailable/empty explanation. This does not relax .ev-measure: measured
   units remain inert and may never become actions.
   ========================================================================== */

.ev-input-selector {
    --ev-input-selector-choice-width: clamp(7rem, 38%, 14rem);
    display: grid;
    gap: 6px;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.ev-input-selector__label {
    float: none;
    width: auto;
    margin: 0;
    padding: 0;
}

.ev-input-selector__instrument.ev-pocket {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--ev-input-selector-choice-width);
    align-items: stretch;
    min-width: 0;
    min-height: var(--ev-btn-height-md);
    padding: 0;
    overflow: hidden;
}

.ev-input-selector__input,
.ev-input-selector__select {
    min-width: 0;
    width: 100%;
    border: 0;
    outline: 0;
    color: var(--ev-ink);
    font: 400 0.9375rem/1.4 var(--ev-font-sans);
}

.ev-input-selector__input {
    position: relative;
    z-index: 1;
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    background: transparent;
}

/* The second focus target gets a real bounded seat. Its deeper floor and
   internal wall stay visible on the light carrier as well as the dark one. */
.ev-input-selector__choice,
.ev-input-selector__fixed {
    position: relative;
    display: grid;
    align-items: stretch;
    min-width: 0;
    border-inline-start: 1px solid var(--ev-cut-edge);
    background: var(--ev-floor-n2);
    box-shadow: inset 1px 0 0 color-mix(in srgb, var(--ev-edge-glow) 42%, transparent);
}

.ev-input-selector__select {
    position: relative;
    z-index: 1;
    appearance: none;
    -webkit-appearance: none;
    padding: var(--ev-btn-pad-y-sm)
        calc(var(--ev-btn-pad-x-sm) * 2 + 0.75em)
        var(--ev-btn-pad-y-sm)
        var(--ev-btn-pad-x-sm);
    background: transparent;
    cursor: pointer;
    text-overflow: ellipsis;
}

.ev-input-selector__choice::after {
    content: "";
    position: absolute;
    z-index: 2;
    pointer-events: none;
    width: 0.48em;
    height: 0.48em;
    inset-inline-end: var(--ev-btn-pad-x-sm);
    inset-block-start: 50%;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    color: var(--ev-ink-dim);
    transform: translateY(-72%) rotate(45deg);
}

/* Focus is deliberately regional: the text aperture lights only its own land;
   the selector lights the deeper appended seat. No whole-pocket focus ring. */
.ev-input-selector__input:focus {
    color: var(--ev-accent-text);
    box-shadow: inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-input-selector__choice:focus-within {
    box-shadow:
        inset 1px 0 0 color-mix(in srgb, var(--ev-edge-glow) 42%, transparent),
        inset 0 0 0 2px var(--ev-accent-edge);
}

.ev-input-selector__choice:focus-within .ev-input-selector__select,
.ev-input-selector__choice:focus-within::after {
    color: var(--ev-accent-text);
}

.ev-input-selector__fixed {
    place-items: center start;
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    color: var(--ev-ink-dim);
    font: 600 0.8125rem/1.4 var(--ev-font-mono);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ev-input-selector__input[aria-invalid="true"] {
    box-shadow: inset 0 0 0 1px var(--ev-danger-action-ink);
}

.ev-input-selector__input[aria-invalid="true"]:focus {
    box-shadow:
        inset 0 0 0 1px var(--ev-danger-action-ink),
        inset 0 0 0 2px var(--ev-accent-edge);
}

.ev-input-selector__select:disabled,
.ev-input-selector__input:disabled {
    color: var(--ev-ink-dim);
    cursor: default;
    opacity: 0.72;
}

.ev-input-selector__select option {
    background: var(--ev-floor-n1);
    color: var(--ev-ink);
}

@media (max-width: 360px) {
    .ev-input-selector { --ev-input-selector-choice-width: 7rem; }
}

/* ===== src/components/segmented.css ===== */
/* ==========================================================================
   Evident component — the segmented control (channel-with-seat)
   ==========================================================================

   A segmented control is a machined CHANNEL — one recessed track cut into the
   face it sits on — holding 2–4 SEATS. Exactly one seat is SELECTED: it is the
   live segment, and it reads as a pressed piano key that has travelled DOWN
   under the channel's top arris and is accent-lit. The unselected seats are
   NOT drawn as material at all: they are labels lying on the channel floor,
   flush and read-only. This is the same construction as the study's sub-nav
   rail ("a channel with a seat cut into its floor", historical v16 record), lifted
   out of the entity-header context and generalised to a standalone control.
   (cortex-kvvt6y6, epic cortex-lndxpt3.)

   WHY THIS SHAPE, IN THE CHANNEL LANGUAGE
   ---------------------------------------
     Rim / lip weight  → nesting rank. The channel is a cut made into an
       already-machined-or-molded host face, so it takes rank-2 shading (finer
       than a rank-1 panel lip): --ev-r2-*.
     Floor luminance   → nesting depth. The channel floor sits at --ev-floor-n1
       (the deepest rung) so the whole track reads recessed; there is no rung
       below for the seat to descend INTO, which is correct — the selected seat
       does not go deeper, it comes UP as a lit face. Liveness is finish, not
       floor (the eviction is the file's most load-bearing correction; see
       core.css / CLAUDE.md § "The channels").
     Finish            → liveness. The selected seat is polished + accent-lit
       (live); the unselected seats are inert labels on the floor.
     Hue               → the single accent, and ONLY on the live seat.

   THE ONE MATERIAL EVENT PER PART (per-side cut audit, required by CLAUDE.md):
     .ev-segmented          the CHANNEL. Cut on all four sides via the rank-2
                            lip/wall/rim box-shadow. The top rounds in as light
                            land (the --ev-r2-rim run); there is NO dark top
                            arris line (cortex-gifqvxx dropped the ::after that
                            drew one — it read as a stubborn 1px dark contact
                            on the top edge and fought the light rim).
     .ev-segmented__seg::after  a carved GROOVE seam between adjacent segments —
                            a light+dark 1px achromatic pair reading as an inset
                            divider (Evident material). Seams flanking the
                            selected segment fade to a quarter-strength trace:
                            the seat is enough distinction there, while the
                            residual groove preserves material continuity
                            (cortex-gifqvxx, cortex-t03qgev).
     .ev-segmented__seat    the SEAT — ONE moving raised accent-lit block, SEATED
                            WITHIN the channel and SLID to the live segment (like
                            an iOS segmented control). There is exactly one seat
                            for the whole control, not one per segment: liveness
                            is a single machined block that travels, so the accent
                            (the one hue, the one live face) is provably unique by
                            construction. Position + width are driven by --seg-x /
                            --seg-w (the live seat's offsetLeft / offsetWidth, set
                            by the integrator's JS); the block is inset from all
                            four channel walls by --ev-seat-inset so the channel
                            floor + rounded top rim reads UNIFORM above EVERY
                            segment, and it rounds on all four corners to follow
                            the channel's inner rim — it does NOT breach the top
                            edge. Liveness is finish (accent-lit lit-crown,
                            --ev-acc-*, same as .ev-key--primary — a live surface
                            reads bright and takes DARK ink) plus a TIGHT
                            seat-contact seam — not an open-face cast; see the
                            seat rule below (cortex-cvyhdu3). The travel is a
                            transform+width transition only AFTER JS marks the
                            first real placement complete; initial server,
                            default and late-hydrated values therefore snap into
                            place. The platform motion gate still strips later
                            travel for reduced-motion users (cortex-m2m6aqh).
     .ev-segmented__seg     the labels. NOT drawn as material (no fill, no
                            shadow) — labels lying on the channel floor. The live
                            one (--selected) only takes accent ink + bold; the
                            bold width is RESERVED (hidden ::before) so the label
                            never reflows when liveness moves to it. Fix-by-
                            removal: painting a per-seat cut would draw a cut
                            where no material was removed.
     .ev-segmented__seg:disabled   oxidized finish = inert (never a floor move).

   WHY SEATED-INSET, NOT GROWN-FLUSH (cortex-hnrbqfe, 2nd pass)
   -----------------------------------------------------------
   The earlier construction grew the seat's box UPWARD by --ev-seat-travel and
   clipped it flush to the channel's top edge (clip-path inset(0)). That left the
   seat's top as a hard SQUARE edge riding the very top row — proud above the
   channel's rounded top rim — while every unselected label sat recessed BELOW
   that rim. Pixel-measured asymmetry: over a selected seat the accent began at
   the row directly under the arris (no rim recession); over an unselected seat
   the rounded rim + floor shading (196..207) showed first. That square-proud
   selected top vs uniform-rounded recessed rim IS the "weird upper border." The
   grow-flush trick cannot yield a uniform rim in a standalone control (unlike
   the study's rail, where the header chrome's outer rim optically swallowed the
   corner), so it is DROPPED here: the seat is now inset below the rim, lit and
   raised by shadow, following the channel's inner rounding.

   INVARIANT L1 (symmetric axial light): every shadow here is zero-offset, with
   no exception — the one `0 1px` layer that used to sit on the seat is gone
   (cortex-qws8bck; see the seat's box-shadow below). The seat's raised read is
   the accent-shoulder stack (--ev-acc-shoulder-1 and -2, the pair sized to a
   part this small) with --ev-seat-contact as the only outer layer, and its lit
   face is the ::before crown return, which is a centred gradient and not a
   shadow at all — the same physics as --ev-r*-lip.

   LIGHT/DARK PARITY (cortex-cvyhdu3)
   ----------------------------------
   Every treatment on this control has to be judged against BOTH benches, not
   against the one it was authored on. The seat's outer cast was
   --ev-contact-1 + --ev-ambient-1, which measures 4 levels of darkening on the
   near-black dark bench (invisible, so it looked correct) and 26 levels over a
   14px ramp on the light graphite bench (a dark tinge flooding the whole 4px
   floor ring around the seat). One declaration, two readings — the same class
   of defect as the carve floors in cortex-c8qr7zn, and settled the same way:
   the treatment is now a per-theme token (--ev-seat-contact) dialled so both
   benches read alike, rather than one absolute value tuned on one bench.
   ========================================================================== */

.ev-segmented {
    /* THE CHANNEL. One recessed floor, painted directly on the control — no
       per-seat backgrounds, nothing positioned. A cut into the host face, so
       rank-2 shading (finer than a rank-1 panel). All layers zero-offset. */
    --ev-seat-inset: 4px;           /* how far the selected seat is inset from
                                       EVERY channel wall, so the channel floor +
                                       rounded top rim reads uniform above every
                                       seat and the seat reads as a raised block
                                       SEATED in the channel (not a tab grown
                                       flush to the top edge). Named once (not
                                       inlined) so the inset is tuned in one
                                       place across the size scale. */
    /* The moving seat's geometry, in the channel's own coordinate space. The
       integrator's JS sets these from the LIVE segment's offsetLeft/offsetWidth
       on selection (and once on load); the seat transitions between them. The
       defaults place a zero-width seat at the origin so a control with no live
       segment shows no accent (correct: accent only for a live seat). */
    --seg-x: 0px;                   /* live seat's offsetLeft (px) */
    --seg-w: 0px;                   /* live seat's offsetWidth (px) */
    /* A channel and a key at one named size step share one control silhouette:
       height AND outer radius. Material remains legible through cut-vs-raised
       paint, not through competing corner shapes. The travelling seat is the
       nested part, so its radius is derived concentrically below. */
    --ev-segmented-height: var(--ev-btn-height-md);
    --ev-segmented-radius: var(--ev-btn-radius-md);
    /* GROOVE DIVIDER (cortex-gifqvxx) — the carved seam painted between adjacent
       segments. Two 1px achromatic runs a pixel apart (ink then land) read as an
       inset milled groove, the same physics as the pinstripe grain: a dark line
       with a lit companion. Light theme carries the seam mostly by ink over the
       grey floor; dark inverts to a near-black groove with a faint lit thread.
       --ev-seg-groove-ink / --ev-seg-groove-land / --ev-seg-groove-inset now
       live in tokens.css (both themes): the Bootstrap adapter draws this same
       seam on a .btn-group and cannot reach a component-local property, and
       restating the colours there would put literals in the adapter
       (cortex-wp0qzvk). Consumed below, not declared. */
    display: inline-flex;
    height: var(--ev-segmented-height);
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    position: relative;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-segmented-radius);
    color: var(--ev-ink);
    /* The channel's cut: rank-2 lip + wall + rim. The rim (--ev-r2-rim) is the
       light land that rounds the top edge in cleanly — no dark top arris line
       sits over it (cortex-gifqvxx removed the ::after that drew one). */
    box-shadow:
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
    /* Clip seats to the channel's own rounded box so nothing overflows the cut
       (the selected seat is inset well within this, so the clip only guards the
       channel's rounded corners against any seat background). */
    clip-path: inset(0 round var(--ev-segmented-radius));
    transition: var(--ev-transition-fast);
}

/* Dark stock: the groove inverts, carried mostly by a faint scattered LIGHT
   sheen (no room to darken over a near-black floor) — a near-black ink run with
   an almost-invisible lit companion. Same inversion the pinstripe grain makes.
   That inversion moved to tokens.css's dark theme block with the tokens
   themselves (cortex-wp0qzvk), so it now applies to the adapter's .btn-group
   seam as well as to this control, from one declaration. */

/* NO TOP ARRIS (cortex-gifqvxx). Earlier passes drew a 1px dark contact line
   across the channel's top row via .ev-segmented::after (border-top:
   --ev-seg-arris), tuned down over successive fixes but never eliminated — a
   founder readthrough still caught a stubborn 1px dark-grey line on the top
   edge. Fix-by-removal: the channel's own rank-2 rim (--ev-r2-rim, the light
   land in the box-shadow above) already rounds the top in cleanly; a dark
   contact line on top of it fought that rim rather than completing it. The
   whole arris construct (the ::after, its --ev-seg-arris colour token, and the
   dark-theme override of that token) is dropped, so the channel's top rounds in
   as light land with NO dark contact line in either theme. */

/* ---- THE SEAT: ONE moving accent-lit block, SLID to the live segment ------
   There is exactly one seat element for the whole control (not one per
   segment). It is a raised accent face inset from EVERY channel wall by
   --ev-seat-inset, so the channel's floor + rounded top rim reads uniform above
   EVERY segment and the block reads as SEATED WITHIN the channel rather than a
   square tab grown flush to the top edge. Rounded on all four corners (radius
   reduced by the inset so it hugs the channel's inner rim). The accent face is
   the lit crown treatment (--ev-acc-*, the same stack as .ev-key--primary) — a
   live surface reads bright and takes DARK ink (--ev-accent-ink on the label).
   Depth is carried by the blurred accent-shoulder pair plus the seat's contact
   cast, and the face is lit by the ::before crown return; all zero-offset
   (Invariant L1).

   POSITION: the seat lives in the channel's coordinate space and is placed over
   the LIVE segment via --seg-x (its offsetLeft) and --seg-w (its offsetWidth),
   both set by the integrator's JS. The inset is applied here: the seat starts
   --ev-seat-inset in from the channel's left/top and is --ev-seat-inset
   narrower/shorter than the segment on each axis. It sits at z-index 0 — BELOW
   the labels (which are z-index 1) so ink reads on top of the accent.

   TRAVEL (Fix — slide, not jump): transform + width transition, so the single
   seat SLIDES between segments like an iOS segmented control. The transition
   is armed only by data-ev-segmented-ready, after JS has painted the first
   selected geometry without it. A server-selected value, a client default and
   a selection arriving after hydration therefore begin at their real position
   instead of travelling there from --seg-x/--seg-w = 0. Later value changes
   retain the slide. The platform motion gate remains authoritative, so reduced-
   motion users get every move instantly (cortex-m2m6aqh). */
.ev-segmented__seat {
    --ev-direct-carve-floor: initial;
    position: absolute;
    top: var(--ev-seat-inset);
    left: 0;
    height: calc(100% - 2 * var(--ev-seat-inset));
    width: calc(var(--seg-w) - 2 * var(--ev-seat-inset));
    transform: translateX(calc(var(--seg-x) + var(--ev-seat-inset)));
    background-color: var(--ev-accent);
    /* Nested corners stay concentric: inner radius = host radius − inset.
       Using an unrelated or half-inset radius makes the two curves visibly
       diverge even when each radius looks plausible in isolation. */
    border-radius: calc(var(--ev-segmented-radius) - var(--ev-seat-inset));
    box-shadow:
        /* NO LIT TOP RIM (cortex-qws8bck). A bright 1px inset line used to sit
           first here — `inset 0 1px 0 0 var(--ev-acc-crown)`, added by
           cortex-rrjqqze against a founder note that the seat's top "must NOT be
           darkened over the blue". It was a counter-treatment, and BOTH of the
           darkenings it answered have since been removed: cortex-gifqvxx deleted
           the channel's dark top arris (.ev-segmented::after), and cortex-cvyhdu3
           replaced the seat's open-face cast with the tight 2px --ev-seat-contact
           seam that lands on the channel floor rather than over the accent. With
           nothing left to counteract, the line stopped reading as a lit crown and
           started reading as a white outline: it follows the seat's rounded top
           corners, so on a 29px seat it draws a bright arc across the whole upper
           half. A founder readthrough of Control Center's file-manager toolbar
           caught exactly that — the seat "floating proud of its slot rather than
           seated in it", and not matching the .ev-key--primary sitting inches
           away on the same row. Fix-by-removal: delete the compensating layer now
           that its cause is gone.

           It was also the file's one INVARIANT L1 breach. L1 allows exactly two
           offset shadows library-wide (.leftnav parting line, .appbar overhang);
           `0 1px` here was neither, and the comment justifying it claimed "zero
           y-offset" while declaring one. Every layer below is zero-offset, so the
           paragraph under WHY THIS SHAPE is now true as written.

           Liveness is unchanged and still finish, not geometry: the accent face,
           the ::before crown return and the accent-shoulder stack all remain.
           What is gone is the hard edge, which makes this stack byte-identical
           in kind to .ev-key--primary's — two accent-lit faces on one toolbar
           now read as one material.

           THE FALLOFF IS NOW SIZED TO THE PART (cortex-ht04oo2). Removing the
           rim left the seat with neither a dark contact nor a lit crown — a
           third state nobody chose — and the cause was measurable: this stack
           also carried var(--ev-acc-shoulder-3), `inset 0 0 15px`, on a seat
           that is 29-31px TALL. A 15px falloff exceeds the part's half-height,
           so the falloff arriving from the top edge meets the one arriving from
           the bottom and there is no un-darkened crown left in between. Scanned
           on the light bench, the seat never reached the accent anywhere: peak
           rgb(60,184,243) against .ev-key--primary's flat rgb(43,179,243), with
           its top run down at rgb(64,167,215) — i.e. the seat's top WAS being
           darkened over the blue, the one thing the founder's note forbade, by
           a shoulder sized for a much larger face. .ev-key--primary omits
           shoulder-3 for exactly this reason; the seat now does too, and the
           two accent faces are once again the same stack. */
        var(--ev-acc-shoulder-1),
        var(--ev-acc-shoulder-2),
        /* SEAT CONTACT, NOT AN OPEN-FACE CAST (cortex-cvyhdu3). This used to be
           var(--ev-contact-1), var(--ev-ambient-1) — the treatment for a part
           standing proud on an open face. The seat is not that: it is inset
           --ev-seat-inset (4px) from every channel wall and sits BELOW the
           channel's top arris, so the only surface its shadow can land on is
           that 4px ring of channel floor. A 14px ambient throw has nowhere to
           fall off to and simply floods the ring, which is exactly the file's
           own uniform-floor claim above being broken by its own shadow.
           Measured on the light bench it read as a 26-level, 14px-wide dark
           wash hugging the seat — the "tinge" — while on the near-black dark
           bench the identical cast measured 4 levels and was invisible. Same
           declaration, two completely different reads: a light/dark parity bug.
           --ev-seat-contact is the per-theme replacement (tokens.css), tight
           enough that the floor is at full value 2px out in BOTH themes. */
        var(--ev-seat-contact);
    pointer-events: none;
    z-index: 0;
    /* No live segment (zero width) → no accent shows. Accent only for a live
       seat, by construction. */
}
/* Hidden until a live seat exists (JS sets --seg-w > 0). A zero-width block
   would still paint its 1px shadows; collapse it out entirely instead. */
.ev-segmented:not(:has(.ev-segmented__seg--selected)) .ev-segmented__seat {
    display: none;
}

/* THE CROWN RETURN — the lit face, and the reason it cannot arc (cortex-ht04oo2)
   ---------------------------------------------------------------------------
   The seat is a raised block with a CROWNED face. Under the one axial light
   (L1: the viewer) a crowned face returns most light at its crest and rolls
   away toward every shoulder, so the honest highlight is a soft centred ellipse
   — zero-offset, symmetric, brightest in the middle of the face.

   THIS REPLACES A SWOOP, and the swoop was the second half of the "not lit"
   bug. `linear-gradient(var(--ev-swoop-angle), --ev-acc-lum-hi 0%, …)` anchors
   its bright stop at the top-LEFT CORNER. On a 52 x 29 seat that axis is very
   nearly horizontal, so it was never a crown: it laid a directional white wash
   that lifted R from 43 to 60-65 — DESATURATING the accent rather than lighting
   it, which is the milky read. Scanning the top row left-to-right measured
   221 → 235 → 202: brighter on one side than the other, on a language whose
   first invariant is symmetric straight-on light. The doctrine already said
   this: the swoop is for a live molded face at FACEPLATE SIZE, and "chips,
   badges and secondary keys are below the useful scale, where the sweep becomes
   noise" (CLAUDE.md § The channels). A 29px seat is chip scale, which is also
   why .ev-key--primary — the material sibling — carries no swoop at all.
   Removing it here narrows swoop-present ⇔ live cast face rather than widening
   it; the shared --ev-swoop-angle is untouched and un-varied.

   WHY IT CANNOT ARC OVER THE ROUNDED CORNERS. This is the failure that made
   cortex-qws8bck delete the previous crown, so it is settled by construction
   rather than by tuning. For radial-gradient(W% H% at 50% 50%), a stop's
   position is a fraction of the gradient's own scale, and the box's corner
   always sits at hypot(0.5/W, 0.5/H) of that scale — a constant, INDEPENDENT of
   the seat's size and aspect ratio. At 90% / 160% that constant is 0.637, while
   the middle of the top edge sits at 0.5/1.60 = 0.312. So a `transparent` stop
   at 50% is past every corner and well short of the top-edge crest, at every
   size step and at any width the JS geometry bridge hands the seat — from the
   47px sm seat to the 225px fill seat. The crown is BRIGHTEST where the face
   faces the viewer and is already fully transparent by the time the silhouette
   starts to curve. Measured after the change, the top row reads
   221 → 240 → 221: it rises to the middle and falls back symmetrically, the
   exact inverse of an arc, and the face mean lifts 230.4 → 238.7.

   Two stops only, and deliberately: --ev-acc-lum-mid and --ev-acc-lum-lo were
   both tried here and neither renders — every point inside the box is under
   0.637 of the scale, so any stop beyond the transparent one is off the part.
   A declared stop that cannot paint is a comment lying in CSS syntax.

   Inherits the seat's all-four-corner radius so it stays inside the block and
   never bleeds over the channel rim. No offset anywhere (Invariant L1). */
.ev-segmented__seat::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: radial-gradient(
        90% 160% at 50% 50%,
        var(--ev-acc-lum-hi) 0%,
        transparent 50%);
}

/* The slide is deliberately absent until the geometry bridge has completed
   one selected placement and forced its layout. Adding the readiness marker
   in the same unflushed style change would still animate the initial custom-
   property update, so the JS contract is: write geometry without this marker,
   force the seat's layout, then add the marker. A control with no selected
   segment stays unarmed; its first late-hydrated selection is therefore still
   an initial placement, not a value change. */
.ev-segmented[data-ev-segmented-ready] .ev-segmented__seat {
    transition: transform var(--ev-transition-fast), width var(--ev-transition-fast);
}

/* ---- the labels ----------------------------------------------------------
   A segment is NOT drawn as material: no background, no shadow. It is a label
   lying on the channel floor, per the study's rail measurement — the visible
   track between labels is what reads as a channel. The single moving seat above
   supplies the one live face. Fix-by-removal: painting a per-seg cut would draw
   a cut where no material was removed. */
.ev-segmented__seg {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    margin: 0;
    background-color: transparent;
    color: var(--ev-ink-dim);
    font: 500 var(--ev-btn-font-md)/1 var(--ev-font-sans);
    letter-spacing: 0.005em;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    /* Column flex so the hidden bold twin (::before, height 0) stacks ABOVE the
       visible label and its width still drives the button's cross-size (width).
       This reserves the BOLD width for the box whether the label is bare text
       (<button>List</button>) or wrapped — no markup wrapper required — so the
       weight flip on selection cannot reflow (see the text-shift fix below).
       align-items:center keeps the label optically centred. */
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    flex: 0 0 auto;
    /* Labels sit ABOVE the moving seat so accent ink reads on the accent face. */
    z-index: 1;
    /* The visible band: --ev-btn-pad-y-md above/below the label sets the track
       height; the horizontal pad sizes each seat. Content-sized (not flex:1)
       so bare channel remains between short labels and reads as track. */
    padding: var(--ev-btn-pad-y-md) var(--ev-btn-pad-x-md);
    transition:
        color 0.12s ease,
        background-color var(--ev-transition-fast);
}

/* Fix (text-shift on select): the live label is bold (--selected sets
   font-weight 600), but a weight change alters text metrics and would shift the
   label — and, worse, re-flow the whole row, breaking every segment's measured
   offsetLeft/offsetWidth mid-slide. Reserve the BOLD width up front: this hidden
   twin renders the same text at weight 600 as a zero-height column item, so the
   button's width is ALWAYS the bold width and nothing moves when liveness
   arrives or leaves. It reads the label from data-label="…" (the integrator
   mirrors the visible text there; see the gallery-JS note below). height:0 keeps
   it off the vertical band; the visible label carries the real line-box. */
.ev-segmented__seg::before {
    content: attr(data-label);
    font-weight: 600;
    height: 0;
    overflow: hidden;
    visibility: hidden;
    pointer-events: none;
    letter-spacing: inherit;
}

/* ---- GROOVE DIVIDERS between segments (cortex-gifqvxx) --------------------
   A thin carved seam between adjacent segments: two 1px achromatic runs a pixel
   apart (ink then land) reading as an inset milled groove, per Evident material.
   Drawn as a ::after on each segment's LEFT edge, so it sits in the gap between
   that segment and its predecessor — matched via `seg + seg` (a segment that
   FOLLOWS another segment), NOT :not(:first-child): the channel's first DOM
   child is the .ev-segmented__seat <span>, so :first-child would never match a
   label and the leading label would draw a spurious seam at the channel's left
   inner edge. The seam is inset top/bottom (--ev-seg-groove-inset)
   so it reads as a short carved detail on the channel floor, not a full-height
   rule. It sits at z-index 2 — ABOVE the moving seat (z 0) and the labels (z 1)
   would be fine too, but the seam is achromatic and thin so it reads on the
   floor between labels regardless.

   MUTING: dividers touching the SELECTED segment on either side recede to a
   quarter-strength trace — the seat is enough distinction there, but the groove
   remains physically continuous instead of blinking out. That is two seams:
   the one on the selected segment's own left edge, and the one on its right
   (which is the NEXT segment's left-edge divider). Opacity transitions on the
   persistent pseudo-element, so muting follows the moving selection without an
   abrupt hide/show. The library motion gate removes that transition for
   reduced-motion users. */
.ev-segmented__seg + .ev-segmented__seg::after {
    content: "";
    position: absolute;
    left: 0;
    top: var(--ev-seg-groove-inset);
    bottom: var(--ev-seg-groove-inset);
    width: 2px;
    /* ink run then lit companion, a pixel apart — the milled-groove pair. */
    background: linear-gradient(
        90deg,
        var(--ev-seg-groove-ink) 0,
        var(--ev-seg-groove-ink) 1px,
        var(--ev-seg-groove-land) 1px,
        var(--ev-seg-groove-land) 2px);
    /* Centre the 2px seam on the inter-segment boundary. */
    transform: translateX(-1px);
    opacity: 1;
    transition: opacity var(--ev-transition-fast);
    pointer-events: none;
    z-index: 2;
}
/* Mute the seam on the selected segment's OWN left edge. Keep the adjacency
   arm so this state has the same specificity as the seam's base rule. */
.ev-segmented__seg + .ev-segmented__seg--selected::after {
    opacity: var(--ev-seg-groove-muted-opacity);
}
/* ...and mute the seam on the segment immediately AFTER the selected one (that seam
   IS the selected segment's right-side boundary). */
.ev-segmented__seg--selected + .ev-segmented__seg::after {
    opacity: var(--ev-seg-groove-muted-opacity);
}

/* NO hover ink change (cortex-gifqvxx). An earlier pass woke a hovered label
   toward full ink; a founder readthrough found it "flicking" — and because the
   only label that goes bright happens to be the selected one, hover ink read as
   a spurious selection flicker. You just click a segment, so hover interactivity
   must stay out of the ink channel. Label colour changes ONLY on selection.
   Hover instead lays a quiet achromatic sheen over the segment's hit area: a
   finish response, not a second selected state and not a depth change. */
.ev-segmented__seg:not(:disabled):not(.ev-segmented__seg--disabled):hover {
    background-color: var(--ev-lum-mid);
}

.ev-segmented__seg:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: -2px;
    z-index: 4;
}

/* The live label: accent ink + bold. NO material here — the moving seat carries
   the accent face. Because the bold width is reserved above, flipping to 600
   does not reflow. */
.ev-segmented__seg--selected {
    color: var(--ev-accent-ink);
    font-weight: 600;
}
/* No selected:hover override (cortex-gifqvxx): the selected label keeps its
   accent ink on hover too, so no colour changes on hover anywhere. */

/* ---- disabled — oxidized finish = inert (never a floor move) ------------- */
.ev-segmented__seg:disabled,
.ev-segmented__seg.ev-segmented__seg--disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
/* A wholly-disabled control dulls uniformly — a thin achromatic veil, no
   colour shift, matching .ev-fin-oxidized. */
.ev-segmented--disabled {
    filter: saturate(0.9) brightness(0.98);
    opacity: 0.86;
    pointer-events: none;
}

/* ---- size scale ----------------------------------------------------------
   Default is md. --sm and --lg map both HEIGHT and OUTER RADIUS to the matching
   key step, so peer controls in one toolbar do not mix silhouettes. The cut is
   still a cut through its rank-2 lip/wall/rim; geometry need not carry material
   identity a second time. The nested seat keeps the concentric subtraction. */
.ev-segmented--sm {
    --ev-segmented-height: var(--ev-btn-height-sm);
    --ev-segmented-radius: var(--ev-btn-radius-sm);
    --ev-seat-inset: 3px;
}
.ev-segmented--sm .ev-segmented__seg {
    font-size: var(--ev-btn-font-sm);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
}
.ev-segmented--lg {
    --ev-segmented-height: var(--ev-btn-height-lg);
    --ev-segmented-radius: var(--ev-btn-radius-lg);
    --ev-seat-inset: 5px;
}
.ev-segmented--lg .ev-segmented__seg {
    font-size: var(--ev-btn-font-lg);
    padding: var(--ev-btn-pad-y-lg) var(--ev-btn-pad-x-lg);
}
/* ---- full-width — seats share the track equally (view-toggle idiom) ------
   For the 2/3/4-segment view toggles CC uses, the control often spans a
   toolbar cell with seats sharing the width. This is opt-in because the
   default (content-sized) is what keeps bare channel readable as track. */
.ev-segmented--fill { display: flex; width: 100%; }
.ev-segmented--fill .ev-segmented__seg { flex: 1 1 0; }

/* ===== src/components/dns-ttl-selector.css ===== */
/* ==========================================================================
   Evident opinionated component — DNS TTL selector
   ==========================================================================

   A DNS TTL is one value with two legitimate ways to enter it: choose one of
   four common durations, or type an exact number of seconds. This component
   keeps both routes visible and keeps ONE numeric input authoritative.

   The preset rack is the shipped segmented channel, not four unrelated keys.
   Exactly one seat may be live because a TTL has one current value. The exact
   input remains visible beside it when space permits and below it when space
   is tight, so the user can see what will be submitted without finding a
   hidden "Custom" mode first.

   STRUCTURAL CONTRACT
     .ev-dns-ttl-selector                     fieldset/root
     .ev-dns-ttl-selector__legend             visible form label
     .ev-dns-ttl-selector__presets            the .ev-segmented preset rack
     .ev-dns-ttl-selector__preset              one .ev-segmented__seg
     .ev-dns-ttl-selector__duration            human duration (1 hour)
     .ev-dns-ttl-selector__seconds             submitted equivalent (3600 s)
     .ev-dns-ttl-selector__exact               exact-value row
     .ev-dns-ttl-selector__exact-label         label + explanation

   The component introduces no new material. The channel/seat come from
   .ev-segmented and the exact value comes from .ev-measure. These selectors
   only impose the DNS-specific structure, hierarchy and responsive layout.
   Consumer behaviour sets the numeric input from data-ttl, keeps aria-pressed
   and .ev-segmented__seg--selected aligned, then moves the segmented seat.
   The initial server render is complete without JavaScript.
   ========================================================================== */

.ev-dns-ttl-selector {
    /* TTL is one compact instrument: its preset channel and exact-value
       pocket share the same low-radius silhouette. Ordinary segmented
       controls keep their size-step button radii. */
    --ev-dns-ttl-selector-radius: var(--ev-radius-sm);
    --ev-dns-ttl-selector-height: var(--ev-btn-height-md);

    display: grid;
    gap: 10px;
    width: 100%;
    max-width: 48rem;
    min-inline-size: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.ev-dns-ttl-selector__legend {
    display: block;
    margin: 0 0 6px;
    padding: 0;
}

.ev-dns-ttl-selector__presets.ev-segmented {
    --ev-segmented-radius: var(--ev-dns-ttl-selector-radius);
    --ev-segmented-height: var(--ev-dns-ttl-selector-height);

    display: flex;
    width: 100%;
}

.ev-dns-ttl-selector__preset.ev-segmented__seg {
    flex: 1 1 0;
    min-width: 0;
    padding-inline: 10px;
}

.ev-dns-ttl-selector__duration,
.ev-dns-ttl-selector__seconds {
    display: block;
    white-space: nowrap;
}

.ev-dns-ttl-selector__duration {
    font: 600 0.875rem/1.2 var(--ev-font-sans);
}

.ev-dns-ttl-selector__seconds {
    margin-top: 3px;
    color: currentColor;
    font: 400 0.6875rem/1.1 var(--ev-font-mono);
    opacity: 0.68;
}

.ev-dns-ttl-selector__exact {
    display: grid;
    gap: 7px;
}

.ev-dns-ttl-selector__exact-label {
    display: grid;
    gap: 3px;
}

.ev-dns-ttl-selector__exact > .ev-measure {
    width: min(100%, 20rem);
    border-radius: var(--ev-dns-ttl-selector-radius);
}

@media (min-width: 700px) {
    .ev-dns-ttl-selector {
        grid-template-columns: minmax(0, 1fr) minmax(10rem, 12rem);
        column-gap: 8px;
        row-gap: 6px;
    }

    .ev-dns-ttl-selector__legend {
        grid-column: 1 / -1;
    }

    .ev-dns-ttl-selector__seconds {
        display: none;
    }

    .ev-dns-ttl-selector__exact {
        display: block;
        min-width: 0;
    }

    /* The fieldset legend names the control and the unit names the datum. Keep
       the exact-entry instruction available to assistive technology without
       inserting a second visible row into the horizontal instrument. */
    .ev-dns-ttl-selector__exact-label {
        position: absolute;
        inline-size: 1px;
        block-size: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .ev-dns-ttl-selector__exact > .ev-measure {
        width: 100%;
        height: var(--ev-dns-ttl-selector-height);
        min-height: var(--ev-dns-ttl-selector-height);
    }
}

@media (max-width: 560px) {
    .ev-dns-ttl-selector__preset.ev-segmented__seg {
        padding-inline: 6px;
    }

    .ev-dns-ttl-selector__duration {
        font-size: 0.75rem;
    }

    .ev-dns-ttl-selector__seconds {
        font-size: 0.625rem;
    }

}

/* ===== src/components/dns-hostname.css ===== */
/* ==========================================================================
   Evident opinionated component — DNS hostname
   ==========================================================================

   A DNS owner name inside a known zone is one value with one editable part.
   The zone is fixed context, so it stays visible and inert while the prefix is
   edited. At rest an empty prefix shows the zone in the ordinary input-text
   position. Focus cross-fades that resting copy while the same zone seats as
   the dotted fixed suffix.

   STRUCTURAL CONTRACT
     .ev-dns-hostname                    component root
     .ev-dns-hostname__label             visible field label
     .ev-dns-hostname__instrument        shared .ev-pocket
     .ev-dns-hostname__root              legacy server-rendered root label
     .ev-dns-hostname__input             editable prefix; no submitted name
     .ev-dns-hostname__zone              fixed zone suffix
     .ev-dns-hostname__value             hidden submitted FQDN
     .ev-dns-hostname__feedback          polite compatibility/error message

   dist/evident-dns-hostname.js owns prefix/FQDN synchronization and accepts
   the conventional "@" spelling as an input alias when the root is allowed.
   The initial server render still owns its visible state and hidden value.
   ========================================================================== */

.ev-dns-hostname {
    display: grid;
    gap: 6px;
    width: 100%;
}

.ev-dns-hostname__label {
    display: block;
}

.ev-dns-hostname__instrument.ev-pocket {
    display: grid;
    grid-template-columns: minmax(5ch, 1fr) minmax(0, auto);
    align-items: stretch;
    width: 100%;
    padding: 0;
    overflow: hidden;
}

.ev-dns-hostname__prefix {
    position: relative;
    min-width: 0;
}

.ev-dns-hostname__input {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    min-width: 0;
    height: 100%;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ev-ink);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    font: 400 0.9375rem/1.4 var(--ev-font-mono);
}

.ev-dns-hostname__input::placeholder {
    color: var(--ev-ink-dim);
    opacity: 1;
    transition: opacity 120ms ease;
}
.ev-dns-hostname__input:focus::placeholder,
.ev-dns-hostname__instrument:focus-within
    .ev-dns-hostname__input::placeholder {
    color: transparent;
    opacity: 0;
}

/* The label occupies the editable prefix opening while it is empty. It stays
   present on focus, so clicking Root domain lets typing begin immediately
   without flashing an unexplained blank state. */
.ev-dns-hostname__root {
    position: absolute;
    z-index: 2;
    inset-block: 0;
    inset-inline-start: 0;
    display: none;
    align-items: center;
    padding-inline-start: var(--ev-btn-pad-x-sm);
    color: var(--ev-ink);
    font: 600 0.875rem/1.2 var(--ev-font-sans);
    pointer-events: none;
    transition: var(--ev-transition-fast);
}

.ev-dns-hostname__input:not(:placeholder-shown) + .ev-dns-hostname__root,
.ev-dns-hostname--prefix .ev-dns-hostname__root,
.ev-dns-hostname[data-root-allowed="false"] .ev-dns-hostname__root {
    opacity: 0;
}

.ev-dns-hostname__zone {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 0;
    max-inline-size: 0;
    margin-block: 0.35rem;
    padding-inline: 0;
    overflow: hidden;
    border-inline-start: 1px solid color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    color: var(--ev-ink-dim);
    font: 600 0.8125rem/1 var(--ev-font-mono);
    white-space: nowrap;
    user-select: all;
    opacity: 0;
    transform: translateX(-0.45rem);
    transition:
        max-inline-size 180ms ease,
        padding-inline 180ms ease,
        opacity 140ms ease,
        transform 180ms ease,
        color var(--ev-transition-fast);
}

.ev-dns-hostname__zone::before {
    content: ".";
}

.ev-dns-hostname__instrument:focus-within .ev-dns-hostname__zone,
.ev-dns-hostname--prefix .ev-dns-hostname__zone,
.ev-dns-hostname--root-alias .ev-dns-hostname__zone,
.ev-dns-hostname[data-root-allowed="false"] .ev-dns-hostname__zone {
    max-inline-size: 32ch;
    padding-inline: 0.75rem;
    opacity: 1;
    transform: translateX(0);
}

.ev-dns-hostname__instrument:focus-within {
    outline: none;
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

.ev-dns-hostname__instrument:focus-within .ev-dns-hostname__input,
.ev-dns-hostname__instrument:focus-within .ev-dns-hostname__root {
    color: var(--ev-accent-text);
}

.ev-dns-hostname__instrument:focus-within .ev-dns-hostname__zone {
    border-inline-start-color:
        color-mix(in srgb, var(--ev-accent-edge) 48%, var(--ev-ink-faint));
    color: color-mix(in srgb, var(--ev-accent-text) 68%, var(--ev-ink-dim));
}

.ev-dns-hostname__feedback {
    min-height: 1.1em;
    color: var(--ev-ink-dim);
    font: 400 0.75rem/1.35 var(--ev-font-sans);
}

.ev-dns-hostname__value {
    display: none;
}

.ev-dns-hostname__feedback:empty {
    min-height: 0;
}

.ev-dns-hostname[data-hostname-state="invalid"] .ev-dns-hostname__feedback {
    color: var(--ev-danger);
}

@media (max-width: 460px) {
    .ev-dns-hostname__instrument.ev-pocket {
        grid-template-columns: minmax(4ch, 1fr) auto;
    }

    .ev-dns-hostname__zone {
        padding-inline: 0.55rem;
        font-size: 0.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .ev-dns-hostname__zone,
    .ev-dns-hostname__input::placeholder { transition: none; }
}

/* ===== src/components/postal-city.css ===== */
/* ==========================================================================
   Evident component — postal code and city
   ===========================================================================

   Two unrestricted native inputs form one compound address instrument. The
   optional lookup is guidance, never validation: it may fill an empty city or
   offer one explicit action, but it may not overwrite authored text.

   The suggestion is a small live molded face added beside the fields. It is
   not validation colour and never turns either input into a locked value.
   ========================================================================== */

.ev-postal-city {
    container-type: inline-size;
    display: grid;
    gap: 0.75rem;
    width: 100%;
}

.ev-postal-city__fields {
    display: grid;
    grid-template-columns: minmax(8rem, 0.65fr) minmax(12rem, 1.35fr);
    gap: 0.75rem;
    align-items: end;
}

.ev-postal-city__field {
    display: grid;
    gap: 0.35rem;
    min-width: 0;
}

.ev-postal-city__country {
    grid-column: 1 / -1;
    max-width: 18rem;
}

.ev-postal-city__suggestion {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.625rem 0.75rem;
    background: var(--ev-metal-hi);
    border: 1px solid var(--ev-rule);
    border-radius: var(--ev-radius-sm);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

.ev-postal-city__suggestion[hidden] {
    display: none;
}

.ev-postal-city__suggestion-copy,
.ev-postal-city__status {
    margin: 0;
}

/* Quiet is the default: lookup is a pleasant completion, not a workflow the
   form needs to announce. Consumers opt into narrative guidance with
   data-ev-postal-city-verbose or provide their own messages in JavaScript. */
.ev-postal-city:not([data-ev-postal-city-verbose]) .ev-postal-city__status:empty {
    display: none;
}

.ev-postal-city__status {
    min-height: 1.4em;
    color: var(--ev-ink-dim);
    font-size: 0.875rem;
}

/* The suggestion face already states the candidate for sighted users. Keep
   the same update in the live region for assistive technology without drawing
   a duplicate third city value directly below the actionable face. */
.ev-postal-city[data-ev-postal-city-state="suggested"]
    .ev-postal-city__status {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 34rem) {
    .ev-postal-city__fields { grid-template-columns: 1fr; }
    .ev-postal-city__country { grid-column: auto; max-width: none; }
    .ev-postal-city__suggestion { align-items: stretch; flex-direction: column; }
}

@container (max-width: 28rem) {
    .ev-postal-city__fields { grid-template-columns: 1fr; }
    .ev-postal-city__country { grid-column: auto; max-width: none; }
    .ev-postal-city__suggestion { align-items: stretch; flex-direction: column; }
}

/* ===== src/components/phone.css ===== */
/* ==========================================================================
   Evident opinionated component — international phone number
   ===========================================================================

   A calling code and an editable national number are one value. The calling
   code is context, not a second field: only .ev-phone__value has a submitted
   name. The visible input remains the native validation target and accepts a
   leading "+" at any time to enter an international number manually.

   Country labels and calling-code data belong to the consumer. Evident owns
   the compound geometry, accessible state hooks and value synchronization.
   ========================================================================== */

.ev-phone {
    container-type: inline-size;
    display: grid;
    gap: 0.35rem;
    width: 100%;
}

.ev-phone__label { display: block; }

.ev-phone__instrument.ev-pocket {
    display: grid;
    grid-template-columns: minmax(8.5rem, auto) minmax(8rem, 1fr);
    align-items: stretch;
    width: 100%;
    padding: 0;
    overflow: hidden;
}

/* Compact is an explicit density choice, not a container accident. It keeps
   country context inline, shortens its register and never stacks. */
.ev-phone--compact .ev-phone__instrument.ev-pocket {
    grid-template-columns: minmax(6.75rem, 0.72fr) minmax(8rem, 1.28fr);
}

.ev-phone--compact .ev-phone__code {
    min-height: 0;
    margin-block: 0.25rem;
    border-inline-end: 1px solid
        color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    border-block-end: 0;
}

.ev-phone--compact .ev-phone__calling-code {
    padding-inline-start: 0.65rem;
    padding-inline-end: 1.75rem;
    font-size: var(--ev-text-small);
}

.ev-phone--compact .ev-phone__code::after { inset-inline-end: 0.6rem; }
.ev-phone--compact .ev-phone__number { padding-inline: 0.65rem; }

.ev-phone__code {
    position: relative;
    display: flex;
    align-items: stretch;
    min-width: 0;
    margin-block: 0.35rem;
    border-inline-end: 1px solid
        color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    transition: border-color var(--ev-transition-fast);
}

.ev-phone__code::after {
    content: "";
    position: absolute;
    pointer-events: none;
    width: 0.42em;
    height: 0.42em;
    inset-inline-end: 0.75rem;
    inset-block-start: 50%;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    color: var(--ev-ink-dim);
    transform: translateY(-72%) rotate(45deg);
    transition: color var(--ev-transition-fast);
}

.ev-phone__calling-code,
.ev-phone__number {
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    font: 400 0.9375rem/1.4 var(--ev-font-sans);
}

.ev-phone__calling-code {
    width: 100%;
    appearance: none;
    -webkit-appearance: none;
    padding: 0 var(--ev-btn-pad-x-sm);
    padding-inline-end: 2.25rem;
    color: var(--ev-ink-dim);
    cursor: pointer;
}

.ev-phone__calling-code option {
    background: var(--ev-floor-n1);
    color: var(--ev-ink);
}

.ev-phone__number {
    width: 100%;
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-sm);
    color: var(--ev-ink);
}

.ev-phone__number::placeholder { color: var(--ev-ink-dim); }
.ev-phone__number:focus::placeholder { color: transparent; }

.ev-phone__instrument:focus-within {
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-accent-edge);
}

/* Code, divider, chevron and editable ink acknowledge one focus event. The
   calling-code side remains slightly muted so context never competes with the
   authored number. */
.ev-phone__instrument:focus-within .ev-phone__number {
    color: var(--ev-accent-text);
}

.ev-phone__instrument:focus-within .ev-phone__calling-code,
.ev-phone__instrument:focus-within .ev-phone__code::after {
    color: color-mix(in srgb, var(--ev-accent-text) 72%, var(--ev-ink-dim));
}

.ev-phone__instrument:focus-within .ev-phone__code {
    border-inline-end-color:
        color-mix(in srgb, var(--ev-accent-edge) 48%, var(--ev-ink-faint));
}

.ev-phone:has(.ev-phone__number[aria-invalid="true"]) .ev-phone__instrument {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink);
}

.ev-phone:has(.ev-phone__number[aria-invalid="true"])
    .ev-phone__instrument:focus-within {
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim),
        inset 0 0 0 1px var(--ev-danger-action-ink),
        inset 0 0 0 2px var(--ev-accent-edge);
}

.ev-phone__feedback {
    min-height: 1.1em;
    margin: 0;
    color: var(--ev-ink-dim);
    font: 400 0.75rem/1.35 var(--ev-font-sans);
}

.ev-phone__feedback:empty { min-height: 0; }

.ev-phone:has(.ev-phone__number[aria-invalid="true"]) .ev-phone__feedback {
    color: var(--ev-danger-action-ink);
}

.ev-phone__value { display: none; }

.ev-phone:has(.ev-phone__number:disabled) {
    opacity: 0.58;
}

.ev-phone:has(.ev-phone__number:disabled) .ev-phone__calling-code {
    cursor: not-allowed;
}

@container (max-width: 22rem) {
    .ev-phone:not(.ev-phone--compact) .ev-phone__instrument.ev-pocket { grid-template-columns: 1fr; }
    .ev-phone:not(.ev-phone--compact) .ev-phone__code {
        min-height: 2.1rem;
        margin-block: 0;
        border-inline-end: 0;
        border-block-end: 1px solid
            color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    }
}

@media (max-width: 360px) {
    .ev-phone:not(.ev-phone--compact) .ev-phone__instrument.ev-pocket { grid-template-columns: 1fr; }
    .ev-phone:not(.ev-phone--compact) .ev-phone__code {
        min-height: 2.1rem;
        margin-block: 0;
        border-inline-end: 0;
        border-block-end: 1px solid
            color-mix(in srgb, var(--ev-ink-faint) 72%, transparent);
    }
}

/* ===== src/components/rail.css ===== */
/* ==========================================================================
   Evident component — the rail (a channel with a seat cut into its floor)
   ==========================================================================

   A rail is a machined CHANNEL — a shallow recessed track milled into the face
   it sits on — whose selected item is a SEAT: a SECOND, DEEPER POCKET cut into
   the channel's own floor, like a detent. The seat has a DARKER floor than the
   channel, its own finer lip, and the label ink brightened to hold contrast.
   This is the sub-nav idiom — the recessed rail that holds the selected item.
   Ported from the study's rail ("The rail — a channel with a seat cut into its
   floor", historical v16 record) on the canonical `--ev-*` tokens, and MEASURED off
   that render — the geometry below is the study's actual values, not a brief.
   (cortex-38ynluu / promote-the-rail, epic cortex-pzakjzf.)

   THE RAIL vs THE SEGMENTED CONTROL — same family, opposite seat direction
   -----------------------------------------------------------------------
   Both are "a channel with a seat", but the seat moves the OTHER WAY:

     .ev-segmented   the seat comes UP — a raised, accent-lit pressed key that
                     has travelled DOWN under the channel's arris (a control:
                     one live segment, hue = live). Liveness is FINISH.
     .ev-rail        the seat goes DOWN — a deeper achromatic detent pocket cut
                     into the channel floor (navigation: the current section is
                     a place you have settled INTO). NO accent; the current item
                     is not "live", it is WHERE YOU ARE. Depth is nesting.

   The rail is therefore an INSET seat, not a proud one — this is deliberately
   the study's construction, which the segmented control (a control, not a
   nav) reinterpreted as a raised key. A recessed detent is the honest
   fabrication story for "the section you are inside".

   WHY THIS SHAPE, IN THE CHANNEL LANGUAGE
   ---------------------------------------
     Rim / lip weight  → nesting rank. The channel is a cut into the host face,
       so it takes rank-2 shading (finer than a rank-1 panel). The seat is a cut
       inside the channel, so inverted nesting keeps its side-wall LINE finer
       still (rank-3) — but its lip/wall SHADING is promoted to rank-2 because a
       detent is a real pocket floor, not a scribe, and needs the depth to read.
     Floor luminance   → nesting depth. Channel floor at --ev-floor-n1; the seat
       floor is a further rung DOWN (--ev-rail-seat, darker than the channel),
       because the seat genuinely descends into the floor. The step is held to a
       small swing so it reads as a deeper pocket in one surface, not a second
       material lying on top.
     Finish            → liveness. Not used here: a nav rail has no live/inert
       axis. Every part is polished metal.
     Hue               → NOT used. A rail carries no accent — "where you are" is
       nesting depth + ink brightness, not the interactive hue.

   THE ONE MATERIAL EVENT PER PART (per-side cut audit, required by CLAUDE.md):
     .ev-rail             the CHANNEL. Cut on all four sides EXCEPT the top
                          arris, which is drawn by ::after so it paints ABOVE the
                          seat (an inset ring on the channel would paint UNDER
                          its children and the seat would cover it — the exact
                          break the study's v13 fixed). Rank-2 inset.
     .ev-rail::after      the channel's TOP arris only. One side. A border, not a
                          spread ring, so it is structurally incapable of leaking
                          onto the three sides it did not cut.
     .ev-rail__item       unselected: NOT drawn (no fill, no shadow). A label
                          lying on the channel floor. Fix-by-removal.
     .ev-rail__item--selected   the SEAT. A deeper pocket cut into the channel
                          floor: darker floor + rank-3 side-wall line + rank-2
                          lip/wall shading. Inset from the channel's left/right
                          walls so surviving channel floor reads around it (a
                          detent SEATED in the track, not a slab abutting the
                          walls). Rounded on all four corners — it is a pocket
                          milled INTO the floor, so a round tool left its radius.

   INVARIANT L1 (symmetric axial light): every shadow here is zero-offset — the
   seat's depth is carried by inset lip/wall blur (the same physics as
   --ev-r*-lip), never by a y-offset.
   ========================================================================== */

.ev-rail {
    /* The seat's inset from the channel's left/right walls — surviving channel
       floor reads around the detent so it seats WITHIN the track rather than
       spanning it wall-to-wall. This composes the same measured seat inset as
       the lobe's sprung sockets inside their keyplate cut. */
    --ev-rail-seat-inset: var(--ev-seat-inset);
    /* The seat floor — a rung DARKER than the channel floor (--ev-floor-n1), so
       the detent reads a further cut down. The swing is deliberately small
       (well under the metal-hi→n1 step) so it reads as a deeper pocket within
       one surface, not a second material. Light + dark, both achromatic (L4).
       --ev-rail-seat and its dark mirror now live in tokens.css: the Bootstrap
       adapter paints .nav-pills as this same rail and cannot reach a
       component-local property (cortex-wp0qzvk). Consumed below, not declared. */

    display: inline-flex;
    align-items: stretch;
    justify-content: flex-start;   /* packed left — bare channel to the right
                                      reads as track, not a row of cells. */
    gap: 0;
    position: relative;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-radius-sm);
    color: var(--ev-ink);
    /* The channel's cut: rank-2 lip + wall + rim. NO four-sided --ev-r2-line
       inset ring — its top run moves to ::after so the arris paints ABOVE the
       seat; the other three runs are covered by the lip falloff and the rim,
       and re-stating them here would double-draw the top pixel (study v13). */
    box-shadow:
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
    /* Clip the seats to the channel's own rounded box so a seat never overflows
       the cut. The seat is inset well within this, so the clip only guards the
       channel's rounded corners. */
    clip-path: inset(0 round var(--ev-radius-sm));
    transition: var(--ev-transition-fast);
}

/* The channel's TOP arris — one continuous hard cut edge along the channel's
   top row, unbroken across the seat. A cut's own edge does not stop where a
   seat sits in it. Painted here (z above the seats) rather than as the
   channel's own inset ring, because an inset shadow on a parent paints UNDER
   its children and the seat would cover it. ONE side only — a border, not a
   ring — so it cannot leak onto uncut sides. */
.ev-rail::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 0;
    border-top: 1px solid var(--ev-cut-edge);
    z-index: 3;
    pointer-events: none;
}

/* ---- the items -----------------------------------------------------------
   An unselected item is NOT drawn: no background, no shadow. It is a label
   lying on the channel floor, per the study's rail measurement — the visible
   track between labels is what reads as a channel. Fix-by-removal: painting an
   unselected item would draw a cut where no material was removed. */
.ev-rail__item {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    margin: 0;
    background: none;
    color: var(--ev-ink-dim);
    font: 500 var(--ev-btn-font-sm)/1 var(--ev-font-sans);
    letter-spacing: 0.005em;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    position: relative;
    flex: 0 0 auto;
    /* The visible band: pad above/below the label sets the shallow track
       height; the horizontal pad sizes each item. Content-sized (not flex:1)
       so bare channel remains between short labels and reads as track. */
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-md);
    transition:
        color 0.12s ease,
        box-shadow var(--ev-transition-fast);
}

/* A hovered unselected item wakes toward full ink — a finish event on the
   label, not a material one (no fill appears). */
.ev-rail__item:hover:not(.ev-rail__item--selected):not(:disabled) {
    color: var(--ev-ink);
}

.ev-rail__item:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: -2px;
    z-index: 4;
}

/* ---- THE SEAT (selected): a deeper detent pocket cut into the channel floor -
   The current item. A second, deeper pocket cut into the channel's own floor:
   a darker floor (--ev-rail-seat, a rung below --ev-floor-n1), a rank-3 side
   wall LINE (finer than the channel, per inverted nesting — the seat lives
   inside the channel), and rank-2 lip + wall SHADING (a real pocket floor, not
   a scribe — this is what carries "deeper"). Inset from the channel's left and
   right walls by --ev-rail-seat-inset via margin, so surviving channel floor
   reads around it and it seats WITHIN the track. Rounded on all four corners:
   a pocket milled into the floor legitimately shows the tool's radius (unlike
   the segmented seat, which is a key SLIDING under the arris and so has no top
   corner). The label ink brightens to --ev-ink to hold contrast on the darker
   floor. NO accent — a rail is navigation, not a control. All layers
   zero-offset (Invariant L1). */
.ev-rail__item--selected {
    color: var(--ev-ink);
    font-weight: 600;
    background-color: var(--ev-direct-carve-floor, var(--ev-rail-seat));
    /* The floor gradient: shading WITHIN one surface (not a second surface).
       Amplitude held well under the seat/channel step, per the study. */
    background-image:
        linear-gradient(var(--ev-swoop-angle),
            var(--ev-lum-lo) 0%,
            transparent 55%,
            var(--ev-lum-hi) 100%);
    background-repeat: no-repeat;
    margin: var(--ev-rail-seat-inset);
    /* Follow the channel's inner rim (channel radius minus the inset). */
    border-radius: calc(var(--ev-radius-sm) - var(--ev-rail-seat-inset));
    /* The cut stack: rank-3 side-wall LINE (finer than the channel), rank-2
       lip + wall SHADING (the depth). No rim — a --ev-r*-rim is an OUTER bright
       burr, and this box sits inside the channel where its top run would ride
       un-cut channel arris (the study's v12/v13 correction). */
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
    z-index: 1;
}

/* The selected item is where you are, so its ink and depth stay fixed. A quiet
   symmetric polish line still acknowledges the pointer; selection does not
   excuse an otherwise inert clickable surface. */
.ev-rail__item--selected:not(:disabled):not(.ev-rail__item--disabled):hover {
    color: var(--ev-ink);
    box-shadow:
        inset 0 0 0 1px var(--ev-edge-glow),
        var(--ev-r3-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
}

/* ---- disabled — oxidized finish = inert (never a floor move) ------------- */
.ev-rail__item:disabled,
.ev-rail__item.ev-rail__item--disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* ---- size scale ----------------------------------------------------------
   Default is a shallow sm-height band (a rail is chrome, lighter than the
   md-height segmented control). --lg steps the band up one rung; the seat
   inset comes with it so the detent proportion holds. */
.ev-rail--lg .ev-rail__item {
    font-size: var(--ev-btn-font-md);
    padding: var(--ev-btn-pad-y-md) var(--ev-btn-pad-x-lg);
}
.ev-rail--lg { border-radius: var(--ev-radius-md); }
.ev-rail--lg .ev-rail__item--selected {
    /* Large standalone rails deliberately step beyond the shared entity-header
       / lobe inset; keep that size override local to this modifier. */
    --ev-rail-seat-inset: 4px;
    border-radius: calc(var(--ev-radius-md) - var(--ev-rail-seat-inset));
}

/* ---- full-width — items share the track equally -------------------------- */
.ev-rail--fill { display: flex; width: 100%; }
.ev-rail--fill .ev-rail__item { flex: 1 1 0; }

/* ==========================================================================
   .ev-rail--band — one channel for destinations and seated actions
   ==========================================================================
   This is the narrow, named exception to "raised only on raised". A shallow
   purpose-built seating channel may carry a raised key only in its declared
   action land: `.ev-rail__actions` preserves one full --ev-seat-inset around
   the key, and the key's contact shadow visibly plants on that floor. The key
   remains its canonical neutral / primary / danger material; converting it to
   a detent would erase the pressable raised affordance, while socket conversion
   belongs to the deeper keyplate construction. This does NOT license a raised
   control in an arbitrary carve or empty-state void.

   One part, one cut: the band IS the existing rail channel. The nested track
   and action land add no floor, shadow, or border. The track alone scrolls, so
   crowded destinations remain reachable while actions stay seated. The band
   deliberately removes the base rail's clip: the 3px seat inset guards its
   corners, focus outlines remain visible, and a menu opened from the action
   land may escape the shallow channel instead of being guillotined by it. */
.ev-rail--band {
    display: flex;
    width: 100%;
    min-width: 0;
    min-height: calc(var(--ev-btn-height-sm) + 2 * var(--ev-seat-inset));
    overflow: visible;
    clip-path: none;
}

.ev-rail--band .ev-rail__track {
    display: flex;
    align-items: stretch;
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scrollbar-width: thin;
}

.ev-rail--band .ev-rail__actions {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    gap: var(--ev-seat-inset);
    margin: var(--ev-seat-inset);
    position: relative;
    z-index: 4;
}

/* A key seated inside the band is geometrically subordinate to that band.
   Derive its corner from the host curve and the surviving floor inset instead
   of mixing the key scale's freestanding pill radius into a tighter channel. */
.ev-rail--band .ev-rail__actions .ev-key {
    border-radius: calc(var(--ev-radius-sm) - var(--ev-seat-inset));
}

/* The action slot is the exception boundary. A raised key anywhere else in the
   scrolling lane would again be an unsupported block in a cut, so it flattens
   to the existing ghost-key reading rather than silently expanding the rule. */
.ev-rail--band .ev-rail__track .ev-key {
    background: transparent;
    color: var(--ev-accent-text);
    box-shadow: none;
}
.ev-rail--band .ev-rail__track .ev-key:hover,
.ev-rail--band .ev-rail__track .ev-key:active {
    background: transparent;
    box-shadow: none;
}

/* ==========================================================================
   .ev-rail--header — the ENTITY-HEADER rail (the study's thicker bevel)
   ==========================================================================
   The plain .ev-rail is chrome sitting on a page: a shallow, FINE (rank-2)
   channel. The study's rail lives in a different place — it is milled into the
   LOWER band of the entity header, a heavier molded slab, so its channel is cut
   into a THICKER host and reads with a heavier bevel accordingly. The founder's
   note: the plain rail is "another kind of rail, without the thicker bevel …
   as in the study." This variant restores it.

   What "thicker bevel" is, materially: the channel's own walls are promoted one
   rung of shading weight (rank-1 lip + wall over the rank-2 line), so the cut
   reads deeper and the bevel around it reads thicker — matching the study's
   entity-header channel, which is a cut into the header's own outermost chamfer
   (a thicker part) rather than a cut into a thin chrome strip. The seat
   (selected) and the top-arris construction are UNCHANGED — only the channel's
   bevel weight steps up, so the rail's identity (an inset detent, achromatic)
   is preserved. Fill by default (the header rail spans its band).

   MEASURED (study entity-header rail): band ~38px of a 181px card (~21%); items
   packed left with bare channel to the right reading as track; item pad --s-3
   (12px) vertical / --s-5 (20px) horizontal; channel top corners --r-sm (10px),
   bottom open (runs off the band). We reproduce the band height + the packed-
   left proportion; the open bottom is a header-band composition detail shown in
   the entity-header demo (the rail band clips its channel's overshoot). */
.ev-rail--header {
    display: flex;
    width: 100%;
    /* the thicker bevel: rank-1 lip + wall over the rank-2 top line, plus the
       rank-2 outer rim. A deeper cut into a thicker host. */
    box-shadow:
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r2-rim);
    /* the header band's channel corners: only the TOP is radiused (an endmill
       entering the material); the bottom runs open in the header composition. */
    border-radius: var(--ev-radius-md) var(--ev-radius-md) 0 0;
    clip-path: inset(0 round var(--ev-radius-md) var(--ev-radius-md) 0 0);
}
.ev-rail--header .ev-rail__item {
    /* the study's band proportion: --s-3 (12px) above/below the label lands the
       rail on ~38px, and --s-5 (20px) horizontal packs items content-sized. */
    padding: 12px 20px;
    font-size: var(--ev-btn-font-sm);
}
/* the seat, in the thicker host, follows the header channel's inner radius */
.ev-rail--header .ev-rail__item--selected {
    border-radius: calc(var(--ev-radius-md) - var(--ev-rail-seat-inset)) calc(var(--ev-radius-md) - var(--ev-rail-seat-inset)) 0 0;
}

/* ==========================================================================
   Dark theme — the seat floor mirrored.
   ==========================================================================
   The dark value is NOT the light one inverted (light channel→seat swing ~19
   units, dark ~11, because dark floors have far less headroom to darken into).
   Both values moved to tokens.css alongside the rest of the per-theme material
   layer when the adapter began painting .nav-pills as this rail
   (cortex-wp0qzvk); the rail consumes --ev-rail-seat and the theme block in
   tokens.css supplies it, so this file no longer needs a dark override. */

/* ===== src/components/viewer.css ===== */
/* ==========================================================================
   Evident opinionated component — document viewer surface
   ===========================================================================

   A document is the page's subject, so this is a ROUTE SURFACE, never an
   overlay. The server already knows the document URL and authors it directly
   into an <object>; the correct first render and the object's native fallback
   therefore exist without JavaScript. No elapsed-time guess chooses between
   them, and the fallback persists for as long as it is actionable.

     .ev-viewer              raised document-work surface
     .ev-viewer__bar         composes .ev-rail.ev-rail--band for title/actions
     .ev-viewer__document    composes .ev-aperture around the native object
     .ev-viewer__fallback    composes .ev-empty-state inside that object

   MATERIAL DECISION — BARE APERTURE, NOT GLASS
   ------------------------------------------------
   The reading window deliberately does NOT compose `.ev-glass`. Glass is the
   sanctioned part for look-at content, but its optical signature is a glint
   plus an under-pane scrim. The 3x branch comparison crops show the same paper
   bare (blob:9887317b52844cb8c038f37d4a289dd09e38ffc0c7fbea8ee36c4a065f924508)
   and under the rejected lens
   (blob:cab8b99331a3f6393664eae5580b70f4438bc0e5629d3bb257eeda4a2baca495):
   a white centre pixel falls from RGB 255/255/255 to 231/231/231, while the
   sampled paper region falls from mean RGB 248.3 to 225.0 and the glint crosses
   readable content. That is not a harmless frame: it impairs the channel it
   carries. The rejected lens therefore stays out of both the public selector
   and the demo markup. The rank-1 aperture supplies the whole fabrication
   story.

   GEOMETRY
   --------
   This is the same complete housing relationship already measured for the
   entity-header slab: a 28px shell with a 9px surviving rim leaves a 19px
   concentric reading aperture. The top band and document edges share that
   inner radius, and the bar's title and action seats align with the aperture.
   No new dimensional value or colour is coined here: every measurement and
   every paint layer composes an existing Evident carrier.
   ========================================================================== */

.ev-viewer {
    --ev-viewer-document-height: calc(var(--ev-btn-height-xl) * 12);
    --ev-direct-carve-floor: var(--ev-raised-carve-floor);

    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    gap: var(--ev-entity-header-rim-width);
    min-width: 0;
    padding: var(--ev-entity-header-rim-width);
    color: var(--ev-ink);
    background-color: var(--ev-metal-hi);
    border-radius: var(--ev-entity-header-shell-radius);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-shoulder-2),
        var(--ev-shoulder-3),
        var(--ev-contact-2),
        var(--ev-ambient-2);
}

/* The bar IS the shipped action band. This selector owns only its fit in the
   viewer shell; .ev-rail--band continues to own the channel, scrolling track,
   sanctioned action land, key seating, and focus/menu escape contract. */
.ev-viewer__bar.ev-rail--band {
    border-radius: calc(
        var(--ev-entity-header-shell-radius) -
        var(--ev-entity-header-rim-width)
    );
}

/* The viewer housing already supplies the bar's complete upper boundary. The
   rail's standalone top arris would draw a second dark cut across that intact
   shoulder, so remove that one redundant material event in this composition. */
.ev-viewer__bar.ev-rail--band::after {
    content: none;
}

.ev-viewer__bar .ev-rail__track {
    align-items: center;
    gap: var(--ev-seat-inset);
    padding-inline: var(--ev-btn-pad-x-sm);
    color: var(--ev-ink);
}

/* A document is a major window cut into a complete raised housing, not a small
   lens bezel. Rank-2 produced only a shallow four-step tone change on the
   raised stock; rank-1 wall shading is what makes the removal legible while
   the contextual floor stays achromatic and close to its parent face. */
.ev-viewer__document.ev-aperture {
    block-size: var(--ev-viewer-document-height);
    min-block-size: var(--ev-btn-height-xl);
    border-radius: calc(
        var(--ev-entity-header-shell-radius) -
        var(--ev-entity-header-rim-width)
    );
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
}

.ev-viewer__document > object {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    border: 0;
    background: transparent;
}

/* Native <object> fallback content is real initial markup. Composing the
   shipped empty state gives an unframable document the correct persistent,
   actionable carved-void treatment without a loader, timer, or JS branch. */
.ev-viewer__fallback.ev-empty-state {
    box-sizing: border-box;
    block-size: 100%;
    border-radius: inherit;
}

/* ===== src/components/boss.css ===== */
/* ==========================================================================
   Evident component — the boss (a lobe of un-cut land) + the keyplate
   ==========================================================================

   THE BOSS / LOBE — the vocabulary, verbatim from the study
   ---------------------------------------------------------
   A boss is "a localized thickening of un-cut land, left behind because the
   surrounding pocket detours AROUND it — not material added, material NOT cut
   away, which is why raised keys may legally sit on it." It is the answer to
   the question every prior action-placement concept could not answer — WHAT
   HOLDS IT UP — because nothing is added: the rim simply swells inward and the
   keys sit in the swelling. The legality question therefore never arises.

   Ported from the Evident v16 study's entity-header boss and keyplate,
   specifically "The rail — a channel with a seat cut into its floor". The
   study realises the lobe as a DETOUR in the rim
   band's pocket clip-path (a `shape()` that goes around the lobe region), which
   leaves the lobe as a region of the card's own un-cut face. This library
   component reproduces the SAME material reading with a robust, build-free
   technique: the boss is a RAISED land carrying its own molded shoulder (the
   swell) over a face that reads continuous with the host, and the keyplate is a
   recessed strip cut INTO that raised land. Colour/luminance comes entirely
   from `--ev-*` tokens; the GEOMETRY below is measured off the study render.

   MEASURED STUDY GEOMETRY (light theme, off the render; tokens at study :root)
   ---------------------------------------------------------------------------
     lobe swell / rim band width   9px  (--rim-w — "the thicker bevel")
     lobe bottom from card edge   40px  (lobe_bottom = key + 2c_plate + 2c_lobe)
     keyplate height              32px  (--kp-h  = key 26 + 2 * c_plate 3)
     keyplate radius               6px  (--kp-r  = --r-sm 10 - --kp-inset 4)
     keyplate readable band        4px  (--kp-inset — lobe land AROUND the plate)
     keyplate inner pad            3px  (--kp-pad — c_plate, room for the groove)
     key height                   26px  (--kp-key-h — leaves the button scale)
     key radius                    6px  (blessed sprung-socket silhouette)
     key side padding             13px  (--kp-key-px)
     key gap                       3px  (--kp-gap = --kp-pad, close-set)
     key ink                    10.5px  (= --btn-f-xs; scale ink kept)
   Floors (three-rung ladder, monotonic ceiling / L6): un-cut lobe face is the
   host --ev-metal-hi; the keyplate floor is --ev-floor-n2 (a cut within the
   land), one rung down. The 3px socket-to-plate-wall distance is the shared
   --ev-seat-inset measured from the rendered entity-header rail; the separate
   4px boss land remains visible outside the plate. Every rung strictly darker
   than the face cut into it.

   PER-SIDE CUT AUDIT (required by CLAUDE.md)
   -----------------------------------------
     .ev-boss        the SWELL. Draws a molded shoulder (rank-1 lip + a bright
                     crest) — a raised land, NOT a cut. No cut edges: a boss is
                     un-cut material, so the "edge where no material was removed"
                     defect is structurally unreachable (nothing is cut here).
     .ev-boss__plate the KEYPLATE. A pocket cut into the raised land, on ALL
                     four sides (a recessed strip): rank-2 line + lip + wall,
                     floor one rung down (--ev-floor-n2). This is the one
                     material event on the boss.
     .ev-boss__plate .ev-key
                     the keys are rigid sprung SOCKETS seated in the plate:
                     bounded dark hardware that travels into the cut on press.

   INVARIANT L1 (symmetric axial light): every shadow here is zero-offset — the
   swell's roundness and the plate's depth are carried by inset/spread blur, the
   same physics as --ev-r*-lip, never by a y-offset. INVARIANT L4 (achromatic):
   R=G=B at rest. INVARIANT L6 (monotonic ceiling): the lobe face never rises
   above the host --ev-metal-hi.

   RESPONSIVE CONTRACT
   -------------------
   Put `.ev-boss__host` on the entity-header slab that contains the boss. It is
   the named INLINE-SIZE query container: the header's actual available width,
   not the viewport and not the content-sized boss, decides whether lobe labels
   fit. Wrap each removable legend in `.ev-key__label`; keep the glyph in
   `.ev-key__glyph` (or an SVG). At 460px and below only the label is removed,
   so the same server-rendered markup becomes icon-only without JavaScript.
   ========================================================================== */

/* THE HOST, not the boss, owns size containment. Applying inline-size
   containment to `.ev-boss` itself would zero the intrinsic contribution of
   its content-sized inline-flex box and collapse the lobe. The containing
   entity-header slab already has a real constrained width, so it is the honest
   measurement surface for the cramped decision. */
.ev-boss__host {
    container-type: inline-size;
    container-name: ev-boss-host;
}

.ev-boss {
    --ev-direct-carve-floor: initial;
    /* The molded swell: how far the raised shoulder rolls before it meets the
       plate. Matches the study's 9px rim-band width — this is "the thicker
       bevel" the plain rail was missing. Named once so it tunes in one place. */
    --ev-boss-swell: 9px;
    /* The readable lobe band AROUND the keyplate (study --kp-inset). Kept so the
       keyplate never runs to the swell's edge — otherwise "it's not visible that
       there is a lobe at all" (the founder's own v16 note). */
    --ev-boss-land: 4px;

    display: inline-flex;
    align-items: center;
    gap: var(--ev-boss-land);
    flex: 0 0 auto;
    position: relative;
    box-sizing: border-box;
    /* The raised land's own padding is the readable lobe band: surviving un-cut
       land shows around the plate on every side. */
    padding: var(--ev-boss-land);
    border-radius: var(--ev-radius-md);

    /* THE SWELL — a raised, molded shoulder. The lobe face is the host's own
       --ev-metal-hi with the axial swoop, and the roll is a rank-1 crest (the
       bright arris where the swell meets the surrounding land) plus a soft
       shoulder falloff. This is what makes the boss read as PROUD land rather
       than as a flat patch — a localized thickening, lit on its crown. */
    background-color: var(--ev-metal-hi);
    background-image:
        linear-gradient(var(--ev-swoop-angle),
            var(--ev-lum-hi) 0%,
            var(--ev-lum-mid) 42%,
            transparent 72%,
            var(--ev-lum-lo) 100%);
    background-repeat: no-repeat;
    box-shadow:
        /* the crown light — the swell catches the axial light on top */
        var(--ev-shoulder-lite),
        /* the roll onto the surrounding land: soft, wide, no hard edge */
        var(--ev-shoulder-1),
        var(--ev-shoulder-2),
        /* the bright crest at the swell's outer arris — 1px, the brightest line
           on the boss, the "raised" tell. A spread ring (proud), never inset. */
        var(--ev-r1-rim),
        /* the swell plants on the land — a soft contact, zero-offset */
        var(--ev-ambient-1);
    z-index: 1;
}

/* An empty boss is not a boss — a swell exists to provide land for a feature,
   so with nothing to carry it collapses entirely and the rim runs straight (no
   empty bulge, no gap artefact in the header's title row). Fix-by-removal. */
.ev-boss:empty { display: none; }

/* ---- THE KEYPLATE — a recessed strip cut into the raised land -------------
   A pocket milled into the boss: floor one rung below the lobe face
   (--ev-floor-n2), with the three-layer cut stack every pocket in the study
   uses — line (the wall's top arris), lip (the wall turning down), wall (the
   falloff onto the floor). Rank-2, matching the key's own groove: this cut and
   the key's cut are the same depth of operation on the same part. Cut on all
   four sides (a real recessed strip, unlike the boss which cuts nothing). */
.ev-boss__plate {
    display: inline-flex;
    align-items: center;
    gap: var(--ev-boss-plate-gap, var(--ev-seat-inset));
    padding: var(--ev-seat-inset);
    box-sizing: border-box;
    border-radius: calc(var(--ev-radius-md) - var(--ev-boss-land));
    background-color: var(--ev-floor-n2);
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
    position: relative;
    z-index: 1;
}

/* A keyplate with no keys is not a plate — same reasoning as the empty boss one
   level up: it collapses so the empty case leaves no recessed strip sitting in
   the land with nothing in it. */
.ev-boss__plate:empty { display: none; }

/* THE SPRUNG SOCKET IN THE PLATE. The 26px height, side padding and ink size
   retain the measured keyplate geometry, outside the general button scale.
   The founder's 2026-07-28 amendment supersedes the generic keys.css material
   and derived 3px radius here: every lobe action wears the bounded 6px socket
   silhouette.

   The fabrication story licenses motion that the generic key forbids. This is
   a discrete BUTTON ON A SPRING: the whole rigid part travels 2px into its
   bounded seat, while its silhouette stays fixed and its proud contact shadow
   disappears. Its tokenised material follows the host theme. */
.ev-boss__plate .ev-key {
    height: 26px;
    min-height: 26px;
    padding: 0 13px;
    border-radius: var(--ev-socket-radius);
    font-size: var(--ev-btn-font-xs);
    gap: 6px;
    color: var(--ev-socket-ink-dim);
    background-color: var(--ev-socket-face);
    background-image: var(--ev-socket-body);
    background-repeat: no-repeat;
    box-shadow:
        var(--ev-socket-top),
        var(--ev-socket-edge),
        var(--ev-socket-groove),
        var(--ev-socket-contact);
    transform: translateY(0);
    transition:
        transform var(--ev-press-out) var(--ev-press-out-ease),
        box-shadow var(--ev-press-out) var(--ev-press-out-ease),
        color 120ms ease;
}
.ev-boss__plate .ev-key:not(:disabled):not(.ev-key--disabled):hover {
    color: var(--ev-socket-ink);
}
.ev-boss__plate .ev-key:active,
.ev-boss__plate .ev-key.is-pressed {
    color: var(--ev-socket-ink);
    background-color: var(--ev-socket-face);
    background-image: var(--ev-socket-pressed);
    box-shadow:
        var(--ev-socket-edge),
        var(--ev-socket-pressed-depth);
    transform: translateY(2px);
    transition:
        transform var(--ev-press-in) var(--ev-press-in-ease),
        box-shadow var(--ev-press-in) var(--ev-press-in-ease),
        color 120ms ease;
}
.ev-boss__plate .ev-key svg,
.ev-boss__plate .ev-key .ev-key__glyph { width: 12px; height: 12px; }

/* A cramped lobe is ICON-ONLY. The hook is semantic rather than positional:
   only the removable legend disappears, never the glyph, and generic keys
   outside a boss are untouched. Authors should retain the label as the
   button's `aria-label`, because display:none removes this span from the
   accessibility tree along with the visual layout. With every surviving glyph
   fixed at 12px and every socket retaining the same 13px side padding, all
   cramped actions resolve to one silhouette rather than icon/text variants. */
@container ev-boss-host (max-width: 460px) {
    .ev-boss__plate .ev-key__label {
        display: none;
    }
}

/* ==========================================================================
   Dark theme — the swell mirrored.
   ==========================================================================
   The lobe face and the keyplate floor both key off the shared --ev-metal-hi /
   --ev-floor-n2 tokens, which the dark block already remaps, so the swell and
   the pocket track the theme for free. The crest (--ev-r1-rim) and shoulder
   stack are likewise token-driven — in dark the swell reads proud by a bright
   crest against darker land, the same construction inverted (L4 preserved).
   The socket face is token-driven and mirrors with its host: light stock on
   the light swell, dark stock on the dark swell.
   ========================================================================== */

/* ===== src/components/switch.css ===== */
/* ==========================================================================
   Evident component — the on/off switch (track + travelling knob)
   ==========================================================================

   A switch is a real material event: a KNOB — a raised, cast boss — that
   TRAVELS along a milled CHANNEL. Two planes, stated honestly:

     TRACK  (.ev-switch__track)  — MACHINED. A pill-shaped channel cut into the
                                    face the switch sits on. Lip, wall, floor,
                                    inset shadow. Reads RECESSED. It is the
                                    housing the knob rides in.
     KNOB   (.ev-switch__knob)   — MOLDED. A cast boss with a shoulder roll and
                                    a tight seat-contact seam. Reads as a real
                                    part contained by the cut, and slides.

   The knob is a real moving part SEATED IN the channel, not a raised part on an
   open face. Its 20px face is contained by the 26px track with 3px of carved
   floor on every block side; no shoulder reaches either raised lip. Therefore
   its outer seam is `--ev-seat-contact`, the same contact-only treatment as a
   segmented seat. An open-face contact + ambient pair would spend its 14px
   throw on a 3px runway and wash the light floor while disappearing on dark.
   (L1 — every shadow stays zero-offset.)

   THE CHANNELS carry the meaning, one each (Invariant 2):
     - GEOMETRY  (knob position)  — the state: seated LEFT = off, RIGHT = on.
     - FINISH    (track polish)   — LIVENESS. off = oxidized/read-only channel,
                                    on = polished, live.
     - HUE       (--ev-accent)    — live/active ONLY. The ON channel floor lights
                                    to the accent as an INDICATOR fill (legal,
                                    exactly like .ev-pocket--check:checked — an
                                    indicator, not a material face). OFF carries
                                    no hue at all: pure achromatic milled metal.

   Nothing is depicted that is not there: the knob's travel is a translate along
   the channel axis (a part sliding IS lateral motion, so lateral motion is
   honest here — unlike a press, which must not translate). The channel does not
   move; only the part in it does.

   States: off / on / hover / :active (knob seats deeper) / disabled / focus.
   Size variant: --sm. Both themes via the shared --ev-* dark mirror.

     .ev-switch              the control (label wrapper, click target)
     .ev-switch__track       the milled channel (machined)
     .ev-switch__knob        the travelling cast boss (molded)
     .ev-switch--on          knob travelled right, channel accent-lit / live
     .ev-switch--sm          the compact size variant
     .ev-switch--disabled    oxidized, inert, not-allowed
     .ev-switch__label       an optional adjacent flat text label
   ========================================================================== */

.ev-switch {
    /* Geometry is named once and every part derives from it (compose, don't
       inline: the knob diameter, the travel distance and the padding are all
       functions of the track height, so the boss can never drift off the
       channel). Default (md) sizing. */
    --ev-sw-h: 26px;                                  /* track height */
    --ev-sw-w: 46px;                                  /* track width  */
    --ev-sw-pad: 3px;                                 /* land inset the knob rides within */
    --ev-sw-knob: calc(var(--ev-sw-h) - 2 * var(--ev-sw-pad));   /* knob diameter */
    --ev-sw-travel: calc(var(--ev-sw-w) - var(--ev-sw-h));       /* left seat -> right seat */

    display: inline-flex;
    align-items: center;
    gap: 0.55em;
    cursor: pointer;
    user-select: none;
    vertical-align: middle;
    -webkit-tap-highlight-color: transparent;
}

/* --------------------------------------------------------------------------
   THE TRACK — a machined channel. Pill-shaped rank-3 cut into the host face.
   OFF: achromatic milled floor, oxidized finish (read-only, inert). The floor
   sits at n1 (the deepest rung) because the channel is a genuine cut the knob
   drops into. Rank-3 SHADING keeps the lip tight — a channel is a fine cut,
   not a rank-1 panel. The inset shadow is the whole plane read: recessed.
   -------------------------------------------------------------------------- */
.ev-switch__track {
    position: relative;
    flex: 0 0 auto;
    width: var(--ev-sw-w);
    height: var(--ev-sw-h);
    border-radius: var(--ev-radius-pill);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    /* recessed: lip + wall + line, INSET only. No outer depth shadow — an
       inset+outer pair would claim cast-and-cut at once (core.css). */
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
    /* OFF is oxidized: the finish channel carries liveness, so a read-only
       channel reads dulled — a thin achromatic veil, no colour (core.css
       .ev-fin-oxidized). */
    filter: saturate(0.9) brightness(0.98);
    opacity: 0.92;
    transition:
        background-color var(--ev-transition-fast),
        box-shadow var(--ev-transition-fast),
        filter var(--ev-transition-fast),
        opacity var(--ev-transition-fast);
}

/* The channel floor's own curvature — a shallow centre sheen falling to the
   walls, exactly as .ev-machined::before draws a milled floor. NOT a grain:
   finish already means liveness, so a texture would be a third state. */
.ev-switch__track::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(120% 140% at 50% 50%,
            var(--ev-lum-mid) 0%,
            transparent      54%,
            transparent      80%,
            var(--ev-lum-lo) 100%);
}

/* --------------------------------------------------------------------------
   THE KNOB — a cast, raised boss that TRAVELS. Molded: shoulder roll + outer
   contact seam, so it reads as a real part rather than paint. Seated LEFT at
   rest (off). Its diameter is the track height minus the floor pad on each
   side: that arithmetic proves it is contained by the cut rather than bridging
   its lips. Motion is a lateral translate: a part sliding IS lateral motion,
   and that is the ONE honest place a translate belongs.
   -------------------------------------------------------------------------- */
.ev-switch__knob {
    --ev-direct-carve-floor: initial;
    position: absolute;
    top: var(--ev-sw-pad);
    left: var(--ev-sw-pad);
    width: var(--ev-sw-knob);
    height: var(--ev-sw-knob);
    border-radius: 50%;
    background: var(--ev-metal-hi);
    /* molded face + seated seam. The shoulder rolls dome the cast face; the
       tight contact-only seam occludes where that part meets the carved floor.
       There is deliberately no ambient throw inside this 3px runway. */
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-seat-contact);
    transform: translateX(0);
    transition:
        transform 160ms var(--ev-press-out-ease),
        background-color var(--ev-transition-fast),
        box-shadow var(--ev-transition-fast);
}

/* Hover rolls the cast face one shoulder step while retaining the same physical
   seat. Interaction does not teleport the knob out of its channel, so it does
   not earn the open-face contact/ambient pair. */
.ev-switch:not(.ev-switch--disabled):hover .ev-switch__knob {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-seat-contact);
}

/* :active — the part seats DOWN into its housing as you grab it: drop the
   outer falloff for the cut stack, exactly as .ev-key:active travels into the
   panel. No translateY; the seat is carried by the shadow swap, not a light. */
.ev-switch:not(.ev-switch--disabled):active .ev-switch__knob {
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

/* --------------------------------------------------------------------------
   ON — the knob has TRAVELLED to the right seat and the channel is LIVE.
   Geometry: translate the knob one full travel. Finish: the oxide veil lifts
   (polished = live). Hue: the channel floor lights to the accent as an
   INDICATOR fill — legal because it is an indicator of state, not a material
   face (same license as .ev-pocket--check:checked). The knob face stays
   achromatic cast metal; only the channel behind it carries the accent, so
   hue never leaks onto the raised part (which would read as painted metal).
   -------------------------------------------------------------------------- */
.ev-switch--on .ev-switch__track {
    background-color: var(--ev-accent);
    /* polished / live: veil lifted. */
    filter: none;
    opacity: 1;
    /* keep the recessed inset read; the accent-tinted inner shading uses the
       accent's own dark ink stack so the channel still reads carved, not flat
       paint. */
    box-shadow:
        var(--ev-acc-shoulder-1),
        var(--ev-acc-shoulder-2),
        var(--ev-acc-shoulder-3);
}

/* On the lit channel the floor-curvature sheen switches to the accent crown /
   shading pair so the milled-floor read survives the colour change. */
.ev-switch--on .ev-switch__track::before {
    background:
        radial-gradient(120% 140% at 50% 50%,
            var(--ev-acc-lum-hi) 0%,
            transparent      54%,
            transparent      80%,
            var(--ev-acc-lum-lo) 100%);
}

.ev-switch--on .ev-switch__knob {
    transform: translateX(var(--ev-sw-travel));
}
.ev-switch--on:not(.ev-switch--disabled):hover .ev-switch__knob {
    transform: translateX(var(--ev-sw-travel));
}
.ev-switch--on:not(.ev-switch--disabled):active .ev-switch__knob {
    transform: translateX(var(--ev-sw-travel));
}

/* --------------------------------------------------------------------------
   Focus — a finish event on the track lip, never a bloom (L4). The accent
   shows as a thin lit edge on the channel lip, exactly like .ev-pocket:focus.
   Keyboard-only via :focus-visible on the native control if present; the
   demo drives it on the wrapper for the visual.
   -------------------------------------------------------------------------- */
.ev-switch:focus-visible {
    outline: none;
}
.ev-switch:focus-visible .ev-switch__track,
.ev-switch__input:focus-visible + .ev-switch__track {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        inset 0 0 0 1px var(--ev-accent-edge);
}
.ev-switch--on:focus-visible .ev-switch__track,
.ev-switch--on .ev-switch__input:focus-visible + .ev-switch__track {
    box-shadow:
        var(--ev-acc-shoulder-1),
        var(--ev-acc-shoulder-2),
        inset 0 0 0 1px var(--ev-acc-edge-glow);
}

/* A visually-hidden native <input> keeps the control accessible and keyboard-
   operable without any JavaScript in the language (L: no JS). Consumers wire a
   real checkbox; the label wrapper is the paint. */
.ev-switch__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   DISABLED — oxidized and inert, on top of whatever on/off state it holds.
   Read-only finish (the oxide veil) plus not-allowed. The knob stops lifting.
   -------------------------------------------------------------------------- */
.ev-switch--disabled {
    cursor: not-allowed;
}
.ev-switch--disabled .ev-switch__track {
    filter: saturate(0.9) brightness(0.98);
    opacity: 0.7;
}
.ev-switch--disabled .ev-switch__knob {
    opacity: 0.82;
}

/* --------------------------------------------------------------------------
   An optional flat text label — sits on a solid control face, flat glyphs
   (L3), dim ink. Turns to full ink meaning "this is the live setting" is NOT
   encoded here (that would double-encode state onto ink); the label is just a
   name and stays neutral in both states.
   -------------------------------------------------------------------------- */
.ev-switch__label {
    font: 500 13px/1 var(--ev-font-sans);
    color: var(--ev-ink-dim);
    text-shadow: none;
}

/* --------------------------------------------------------------------------
   SIZE VARIANT — --sm. Only geometry changes; every part re-derives from the
   re-declared track height/width, so the boss stays centred in the channel.
   -------------------------------------------------------------------------- */
.ev-switch--sm {
    --ev-sw-h: 20px;
    --ev-sw-w: 36px;
    --ev-sw-pad: 2.5px;
}
.ev-switch--sm .ev-switch__label {
    font-size: 12px;
}

/* ===== src/components/readout.css ===== */
/* ==========================================================================
   Evident component — readouts
   ==========================================================================

   Two related things live here, both about displaying genuine MACHINE VALUES
   (ids, metrics, counts, hostnames) — mono is EARNED, Invariant L5 reserves it
   for real machine values, never decoration:

   1. The readout PRIMITIVE — a mono value on a machined well. Small, inline,
      key/value. Used inside panels and detail views.

        .ev-well             a machined well that CONTAINS controls / readouts
        .ev-carve-label      the label above the values — the shared in-carve
                             label role from typography.css, NOT a well-scoped
                             element (it replaced .ev-well__title; cortex-4fg3ps6)
        .ev-readout          a single mono machine value (key + value row)
        .ev-readout__label   the (sans) key
        .ev-readout__value   the (mono) value

   2. The readout CLUSTER (the "instrument cluster" / dashboard status grid) — a
      molded metal faceplate holding a responsive row of milled readout pockets,
      one big headline number each. The account/overview strip. De-scoped from
      a production dashboard's `.readout-cluster` / `.readout`
      (`src/css/layout-components.css`, committed 9d0bc6bd), reconciled onto the
      canonical `--ev-*` tokens — see the drift note on the cluster block below.

        .ev-readout-cluster            the molded faceplate (the plate)
        .ev-readout-cluster__cell      one milled readout pocket
        .ev-readout-cluster__value     the big mono number
        .ev-readout-cluster__unit      the split-off sans unit (GB, år, …)
        .ev-readout-cluster__label     the caption under the number

        .ev-readout-cluster__cell--interactive
                                      opt-in for a custom focusable cell host;
                                      a link or a button opts in by native
                                      semantics. An interactive cell marks
                                      itself at rest — see "The INTERACTIVE
                                      cell" below.

      The cluster has TWO CELL TREATMENTS, selected by a modifier on the block:

        (default)                     FLAT — a shallow milled pocket, flat ink.
        .ev-readout-cluster--lit      LIT  — a milled aperture with a glass
                                      insert over a smoked display substrate,
                                      and a value that luminates.

      The plate is identical either way, so the modifier changes nothing at the
      block level and lives with the glass material that defines it:
      src/components/glass.css § PIECE 1. It shipped as a separate "instrument"
      block until cortex-v41smw1 consolidated it here; that block's five removed
      names are listed in docs/removed-names.tsv.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The readout primitive — mono value on a machined well.
   -------------------------------------------------------------------------- */

.ev-well {
    /* A machined well that HOLDS content — reset the bench-floor override so the
       well uses the floor ladder; otherwise, shown on the bench, it collapses to
       the near-black bench floor in dark (regression fix, cortex-a2ca9mx). */
    --ev-direct-carve-floor: initial;
    /* Named because the in-carve label's margin has to subtract it — the grid
       supplies part of the air under the title, and the two must add up to
       --ev-carve-label-gap exactly. A bare 0.4rem in two places would drift. */
    --ev-well-row-gap: 0.4rem;
    /* Two-column key/value grid: a single VALUE COLUMN shared by every readout
       row, so the values line up under each other regardless of how wide each
       key is. Column 1 sizes to the widest label (max-content); column 2 is the
       value column and takes the rest. The `.ev-readout` rows use
       `display:contents` (below) so their label/value drop straight into THIS
       grid — one column axis for the whole well, not a per-row flex gap that
       let every value start at its own x (the "values aren't aligned under each
       other" defect, cortex-jryapfc). */
    display: grid;
    grid-template-columns: max-content 1fr;
    align-items: baseline;
    column-gap: 0.75em;
    row-gap: var(--ev-well-row-gap);

    /* Padding IS the label gap here too: a well that carries a .ev-carve-label
       must have the same air above it as below it, and the air above is this
       padding. DECLARED, not merely consumed — the property inherits, so a well
       nested inside a tighter carve would otherwise take that carve's inset.
       (cortex-4fg3ps6) */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);
    padding: var(--ev-carve-label-gap);
    border-radius: var(--ev-radius-lg);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
    position: relative;
}

/* The well's title is an IN-CARVE LABEL — author `.ev-carve-label`, the same
   class the lip ranks and the baseplate captions use. It replaces the
   well-scoped `.ev-well__title`, which carried its own type (600 13px sans,
   sentence case) and so made the readout the one place in the library where a
   label inside a cut looked different from every other label inside a cut. One
   treatment across lip / readout / baseplate was the founder's ask
   (cortex-4fg3ps6); the old name is removed cleanly, no alias, and its row is
   in docs/removed-names.tsv (cortex-qairdc1).

   Two things the label cannot know about itself, so the well states them:
   the title is not a key/value row and must span BOTH columns; and part of the
   air below it is already supplied by the grid's own row-gap, so the label's
   margin carries only the remainder. Total below = margin + row-gap =
   --ev-carve-label-gap = the padding above. */
.ev-well > .ev-carve-label {
    grid-column: 1 / -1;
}

.ev-well > .ev-carve-label:not(:last-child) {
    margin-bottom: calc(var(--ev-carve-label-gap) - var(--ev-well-row-gap));
}

/* A readout row. Standalone (outside a well) it is its own two-column grid so a
   lone key/value still aligns its own value; inside a well it dissolves into the
   well's shared grid via `display:contents` so ALL rows share one value column. */
.ev-readout {
    display: grid;
    grid-template-columns: max-content 1fr;
    align-items: baseline;
    column-gap: 0.75em;
    padding: 0.2rem 0;
}

/* Inside a well, promote the label/value into the well's grid so every value
   aligns on the well's single value column (not each row's own). The row div
   itself carries no box, so its padding is dropped and the well's row-gap owns
   the vertical rhythm. */
.ev-well .ev-readout {
    display: contents;
}

.ev-readout__label {
    font: 500 12px/1.4 var(--ev-font-sans);
    color: var(--ev-ink-dim);
    /* left edge of the key column; grid tracks own the horizontal placement. */
    justify-self: start;
}

/* The value — mono, because it is a genuine machine value. Left-aligned in the
   value column (its left edge is the shared alignment line the founder wants);
   tabular-nums so numerals share one advance width and columns of digits line
   up vertically across rows. */
.ev-readout__value {
    font: 400 13px/1.4 var(--ev-font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--ev-ink);
    letter-spacing: 0.01em;
    justify-self: start;
    min-width: 0;
    word-break: break-all;
}

/* An accent readout value — accent as INK (a live/active value), not a face.
   Ink takes --ev-accent-text (the accent walked down a luminance step) because
   --ev-accent is a face value and fails AA as ink on light. (cortex-8jhd90a) */
.ev-readout__value--accent { color: var(--ev-accent-text); }

/* --------------------------------------------------------------------------
   2. The readout cluster — the machined instrument cluster / status grid.
   --------------------------------------------------------------------------

   Canonical reconciliation of a production dashboard source. It was iterated
   live against real operational data (cortex-nyd0flk); its
   `layout-components.css` copy uses application-local token aliases. Here it is
   rebased onto the canonical Evident
   `--ev-*` tokens that dist/evident.css ships. Application aliases resolve to:

     --radius-lg / --radius-md / --radius-sm   ->  --ev-radius-lg/md/sm
     --text-strong                             ->  --ev-ink
     --text-dim                                ->  --ev-ink-dim
     --text                                    ->  --ev-ink
     --accent                                  ->  --ev-accent

   Everything else (the faceplate swoop/molded stack, the rank-3 milled pocket,
   hover=finish, active=deeper-cut, the split mono-number + sans-unit) is CC's
   higher-fidelity construction carried over verbatim — that is the canonical
   version. Class names are de-scoped to the `.ev-*` public vocabulary and the
   value/unit/label carry explicit BEM slots so the library markup is
   self-contained (CC leaned on its private .stat-value / .stat-unit AJAX
   contract, which is a consumer concern, not part of the primitive). */

.ev-readout-cluster {
    --ev-direct-carve-floor: initial;

    /* The metal RIDGE between pockets — the gap that used to be each cell's
       3px margin, hoisted to the plate so it drives BOTH the flex gap and the
       flex-basis column math from one number. Defined once here (defaultable by
       a consumer via --readout-ridge) so the two can never drift: change the
       ridge and every column basis recomputes with it. */
    --readout-ridge: 6px;

    /* COUNT-AWARE, BALANCED/CENTERED responsive layout (cortex-ksxbiw7, folding
       in the CC-trunk doctrine of cortex-pb6k6j5). The plate is a centered flex
       wrap keyed to its OWN width — container queries, not viewport media —
       because a consumer's cluster sits inside a side-nav shell whose available
       width is not the viewport width.

       The invariant: every arrangement is BALANCED — a full row of equal tiles,
       or a centered short final row (the 2 in a 3+2) — never an orphan single
       tile stranded on its own row (no 5+1, no 4+1, no 2+1). This is achieved
       structurally, not with per-count wrap hacks:

         - flex, wrap, justify-content:center → rows center; a short final row
           sits centered under the row above it.
         - tiles are `flex: 0 1 <basis>` with NO grow, so a short final row
           keeps each tile at its column basis (the 2 in a 3+2 stay the same
           size as the 3 above them) instead of stretching to fill the row.
         - a FULL row still fills edge-to-edge because the basis is exactly
           calc((100% - (cols-1)*ridge) / cols) — N such tiles plus (N-1) ridges
           sum to 100%.
         - the column COUNT per breakpoint is chosen so the wrap only ever
           produces an allowed arrangement for that tile count (below).

       Base (this rule, OUTSIDE every @container) = the 1-col STACK. Container
       queries only ever WIDEN it, so anything narrower than the first threshold
       — and any consumer on an engine without container-query support —
       degrades gracefully to a single stacked column. --readout-cols defaults
       to 1 and each @container below overrides it for a given [data-count]. */
    container-type: inline-size;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--readout-ridge);
    --readout-cols: 1;

    /* The faceplate: a molded metal plate, cast + swoop sheen, floating on the
       page by its outer contact/ambient. Zero-offset — Invariant 6. */
    background-color: var(--ev-metal-hi);
    background-image:
        linear-gradient(var(--ev-swoop-angle),
            var(--ev-lum-hi)  0%,
            var(--ev-lum-hi)  8%,
            var(--ev-lum-mid) 34%,
            transparent       62%,
            var(--ev-lum-lo)  100%);
    background-repeat: no-repeat;
    border-radius: var(--ev-radius-lg);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-contact-1),
        var(--ev-ambient-1);
    padding: 5px;
}

/* --------------------------------------------------------------------------
   The column SCHEDULE — count-aware container-query breakpoints.
   --------------------------------------------------------------------------

   Each rule widens --readout-cols for a given VISIBLE tile count once the plate
   (not the viewport) is wide enough that the resulting arrangement is balanced.
   The consumer sets [data-count="N"] to the number of tiles it actually renders
   (a hidden/absent tile must not be counted — an empty pocket is a bug). The
   step schedule per count, each starting from the base 1-col stack:

     2 → [1 ; ≥330: 2]                         2-across or stacked
     3 → [1 ; ≥500: 3]                         3-across or stacked (never 2+1)
     4 → [1 ; ≥330: 2 ; ≥680: 4]               4-across, 2+2, or stacked
     5 → [1 ; ≥500: 3(=3+2) ; ≥860: 5]         5-across, 3+2 CENTERED, or stacked
     6 → [1 ; ≥500: 3(=3+3) ; ≥1040: 6]        6-across, 3+3, or stacked

   The 5→3 and 6→3 rows are where the balance falls out for free: at cols=3 a
   5-tile cluster wraps 3 then a centered 2 (never 5+1/4+1), and a 6-tile cluster
   wraps 3+3. cols is never set to a value that would strand a lone tile (a 5 is
   never given cols=4, which would wrap 4+1). Thresholds are ~168px/tile, tuned
   by rendering on the plate's actual width; raise the number to demand a wider
   plate before a given arrangement engages. data-count="0" matches nothing here
   and stays the (empty, collapsed) base — the consumer hides the plate at 0.

   THE SUBJECT OF EVERY RULE BELOW IS THE __cell, NOT THE PLATE — this is load
   bearing, not a style choice. A @container rule can only match DESCENDANTS of
   the query container; it can never match the container element itself. Since
   .ev-readout-cluster carries `container-type: inline-size`, it IS the
   container, so a rule reading `@container … { .ev-readout-cluster[data-count]
   { --readout-cols: N } }` matches NOTHING — --readout-cols stays 1 and every
   cluster silently renders as a 1-col stack at every width, which is exactly
   the arrangement this component exists to avoid. So the custom property is set
   on the cell (a descendant, matchable) and read by the flex-basis on that same
   cell; the plate's [data-count] is reached through the descendant combinator.
   (cortex-ksxbiw7 — caught by measuring rendered row patterns on the sandbox,
   not by reading the CSS: it parses and validates clean either way.)

   The same 1-col stack is reachable from the OTHER side, and that is the way it
   actually recurs: the CSS above stays correct and the MARKUP loses its
   data-count. Three of the showcase's own clusters were stacking this way at
   cortex-r3j7c99 — both lit demos and, worse, the account-overview recipe
   captioned "Copy this", so the omission was propagating to consumers. The
   failure is silent from here too: a cluster with no data-count matches no rule
   above, so nothing errors, nothing warns, and the page renders. WHEN YOU ADD OR
   MOVE A CLUSTER, SWEEP THEM ALL — `grep -rn 'class="ev-readout-cluster[">]'` —
   and check each count against its visible cells. Do not add a source-level
   build assertion for this: grepping the source for the attribute is the weaker
   check this repo has already ruled against (invcheck.js exists because its
   predecessor did exactly that and passed while 41 bad layers were live). A real
   check measures the rendered row pattern in a live DOM. */

@container (min-width: 330px) {
    .ev-readout-cluster[data-count="2"] > .ev-readout-cluster__cell,
    .ev-readout-cluster[data-count="4"] > .ev-readout-cluster__cell { --readout-cols: 2; }
}
@container (min-width: 500px) {
    .ev-readout-cluster[data-count="3"] > .ev-readout-cluster__cell,
    .ev-readout-cluster[data-count="5"] > .ev-readout-cluster__cell,
    .ev-readout-cluster[data-count="6"] > .ev-readout-cluster__cell { --readout-cols: 3; }
}
@container (min-width: 680px) {
    .ev-readout-cluster[data-count="4"] > .ev-readout-cluster__cell { --readout-cols: 4; }
}
@container (min-width: 860px) {
    .ev-readout-cluster[data-count="5"] > .ev-readout-cluster__cell { --readout-cols: 5; }
}
@container (min-width: 1040px) {
    .ev-readout-cluster[data-count="6"] > .ev-readout-cluster__cell { --readout-cols: 6; }
}

/* Each cell is a shallow pocket milled into the plate (rank-3 cut). The metal
   ridge that divides it from its neighbours is the plate's flex `gap` now
   (--readout-ridge), not a per-cell margin — so the cell carries no margin and
   its width comes from the column basis below.

   flex: 0 1 <basis> — NO grow (0), may shrink (1), basis = one column of the
   current --readout-cols. A FULL row of N tiles + (N-1) ridges fills 100%; a
   SHORT final row (the 2 in a 3+2) keeps each tile at exactly this basis and,
   because the plate centers, sits centered under the row above — the balanced,
   never-orphaned arrangement. The min() floor keeps a lone tile (or a 1-col
   stack) from overflowing a plate narrower than the computed basis. */
.ev-readout-cluster__cell {
    flex: 0 1 min(100%,
        calc((100% - (var(--readout-cols) - 1) * var(--readout-ridge)) / var(--readout-cols)));
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* The cell is often an <a>, and with no resting colour it fell through to
       the UA default link blue rgb(0,0,238) — the last non-achromatic value the
       live-DOM sweep found. It renders nowhere today because every descendant
       sets its own ink, but any un-styled text a consumer drops in a cell would
       inherit it, putting a hue in the output that is not the accent (L4).
       Inheriting the surrounding ink is the correct resting state; the hover
       accent below is unaffected. (cortex-yzjllwa) */
    color: inherit;
    /* space-between anchors the value block to a fixed TOP and the label block
       to a fixed BOTTOM of the cell — so across every cell the big numbers share
       one baseline and the captions share another, regardless of whether a cell
       carries a unit, wraps, or runs a different digit count. `center` floated
       the whole group by content height, so a unit-bearing cell (128GB) drifted
       out of line with a bare-number cell (14) — the "texts aren't aligned under
       each other" defect (cortex-5muzv5o). */
    justify-content: space-between;
    gap: 9px;
    min-height: 116px;
    padding: 20px 22px;
    text-decoration: none;
    border-radius: var(--ev-radius-md);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n3));
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-r3-rim);
    transition: box-shadow var(--ev-press-out) var(--ev-press-out-ease),
                background-color var(--ev-press-out) var(--ev-press-out-ease);
}

.ev-readout-cluster__value {
    font-family: var(--ev-font-mono);
    font-weight: 500;
    font-size: 2.35rem;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--ev-ink);
}

/* The unit (GB, år) leaves the mono run — a proportional gap, not a monospace
   advance (cortex-zr2prlm). Split from the numeral by the consumer. */
.ev-readout-cluster__unit {
    font-family: var(--ev-font-sans);
    font-size: 0.42em;
    font-weight: 600;
    letter-spacing: 0;
    margin-left: 0.22em;
    color: var(--ev-ink-dim);
}

.ev-readout-cluster__label {
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    font-weight: 600;
    color: var(--ev-ink-dim);
}

/* --------------------------------------------------------------------------
   The INTERACTIVE cell — its three hosts, and the mark it wears AT REST.
   --------------------------------------------------------------------------

   A cluster legally MIXES cells: one that navigates is rendered as a link, one
   that only displays is rendered as a plain box. Until cortex-pmctr5c the two
   were identical at rest and separated only once a pointer arrived. So a
   clickable pocket did not read as clickable — the inert-clickable half of
   "hover iff clickable" — and on touch, where there is no hover channel at
   all, the affordance was absent outright. A shipped consumer dashboard was
   six links wearing the treatment of six read-only readouts.

   THE MARK IS ACCENT INK ON THE CAPTION, and it introduces no new channel:
   the library already rules that accent ink is the RESTING property meaning
   "interactive" (the link doctrine), and hue's single meaning is live /
   active / interactive. The caption is the right run to carry it — it NAMES
   the destination — and it is indicator scale, so the achromatic panel is
   untouched: plate, floors, rim ladder and the 2.35rem value are all exactly
   what they were. A static cell keeps the dim achromatic caption and still
   does not react, so the interactive half was not fixed by handing the static
   half a false affordance.

   The escalation is MONOTONE, which is why the caption no longer changes on
   hover (it used to brighten to --ev-ink):

     rest    caption accent                    this pocket goes somewhere
     hover   + value accent, arris polished    it is under the pointer
     press   travels a rung deeper             it is being actuated

   Swapping the caption away from the accent on hover would have the two
   readings contradict each other — a resting property behaving like a
   transient one, which is exactly the confusion the link doctrine names when a
   run's ink and its highlight disagree.

   THE THREE HOSTS. A link or a button opts in by native semantics; a custom
   focusable host opts in with .ev-readout-cluster__cell--interactive and must
   then supply its own keyboard semantics. That host list was already the LIT
   register's contract (glass.css, PIECE 1) while the flat register recognised
   only :where(a) — so here the documented modifier and a button host got no
   states whatsoever. Both registers now name the same three hosts.

   Every selector below keeps that list inside :where(), which contributes ZERO
   specificity: these rules weigh exactly what they weighed when they read
   :where(a), so the lit register's overrides still win on the source order
   they were written against (glass.css is concatenated after this file).
   -------------------------------------------------------------------------- */

.ev-readout-cluster__cell:where(a, button, .ev-readout-cluster__cell--interactive) {
    cursor: pointer;
}

/* A button host arrives wearing UA chrome the milled pocket must not carry. */
.ev-readout-cluster__cell:where(button) {
    appearance: none;
    border: 0;
    font: inherit;
    text-align: inherit;
}

/* The resting mark itself. --ev-accent-text, not --ev-accent: the plain accent
   is a FACE value and fails as ink on light. MEASURED on the rendered pocket
   floor, not computed from the declarations — light rgb(6,68,102) on
   rgb(217,217,217) is 7.34:1, and in dark the token collapses to the accent
   itself, rgb(43,179,243) on rgb(38,38,38), 6.37:1. Both clear AA for the
   caption's small size with room to spare. */
.ev-readout-cluster__cell:where(a, button, .ev-readout-cluster__cell--interactive)
    .ev-readout-cluster__label {
    color: var(--ev-accent-text);
}

/* Hover = FINISH, not depth: the pocket reads freshly polished — a lit interior
   crown and a bright arris — while its floor and cut depth stay put. Ink
   sharpens to the accent. Depth change belongs to :active (Invariant 4).
   :focus-visible takes the same finish: a keyboard arrival is the same
   arrival, and the flat register had no focus treatment at all while the lit
   one did — a keyboard user got the UA outline and nothing else. */
.ev-readout-cluster__cell:where(a, button, .ev-readout-cluster__cell--interactive):is(:hover, :focus-visible) {
    transition: none;
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-shoulder-lite),
        var(--ev-r1-rim);
}
.ev-readout-cluster__cell:where(a, button, .ev-readout-cluster__cell--interactive):is(:hover, :focus-visible)
    .ev-readout-cluster__value { color: var(--ev-accent-text); }

/* The keyboard ring — the accent as a BOUNDARY (--ev-accent-edge clears the
   3:1 non-text floor that --ev-accent misses), matching the lit register's
   ring so a cluster reads the same to the keyboard in either treatment. */
.ev-readout-cluster__cell:where(a, button, .ev-readout-cluster__cell--interactive):focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

/* Press = the readout travels down a rung into a deeper cut. */
.ev-readout-cluster__cell:where(a, button, .ev-readout-cluster__cell--interactive):active {
    transition: box-shadow var(--ev-press-in) var(--ev-press-in-ease),
                background-color var(--ev-press-in) var(--ev-press-in-ease);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r3-rim);
}

/* Loading placeholder: an empty milled slot waiting to be filled
   (cortex-vnt3p6m pattern), shown while a consumer's loader populates the value. */
.ev-readout-cluster__cell[data-loading="true"] .ev-readout-cluster__value {
    display: inline-block;
    min-width: 52px;
    height: 0.7em;
    vertical-align: middle;
    border-radius: var(--ev-radius-sm);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-r3-rim);
}

/* Narrower value on small viewports so a two-per-row layout stays balanced. */
@media only screen and (max-width: 575px) {
    .ev-readout-cluster__cell { min-height: 100px; padding: 16px 18px; }
    .ev-readout-cluster__value { font-size: 2rem; }
}

/* ===== src/components/stat-card.css ===== */
/* ==========================================================================
   Evident opinionated component — stat card
   ==========================================================================

   One standalone dashboard metric: a molded metal carrier holding one milled
   reading. It is the single-instrument sibling of `.ev-readout-cluster`, not a
   one-cell cluster: there is no count-aware plate or ridge because this card is
   already the complete housing.

     .ev-stat-card             medium standalone metric
     .ev-stat-card--sm/--lg    allowlisted density, not arbitrary type classes
     .ev-stat-card__value      the machine reading
     .ev-stat-card__suffix     the proportional unit within the value line
     .ev-stat-card__label      the human caption

   The housing is deliberately ACHROMATIC. A metric's meaning is not a colour:
   warning/success state belongs in adjacent text or a badge, while lit/live
   readings belong to `.ev-readout-cluster--lit`.
   ========================================================================== */

.ev-stat-card {
    --stat-card-value-size: 2.35rem;
    --stat-card-min-height: 116px;
    --stat-card-pad-block: 20px;
    --stat-card-pad-inline: 22px;

    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    gap: 9px;
    min-width: 0;
    min-height: calc(var(--stat-card-min-height) + 10px);
    padding:
        calc(var(--stat-card-pad-block) + 5px)
        calc(var(--stat-card-pad-inline) + 5px);
    overflow: hidden;
    color: var(--ev-ink);
    text-align: left;
    background-color: var(--ev-metal-hi);
    background-image:
        linear-gradient(var(--ev-swoop-angle),
            var(--ev-lum-hi) 0%,
            var(--ev-lum-hi) 8%,
            var(--ev-lum-mid) 34%,
            transparent 62%,
            var(--ev-lum-lo) 100%);
    background-repeat: no-repeat;
    border: 0;
    border-radius: var(--ev-radius-lg);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

/* The reading needs a cut to live in, and a cut needs a parent surface. The
   pseudo-element is that inner pocket; the root remains the raised carrier. */
.ev-stat-card::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 5px;
    border-radius: var(--ev-radius-md);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n3));
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-r3-rim);
}

.ev-stat-card--sm {
    --stat-card-value-size: 1.75rem;
    --stat-card-min-height: 88px;
    --stat-card-pad-block: 15px;
    --stat-card-pad-inline: 17px;
}

.ev-stat-card--lg {
    --stat-card-value-size: 3rem;
    --stat-card-min-height: 144px;
    --stat-card-pad-block: 26px;
    --stat-card-pad-inline: 28px;
}

.ev-stat-card__value {
    position: relative;
    font-family: var(--ev-font-mono);
    font-size: var(--stat-card-value-size);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--ev-ink);
}

.ev-stat-card__suffix {
    margin-left: 0.22em;
    font-family: var(--ev-font-sans);
    font-size: 0.42em;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--ev-ink-dim);
}

.ev-stat-card__label {
    position: relative;
    font: 600 0.7rem/1.35 var(--ev-font-sans);
    letter-spacing: 0.06em;
    color: var(--ev-ink-dim);
}

/* ===== src/components/pagination.css ===== */
/* ==========================================================================
   Evident opinionated component — pagination
   ==========================================================================

   Bounded page navigation is one recessed channel. Available destinations are
   labels on its floor; the current page is the one achromatic seat resting in
   that channel. Selection is location, not liveness, so the seat stays neutral
   metal rather than borrowing the accent-lit segmented-control treatment.

     .ev-pagination__status     visible "Page X of Y" extent
     .ev-pagination__nav        labelled navigation region
     .ev-pagination__pages      the one machined channel
     .ev-pagination__page       a numbered destination / current seat
     .ev-pagination__control    previous or next destination
     .ev-pagination__chevron    centered previous/next glyph
     .ev-pagination__ellipsis   a gap, never an action

   The markup owns no colour, density, compact, or alignment options. The
   current page is expressed semantically with aria-current="page"; unavailable
   edge controls are non-link spans with aria-disabled="true".
   ========================================================================== */

.ev-pagination {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 9px;
    min-width: 0;
    color: var(--ev-ink);
}

.ev-pagination__status {
    margin: 0;
    font: 600 0.7rem/1.25 var(--ev-font-sans);
    letter-spacing: 0.055em;
    color: var(--ev-ink-dim);
}

.ev-pagination__status strong {
    font-family: var(--ev-font-mono);
    font-weight: 600;
    letter-spacing: 0;
    color: var(--ev-ink);
}

.ev-pagination__nav {
    max-width: 100%;
}

/* THE CHANNEL. It is one rank-2 cut; children do not draw competing boxes. */
.ev-pagination__pages {
    display: inline-flex;
    align-items: stretch;
    gap: 0;
    max-width: 100%;
    min-height: var(--ev-btn-height-sm);
    padding: 3px;
    margin: 0;
    overflow-x: auto;
    list-style: none;
    scrollbar-width: thin;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-radius-sm);
    box-shadow:
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
}

.ev-pagination__item {
    display: flex;
    flex: 0 0 auto;
    align-items: stretch;
}

.ev-pagination__page,
.ev-pagination__control,
.ev-pagination__ellipsis {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: calc(var(--ev-btn-height-sm) - 6px);
    min-height: calc(var(--ev-btn-height-sm) - 6px);
    padding: 0 8px;
    border: 0;
    border-radius: calc(var(--ev-radius-sm) - 2px);
    font: 600 var(--ev-btn-font-sm)/1 var(--ev-font-sans);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    white-space: nowrap;
    color: var(--ev-ink-dim);
    background: transparent;
}

.ev-pagination__page {
    font-family: var(--ev-font-mono);
}

.ev-pagination__control {
    gap: 0.42em;
    min-width: 84px;
    padding-inline: 10px;
}

.ev-pagination__control--previous {
    justify-content: flex-start;
}

.ev-pagination__control--next {
    justify-content: flex-end;
}

.ev-pagination__chevron {
    display: block;
    inline-size: 0.55rem;
    block-size: 0.85rem;
    flex: 0 0 auto;
    background: currentColor;
    font-size: 0;
    line-height: 0;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='m6.5 1.5-4 4.5 4 4.5' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 12'%3E%3Cpath d='m6.5 1.5-4 4.5 4 4.5' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

.ev-pagination__control--next > .ev-pagination__chevron {
    transform: rotate(180deg);
}

/* Destinations are labels on the channel floor until interaction gives them
   accent ink. No idle background/shadow means no fictional separate part. */
a.ev-pagination__page:hover,
a.ev-pagination__control:hover {
    color: var(--ev-accent-text);
}

a.ev-pagination__page:focus-visible,
a.ev-pagination__control:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: -1px;
    color: var(--ev-accent-text);
}

/* THE SEAT. Current location is a raised but achromatic block resting inside
   the channel: selected, not live. It never receives hover or focus states
   because the current page is deliberately not a link. */
.ev-pagination__page[aria-current="page"] {
    color: var(--ev-ink);
    background-color: var(--ev-metal-hi);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-contact-1);
}

.ev-pagination__control[aria-disabled="true"] {
    color: var(--ev-ink-dim);
    opacity: 0.45;
    cursor: default;
}

.ev-pagination__ellipsis {
    min-width: 26px;
    padding-inline: 4px;
    color: var(--ev-ink-dim);
    user-select: none;
}

@media (max-width: 520px) {
    .ev-pagination__word {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .ev-pagination__control {
        min-width: calc(var(--ev-btn-height-sm) - 6px);
        padding-inline: 7px;
    }
}

/* ===== src/components/empty-state.css ===== */
/* ==========================================================================
   Evident component — empty state (the carved void)
   ==========================================================================

   "Nothing here yet" is an ABSENCE, and a machined pocket IS an absence carved
   into the surface — so the empty state is a CARVED recessed plane (Evident
   rank-1 carve, the same tool-cut idiom as .ev-machined / .rounded-light). It
   is not a raised card sitting empty; it is a hollow in the face, awaiting
   content. (cortex-pa29jiy)

     .ev-empty-state            the carved pocket (rank-1 cut, deeper floor)
     .ev-empty-state__icon      the centered glyph slot (default-on) — a generic
                                placeholder glyph, or later the empty entity
                                type's own glyph (cortex-nmk34wy)
     .ev-empty-state__title     optional heading
     .ev-empty-state__message   the muted message (the definite content)
     .ev-empty-state__action       optional call-to-action — a FLAT/INSET LINK

   THE MATERIAL RULE, ENFORCED IN CSS (this is the whole point):

     A carved plane CANNOT host a RAISED button. "Raised only on raised" is the
     additive rule — a pressable cast affordance belongs on a cast surface. So
     the in-pocket CTA is a FLAT LINK or ABSENT: there is NO raised-button slot
     on this component. The founder's material reason (cortex-pa29jiy comment):
     a button's meaning IS the raised, pressable affordance; carving it to fit
     the pocket strips exactly that, so it reads as neither — a carved
     not-quite-button. That "off" is the material rejecting the disguise (rule
     1: nothing depicted that isn't there).

     We make "put a raised .ev-key / <button> here" STRUCTURALLY UNEXPRESSIBLE
     (self-enforcing, cortex-wliu7d1) two ways:
       - the CTA is authored as `a.ev-empty-state__action` — an anchor, a flat text
         link, which is the element that BELONGS in a carved context;
       - a guard selector (bottom of file) DISARMS any raised key or <button>
         mistakenly dropped in the pocket — stripping its cast shadow and
         flattening it to a link — so the wrong markup cannot render as a raised
         button. If a create-action must be PROMINENT it belongs on the RAISED
         page OUTSIDE the pocket (a raised .ev-key on the molded surface around
         it), which is not this component's concern.

   Customization that reads "empty" vs a generic .ev-machined pocket: a slightly
   DEEPER floor (--ev-floor-n1, the deepest cut), MUTED centered content, and a
   faint inner SCRIBE — calm, "awaiting content."
   ========================================================================== */

.ev-empty-state {
    /* A land cut into the page/host: the empty state sits ONE rung below its
       host and holds nothing but its own quiet content, so it takes the deepest
       floor directly — the void reads deeper than an ordinary machined panel.
       Reset the bench-floor override so the deep floor is honoured on the bench
       (same reasoning as .ev-machined:has(.ev-pocket), core.css). */
    --ev-direct-carve-floor: initial;
    background-color: var(--ev-floor-n1);
    color: var(--ev-ink);
    border-radius: var(--ev-radius-md);
    /* rank-1 carve — the heavy 6px lip, deep wall, lit rim burr. */
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
    position: relative;

    /* Centered column — icon → title → message → cta, stacked and centered in
       the pocket. The content is MUTED and centered (definite, per founder). */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.75rem;
    padding: var(--ev-btn-pad-x-lg) var(--ev-btn-pad-x-md);
    min-height: 148px;

    /* fillet ratio for the rank-1 carve (Invariant 5) — matches .ev-machined. */
    --ev-fillet-l: var(--ev-fillet-light);
    --ev-fillet-s: var(--ev-fillet-size);
}

/* The faint inner SCRIBE — a hairline dashed marking lying ON the floor a short
   inset from the wall, saying "awaiting content." A marking, not a cut: it uses
   the faint NON-TEXT ink rung and sits under the content. Distinct from the
   machined pocket, this scribe is what makes the void read as "empty" rather
   than merely "recessed." */
.ev-empty-state::before {
    content: '';
    position: absolute;
    inset: 10px;
    border-radius: calc(var(--ev-radius-md) - 3px);
    border: 1px dashed var(--ev-ink-faint);
    opacity: 0.4;
    pointer-events: none;
}

/* Corner counter-light (fillet) — same rank-1 ratio as .ev-machined so the
   carved corners read at the correct darkness (Invariant 5). */
.ev-empty-state::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 0% 0%,
            var(--ev-fillet-l), transparent 72%),
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 100% 0%,
            var(--ev-fillet-l), transparent 72%),
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 0% 100%,
            var(--ev-fillet-l), transparent 72%),
        radial-gradient(var(--ev-fillet-s) var(--ev-fillet-s) at 100% 100%,
            var(--ev-fillet-l), transparent 72%);
}

/* Content sits above both decoration layers. */
.ev-empty-state > * {
    position: relative;
    z-index: 1;
}

/* Flat glyphs on a carve — Invariant L3. No embossed/shadowed headings. */
.ev-empty-state :is(h1, h2, h3, h4, h5, h6) {
    text-shadow: none;
    color: var(--ev-ink);
}

/* --------------------------------------------------------------------------
   The slots — all MUTED (definite), all centered by the flex column above.
   -------------------------------------------------------------------------- */

/* Icon slot — default-on, a generic placeholder glyph. Muted: the icon uses
   the faint non-text ink rung (it is decoration, not a value). When the empty
   thing is an entity type it will later carry that entity's own glyph
   (cortex-nmk34wy); the slot is glyph-agnostic. */
.ev-empty-state__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    color: var(--ev-ink-dim);
    opacity: 0.72;
    margin-bottom: 0.15rem;
}
.ev-empty-state__icon svg {
    width: 28px;
    height: 28px;
    display: block;
}
.ev-empty-state__icon svg [stroke] { stroke: currentColor; }
.ev-empty-state__icon svg [fill]:not([fill="none"]) { fill: currentColor; }

/* Optional title — the clear first reading layer. The pocket stays quiet
   through scale and flat paint; weakening the title to the message rung made
   the dark empty state read as one indistinct watermark. */
.ev-empty-state__title {
    margin: 0;
    font: 650 1rem/1.3 var(--ev-font-sans);
    color: var(--ev-ink);
}

/* The message — the definite muted content. */
.ev-empty-state__message {
    margin: 0;
    max-width: 42ch;
    font: 400 0.875rem/1.5 var(--ev-font-sans);
    color: var(--ev-ink-dim);
}

/* --------------------------------------------------------------------------
   The CTA — a FLAT/INSET LINK. The element that belongs in a carved context.
   Not a key, not a cast part: flat text, the accent as INK (interactive), an
   underline on hover. No box, no shadow, no raised affordance — because a
   carved plane cannot host one.
   -------------------------------------------------------------------------- */
.ev-empty-state__action {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    margin-top: 0.25rem;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    font: 600 0.875rem/1 var(--ev-font-sans);
    /* accent as INK (a live/interactive value), the AA-safe text rung — never
       --ev-accent, which is a FACE value and fails as ink on the deep floor
       (same rule as .ev-readout__value--accent, cortex-8jhd90a). */
    color: var(--ev-accent-text);
    text-decoration: none;
    cursor: pointer;
    transition: var(--ev-transition-fast);
}
.ev-empty-state__action:hover {
    text-decoration: underline;
    text-underline-offset: 0.2em;
}
.ev-empty-state__action:focus-visible {
    outline: none;
    border-radius: var(--ev-radius-sm);
    box-shadow: 0 0 0 2px var(--ev-accent-edge);
}

/* --------------------------------------------------------------------------
   THE GUARD — "raised only on raised," enforced. (cortex-wliu7d1)
   -------------------------------------------------------------------------- */

/* A raised key or a <button> dropped inside the carved void is a material
   violation: a cast pressable affordance depicted on a cut floor (the exact
   old-CC hack the founder called out — a button carved to "fit" .rounded-light,
   reading as neither). We do not let it render as a raised button. Any such
   element is DISARMED — stripped of its cast shadow, height, and fill, and
   flattened into the flat accent link that belongs here — so authoring the
   wrong markup produces the right (link) result, and a raised button on a
   carved plane is structurally unexpressible. If you actually need a raised
   button, you need a RAISED surface: move it outside the pocket. */
.ev-empty-state :is(button, .ev-key, [class*="ev-key--"], input[type="button"], input[type="submit"]) {
    -webkit-appearance: none;
    appearance: none;
    height: auto;
    min-height: 0;
    background: none !important;
    background-image: none !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin-top: 0.25rem;
    font: 600 0.875rem/1 var(--ev-font-sans) !important;
    color: var(--ev-accent-text) !important;
    text-decoration: none;
    cursor: pointer;
    transition: var(--ev-transition-fast);
}
.ev-empty-state :is(button, .ev-key, [class*="ev-key--"], input[type="button"], input[type="submit"]):hover {
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

/* ===== src/components/baseplate.css ===== */
/* ==========================================================================
   Evident component — the baseplate (a carve composition, as a control surface)
   ==========================================================================

   The baseplate is not a new primitive — it is a small, reusable COMPOSITION of
   the carve primitives (.ev-machined) and the readout primitive
   (.ev-readout / .ev-eyebrow), shaped into a realistic control surface: an
   outer heavy carve holding finer inner readout pockets doing real work
   (a node's identity + its live metrics). Ported from the study's
   "The baseplate, as a control surface" (the .nest-stack column,
   historical v16 record) onto the canonical `--ev-*` tokens.
   (cortex-38ynluu / promote-the-baseplate, epic cortex-pzakjzf.)

   WHAT IT DEMONSTRATES — the two carve channels, moving independently
   -------------------------------------------------------------------
   The whole point is that the baseplate shows BOTH carve channels at once, in
   a plausible surface rather than an abstract nesting demo:

     INVERTED NESTING WEIGHT (rim/lip = rank). The OUTER carve is the HEAVIEST
       cut (rank-1: 6px lip, 1px line, bright rim). Each pocket cut inside it is
       FINER (rank-2: 3px lip). Weight runs OUTWARD — the intuitive direction is
       wrong (CLAUDE.md § "The weight runs outward").

     THE FLOOR LADDER (floor luminance = depth). The outer baseplate floor sits
       at --ev-floor-n2; each inner pocket is cut a rung DEEPER, to
       --ev-floor-n1 (the deepest rung). n1 is deepest, monotonic ceiling holds
       — every floor stays below the un-cut --ev-metal-hi face.

   These are two SEPARATE channels (CLAUDE.md § "The channels"): the outer is
   heavier-shaded AND shallower-floored than its children, and that is correct —
   a big shallow pocket holding smaller deeper ones. Reading the rims tells you
   rank; reading the floors tells you depth.

   IT IS A COMPOSITION FIRST. The two helper classes below are a thin
   convenience so a consumer does not re-derive the floor/rank pairing by hand;
   the same surface can be built inline from .ev-machined + .ev-machined--medium
   with explicit floor overrides. Labels use .ev-eyebrow (the "RANK 1" upperspace
   type) with .ev-aux for the machine companion beside them; values use
   .ev-readout__value (mono is earned — genuine machine values, Invariant L5).
   ========================================================================== */

/* The outer baseplate: the heavy cut. Rank-1 shading (inherited from
   .ev-machined) with the floor pinned at n2 so the pockets have n1 to descend
   into. Consumers apply .ev-baseplate alongside .ev-machined. */
.ev-baseplate {
    /* A slab holding nested pockets, not a direct bench carve — reset the
       bench-floor override so the baseplate + its pockets use the floor ladder,
       else the inner cuts collapse to the near-black bench floor on the bench
       (regression fix, cortex-a2ca9mx). */
    --ev-direct-carve-floor: initial;
    display: flex;
    flex-direction: column;
    /* The slab's own caption (the node's name) is an in-carve label, and the
       first pocket is the cut below it — so the flex gap IS the air under that
       label and has to equal the padding above it. One value for both, from
       --ev-carve-label-gap (cortex-4fg3ps6). It was a 10.5px gap against 20px
       of padding, the same imbalance the lip progression had. Declared here, so
       a baseplate nested in a tighter carve keeps its own inset — the property
       inherits, and consuming an ancestor's value would silently retune it. */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);
    gap: var(--ev-carve-label-gap);
    padding: var(--ev-carve-label-gap);
    /* Floor n2 (shallowest of the two levels used here) — the pockets go to n1.
       .ev-machined already sets n2, but pin it explicitly so the composition is
       self-describing and survives a consumer overriding .ev-machined's floor. */
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n2));
}

/* An inner readout pocket: a finer cut, one floor-rung DEEPER than the
   baseplate. Rank-2 shading via .ev-machined--medium; the floor drops to n1
   here — the depth channel — while the rim weight drops to rank-2 — the
   inverted-weight channel. Both move, in opposite senses, exactly as the model
   requires. */
.ev-baseplate__pocket {
    /* A pocket is TIGHTER than the slab that holds it, so it declares its own
       label gap rather than inheriting the slab's. This is the whole reason
       --ev-carve-label-gap is contextual: the equality has to hold at both
       insets, and a single global number could only hold at one. */
    --ev-carve-label-gap: var(--ev-btn-pad-y-sm);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    padding: var(--ev-carve-label-gap) var(--ev-btn-pad-x-md);
    border-radius: var(--ev-radius-sm);
}

/* The pocket's caption ROW: an in-carve label plus an optional aux companion,
   sitting above the readout value. A row so "NODE  fra-01" reads as one line;
   the readout value sits under it.

   The ROW carries the label gap here, not the label — the label is a flex item
   inside it, and a margin on a flex item would grow the row rather than open
   air beneath it. Same value either way, so the equality (pocket top padding ==
   air under the caption) holds identically. */
.ev-baseplate__cap {
    display: flex;
    align-items: baseline;
    gap: 0.5em;
    margin: 0;
}

.ev-baseplate__cap > .ev-carve-label {
    margin-bottom: 0;   /* the row owns the gap; see above. */
}

/* Only when something follows it — a caption that IS its pocket's whole content
   already has the pocket's bottom padding under it, and adding the gap on top
   would unbalance it the other way. Same reasoning as .ev-carve-label's own
   :not(:last-child). */
.ev-baseplate__cap:not(:last-child) {
    margin-bottom: var(--ev-carve-label-gap);
}

/* Directly on the slab (the node's own caption) the baseplate is a flex column
   whose `gap` already supplies the air below — a margin here would stack on top
   of it and double the distance. */
.ev-baseplate > .ev-baseplate__cap {
    margin-bottom: 0;
}

/* WHERE AN AUX LANDS is the host's business, not the role's (cortex-l6wn803).
   .ev-aux itself carries no alignment — it is a role, not a position — so the
   baseplate's own caption row is what pushes a trailing companion to the far
   edge: the label names the pocket at the start of the row, the machine value
   sits at the end. Keyed on :last-child so a caption that continues after the
   aux still reads as one phrase.

   This rule needs a flex row to act on, which is why it lives HERE and not on
   .ev-aux: making .ev-eyebrow a flex container to get the same effect would
   change every eyebrow in the library for the benefit of one composition. */
.ev-baseplate__cap > .ev-aux:last-child {
    margin-left: auto;
}

/* ===== src/components/identity.css ===== */
/* ==========================================================================
   Evident component — the identity chip
   ==========================================================================

   An identity chip is a small MACHINED plate carrying a person's identity:
   an avatar (photo, or a coloured monogram tile), their name, and a status
   indicator. It is the answer to an unsatisfying top-nav user pill
   (cortex-swxsfdm) and to the open question "what carries
   identity now that colour cannot?" (gate cortex-dkef0w5).

   THE MATERIAL-VS-CONTENT SPLIT — the load-bearing design decision here.
   Founder ruling 2026-07-27 (cortex-swxsfdm comment, resolving cortex-dkef0w5
   / cortex-pzg8v81): an avatar is CONTENT, not material — a thumbnail of a
   user's domain, like an image in a card. So:

     - the PLATE / FRAME is achromatic Evident material. The chip is a machined
       plate; its lip, floor and rim obey the carve language exactly like a
       readout well. Hue never touches the frame.
     - the AVATAR itself may carry its OWN colour: a photo, or a coloured
       monogram tile whose fill is a per-user hue. This colour is content, the
       same exemption an <img> in a card enjoys. It is NOT forced to greyscale.

   The two never blur: a coloured face on the FRAME would read as "selected /
   live" (Invariant 7) and would be wrong; a coloured face in the AVATAR SEAT
   reads as a picture and is right. The seat is a real cut, so the coloured
   content sits at the BOTTOM of a milled recess (an inlaid tile / printed
   disc) — a valid fabrication story, not a coloured sticker floating on land.

   STATUS is carried achromatically first, with the ONE sanctioned accent for
   the single live state:
     online  — a lit accent dot (accent == live / active, its one meaning).
     away    — a hollow ring in dim ink: present but not lit. Achromatic.
     busy    — a filled dim-ink dot with a milled notch (a hyphen bar).
     offline — an oxidized (inert) dot, dropped back into the floor. Achromatic.
   Only `online` spends the accent; the other three are pure grey, so a
   colour-blind or achromatic read still separates them by fill/ring/notch.

   Public API (BEM under the ev- prefix, per cortex-q29li00):
     .ev-identity                 the chip plate (a machined seat carrier)
     .ev-identity__avatar         the avatar seat (a circular milled pocket)
     .ev-identity__img            a photo filling the seat  (content colour ok)
     .ev-identity__initials       a monogram tile           (content colour ok)
     .ev-identity__body           name + meta stack
     .ev-identity__name           the person's name (flat sans ink)
     .ev-identity__meta           optional secondary line (handle / role)
     .ev-identity__status         the status indicator, seated on the avatar
     .ev-identity--sm / --lg       size scale (md is the default)
     .ev-identity--button          make the whole chip an interactive key
     .ev-identity__status--online / --away / --busy / --offline
   ========================================================================== */

.ev-identity {
    /* ---- the chip's own scale knobs (md default) --------------------------
       One name per number, per the "name it if you need it twice" rule. */
    --ev-id-avatar:   34px;   /* avatar seat diameter */
    --ev-id-gap:      10px;   /* seat -> name gutter */
    --ev-id-pad-y:    6px;
    --ev-id-pad-x:    9px;
    --ev-id-name:     13.5px; /* matches btn-font-md */
    --ev-id-meta:     11.5px;
    --ev-id-status:   11px;   /* status dot diameter */
    --ev-id-monogram: 14px;   /* initials glyph size */

    display: inline-grid;
    grid-template-columns: auto auto;
    align-items: center;
    gap: var(--ev-id-gap);
    padding: var(--ev-id-pad-y) var(--ev-id-pad-x);
    /* The plate is a machined carrier — a shallow rank-2 pocket, the same
       information-display posture as .ev-well, not a raised molded float:
       identity is read, not pressed. Floor n2 leaves n1 below for the seat. */
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n2));
    border-radius: var(--ev-radius-lg);
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
    color: var(--ev-ink);
    font-family: var(--ev-font-sans);
    text-decoration: none;
    position: relative;
}

/* --------------------------------------------------------------------------
   The avatar seat — a circular pocket cut ONE rung deeper than the plate
   (plate is n2, so the seat floor is n1, the deepest carve). The coloured
   content sits AT the bottom of this real recess: an inlaid tile, not a
   sticker. The seat is where the material language ends and content begins.
   -------------------------------------------------------------------------- */
.ev-identity__avatar {
    position: relative;
    width: var(--ev-id-avatar);
    height: var(--ev-id-avatar);
    border-radius: 50%;
    /* the seat floor (a deep cut) + its own rank-2 cut shading, so the recess
       reads before any content lands in it. overflow clips content to the cut. */
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-rim);
    overflow: hidden;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
}

/* The photo — CONTENT. Fills the seat edge-to-edge; its colour is its own,
   exempt from the achromatic-material rule (a thumbnail of the user). */
.ev-identity__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* no filter: content keeps its colour. This is the exemption, stated. */
}

/* The monogram tile — CONTENT. A coloured disc carrying the initials. The
   fill is a per-user hue, set inline via --ev-id-tile (a content token, NOT an
   --ev-* material token). Ink on the tile is picked by the consumer for
   contrast; default is a light ink because tiles trend mid/dark. */
.ev-identity__initials {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
    /* content colour — a neutral slate DEFAULT so an un-themed monogram still
       reads; consumers override --ev-id-tile per user. */
    background: var(--ev-id-tile, #5b6673);
    color: var(--ev-id-tile-ink, #f4f6f8);
    font: 600 var(--ev-id-monogram)/1 var(--ev-font-sans);
    letter-spacing: 0.01em;
    text-transform: uppercase;
    /* a hairline inner seat-shadow so even the coloured tile reads as SEATED
       in the recess rather than pasted on top — achromatic ink, geometry not
       hue, so it does not tint the content. */
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14),
                inset 0 0 5px rgba(0, 0, 0, 0.22);
    user-select: none;
}

/* --------------------------------------------------------------------------
   Name + meta stack — flat achromatic ink (Invariant L3 / L4). The name is
   sans; an optional meta line (a handle / role) sits under it in dim ink. A
   genuine machine handle (an @id) may opt into mono via --mono.
   -------------------------------------------------------------------------- */
.ev-identity__body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
    padding-right: 2px;
}

.ev-identity__name {
    font: 600 var(--ev-id-name)/1.25 var(--ev-font-sans);
    color: var(--ev-ink);
    letter-spacing: 0.005em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ev-identity__meta {
    font: 500 var(--ev-id-meta)/1.3 var(--ev-font-sans);
    color: var(--ev-ink-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* A meta line that is a genuine machine value (an @handle, a user id) earns
   mono — Invariant L5. Opt-in, never default. */
.ev-identity__meta--mono {
    font-family: var(--ev-font-mono);
    font-size: calc(var(--ev-id-meta) - 0.5px);
    letter-spacing: 0.01em;
}

/* --------------------------------------------------------------------------
   The status indicator — a small dot seated on the lower-right of the avatar.
   It is a milled feature ON the plate, so it carries a hairline cut ring that
   separates it from the seat behind it (a badge sitting on a floor is cut one
   rung, per badges.css). Status meaning is achromatic first; only `online`
   spends the one accent.
   -------------------------------------------------------------------------- */
.ev-identity__status {
    position: absolute;
    right: -1px;
    bottom: -1px;
    width: var(--ev-id-status);
    height: var(--ev-id-status);
    border-radius: 50%;
    /* the collar — a ring of PLATE material punched around the dot so the dot
       reads as set INTO the plate, not floating over the avatar seat. Uses the
       plate floor colour, achromatic. */
    box-shadow:
        0 0 0 2px var(--ev-floor-n2),
        var(--ev-r3-line);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    z-index: 2;
}

/* online — the ONE live state. Accent as a lit face (its single meaning:
   live / active). This is the sanctioned use of hue. */
.ev-identity__status--online {
    background-color: var(--ev-accent);
    box-shadow:
        0 0 0 2px var(--ev-floor-n2),
        inset 0 0 0 1px rgba(6, 35, 47, 0.30),
        inset 0 0 2px rgba(250, 250, 250, 0.45);
}

/* away — present but not lit. A hollow ring in dim ink: the dot is a cut with
   an empty centre (floor showing through). Achromatic. */
.ev-identity__status--away {
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        0 0 0 2px var(--ev-floor-n2),
        inset 0 0 0 2px var(--ev-ink-faint);
}

/* busy — a filled dim-ink dot with a milled notch (a hyphen bar cut across).
   Achromatic; the notch is geometry, distinguishing it from away/offline. */
.ev-identity__status--busy {
    background-color: var(--ev-ink-dim);
    box-shadow:
        0 0 0 2px var(--ev-floor-n2),
        inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}
.ev-identity__status--busy::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 52%;
    height: 2px;
    transform: translate(-50%, -50%);
    border-radius: 1px;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
}

/* offline — inert. An oxidized dot dropped back toward the floor (no accent,
   dulled), reading as switched-off. Achromatic. */
.ev-identity__status--offline {
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n3));
    box-shadow:
        0 0 0 2px var(--ev-floor-n2),
        var(--ev-r3-line),
        inset 0 0 3px var(--ev-lum-lo);
}

/* --------------------------------------------------------------------------
   Size scale — sm / md(default) / lg. Only the scale knobs move; every rule
   above is expressed against them, so one variable set drives the whole chip.
   -------------------------------------------------------------------------- */
.ev-identity--sm {
    --ev-id-avatar:   26px;
    --ev-id-gap:      8px;
    --ev-id-pad-y:    4px;
    --ev-id-pad-x:    6px;
    --ev-id-name:     12px;
    --ev-id-meta:     10.5px;
    --ev-id-status:   9px;
    --ev-id-monogram: 11px;
}

.ev-identity--lg {
    --ev-id-avatar:   44px;
    --ev-id-gap:      12px;
    --ev-id-pad-y:    8px;
    --ev-id-pad-x:    11px;
    --ev-id-name:     15px;
    --ev-id-meta:     12.5px;
    --ev-id-status:   13px;
    --ev-id-monogram: 18px;
}

/* --------------------------------------------------------------------------
   Avatar-only variant — the top-nav case at its tightest: seat + status, no
   name. Collapses the grid to one column and squares up the padding so the
   plate hugs the seat.
   -------------------------------------------------------------------------- */
.ev-identity--avatar-only {
    grid-template-columns: auto;
    padding: var(--ev-id-pad-y);
}

/* --------------------------------------------------------------------------
   Interactive variant — a nav avatar is usually a menu trigger. .ev-identity
   is a read plate at rest; --button lets it press. Following the sanctioned
   .btn:active exception, the whole plate travels a hair DEEPER on press (one
   part moving into the panel it sits in), and the lip firms on hover. No hue
   bloom, no glow (Invariant L4).
   -------------------------------------------------------------------------- */
.ev-identity--button {
    cursor: pointer;
    transition: box-shadow var(--ev-press-out) var(--ev-press-out-ease);
    -webkit-appearance: none;
    appearance: none;
    border: 0;
    text-align: left;
    font-family: var(--ev-font-sans);
}
.ev-identity--button:hover {
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
}
.ev-identity--button:active {
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall);
    transition: box-shadow var(--ev-press-in) var(--ev-press-in-ease);
}
/* Keyboard focus — a firm accent scribe ring (accent == interactive), no
   bloom or glow. A single flat ring, achromatic elsewhere. */
.ev-identity--button:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

/* ===== src/components/badge.css ===== */
/* ==========================================================================
   Evident component — badge (v2: sticker / inset planes, semantic BG, lamp)
   ==========================================================================

   Supersedes the achromatic ink-only `badges.css`. Founder pass 2026-07-27
   (cortex-97eki0o): "Metallic stickers (raised plane) and embossed insets
   (lowered plane). Revert to the color being BG color — colour conveying
   alert/status meaning is okay. Live and info overlap — choose one. Live is a
   separate attribute that renders a glowing lamp, applyable per colour, plus
   live-animated for a subtle pulse. Also a non-text form: just the status
   indicator. Some skeumorphism is ok here."

   -------------------------------------------------------------------------
   WHY THIS BREAKS THE HOUSE RULE, ON PURPOSE
   -------------------------------------------------------------------------
   The core language (CLAUDE.md) reserves hue for the ONE accent and forbids
   glow/pulse (Invariant L4). A status badge is the sanctioned exception the
   founder carved here: a badge's ENTIRE job is to shout danger/success/
   warning/info, and severity read off shape alone fails colour-blind-to-
   nobody in the opposite direction — it fails everybody at a glance. So on a
   BADGE, and nowhere else, hue is allowed to mean status, and the "live" lamp
   is allowed a small skeuomorphic glow. This partial is where that exception
   is spent; it does not license hue or glow anywhere outside `.ev-badge` /
   `.ev-badge-lamp`.

   The TWO PLANES still obey Rule 1 (nothing depicted that is not there):
     .ev-badge--sticker  a metallic STICKER pressed ONTO the surface. It sits
                         in the RAISED plane, so it wears an OUTER contact +
                         ambient shadow (it casts onto what it is stuck to)
                         plus an inner shoulder roll (a moulded, domed cap).
                         Reads RAISED.
     .ev-badge--inset    an EMBOSSED INSET machined INTO the surface. It sits
                         in the LOWERED plane, so it wears an INSET lip + wall
                         (a real cut) and NO outer depth shadow. Reads CARVED.
   An element carries one plane or the other, never both — a raised inset has
   no fabrication story (see core.css). Default (bare `.ev-badge`) is sticker.

   -------------------------------------------------------------------------
   THE live / info MERGE DECISION
   -------------------------------------------------------------------------
   Old badges had a blue `--accent`/live variant AND a blue `--info` variant —
   two blue chips meaning nearly the same "active/notice" thing. Resolved by
   SPLITTING THE ROLE, not by keeping both:
     - `info` stays as a SEMANTIC COLOUR (a blue status face). It is one of the
       four alert colours and nothing more.
     - `live` is REMOVED as a colour and REBORN as an ATTRIBUTE — `--live` — a
       glowing lamp that stacks on top of ANY colour (a live danger badge, a
       live success badge). Liveness is now a channel of its own (a lit lamp),
       orthogonal to which alert colour the face carries.
   Net: exactly one blue chip (`info`); "live" no longer competes with it.

   -------------------------------------------------------------------------
   CLASS API
   -------------------------------------------------------------------------
     .ev-badge                 base badge (defaults to the sticker plane)
     .ev-badge--sticker        raised metallic sticker (explicit; = default)
     .ev-badge--inset          lowered embossed inset (carved into surface)

     .ev-badge--danger|--success|--warning|--info
                               semantic BG colour (the alert meaning)

     .ev-badge--live           adds a glowing status lamp to the badge
     .ev-badge--live-animated  the lamp pulses (prefers-reduced-motion aware)

     .ev-badge-lamp                  the non-text form: a standalone status lamp,
                               no label. Same colours + live/animated:
     .ev-badge-lamp--danger|--success|--warning|--info
     .ev-badge-lamp--animated        pulses (prefers-reduced-motion aware)

   Colour classes set the lamp/face hue via `--ev-badge-c` / `--ev-badge-glow`;
   a bare `.ev-badge-lamp` or a live badge with no colour class glows with `--ev-info`.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Semantic tokens. THE ONLY new colours in Evident (per the bead). These are
   status faces — they carry meaning, so they are hued, unlike every other
   surface. Chosen tasteful/desaturated to sit inside Evident's restraint: a
   badge is a small mark, not a toast. Foreground is a near-black/near-white
   ink picked for AA on the corresponding face in each theme.
   Kept in-partial (a :root block) so the palette bead can surface them; do NOT
   fold these into the shared token file from here (parallel-edit isolation).
   The light selector alias mirrors tokens.css so a nested light scope resets
   this component-local semantic register as well as the core material ramp.
   -------------------------------------------------------------------------- */
:root,
:is([data-ev-theme="light"], [data-bs-theme="light"]) {
    /* Light-theme faces — muted, one notch off pure so they read as anodised
       metal stock rather than a web toast. */
    --ev-danger:   #b23c3c;   /* oxidized red   — AA 5.0 on --ev-danger-fg  */
    --ev-success:  #367042;   /* patina green   — darkened to clear AA 4.5  */
    --ev-warning:  #b3852a;   /* brass amber    — dark ink, AA 5.2          */
    --ev-info:     #33719f;   /* steel blue     — darkened to clear AA 4.5  */

    /* Ink that sits ON a semantic face. All four light faces are dark enough
       that near-white ink clears AA (verified against the rendered pixels). */
    --ev-danger-fg:  #fbeaea;
    --ev-success-fg: #eaf4ec;
    --ev-warning-fg: #241a04;   /* amber is the pale one -> dark ink */
    --ev-info-fg:    #eaf3fb;

    /* The same four faces as BARE CHANNEL TRIPLES. Same reason as
       --ev-accent-rgb in tokens.css: Bootstrap's colour utilities are written
       `rgba(var(--bs-danger-rgb), var(--bs-bg-opacity))`, so remapping
       --bs-danger alone leaves .text-bg-danger / .bg-danger on Bootstrap's own
       #dc3545. Stated beside the hex they decompose so the adapter never has to
       carry a literal. MOVE THEM WITH THE HEX ABOVE — nothing checks the pair.
       (cortex-wp0qzvk) */
    --ev-danger-rgb:  178, 60, 60;    /* = #b23c3c */
    --ev-success-rgb: 54, 112, 66;    /* = #367042 */
    --ev-warning-rgb: 179, 133, 42;   /* = #b3852a */
    --ev-info-rgb:    51, 113, 159;   /* = #33719f */
}

:is([data-ev-theme="dark"], [data-bs-theme="dark"]) {
    /* Dark-theme faces — a touch lighter/cleaner so a small chip stays legible
       on the dark bench without blooming. */
    --ev-danger:   #b8433f;   /* deepened so near-white ink clears AA 4.5   */
    --ev-success:  #4f9b60;
    --ev-warning:  #c99a38;
    --ev-info:     #4f93cc;

    /* Danger in dark keeps a LIGHT ink (a hot red lamp reads with white ink);
       the other three faces are pale enough in dark to take dark ink. */
    --ev-danger-fg:  #fbeaea;
    --ev-success-fg: #08210e;
    --ev-warning-fg: #241a04;
    --ev-info-fg:    #061a2a;

    /* Dark faces as bare triples (see the light block for why these exist). */
    --ev-danger-rgb:  184, 67, 63;    /* = #b8433f */
    --ev-success-rgb: 79, 155, 96;    /* = #4f9b60 */
    --ev-warning-rgb: 201, 154, 56;   /* = #c99a38 */
    --ev-info-rgb:    79, 147, 204;   /* = #4f93cc */
}

/* --------------------------------------------------------------------------
   Base badge. Silhouette is shared by both planes; the plane modifiers own the
   shadow stack. Face colour + ink default to the neutral machined stock so a
   colourless `.ev-badge` is still a legible chip. A colour class overrides the
   face and ink via the semantic tokens.
   -------------------------------------------------------------------------- */
.ev-badge {
    --ev-badge-face: var(--ev-metal-hi);   /* overridden by colour classes */
    --ev-badge-ink:  var(--ev-ink-dim);
    --ev-badge-c:    var(--ev-info);        /* lamp/glow hue if uncoloured   */

    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.28em 0.62em;
    font: 600 0.72rem/1 var(--ev-font-sans);
    letter-spacing: 0.02em;
    color: var(--ev-badge-ink);
    background-color: var(--ev-badge-face);
    border-radius: var(--ev-radius-sm);
    /* default plane = sticker (raised) */
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

/* Pill silhouette — radius exceeds height, so it reads as a rounded token. */
.ev-badge--pill {
    border-radius: var(--ev-radius-pill);
    padding-left: 0.8em;
    padding-right: 0.8em;
}

/* --------------------------------------------------------------------------
   PLANE — sticker (raised). A metallic sticker pressed onto the surface: a
   domed moulded cap (inner shoulder highlight + inner shoulder shadow) that
   CASTS onto the surface below (outer contact + ambient). This is the moulded
   plane's shadow grammar, reused. `.ev-badge` already carries it; the explicit
   class exists for readability and to override an `--inset` earlier in a list.
   -------------------------------------------------------------------------- */
.ev-badge--sticker {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

/* --------------------------------------------------------------------------
   PLANE — inset (lowered). An embossed inset machined INTO the surface: a real
   cut with an inner lip + wall and NO outer depth shadow (Rule 1 — a cut casts
   inward, not outward). Uses the rank-2 carve stack (a badge is a small, fine
   cut, not a rank-1 panel). The lit rim is the burr of displaced material.
   -------------------------------------------------------------------------- */
.ev-badge--inset {
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
}

/* --------------------------------------------------------------------------
   SEMANTIC COLOUR — the face becomes the alert colour, ink flips to its fg.
   Also seeds --ev-badge-c so a live lamp on the same chip glows in-hue.
   -------------------------------------------------------------------------- */
.ev-badge--danger  { --ev-badge-face: var(--ev-danger);  --ev-badge-ink: var(--ev-danger-fg);  --ev-badge-c: var(--ev-danger); }
.ev-badge--success { --ev-badge-face: var(--ev-success); --ev-badge-ink: var(--ev-success-fg); --ev-badge-c: var(--ev-success); }
.ev-badge--warning { --ev-badge-face: var(--ev-warning); --ev-badge-ink: var(--ev-warning-fg); --ev-badge-c: var(--ev-warning); }
.ev-badge--info    { --ev-badge-face: var(--ev-info);    --ev-badge-ink: var(--ev-info-fg);    --ev-badge-c: var(--ev-info); }

/* A semantic face owns readable ordinary typography inside it. Inheritance is
   insufficient across a consumer cascade: a later bare `small { color: … }`
   becomes a specified value on the child and silently defeats the paired ink.

   Keep the variant class OUTSIDE :where() so this one class beats later bare
   element rules. Keep the element list INSIDE :where() so a later consumer
   class (or component-targeted selector) can still override intentionally.
   Links, code and arbitrary spans are deliberately absent: those are separate
   channels whose colour may be meaningful. */
:is(
    .ev-badge--danger,
    .ev-badge--success,
    .ev-badge--warning,
    .ev-badge--info
) :where(p, small, h1, h2, h3, h4, h5, h6) {
    color: inherit;
}

/* --------------------------------------------------------------------------
   LIVE — the "this badge is live" attribute (RETHOUGHT, cortex-lf0ji9b).

   OLD PROBLEM: `--live` drew a small lamp dot in the badge's OWN semantic hue,
   so on a coloured face (a danger badge, a success badge) the dot was the same
   colour as the background and vanished. Liveness was invisible on exactly the
   badges that most need it.

   NEW: liveness is LIGHT on the badge itself, not a hidden hued dot. A live
   badge wears a bright achromatic GLOWING RIM (a hairline of light around the
   chip) plus a hair of lifted brightness — the chip reads as "lit / active".
   Because the glow is WHITE-alpha light (achromatic), it contrasts on every
   semantic face AND on the neutral machined stock, in both themes — the exact
   fix for the same-colour-invisible bug. This is the SAME "live = light rising"
   language as the glass lamp's ON/pulse (glass.css `ev-live-breathe`): a live
   badge that also pulses breathes on the identical calm curve, so "live" looks
   the same across lamps and badges.

   `--live`          steady lit rim (visible, static).
   `--live-animated` the rim BREATHES on the shared calm curve (motion-gated).
   A tiny lit lens still leads the label (a physical "power" tell), but it is
   now drawn ACHROMATIC (white light), so it is visible on any face too and no
   longer competes with the semantic hue.
   -------------------------------------------------------------------------- */

/* the shared "live intensity" driver: 0 (rest) .. 1 (peak). --live pins it lit;
   --live-animated breathes it. The rim + lens brightness both read from it, so
   one curve drives the whole badge's liveness. */
.ev-badge--live,
.ev-badge--live-animated {
    --ev-live: 1;
    /* a glowing achromatic rim rides on top of the plane's own shadow stack —
       an outer ring of light (the chip is "lit"), scaled by --ev-live. White
       alpha only: contrasts on every face, adds no hue. Layered BEFORE the base
       box-shadow via a stacked value so the plane's fabrication shadows survive. */
    box-shadow:
        0 0 0 1px    rgba(255, 255, 255, calc(0.40 * var(--ev-live))),
        0 0 5px 0    rgba(255, 255, 255, calc(0.45 * var(--ev-live))),
        0 0 11px 1px rgba(255, 255, 255, calc(0.28 * var(--ev-live))),
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}
/* keep the inset plane's carve stack when live + inset (no outer plane shadow) */
.ev-badge--live.ev-badge--inset,
.ev-badge--live-animated.ev-badge--inset {
    box-shadow:
        0 0 0 1px    rgba(255, 255, 255, calc(0.40 * var(--ev-live))),
        0 0 5px 0    rgba(255, 255, 255, calc(0.45 * var(--ev-live))),
        0 0 11px 1px rgba(255, 255, 255, calc(0.28 * var(--ev-live))),
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
}

/* the leading lit lens — now ACHROMATIC (white light), so it reads on any face.
   A small lit dome: hot white core -> soft white rim, with a white bloom scaled
   by --ev-live. It is a "power on" tell, not a hued status dot. */
.ev-badge--live::before,
.ev-badge--live-animated::before {
    content: '';
    flex: 0 0 auto;
    width: 0.6em;
    height: 0.6em;
    border-radius: 50%;
    background:
        radial-gradient(circle at 42% 36%,
            rgba(255, 255, 255, 0.98) 0%,
            rgba(255, 255, 255, 0.80) 34%,
            rgba(255, 255, 255, 0.42) 62%,
            rgba(255, 255, 255, 0.18) 100%);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, calc(0.35 * var(--ev-live))),
        0 0 4px 1px rgba(255, 255, 255, calc(0.55 * var(--ev-live)));
}

/* --------------------------------------------------------------------------
   PULSE — the badge breathes on the SHARED live curve (same as the glass lamp,
   glass.css `ev-live-breathe`). Motion-gated. We animate the --ev-live driver
   itself, so the rim glow AND the lens bloom breathe together in one motion —
   a soft, calm brightening, never a strobe. `.ev-badge-lamp--animated` (the standalone
   lamp) shares the same curve.
   -------------------------------------------------------------------------- */
@property --ev-live {
    syntax: '<number>';
    inherits: true;
    initial-value: 1;
}

/* Animations are defined UNCONDITIONALLY here; the platform motion gate
   (src/components/motion.css) disables them when the OS asks for reduced
   motion AND the library-level `data-ev-motion` override does not force them
   on, or when it forces them off. Defining them here (not inside a
   prefers-reduced-motion media query) is what lets the override force them ON
   even on a reduce-motion OS. */
.ev-badge--live-animated {
    animation: ev-badge-breathe 2.6s ease-in-out infinite;
}
.ev-badge-lamp--animated {
    animation: ev-badge-lamp-breathe 2.6s ease-in-out infinite;
}

/* breathe the shared --ev-live driver (badge rim + lens glow ride it). Never
   drops fully dark at the trough — a live badge is always clearly lit. Matches
   the glass lamp's ev-live-breathe trough (0.42..1). */
@keyframes ev-badge-breathe {
    0%, 100% { --ev-live: 0.42; }
    50%      { --ev-live: 1; }
}
/* the standalone lamp breathes its own bloom on the same curve/timing. */
@keyframes ev-badge-lamp-breathe {
    0%, 100% {
        box-shadow:
            0 0 0 1px color-mix(in srgb, var(--ev-badge-c) 55%, transparent),
            0 0 3px 1px color-mix(in srgb, var(--ev-badge-c) 50%, transparent),
            0 0 6px 1px color-mix(in srgb, var(--ev-badge-c) 22%, transparent);
    }
    50% {
        box-shadow:
            0 0 0 1px color-mix(in srgb, var(--ev-badge-c) 68%, transparent),
            0 0 6px 2px color-mix(in srgb, var(--ev-badge-c) 78%, transparent),
            0 0 13px 4px color-mix(in srgb, var(--ev-badge-c) 46%, transparent);
    }
}

/* --------------------------------------------------------------------------
   NON-TEXT FORM — .ev-badge-lamp — the lamp on its own, no label. A standalone
   status indicator. Same lit-dome skeuomorphism as the badge lamp, sized a
   touch larger so it is a legible dot. Defaults to info-blue; colour classes
   set the hue. `.ev-badge-lamp--animated` pulses (gated above).
   -------------------------------------------------------------------------- */
.ev-badge-lamp {
    --ev-badge-c: var(--ev-info);
    display: inline-block;
    width: 0.72em;
    height: 0.72em;
    border-radius: 50%;
    vertical-align: middle;
    background:
        radial-gradient(circle at 38% 34%,
            rgba(255, 255, 255, 0.95) 0%,
            rgba(255, 255, 255, 0.35) 14%,
            var(--ev-badge-c) 46%,
            color-mix(in srgb, var(--ev-badge-c) 72%, #000) 100%);
    box-shadow:
        0 0 0 1px color-mix(in srgb, var(--ev-badge-c) 55%, transparent),
        0 0 4px 1px color-mix(in srgb, var(--ev-badge-c) 62%, transparent),
        0 0 9px 2px color-mix(in srgb, var(--ev-badge-c) 34%, transparent);
}

.ev-badge-lamp--danger  { --ev-badge-c: var(--ev-danger); }
.ev-badge-lamp--success { --ev-badge-c: var(--ev-success); }
.ev-badge-lamp--warning { --ev-badge-c: var(--ev-warning); }
.ev-badge-lamp--info    { --ev-badge-c: var(--ev-info); }

/* A status word and its lamp are one compact readout. This carrier owns the
   baseline and gap in prose, tables and dense lists so authors never nudge a
   bare lamp by hand. Its shallow slot makes status an instrument reading,
   rather than a raised sticker attached to each row. */
.ev-status {
    display: inline-flex;
    align-items: center;
    gap: 0.55em;
    min-height: 1.6rem;
    padding: 0.2rem 0.55rem;
    border-radius: calc(var(--ev-radius-sm) - 2px);
    background: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow: var(--ev-r3-line), var(--ev-r3-lip), var(--ev-r3-wall);
    color: var(--ev-ink);
    font: var(--ev-weight-medium) var(--ev-text-small) / 1 var(--ev-font-sans);
    white-space: nowrap;
}

.ev-status .ev-badge-lamp {
    flex: 0 0 auto;
    vertical-align: 0;
}

/* ===== src/components/entity.css ===== */
/* ==========================================================================
   Evident primitive — entity tokens (canonical) — cortex-pmldhto / cortex-8bdulku
   ==========================================================================

   "The text IS the token." An entity token identifies an entity by its GLYPH
   plus its PLATE SILHOUETTE — never by colour (a blue fill reads as "selected"
   in a list) and never by material (material means elevation). It is a shallow
   rank-3 cut into whatever face it sits on.

   This file SUPERSEDES the earlier `src/components/entity-tokens.css`, which
   let each silhouette carry its OWN rim treatment. That divergence is exactly
   the defect the founder flagged (feedback #3, 2026-07-27):

     "Hexagon and user look mildly different from square and pill. Make sure
      they have the same border/inset. [...] the lopsided swoops."

   The root cause was three DIFFERENT rims for four shapes:
     - pill / rect  used the full cut stack  r3-line + r3-lip + r3-rim.
     - hex          could not (clip-path clips box-shadow away), so it faked a
                    rim with a ::before at inset:1px — a hard clipped colour
                    edge, not the soft line+lip+rim of a real cut.
     - org (user)   used r3-rim + `inset 0 0 6px` — an off-centre inner glow
                    that read as a LOPSIDED SWOOP (the "swoops" complaint).

   THE 2026-07-28 RESHAPE (cortex-8bdulku). Founder: "the user entity token
   (the one with semirounded opposing sides) should be phased out, but hexagon
   can come back in." So the shape set is now PILL, SQUARE, HEXAGON — the
   organic/user leaf-lozenge is REMOVED, and hex RETURNS.

   Hex was originally dropped (pmldhto) only because a plain `clip-path` clips
   the `box-shadow` rim away, so hex could not carry the same rim as its
   siblings — and rim parity was the whole point of pmldhto. That specific
   obstacle is now SOLVED rather than avoided (see "THE HEXAGON RIM" below):
   hex carries the IDENTICAL line + lip + rim as pill and square, so the
   pmldhto parity invariant holds across all three shapes.

   ONE RIM, STATED ONCE. Every shape composes the IDENTICAL
   `--ev-r3-line + --ev-r3-lip + --ev-r3-rim` treatment. No shape invents its
   own border or inset. The old off-centre `inset 0 0 6px` glow (the lopsided
   swoop) stays gone. Entity tokens carry no directional sheen.

   API
     .ev-entity-glyph             20 × 20 external-sprite SVG carrier
     .ev-entity-token             base token (shallow cut: glyph gutter + name)
     .ev-entity-token--pill       round both ends
     .ev-entity-token--square     tight all four corners
     .ev-entity-token--hexagon    pointed machined hex (returns; was dropped in pmldhto)
     .ev-entity-token--inline     smaller inline variant
     .ev-entity-token--clickable  opt-in hover-enlarge for interactive tokens;
                                  `a.ev-entity-token` gets it automatically.
     .ev-entity-token__glyph      glyph gutter (fixed width across ALL shapes)
     .ev-entity-token__name       the engraved name

   THE FIXED GUTTER is the founder's hard rule: the glyph region is exactly one
   width in EVERY shape, so a mixed column has all names on one x. Silhouettes
   differ in outline only and pay for their own end with padding on the far
   side, never out of the gutter.
   ========================================================================== */

/* The rim highlight is theme material, not element state. Put it on the same
   inherited scopes as the core ramp so the nearest explicit theme boundary is
   authoritative in both directions. A descendant selector cannot express
   that contract: excluding any light ancestor also suppresses a legitimate
   dark insert inside a light page. */
:root,
:is([data-ev-theme="light"], [data-bs-theme="light"]) {
    --ev-entity-token-rim-color: rgba(250, 250, 250, 0.30);
}

:is([data-ev-theme="dark"], [data-bs-theme="dark"]) {
    --ev-entity-token-rim-color: rgba(245, 245, 245, 0.06);
}

/* The reusable entity-glyph carrier. Geometry stays in
   dist/evident-glyphs.svg; consumers reference one public symbol rather than
   copying path data into their markup:

     <svg class="ev-entity-glyph" viewBox="0 0 20 20"
          aria-hidden="true" focusable="false">
       <use href="/lib/evident/evident-glyphs.svg#ev-glyph-domain"></use>
     </svg>

   The sprite paints with currentColor, so the carrier inherits ink from its
   context. The base carrier is the drawing contract's 20 × 20 size. Composed
   slots below override only its rendered dimensions; they do not redraw it,
   tune its stroke, or create a generic icon-size API. */
.ev-entity-glyph {
    display: block;
    inline-size: 20px;
    block-size: 20px;
    flex: 0 0 auto;
    color: inherit;
}

.ev-entity-token {
    --ev-tok-glyph-w: 30px;
    --ev-tok-name-gap: 8px;

    /* ONE RIM, STATED ONCE. Every shape composes exactly this stack — the
       whole point of the fix. Change the rim here and all three shapes move
       together; no shape may redefine it. */
    --ev-entity-token-rim:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-rim);

    /* The outer-rim highlight as a COLOUR (not a full box-shadow value), so
       the hexagon can reproduce the same 1px outer ring via drop-shadow —
       which traces the clipped hexagon alpha, whereas an outer box-shadow
       would be clipped away. This MUST track the colour inside --ev-r3-rim in
       tokens.css (single-file constraint of cortex-8bdulku: the reshape may
       only touch this component). */

    /* Hover-enlarge target. Neutral at rest; the clickable modifier lifts it
       under a prefers-reduced-motion guard. Named so the transform is stated
       once and every shape scales identically. */
    --ev-entity-token-scale: 1;

    display: inline-grid;
    grid-template-columns: var(--ev-tok-glyph-w) auto;
    align-items: center;
    height: 24px;
    padding: 0 10px 0 0;

    /* shallow rank-3 cut into the host face */
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n3));
    box-shadow: var(--ev-entity-token-rim);

    color: var(--ev-ink);
    /* Keep the fixed 24px plate compact, but give IBM Plex Sans its real
       ascender/descender line box. A unit line-height can crop the bottom of
       marked names (notably g, p, q and y) when a consumer clips the token to
       its silhouette; 1.2 still leaves 4.5px of total vertical land here. */
    font: 500 12.5px/1.2 var(--ev-font-sans);
    letter-spacing: 0.005em;
    text-decoration: none;
    white-space: nowrap;
    position: relative;

    transform: scale(var(--ev-entity-token-scale));
    /* transform-origin centre so the whole token grows evenly about itself */
    transform-origin: center;
}

/* The glyph gutter — a scribe division (a border, geometry, not a shadow). */
.ev-entity-token__glyph {
    display: grid;
    place-items: center;
    height: 100%;
    border-right: 1px solid var(--ev-rule-strong);
}
.ev-entity-token__glyph svg { width: 12px; height: 12px; display: block; }
.ev-entity-token__glyph .ev-entity-glyph { color: var(--ev-ink-dim); }
.ev-entity-token__glyph svg [stroke] { stroke: var(--ev-ink-dim); }
.ev-entity-token__glyph svg [fill]:not([fill="none"]) { fill: var(--ev-ink-dim); }

/* The engraved name — flat text (Invariant L3), padded off the divider. */
.ev-entity-token__name {
    padding-left: var(--ev-tok-name-gap);
    color: var(--ev-ink);
}

/* ---- THE THREE SILHOUETTES ------------------------------------------------
   pill and square are pure border-radius, so the SAME box-shadow rim
   (--ev-entity-token-rim, inherited from .ev-entity-token) survives on both. hexagon uses
   clip-path for its pointed outline and rebuilds that exact rim (see below),
   so all three share the identical line + lip + rim — the whole point. */

/* PILL — round both ends. */
.ev-entity-token--pill { border-radius: 999px; }

/* SQUARE — tight machined corners. */
.ev-entity-token--square { border-radius: 3px; }

/* HEXAGON — pointed machined plate; returns to the set (cortex-8bdulku).

   THE HEXAGON RIM — how it carries the SAME rim as pill/square despite the
   pointed outline. A plain `clip-path` clips box-shadow, which is exactly why
   hex was dropped in pmldhto. The fix splits the rim by which layers survive
   the clip:

     - LINE + LIP (both `inset`): kept as real box-shadow on the clipped
       element. Inset shadows paint INSIDE the border-box, so the clip does not
       remove them — these are the SAME --ev-r3-line / --ev-r3-lip tokens the
       siblings use, pixel for pixel.

     - RIM (the outer `0 0 0 1px` highlight, NOT inset): an outer box-shadow
       WOULD be clipped away, so instead it is drawn with `drop-shadow`, which
       traces the clipped hexagon's alpha and therefore wraps every edge —
       INCLUDING the two diagonal points — with a uniform ~1px ring. (A
       geometry-expanded ::before was tried and rejected: expanding a polygon
       by ±1px in x/y thins the ring on the diagonal edges, so the points read
       lighter than pill/square. drop-shadow's alpha-trace is uniform.) Blur is
       ~0, so the ring is as crisp as the siblings' box-shadow spread; the
       colour is --ev-entity-token-rim-color, the same value --ev-r3-rim carries.

   Result: hex composes the identical line + lip + rim as pill and square, no
   shape-specific border or inset — the pmldhto parity invariant, now upheld
   WITH the hexagon in the set rather than by excluding it. */
.ev-entity-token--hexagon {
    --ev-entity-token-hex-point: 11px; /* horizontal inset of the two side points */

    /* silhouette */
    clip-path: polygon(
        var(--ev-entity-token-hex-point) 0,
        calc(100% - var(--ev-entity-token-hex-point)) 0,
        100% 50%,
        calc(100% - var(--ev-entity-token-hex-point)) 100%,
        var(--ev-entity-token-hex-point) 100%,
        0 50%
    );

    /* keep ONLY the inset layers as box-shadow (they survive the clip) */
    box-shadow: var(--ev-r3-line), var(--ev-r3-lip);

    /* rebuild the outer rim so it follows the clipped outline uniformly;
       stacked to reach the token opacity, ~0 blur to stay a crisp 1px ring. */
    filter:
        drop-shadow(0 0 0.01px var(--ev-entity-token-rim-color))
        drop-shadow(0 0 0.01px var(--ev-entity-token-rim-color))
        drop-shadow(0 0 0.01px var(--ev-entity-token-rim-color));

    /* the points eat horizontal space OUTSIDE the glyph gutter, so the gutter
       itself stays invariant across all three shapes. */
    padding-left: 13px;
    padding-right: 21px;
}
.ev-entity-token--hexagon .ev-entity-token__glyph {
    /* the scribe divider does not run through the left point's bare shoulder */
    margin-left: 2px;
}

/* ---- CLICKABLE — the hover-enlarge (founder feedback #11) -----------------
   "The entity tokens should have a satisfying hover (when clickable), maybe
    slight animated enlargement of the whole token."

   Opt-in via .ev-entity-token--clickable, and automatic on any `a.ev-entity-token` (a link IS
   interactive). At rest the token is identical to a static one — no extra
   affordance ink — so the enlarge is the whole signal. The scale is applied
   through --ev-entity-token-scale so it composes with any shape (hexagon included)
   without redefining the transform. cursor:pointer states clickability even
   with motion disabled. */
.ev-entity-token--clickable,
a.ev-entity-token {
    cursor: pointer;
}

/* The animated enlargement — motion is OPT-IN per Invariant L4 (no glow/pulse)
   and per the platform reduced-motion contract. The scale-on-hover is declared
   unconditionally; the platform motion gate (src/components/motion.css) strips
   the transition for reduced-motion users (unless `data-ev-motion="on"` forces
   it). Without motion the token is fully usable and simply snaps rather than
   eases. */
.ev-entity-token--clickable,
a.ev-entity-token {
    transition: transform 140ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
.ev-entity-token--clickable:hover,
a.ev-entity-token:hover {
    --ev-entity-token-scale: 1.06;
}
/* on press it settles back toward rest — a physical "it moved" beat */
.ev-entity-token--clickable:active,
a.ev-entity-token:active {
    --ev-entity-token-scale: 1.02;
    transition-duration: 60ms;
}

/* ---- inline variant — scales the gutter down proportionally ---------------- */
.ev-entity-token--inline {
    --ev-tok-glyph-w: 22px;
    --ev-tok-name-gap: 6px;
    height: 18px;
    font-size: 11px;
}
.ev-entity-token--inline .ev-entity-token__glyph svg { width: 10px; height: 10px; }

/* ===== src/components/entity-header.css ===== */
/* ==========================================================================
   Evident component — two-band entity header
   ==========================================================================

   A composed identity surface: entity identity and actions occupy the raised
   upper land, while local navigation is milled into the lower band.

   API
     .ev-entity-header
     .ev-entity-header--banded
     .ev-entity-header--identity-lead
     .ev-entity-header__rim
     .ev-entity-header__identity
     .ev-entity-header__identity-mark
     .ev-entity-header__identity-mark--pill|--square|--hexagon
     .ev-entity-header__content
     .ev-entity-header__title
     .ev-entity-header__meta
     .ev-entity-header__status
     .ev-entity-header__status-indicator
     .ev-entity-header__status-label
     .ev-entity-header__action-lobe
     .ev-entity-header__action-cluster
     .ev-entity-header__action
     .ev-entity-header__action--icon-only|--danger|--pressed
     .ev-entity-header__rail
     .ev-entity-header__rail-item
     .ev-entity-header__rail-item--selected

   The seated action geometry is load-bearing. Evident measures the rendered
   action cluster and adds its declared inline land. As a cluster grows from
   2:1 to 4:1, the enhancer adds at most one flank pixel per side as straight
   edges replace rounded ends in the visible perimeter; consumers never guess
   a lobe width. The lobe and every action share
   one 10px corner radius; icon-only removes a legend but does not turn the part
   into a circle. The historical 5px/5px figure centres the 30px BORDER BOX in
   the lobe's complete 40px height, explicitly including the 9px upper rim.
   The visible face is then shifted in the positive block direction by half
   its measured theme-specific bottom overhang. The action surface is the same
   theme-matched sprung socket used by confirm: one part, one silhouette, one
   press story without overpowering the host lobe.

   That action is HOST-ELEMENT NEUTRAL: it draws identically on an `<a>` that
   navigates and a `<button>` that mutates, so a consumer picks its element for
   the semantics it needs and never for the appearance it gets. The rule that
   holds that line, and why the obvious one-line form of it is not enough, sits
   with the action's own declarations below.

   RESPONSIVE CONTRACT
   -------------------
   The standalone header is its own named inline-size query container. The lead
   plate therefore collapses on the header's OWN width rather than the viewport's:
   a wide header inside a narrow column keeps its lead plate, and a header in a
   cramped column loses it even on a desktop screen. That is the whole difference
   between this option and the page-local rule it generalizes, which gated the
   large plate on `min-width: 992px` and so grew the plate for a column that had
   not itself grown. At
   460px and below the upper land recomposes: the fixed identity plate and the
   action lobe remain the two shoulders, while the name and metadata take the
   full surviving land beneath them. At the matching narrow viewport, the
   action keeps its accessible name but yields its visible legend; its 30px key
   retains the same painted seating contract as wider actions; the superseded
   5px/5px figure describes its BORDER BOX only. The rail remains one
   horizontally traversable channel. Headers inside an entity
   drawer keep the drawer's separate icon-only cramped contract, because only
   that wrapper knows the toggle and reserved socket as one composition.
   ========================================================================== */

.ev-entity-header {
    position: relative;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 24px;
    overflow: hidden;
    color: var(--ev-ink);
    background-color: var(--ev-metal-hi);
    background-image:
        linear-gradient(
            var(--ev-swoop-angle),
            var(--ev-lum-hi) 0%,
            var(--ev-lum-hi) 9%,
            var(--ev-lum-mid) 33%,
            transparent 66%,
            var(--ev-lum-lo) 100%
        );
    background-repeat: no-repeat;
    border-radius: var(--ev-entity-header-shell-radius);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-shoulder-2),
        var(--ev-shoulder-3),
        var(--ev-contact-2),
        var(--ev-ambient-2);
    container-type: inline-size;
    container-name: ev-entity-header;
}

.ev-entity-header--banded {
    /* evident-entity-header.js resolves this from the rendered cluster plus
       twice --ev-entity-header-action-inset-x and its bounded silhouette land.
       Until that enhancement runs, the lobe itself remains intrinsically laid
       out; only this decorative pocket contour uses the zero fallback. */
    --ev-entity-header-pocket-radius:
        calc(var(--ev-entity-header-shell-radius) - var(--ev-entity-header-rim-width));
    --ev-entity-header-pocket-start:
        calc(var(--ev-entity-header-rim-width) + var(--ev-entity-header-pocket-radius))
        var(--ev-entity-header-rim-width);
    --ev-entity-header-pocket-run:
        hline to calc(
            100% - var(--ev-entity-header-lobe-offset) -
            var(--ev-entity-header-lobe-span, 0px) -
            var(--ev-entity-header-lobe-radius) -
            var(--ev-entity-header-rim-width)
        ),
        arc to calc(
            100% - var(--ev-entity-header-lobe-offset) -
            var(--ev-entity-header-lobe-span, 0px) -
            var(--ev-entity-header-rim-width)
        ) calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-radius)
        ) of
            var(--ev-entity-header-lobe-radius)
            var(--ev-entity-header-lobe-radius) cw,
        vline to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-dip) -
            var(--ev-entity-header-lobe-radius)
        ),
        arc to calc(
            100% - var(--ev-entity-header-lobe-offset) -
            var(--ev-entity-header-lobe-span, 0px) -
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-radius)
        ) calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-dip)
        ) of
            var(--ev-entity-header-lobe-radius)
            var(--ev-entity-header-lobe-radius) ccw,
        hline to calc(
            100% - var(--ev-entity-header-lobe-offset) -
            var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-lobe-radius)
        ),
        arc to calc(
            100% - var(--ev-entity-header-lobe-offset) -
            var(--ev-entity-header-rim-width)
        ) calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-dip) -
            var(--ev-entity-header-lobe-radius)
        ) of
            var(--ev-entity-header-lobe-radius)
            var(--ev-entity-header-lobe-radius) ccw,
        vline to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-radius)
        ),
        arc to calc(
            100% - var(--ev-entity-header-lobe-offset) -
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-lobe-radius)
        ) var(--ev-entity-header-rim-width) of
            var(--ev-entity-header-lobe-radius)
            var(--ev-entity-header-lobe-radius) cw,
        hline to calc(
            100% - var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-pocket-radius)
        ),
        arc to calc(100% - var(--ev-entity-header-rim-width))
            calc(
                var(--ev-entity-header-rim-width) +
                var(--ev-entity-header-pocket-radius)
            ) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw,
        vline to calc(
            100% - var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-pocket-radius)
        ),
        arc to calc(
            100% - var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-pocket-radius)
        ) calc(100% - var(--ev-entity-header-rim-width)) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw,
        hline to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-pocket-radius)
        ),
        arc to var(--ev-entity-header-rim-width)
            calc(
                100% - var(--ev-entity-header-rim-width) -
                var(--ev-entity-header-pocket-radius)
            ) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw,
        vline to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-pocket-radius)
        ),
        arc to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-pocket-radius)
        ) var(--ev-entity-header-rim-width) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw;

    flex-direction: column;
    align-items: stretch;
    min-height: 176px;
    padding: var(--ev-entity-header-content-inset);
    gap: 24px;
    background-image:
        linear-gradient(
            var(--ev-swoop-angle),
            var(--ev-lum-hi) 0%,
            var(--ev-lum-hi) 14%,
            var(--ev-lum-mid) 40%,
            transparent 70%,
            var(--ev-lum-lo) 100%
        );
}

.ev-entity-header--banded::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    box-shadow: inset 0 0 12px -6px var(--ev-entity-header-chamfer-shade);
    clip-path:
        shape(
            from var(--ev-entity-header-pocket-start),
            var(--ev-entity-header-pocket-run),
            close
        );
}

.ev-entity-header--banded:not(:has(.ev-entity-header__action-lobe > *)) {
    --ev-entity-header-pocket-run:
        hline to calc(
            100% - var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-pocket-radius)
        ),
        arc to calc(100% - var(--ev-entity-header-rim-width))
            calc(
                var(--ev-entity-header-rim-width) +
                var(--ev-entity-header-pocket-radius)
            ) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw,
        vline to calc(
            100% - var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-pocket-radius)
        ),
        arc to calc(
            100% - var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-pocket-radius)
        ) calc(100% - var(--ev-entity-header-rim-width)) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw,
        hline to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-pocket-radius)
        ),
        arc to var(--ev-entity-header-rim-width)
            calc(
                100% - var(--ev-entity-header-rim-width) -
                var(--ev-entity-header-pocket-radius)
            ) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw,
        vline to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-pocket-radius)
        ),
        arc to calc(
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-pocket-radius)
        ) var(--ev-entity-header-rim-width) of
            var(--ev-entity-header-pocket-radius)
            var(--ev-entity-header-pocket-radius) cw;
}

.ev-entity-header__rim {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background-image:
        linear-gradient(
            var(--ev-entity-header-chamfer-lit),
            var(--ev-entity-header-chamfer-lit)
        ),
        linear-gradient(
            var(--ev-entity-header-chamfer-inner),
            var(--ev-entity-header-chamfer-inner)
        );
    clip-path:
        shape(
            evenodd
            from var(--ev-entity-header-shell-radius) 0,
            hline to calc(100% - var(--ev-entity-header-shell-radius)),
            arc to 100% var(--ev-entity-header-shell-radius) of
                var(--ev-entity-header-shell-radius)
                var(--ev-entity-header-shell-radius) cw,
            vline to calc(100% - var(--ev-entity-header-shell-radius)),
            arc to calc(100% - var(--ev-entity-header-shell-radius)) 100% of
                var(--ev-entity-header-shell-radius)
                var(--ev-entity-header-shell-radius) cw,
            hline to var(--ev-entity-header-shell-radius),
            arc to 0 calc(100% - var(--ev-entity-header-shell-radius)) of
                var(--ev-entity-header-shell-radius)
                var(--ev-entity-header-shell-radius) cw,
            vline to var(--ev-entity-header-shell-radius),
            arc to var(--ev-entity-header-shell-radius) 0 of
                var(--ev-entity-header-shell-radius)
                var(--ev-entity-header-shell-radius) cw,
            close,
            move to var(--ev-entity-header-pocket-start),
            var(--ev-entity-header-pocket-run),
            close
        );
}

.ev-entity-header--banded::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    pointer-events: none;
    box-shadow: inset 0 0 0 1px var(--ev-entity-header-chamfer-crest);
}

.ev-entity-header--banded > *:not(.ev-entity-header__rim) {
    position: relative;
    z-index: 1;
}

.ev-entity-header__identity {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    width: 100%;
}

.ev-entity-header__identity-mark {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: var(--ev-entity-header-mark-size);
    height: var(--ev-entity-header-mark-size);
    background-color: var(--ev-metal);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-shoulder-2),
        var(--ev-contact-1);
}

.ev-entity-header__identity-mark--pill { border-radius: var(--ev-radius-pill); }
.ev-entity-header__identity-mark--square { border-radius: 8px; }
.ev-entity-header__identity-mark--hexagon {
    clip-path:
        polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
    box-shadow: none;
}

.ev-entity-header__identity-mark svg {
    display: block;
    width: var(--ev-entity-header-mark-glyph);
    height: var(--ev-entity-header-mark-glyph);
}

/* THE LEAD PLATE — the identity plate sized to lead its own land.
   ---------------------------------------------------------------
   Generalized from the periodic-job consumer, which enlarged this plate in
   page-local CSS. The size is that consumer's proven figure; what the library
   owns is the geometry that makes it mean something.

   The plate is CENTRED in the identity land, so its block-start and block-end
   clearances are always one number. When the plate is the tallest part of that
   land — the shape this option exists for — that number is the shell's own
   content inset, and the inline-start clearance joins it: one figure, three
   sides, no per-side tuning. Copy taller than the plate sets the land instead,
   and the two block clearances stay equal to each other while growing past the
   inset. Compare the compact plate, which hangs from the land's block-start
   edge because there it is the copy, not the plate, that leads.

   The equality is only reachable because the option also releases the slab's
   176px floor and derives one from the plate. Measured before the change: a
   rail-less header stands at exactly that floor with a 55px land, so a 72px
   plate would have left 64px of block-end slack under a 40px block-start
   clearance — the drawing would have asserted a centring that was not there
   (cortex-9ka1sc0). A header carrying a rail is taller than either floor, so
   only the rail-less shape is affected. */
.ev-entity-header--identity-lead {
    --ev-entity-header-mark-size: var(--ev-entity-header-mark-size-lead);
    --ev-entity-header-mark-glyph: var(--ev-entity-header-mark-glyph-lead);

    min-height:
        calc(
            var(--ev-entity-header-mark-size) +
            var(--ev-entity-header-content-inset) * 2
        );
}

/* The plate and the copy are centred against EACH OTHER, not each against the
   land, which is the same statement written once: whichever of the two is
   taller sets the land, and the shorter one centres in it. Hanging the copy
   from the land's block-start edge is right while the copy leads — that is the
   compact plate's own case — but under a leading plate it puts the copy's
   optical centre 8px above the plate's, which the crop shows before any
   measurement does. The action lobe is unaffected: it declares its own
   flex-start seating, because it belongs to the drawn lobe rather than to this
   row's alignment. */
.ev-entity-header--identity-lead .ev-entity-header__identity {
    align-items: center;
}

.ev-entity-header__identity-mark .ev-entity-glyph {
    color: var(--ev-ink-dim);
}

.ev-entity-header__identity-mark svg [stroke] { stroke: var(--ev-ink-dim); }
.ev-entity-header__identity-mark svg [fill]:not([fill="none"]) {
    fill: var(--ev-ink-dim);
}

.ev-entity-header__content {
    flex: 1 1 auto;
    min-width: 0;
}

.ev-entity-header__title {
    margin: 0;
    font-size: 29px;
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.016em;
}

.ev-entity-header__meta {
    margin: 8px 0 0;
    color: var(--ev-entity-header-ink-muted);
    font: 12.5px/normal var(--ev-font-mono);
    letter-spacing: 0.02em;
}

.ev-entity-header__status {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: 12px;
    vertical-align: middle;
}

.ev-entity-header__status-indicator {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--ev-accent);
    box-shadow: 0 0 5px var(--ev-accent);
}

.ev-entity-header__status-label {
    color: var(--ev-entity-header-ink-muted);
    font: 600 11px/normal var(--ev-font-sans);
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.ev-entity-header__action-lobe {
    --ev-socket-radius: var(--ev-entity-header-lobe-radius);

    align-self: flex-start;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-sizing: border-box;
    width: var(--ev-entity-header-lobe-span, max-content);
    padding-inline: var(--ev-entity-header-action-inset-x);
    /* This element is the complete un-cut lobe carrier, not a content-sized
       alias for its keys. Its inline edges therefore coincide with the two
       drawn cut walls and justify-content centres the cluster in that span.
       The identity row's 40px content inset ends 4px inside the right cut wall:
       27px offset + 9px rim - 40px content inset = -4px.

       Vertically, the identity row begins one complete lobe-height (rim + dip)
       below the card edge. Bring the keys back into that lobe, then retain the
       superseded 5px BORDER-BOX inset: 5 - 9 - 31 = -35px. The bounded
       enhancer adds --action-shift-y; positive values move the key face DOWN
       to balance its one-sided painted contact stack. Resting 0 preserves the
       complete no-JS initial render. */
    margin-block-start:
        calc(
            var(--ev-entity-header-action-inset-y) -
            var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-lobe-dip) +
            var(--ev-entity-header-action-shift-y, 0px)
        );
    margin-inline-end:
        calc(
            var(--ev-entity-header-lobe-offset) +
            var(--ev-entity-header-rim-width) -
            var(--ev-entity-header-content-inset)
        );
    margin-inline-start: 20px;
    position: relative;
    z-index: 1;
}

.ev-entity-header__action-lobe:empty,
.ev-entity-header__action-cluster:empty {
    display: none;
}

.ev-entity-header__action-cluster {
    display: flex;
    align-items: center;
    gap: var(--ev-entity-header-action-gap);
    inline-size: max-content;
}

.ev-entity-header__action-lobe .ev-confirm {
    --ev-confirm-idle-h: var(--ev-entity-header-seat-key-height);
}

.ev-entity-header__action {
    appearance: none;
    border: 0;
    box-sizing: border-box;
    cursor: pointer;
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--ev-entity-header-seat-key-height);
    padding-inline:
        var(--ev-entity-header-seat-key-padding-start)
        var(--ev-entity-header-seat-key-padding-end);
    border-radius: var(--ev-entity-header-seat-key-radius);
    color: var(--ev-socket-ink-dim);
    background-color: var(--ev-socket-face);
    background-image: var(--ev-socket-body);
    background-repeat: no-repeat;
    box-shadow:
        var(--ev-socket-top),
        var(--ev-socket-edge),
        var(--ev-socket-groove),
        var(--ev-socket-contact);
    font:
        600 var(--ev-entity-header-seat-key-font-size)/normal
        var(--ev-font-sans);
    letter-spacing: 0.02em;
    text-decoration: none;
    transform: translateY(0);
    transition:
        transform var(--ev-press-out) var(--ev-press-out-ease),
        box-shadow var(--ev-press-out) var(--ev-press-out-ease),
        color 120ms ease;
}

/* HOST-ELEMENT NEUTRALITY. The action is a PART, and which element hosts it is
   a semantic choice, not an appearance one: a destination is a real <a> so the
   browser can navigate, offer the target and report it as a link, and a
   mutation is a real <button>. Both are the same sprung socket, so both must
   draw the same. A consumer that emits the honest element must not be
   punished for it — and Nete was, its Edit and Terminate anchors arriving
   underlined while the identical Delete button did not (cortex-wo8oi61).

   The legend on a key is a laser mark: a tonal change on the socket face that
   removes no material (L3). An underline is a second mark ruled beneath it,
   and no cutter passed there — so it depicts a fabrication event that never
   happened (rule 1). The underline channel is spoken for besides: docs/
   interactive-ink.md gives it to `.ev-link`, where it means *pointer or focus
   has arrived on this text destination*. A key already says that with its own
   ink and edge, and its press with travel. A key that also underlined would
   spend the channel twice (rule 2).

   THE BASE DECLARATION ABOVE IS NOT SUFFICIENT ON ITS OWN, which is the part a
   later reader will be tempted to simplify away. It is (0,1,0), enough for the
   resting form a modern reboot states on the element — Bootstrap 5's
   `a { text-decoration: underline }` is (0,0,1), and the UA sheet's equivalent
   loses to any author rule. But a reboot that states the underline per state
   instead — `a:hover { text-decoration: underline }`, (0,1,1) — outranks it,
   and the existing hover rule below declares only `color`, so the key would
   come back underlined on arrival with nothing in this file appearing wrong.
   Enumerating the states inside `:is()` takes the specificity of its most
   specific argument, so each arm is (0,2,0) and clears both forms without
   reaching for `!important`.

   `--danger`, `--icon-only` and `--pressed` need no arm of their own: they are
   this same element in these same states. `:disabled` and `[aria-disabled]`
   are here for completeness of the property, not as a disabled contract — an
   entity-header action's only inert form remains a native `<button disabled>`,
   the visual-only modifier that once claimed that job having been retired
   because CSS cannot suppress activation. An unavailable destination is not a
   disabled link; it is not rendered as a link. */
.ev-entity-header__action:is(
    :link,
    :visited,
    :hover,
    :focus,
    :focus-visible,
    :active,
    :disabled,
    [aria-disabled="true"]
) {
    text-decoration: none;
}

.ev-entity-header__action > span { white-space: nowrap; }

.ev-entity-header__action svg {
    display: block;
    width: 13px;
    height: 13px;
}

.ev-entity-header__action:not(:disabled):hover {
    color: var(--ev-socket-ink);
}
.ev-entity-header__action--danger:not(:disabled):is(:hover, :focus-visible) {
    color: var(--ev-socket-danger-ink);
    box-shadow:
        var(--ev-socket-top),
        var(--ev-socket-danger-edge),
        var(--ev-socket-groove),
        var(--ev-socket-contact);
}

/* THE RING IS THE SAME PROPERTY QUESTION AS THE UNDERLINE, one state further in.
   Until this rule existed only `--danger` named an outline, so a NEUTRAL action
   fell through to the user agent's focus ring — and that ring is host-specific.
   Chromium draws `auto 1px` on both hosts but offsets it 1px on an `<a>` and 0px
   on a `<button>`, so the same part in the same state sat its ring at two
   different distances depending on which element carried it. Nothing in this
   file looked wrong, because the property was never named: exactly how the
   underline arrived (cortex-wo8oi61).

   `.ev-key` already shows the shape this family uses — the base part owns the
   ring and a `--danger` modifier re-points only its colour — so the action now
   does the same. The rail item one section down declares the same 2px accent
   ring against `--ev-accent-edge`, inset rather than outset because it is milled
   into a channel; a key stands proud of its land, so its ring sits outside it at
   the +2px `.ev-key` uses.

   This must stay ABOVE the `--danger` rule: both weigh (0,2,0), so document
   order is what lets the modifier win. */
.ev-entity-header__action:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

.ev-entity-header__action--danger:focus-visible {
    outline-color: var(--ev-socket-danger-ink);
}

.ev-entity-header__action:not(:disabled):active,
.ev-entity-header__action:not(:disabled).ev-entity-header__action--pressed {
    color: var(--ev-socket-ink);
    background-color: var(--ev-socket-face);
    background-image: var(--ev-socket-pressed);
    box-shadow:
        var(--ev-socket-edge),
        var(--ev-socket-pressed-depth);
    transform: translateY(2px);
    transition:
        transform var(--ev-press-in) var(--ev-press-in-ease),
        box-shadow var(--ev-press-in) var(--ev-press-in-ease),
        color 120ms ease;
}

.ev-entity-header__action--danger:not(:disabled):active,
.ev-entity-header__action--danger:not(:disabled).ev-entity-header__action--pressed {
    color: var(--ev-socket-danger-ink);
    box-shadow:
        var(--ev-socket-danger-edge),
        var(--ev-socket-pressed-depth);
}

.ev-entity-header__action:disabled {
    color: var(--ev-socket-ink-dim);
    cursor: not-allowed;
    opacity: 0.58;
    transform: none;
}

.ev-entity-header__action--icon-only {
    width: var(--ev-entity-header-seat-key-height);
    padding: 0;
    border-radius: var(--ev-entity-header-seat-key-radius);
    gap: 0;
}

.ev-entity-header__action--icon-only > span { display: none; }

/* Standalone cramped composition: move the complete laser-marked identity copy
   onto its own full-width land and compact the action shoulder to one icon
   socket. The socket is redrawn from the same indirection as the pocket, so
   its 30px key keeps the declared 5px of un-cut land on both inline edges;
   hiding the visible legend cannot leave a mysteriously empty 100px cavity.
   `overflow-wrap` is a text-layout permission, not truncation: even an
   unhyphenated machine name remains fully readable. */
@container ev-entity-header (max-width: 460px) {
    /* A cramped land has no room to be led. Resetting the two plate figures on
       the identity row — a DESCENDANT, since a query container cannot restyle
       its own principal box — puts a lead header back on the compact plate, and
       the recomposition below then applies to it unchanged. The grid track reads
       the same reset value, so the plate and the column it sits in cannot
       disagree. */
    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__identity {
        --ev-entity-header-mark-size: var(--ev-entity-header-mark-size-compact);
        --ev-entity-header-mark-glyph: var(--ev-entity-header-mark-glyph-compact);

        display: grid;
        grid-template-columns: var(--ev-entity-header-mark-size) minmax(0, 1fr) auto;
        gap: 14px 20px;
    }

    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__identity-mark {
        grid-column: 1;
        grid-row: 1;
    }

    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__content {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__title {
        overflow-wrap: anywhere;
    }

    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__action-lobe {
        grid-column: 3;
        grid-row: 1;
        margin-inline-start: 0;
    }

}

/* A query container cannot restyle its own principal box. The viewport gate
   therefore hides action legends at the same 460px boundary; the intrinsic
   sizer observes the resulting cluster width and redraws the pocket for one or
   several icon sockets without a separate guessed narrow width. */
@media (max-width: 460px) {
    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__action {
        width: var(--ev-entity-header-seat-key-height);
        padding-inline: 0;
        gap: 0;
    }

    .ev-entity-header:not(.ev-entity-drawer .ev-entity-header)
        .ev-entity-header__action > span {
        display: none;
    }
}

.ev-entity-header__rail {
    /* CRAMPED BEHAVIOUR — the channel traverses; it does not wrap or deform.
       A rail is one rigid milled track, so wrapping it would depict a second
       track that does not exist and collapsing items behind a menu key would
       replace places with an unrelated control. Instead, the rail owns its
       inline overflow and the labels travel through the fixed channel.

       The four background layers are an ACTUAL-overflow witness, not a
       breakpoint guess. Each opaque floor cover is attached locally: at its
       corresponding scroll limit it sits over and erases the fixed edge shade.
       Scroll away and the cover travels with the content, exposing the shade
       only on a side where more track really continues out of view. A roomy
       rail therefore renders exactly as before, with both shades covered.

       Native scrolling preserves touch, trackpad and scrollbar traversal.
       Keyboard focus on an off-screen link also scrolls it into view; the
       scroll padding keeps its complete label clear of the channel wall.
       evident-entity-header.js progressively records the exact live edges and
       aligns the current/focused stop. Its mask softens the otherwise arbitrary
       half-label at a continuing edge; complete native scrolling remains when
       the enhancement is absent. */
    --ev-entity-header-rail-overflow-cover: 30px;
    --ev-entity-header-rail-overflow-shade: 12px;

    position: relative;
    align-self: stretch;
    display: flex;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    min-width: 0;
    max-width: 100%;
    margin:
        24px 0
        calc((40px + var(--ev-entity-header-rail-overshoot)) * -1);
    padding-bottom: var(--ev-entity-header-rail-overshoot);
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-inline: contain;
    scroll-padding-inline: 20px;
    scroll-snap-type: inline proximity;
    scrollbar-width: thin;
    scrollbar-color: var(--ev-entity-header-r2-line-color) transparent;
    border-radius:
        var(--ev-entity-header-lobe-radius)
        var(--ev-entity-header-lobe-radius)
        0 0;
    color: var(--ev-ink-dim);
    background-color: var(--ev-entity-header-rail-floor);
    background-image:
        linear-gradient(
            to right,
            var(--ev-entity-header-rail-floor) 55%,
            transparent
        ),
        linear-gradient(
            to left,
            var(--ev-entity-header-rail-floor) 55%,
            transparent
        ),
        radial-gradient(
            farthest-side at 0 50%,
            var(--ev-entity-header-r2-line-color),
            transparent
        ),
        radial-gradient(
            farthest-side at 100% 50%,
            var(--ev-entity-header-r2-line-color),
            transparent
        );
    background-position:
        left center,
        right center,
        left center,
        right center;
    background-repeat: no-repeat;
    background-size:
        var(--ev-entity-header-rail-overflow-cover) 100%,
        var(--ev-entity-header-rail-overflow-cover) 100%,
        var(--ev-entity-header-rail-overflow-shade) 100%,
        var(--ev-entity-header-rail-overflow-shade) 100%;
    background-attachment: local, local, scroll, scroll;
    box-shadow: var(--ev-r2-lip), var(--ev-r2-wall), var(--ev-r2-rim);
    clip-path:
        inset(
            0 round
            var(--ev-entity-header-lobe-radius)
            var(--ev-entity-header-lobe-radius)
            0 0
        );
}

.ev-entity-header__rail[data-ev-overflow-end="true"] {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}

.ev-entity-header__rail[data-ev-overflow-start="true"] {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 28px);
    mask-image: linear-gradient(to right, transparent, #000 28px);
}

.ev-entity-header__rail[data-ev-overflow-start="true"][data-ev-overflow-end="true"] {
    -webkit-mask-image:
        linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
    mask-image:
        linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}

.ev-entity-header__rail::after {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    z-index: 3;
    height: 0;
    border-top: 1px solid var(--ev-entity-header-r2-line-color);
    pointer-events: none;
}

.ev-entity-header__rail-item {
    appearance: none;
    border: 0;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    padding: 12px 20px;
    color: var(--ev-ink-dim);
    background: none;
    font: 500 12.5px/normal var(--ev-font-sans);
    letter-spacing: 0.005em;
    text-decoration: none;
    white-space: nowrap;
    scroll-snap-align: start;
    scroll-margin-inline: 20px;
    cursor: pointer;
    transition: color 120ms ease, background-color 120ms ease;
}

.ev-entity-header__rail-item:hover { color: var(--ev-ink); }

.ev-entity-header__rail-item:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: -2px;
    z-index: 4;
}

.ev-entity-header__rail-item--selected {
    margin-top: calc(var(--ev-entity-header-seat-travel) * -1);
    padding-top: calc(12px + var(--ev-entity-header-seat-travel));
    border-radius: 0;
    color: var(--ev-ink);
    background-color: var(--ev-entity-header-rail-seat);
    background-image:
        linear-gradient(
            var(--ev-swoop-angle),
            var(--ev-entity-header-rail-seat-low) 0%,
            transparent 55%,
            var(--ev-entity-header-rail-seat-high) 100%
        );
    background-repeat: no-repeat;
    box-shadow: var(--ev-r3-line), var(--ev-r2-lip), var(--ev-r2-wall);
    font-weight: 600;
}

/* ===== src/components/entity-drawer.css ===== */
/* ==========================================================================
   Evident component — entity drawer
   ==========================================================================

   A discrete MOLDED cartridge paired with an entity header. It slides on the
   page bench BEHIND the molded header slab; the opaque header is the foreground
   housing and masks the cartridge foot. A rank-2 MACHINED pocket cut into the
   cartridge holds its content. The navigation rail below is a separate cut
   into the header: its width aligns the cartridge, but it is not the material
   the cartridge is made from. No intermediate fabrication plane exists here.

   A native checkbox keeps the lobe action itself as the toggle: click it again
   and the drawer closes. The reveal occupies document flow above the header,
   so it never obscures the identity being inspected or destroyed.

   API
     .ev-entity-drawer
     .ev-entity-drawer--danger|--info
     .ev-entity-drawer__state
     .ev-entity-drawer__toggle
     .ev-entity-drawer__toggle--info
     .ev-entity-drawer__toggle-space
     .ev-entity-drawer__reveal
     .ev-entity-drawer__reveal-inner
     .ev-entity-drawer__panel
     .ev-entity-drawer__rim
     .ev-entity-drawer__main
     .ev-entity-drawer__mark
     .ev-entity-drawer__copy
     .ev-entity-drawer__title
     .ev-entity-drawer__body
     .ev-entity-drawer__actions
     .ev-entity-drawer-set
     .ev-entity-drawer-set__state--rest|--info|--danger
     .ev-entity-drawer-set__toggle--info|--danger
     .ev-entity-drawer-set__reveal--info|--danger

   The outer columns mirror .ev-entity-header--banded's content inset. The
   cartridge is inset another 6px from that rail-width alignment so its complete
   molded side shoulders remain legible against the bench.

   RESPONSIVE CONTRACT
   -------------------
   The drawer is the named inline-size query container, because it — not the
   header — is what splits one lobe cluster across two elements: the toggle
   sits outside the header while a reserved space holds its footprint inside
   the lobe. Only the drawer knows both halves, so only the drawer can decide
   cramped. At 460px and below every action in the composition becomes
   icon-only: the legends go, the reserved space narrows to match, and the
   lobe's drawn span is re-stated to the smaller cluster so the land around
   the keys stays the same 5px it is at rest. Wrap each removable legend in a
   <span> and keep the glyph as a bare SVG, exactly as at rest.
   ========================================================================== */

.ev-entity-drawer {
    --ev-entity-drawer-edge: var(--ev-accent-edge);
    --ev-entity-drawer-accent: var(--ev-accent-text);
    --ev-entity-drawer-duration: 280ms;
    --ev-entity-drawer-ease: cubic-bezier(0.22, 0.75, 0.18, 1);
    /* The footprint the externally positioned toggle occupies inside the lobe.
       Stated once: the toggle's own offset and the spacer that stands in for it
       must agree, or the reserved hole and the part that fills it drift apart. */
    --ev-entity-drawer-toggle-reserve: 75px;
    --ev-entity-drawer-action-gap: var(--ev-entity-header-action-gap);

    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns:
        var(--ev-entity-header-content-inset)
        minmax(0, 1fr)
        var(--ev-entity-header-content-inset);
    grid-template-rows: auto auto;
    container-type: inline-size;
    container-name: ev-entity-drawer;
}

.ev-entity-drawer--danger {
    --ev-entity-drawer-edge: var(--ev-danger-action-burr);
    --ev-entity-drawer-accent: var(--ev-danger-action-ink);
}

.ev-entity-drawer--info {
    --ev-entity-drawer-edge: var(--ev-accent-edge);
    --ev-entity-drawer-accent: var(--ev-accent-text);
}

.ev-entity-drawer__state {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* One entity can expose calm information or destructive confirmation, but
   never both at once. The three radios are a tiny state machine: each lobe
   action selects a panel and every close action returns to rest. */
.ev-entity-drawer-set__state {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
}

.ev-entity-drawer-set__state--rest {
    /* Named for templates and contract checks; rest intentionally paints no panel. */
}

.ev-entity-drawer-set__toggle--info {
    margin-inline-end: 0;
}

/* The combined drawer owns one compact action group even though its danger
   toggle is positioned outside the header and represented inside by a spacer.
   The cluster gap is the sole distance between the two hit targets. */
.ev-entity-drawer-set .ev-entity-header__action-cluster {
    gap: var(--ev-entity-drawer-action-gap);
}

.ev-entity-drawer-set__toggle--danger {
    /* The external danger key uses the base toggle geometry unchanged. */
}

.ev-entity-drawer-set__reveal--info,
.ev-entity-drawer-set__reveal--danger {
    /* Both cartridges occupy the same closed grid track. Only the selected
       one expands, which preserves the existing slide instead of toggling
       display and popping the panel into place. */
}

.ev-entity-drawer-set__reveal--info {
    --ev-entity-drawer-edge: var(--ev-accent-edge);
    --ev-entity-drawer-accent: var(--ev-accent-text);
}

.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--info:checked)
    > .ev-entity-drawer-set__reveal--info,
.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--danger:checked)
    > .ev-entity-drawer-set__reveal--danger {
    grid-template-rows: 1fr;
    margin-block-end: -16px;
}

.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--info:checked)
    > .ev-entity-drawer-set__reveal--info .ev-entity-drawer__panel,
.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--danger:checked)
    > .ev-entity-drawer-set__reveal--danger .ev-entity-drawer__panel {
    opacity: 1;
    transform: translateY(0);
}

.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--info:checked)
    > .ev-entity-drawer-set__reveal--info .ev-entity-drawer__actions,
.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--info:checked)
    > .ev-entity-drawer-set__reveal--info .ev-entity-drawer__actions *,
.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--danger:checked)
    > .ev-entity-drawer-set__reveal--danger .ev-entity-drawer__actions,
.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state--danger:checked)
    > .ev-entity-drawer-set__reveal--danger .ev-entity-drawer__actions * {
    visibility: visible;
}

.ev-entity-drawer-set:has(> .ev-entity-drawer-set__state:focus-visible)
    .ev-entity-header__action {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

.ev-entity-drawer__toggle {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    justify-self: end;
    z-index: 8;
    margin-block-start: var(--ev-entity-header-action-inset-y);
    /* The toggle lives outside the header but fills a reserved socket inside
       its centred cluster. Move it by the same derived 1px resting correction:
       27px offset + 9px rim + 5px land - 40px content inset = 1px. */
    margin-inline-end:
        calc(
            var(--ev-entity-header-lobe-offset) +
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-action-inset-x) -
            var(--ev-entity-header-content-inset)
        );
    list-style: none;
}

.ev-entity-drawer__state:focus-visible + .ev-entity-drawer__toggle {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

.ev-entity-drawer--danger >
    .ev-entity-drawer__state:focus-visible +
    .ev-entity-drawer__toggle {
    color: var(--ev-socket-danger-ink);
    outline-color: var(--ev-socket-danger-ink);
    box-shadow:
        var(--ev-socket-top),
        var(--ev-socket-danger-edge),
        var(--ev-socket-groove),
        var(--ev-socket-contact);
}

.ev-entity-drawer__toggle--info {
    width: var(--ev-entity-header-seat-key-height);
    padding: 0;
    margin-inline-end:
        calc(
            var(--ev-entity-drawer-toggle-reserve) +
            var(--ev-entity-drawer-action-gap) +
            var(--ev-entity-header-lobe-offset) +
            var(--ev-entity-header-rim-width) +
            var(--ev-entity-header-action-inset-x) -
            var(--ev-entity-header-content-inset)
        );
}

.ev-entity-drawer__toggle-space {
    flex: 0 0 var(--ev-entity-drawer-toggle-reserve);
    width: var(--ev-entity-drawer-toggle-reserve);
    height: var(--ev-entity-header-seat-key-height);
    pointer-events: none;
}

.ev-entity-drawer__toggle-space--info {
    flex-basis: var(--ev-entity-header-seat-key-height);
    width: var(--ev-entity-header-seat-key-height);
}

.ev-entity-drawer > .ev-entity-header {
    grid-column: 1 / -1;
    grid-row: 2;
    z-index: 2;
}

.ev-entity-drawer__reveal {
    grid-column: 2;
    grid-row: 1;
    display: grid;
    grid-template-rows: 0fr;
    z-index: 1;
    min-width: 0;
    margin-block-end: 0;
    transition:
        grid-template-rows
            var(--ev-entity-drawer-duration)
            var(--ev-entity-drawer-ease),
        margin-block-end
            var(--ev-entity-drawer-duration)
            var(--ev-entity-drawer-ease);
}

.ev-entity-drawer__reveal-inner {
    min-height: 0;
    overflow: hidden;
    padding-inline: 6px;
}

.ev-entity-drawer__panel {
    margin-block: 8px 0;
    box-sizing: border-box;
    overflow: hidden;
    padding: 8px 8px 22px;
    border-radius:
        calc(var(--ev-entity-header-lobe-radius) + 4px)
        calc(var(--ev-entity-header-lobe-radius) + 4px)
        0 0;
    color: var(--ev-ink);
    /* Existing plane 1: the moving object is cast stock. Its soft shoulders and
       outer contact/ambient shadows describe one discrete raised PART; there is
       deliberately no hard rim or inset depth shadow on this outer silhouette. */
    background-color: var(--ev-metal-hi);
    background-image:
        linear-gradient(
            var(--ev-swoop-angle),
            var(--ev-lum-hi) 0%,
            var(--ev-lum-mid) 34%,
            transparent 60%,
            var(--ev-lum-lo) 100%
        );
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2);
    opacity: 0;
    /* Closed, the rigid cartridge sits on the bench behind the header housing.
       It translates upward as one part while flow makes room; no cut, band, rim
       or pocket changes shape. The header's higher stacking level masks the
       unrounded foot throughout the travel. */
    transform: translateY(36px);
    transition:
        opacity 150ms ease,
        transform
            var(--ev-entity-drawer-duration)
            var(--ev-entity-drawer-ease);
}

.ev-entity-drawer__state:checked ~ .ev-entity-drawer__reveal {
    grid-template-rows: 1fr;
    /* Bury the cartridge foot and its outer shadow beneath the opaque header.
       The overlap is the physical occlusion that makes foreground/background
       order explicit in both themes. */
    margin-block-end: -16px;
}

.ev-entity-drawer__state:checked ~
    .ev-entity-drawer__reveal
    .ev-entity-drawer__panel {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 40ms, 0ms;
}

.ev-entity-drawer__rim {
    display: flex;
    align-items: center;
    min-height: 28px;
    padding-inline: 10px;
    box-sizing: border-box;
    /* This is surviving cartridge LAND, not a cap and not a third material.
       Danger/info live in flat semantic ink; the molded face stays achromatic. */
    color: var(--ev-entity-drawer-accent);
    background: transparent;
    font: 700 10px/1 var(--ev-font-sans);
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

.ev-entity-drawer__main {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    gap: 0 14px;
    border-radius: var(--ev-entity-header-lobe-radius);
    /* Existing plane 2: a rank-2 pocket cut into the molded cartridge. The
       radial sheen is the shallow curvature of a milled floor, never a molded
       swoop. Its complete lip/wall is inside the cartridge shoulder. */
    background-color: var(--ev-floor-n2);
    background-image:
        radial-gradient(
            125% 125% at 50% 50%,
            var(--ev-lum-mid) 0%,
            transparent 52%,
            transparent 80%,
            var(--ev-lum-lo) 100%
        );
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall);
    /* The lower cartridge foot disappears behind the header mask. Keep a full
       form-space below the action row after that overlap is subtracted. */
    padding: 14px 16px 28px;
}

.ev-entity-drawer__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--ev-entity-header-lobe-radius);
    color: var(--ev-entity-drawer-accent);
    /* A nested rank-3 mark pocket is subtractive and therefore legal inside the
       rank-2 content pocket. The former raised tile floated inside a cut. */
    background: var(--ev-floor-n3);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

.ev-entity-drawer__mark svg {
    width: 16px;
    height: 16px;
}

.ev-entity-drawer__copy {
    min-width: 0;
}

.ev-entity-drawer__title,
.ev-entity-drawer__body {
    margin: 0;
}

.ev-entity-drawer__title {
    color: var(--ev-ink);
    font: 650 14px/1.25 var(--ev-font-sans);
}

.ev-entity-drawer__body {
    margin-block-start: 3px;
    color: var(--ev-ink-dim);
    font: 450 11.5px/1.35 var(--ev-font-sans);
}

.ev-entity-drawer__actions {
    grid-column: 2;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 7px;
    margin-block-start: 11px;
    /* A zero-row/overflow clip is only visual concealment: descendants would
       otherwise remain in sequential focus order and keyboard-activatable.
       Visibility removes the closed action set from hit-testing and the
       accessibility tree while leaving the panel shell free to animate. */
}

.ev-entity-drawer__actions,
.ev-entity-drawer__actions * {
    visibility: hidden;
}

.ev-entity-drawer__state:checked ~
    .ev-entity-drawer__reveal
.ev-entity-drawer__actions,
.ev-entity-drawer__state:checked ~
    .ev-entity-drawer__reveal
    .ev-entity-drawer__actions * {
    visibility: visible;
}

@container ev-entity-drawer (max-width: 520px) {
    .ev-entity-drawer__actions {
        grid-column: 2;
        flex-wrap: wrap;
    }
}

/* A cramped composition is ICON-ONLY, and that has to include the toggle. The
   toggle is the one lobe action that lives OUTSIDE the header, so the rule that
   strips the in-lobe legends has to reach it too — otherwise the cluster
   resolves to one icon and one labelled key, which is the icon/text mixture the
   cramped state exists to avoid. Only the removable legend disappears; the
   glyph never does, and the seated 30px socket, its 10px radius and its press
   travel are all unchanged. Authors must carry the legend as the control's
   `aria-label`: display:none takes the span out of the accessibility tree with
   the layout, and the part still has to say what it does.

   The reserved footprint narrows to the toggle's icon-only width, so the hole
   and the part that fills it still agree. The placeholder remains inside the
   action cluster, so Evident's intrinsic lobe sizer observes the smaller
   complete cluster and retains the same 5px inline land automatically. */
@container ev-entity-drawer (max-width: 460px) {
    .ev-entity-drawer__toggle-space,
    .ev-entity-drawer__toggle--info {
        --ev-entity-drawer-toggle-reserve:
            var(--ev-entity-header-seat-key-height);
    }

    .ev-entity-drawer__toggle,
    .ev-entity-drawer .ev-entity-header__action {
        width: var(--ev-entity-header-seat-key-height);
        padding: 0;
        gap: 0;
    }

    .ev-entity-drawer__toggle > span,
    .ev-entity-drawer .ev-entity-header__action > span {
        display: none;
    }
}

/* ===== src/components/confirm.css ===== */
/* ==========================================================================
   Evident component — inline row confirmation
   ==========================================================================

   A compact row action opens into a stable-height confirmation lane. This is
   deliberately NOT the entity-header drawer and not a lobe widget: it lives in
   ordinary list/table/form territory and therefore uses normal raised form
   keys. The lane expands left from the original action while remaining on the
   row's vertical centreline.

   API
     .ev-confirm
     .ev-confirm--row
     .ev-confirm__toggle
     .ev-confirm__tray
     .ev-confirm__idle
     .ev-confirm__content
     .ev-confirm__prompt
     .ev-confirm__actions
     .ev-confirm__cancel
     .ev-confirm__confirm

   Both dimensions have numeric endpoints. Content stays absolutely positioned
   for the entire state change. There is no auto-size interpolation, layout-mode
   swap or vertical transform to produce a mid-animation jump.
   ========================================================================== */

.ev-confirm {
    --ev-confirm-idle-w: 75px;
    --ev-confirm-idle-h: 30px;
    --ev-confirm-lane-w: min(420px, calc(100vw - 32px));
    --ev-confirm-lane-h: 44px;
    --ev-confirm-settle: 220ms;
    --ev-confirm-reveal-delay: 110ms;
    --ev-confirm-reveal: 130ms;
    --ev-confirm-guard: 280ms;
    --ev-confirm-guard-tick: 1ms;

    position: relative;
    display: block;
    flex: 0 0 var(--ev-confirm-idle-w);
    width: var(--ev-confirm-idle-w);
    height: var(--ev-confirm-idle-h);
}

.ev-confirm--row {
    align-self: stretch;
    height: auto;
    min-height: var(--ev-confirm-lane-h);
}

.ev-confirm__toggle {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.ev-confirm__tray {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: 0;
    z-index: 6;
    width: var(--ev-confirm-idle-w);
    height: var(--ev-confirm-idle-h);
    min-width: 0;
    padding: 0;
    box-sizing: border-box;
    overflow: hidden;
    border-radius: var(--ev-btn-radius-sm);
    color: var(--ev-ink);
    background-color: var(--ev-metal-hi);
    box-shadow:
        var(--ev-contact-1),
        var(--ev-ambient-1);
    transform: translateY(-50%);
    transition:
        width var(--ev-confirm-settle) cubic-bezier(0.25, 0.1, 0.25, 1),
        height var(--ev-confirm-settle) cubic-bezier(0.25, 0.1, 0.25, 1),
        background-color var(--ev-confirm-reveal) ease,
        box-shadow var(--ev-confirm-settle) ease;
}

.ev-confirm__toggle:focus-visible ~ .ev-confirm__tray {
    outline: 2px solid var(--ev-danger-action-ink);
    outline-offset: 2px;
}

.ev-confirm__toggle:focus-visible ~ .ev-confirm__tray .ev-confirm__idle {
    color: var(--ev-danger-action-ink);
    box-shadow: inset 0 0 0 1px var(--ev-danger-action-burr);
}

.ev-confirm__idle {
    position: absolute;
    inset: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding-inline: 9px 12px;
    border-radius: inherit;
    color: var(--ev-ink-dim);
    font: 600 var(--ev-btn-font-xs)/1 var(--ev-font-sans);
    letter-spacing: 0.02em;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    opacity: 1;
    transition: opacity 90ms ease 50ms, color 120ms ease;
}

.ev-confirm__idle:hover {
    color: var(--ev-danger-action-ink);
    box-shadow: inset 0 0 0 1px var(--ev-danger-action-burr);
}

.ev-confirm :is(svg, .ev-key__glyph) {
    width: 12px;
    height: 12px;
    flex: 0 0 auto;
}

.ev-confirm svg [stroke] {
    stroke: currentColor;
}

.ev-confirm__content {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 7px 6px 12px;
    box-sizing: border-box;
    color: var(--ev-ink);
    opacity: 0;
    pointer-events: none;
    transform: translateX(8px);
    transition:
        opacity var(--ev-confirm-reveal) ease,
        transform var(--ev-confirm-reveal) cubic-bezier(0.3, 0, 0.2, 1);
}

.ev-confirm__prompt {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    color: var(--ev-ink-dim);
    font: 500 var(--ev-btn-font-xs)/1.25 var(--ev-font-sans);
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ev-confirm__prompt strong {
    color: var(--ev-ink);
    font-weight: 650;
}

.ev-confirm__actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
}

.ev-confirm__cancel {
    appearance: none;
    border: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    height: 30px;
    padding-inline: 10px;
    border-radius: var(--ev-btn-radius-xs);
    color: var(--ev-ink);
    background: var(--ev-metal-hi);
    box-shadow:
        var(--ev-contact-1),
        var(--ev-ambient-1);
    font: 600 var(--ev-btn-font-xs)/1 var(--ev-font-sans);
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
}

.ev-confirm__cancel {
    order: 2;
}

.ev-confirm__confirm {
    order: 1;
    pointer-events: none;
    visibility: hidden;
    opacity: 0;
    transform: translateX(6px);
}

.ev-confirm__cancel:hover {
    color: var(--ev-ink);
    box-shadow:
        var(--ev-contact-2),
        var(--ev-ambient-1);
}

.ev-confirm__cancel:active {
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

.ev-confirm__toggle:checked ~ .ev-confirm__tray {
    width: var(--ev-confirm-lane-w);
    height: var(--ev-confirm-lane-h);
    color: var(--ev-ink);
    background-color: var(--ev-floor-n2);
    box-shadow:
        inset 0 0 0 1px rgba(159, 47, 40, 0.42),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-contact-1);
}

.ev-confirm__toggle:checked ~ .ev-confirm__tray .ev-confirm__idle {
    opacity: 0;
    pointer-events: none;
    transition: opacity 80ms ease;
}

.ev-confirm__toggle:checked ~ .ev-confirm__tray .ev-confirm__content {
    opacity: 1;
    pointer-events: auto;
    transform: translateX(0);
    transition:
        opacity var(--ev-confirm-reveal) ease var(--ev-confirm-reveal-delay),
        transform
            var(--ev-confirm-reveal)
            cubic-bezier(0.3, 0, 0.2, 1)
            var(--ev-confirm-reveal-delay);
}

@keyframes ev-confirm-arm-guard {
    0%, 64% {
        pointer-events: none;
        visibility: hidden;
        opacity: 0;
        transform: translateX(6px);
    }
    65% {
        pointer-events: none;
        visibility: visible;
        opacity: 0;
        transform: translateX(6px);
    }
    100% {
        pointer-events: auto;
        visibility: visible;
        opacity: 1;
        transform: translateX(0);
    }
}

.ev-confirm__toggle:checked ~
    .ev-confirm__tray
    .ev-confirm__confirm {
    /* The delay, rather than the duration, is the safety boundary. Evident's
       reduced-motion gate shortens animation durations globally but preserves
       delays, so the destructive action remains absent from pointer, keyboard
       and accessibility hit-testing for the full guard in every motion mode. */
    animation:
        ev-confirm-arm-guard
        180ms
        cubic-bezier(0.3, 0, 0.2, 1)
        var(--ev-confirm-guard)
        both;
}

/* ===== src/components/pinstripe.css ===== */
/* ==========================================================================
   Evident component — pinstripe (the identity canvas texture)
   ==========================================================================

   The pinstripe is not decoration; it is Evident's SIGNATURE surface. It is
   the fine machined grain of the un-worked bench — the stock the whole billet
   is cut from. The founder: "The pinstripe background is an integral part of
   the identity and should be used throughout." It was lost in the CC port;
   this partial promotes it to a first-class, reusable background primitive so
   any page or panel can adopt the identity with one class.

   RECOVERED — not reinvented. The exact texture is lifted verbatim from the
   historical v16 record (the `body` canvas + the `--canvas-stripe` /
   `--canvas-lite` token pair):

     pinstripe : REGULAR, 3px pitch, directional (vertical). A 1px ink line
                 on a 3px repeat, plus a faint LIT companion offset by a half
                 pitch. Two ink deltas one pixel apart read as a milled groove
                 rather than a flat rule — that half-pitch lit line is what
                 makes the surface read machined instead of merely striped.

   ACHROMATIC (Invariant 7). Every value here is R = G = B — the stripe is
   MATERIAL, never content. It carries identity, never status; there is no hue
   in it. In light it is a faint DARK line on light stock; in dark it inverts —
   a faint LIT line on dark stock — because a dark bench has no headroom to
   darken into (same reasoning as the r-line stack: cortex-vnt3p6m). Both sit
   well under the luminance ceiling; the stripe is felt, not read.

   The alphas are the study's, quieted (V6-4) so the stripe never fights other
   textures: if a regular stripe and an irregular field share a surface, the
   regular one must yield — a repeating stripe is far more visually assertive
   than an aperiodic field at equal contrast.

   TOKENS (self-contained — this partial owns the pinstripe token layer so it
   composes onto the base token set without editing tokens.css):

     --ev-pinstripe-ink    the dark grain line   (light theme active value)
     --ev-pinstripe-lite   the lit companion line
     --ev-pinstripe-pitch  the stripe repeat     (3px — do not retune blind;
                           the pitch is calibrated against body-text stems so
                           small text on the raw canvas does not beat, per the
                           study's "text on the pinstripe" rule)
     --ev-pinstripe        the composed background-image (both stripe layers).
                           Drop it into any `background` shorthand ABOVE a
                           surface colour, e.g.
                             background: var(--ev-pinstripe), var(--ev-bg);

   DOCTRINE — THE GRAIN IS THE ENVIRONMENT, NEVER A FINISH (cortex-yat5aad).

   The pinstripe belongs to exactly two surfaces:

     1. the PAGE BACKGROUND — the body or a full-bleed app shell, and
     2. the app CHROME that houses the page — the shell's own housing parts.

   Nothing else. Not a card, not a panel, not a pocket, not the floor of a cut.
   The founder, reviewing the gallery: pinstripe "is reserved for the CHROME
   itself and for the page BACKGROUND"; the grain-on-components demos "are not
   relevant".

   It follows from what the grain IS. The stripe is the tooth of UN-WORKED
   STOCK — the bench the billet is cut from, before any tool touches it. A
   molded card is stock that has been cast; a machined pocket is stock a cutter
   has just been through. Both are WORKED faces, and a worked face does not
   still carry the mill grain of the raw bar: putting the stripe on one depicts
   a fabrication history that did not happen (rule 1). It also costs the channel
   its one meaning — grain present ⇔ you are looking at the environment rather
   than at a part (rule 2). Two former modifiers put the grain on a raised face
   and inside a cut; both are removed rather than deprecated (cortex-qairdc1),
   and their rows are in docs/removed-names.tsv.

   USAGE:

     .ev-pinstripe         utility — lays the pinstripe over the element's own
                           --ev-bg page canvas. This is the DEFAULT SURFACE
                           TEXTURE of an Evident page: apply it to the <body>
                           (or a full-bleed app shell) so the whole page wears
                           the machined identity. The founder: "part of the
                           design system i.e. full background" (cortex-g8kexss).
                           The showcase body ships with .ev-pinstripe for exactly
                           this reason; panels and cards laid on top read
                           correctly because they carry their own solid ground.

     CHROME                composes the TOKEN, not the utility. Chrome parts —
                           an app bar, a left nav, a full-height housing — own
                           their own ground (chrome conventionally reads dark,
                           and the ground is what lets the content column sit
                           proud of it), so they stack the grain above it
                           themselves:

                             background-color: <the chrome's own ground>;
                             background-image: var(--ev-pinstripe);

                           This is the second sanctioned home, and it is why the
                           token stays public while the component modifiers do
                           not: chrome is housing, not a part on the bench.

   The stripe SCROLLS with its surface (it is a page texture, not viewport
   environment light — that is the canvas atmosphere's job) and never sits
   under small text directly; small text belongs on a solid cut surface (a
   card/pocket), per the study's "text sitting directly on the pinstripe
   canvas" rule.
   ========================================================================== */

/* The explicit light aliases keep environmental stock honest when a consumer
   places a light sub-canvas inside dark chrome. */
:root,
:is([data-ev-theme="light"], [data-bs-theme="light"]) {
    /* Light stock: a faint DARK grain line + a barely-there lit companion.
       1:1 WITH THE v16 STUDY (cortex-r3qtun9). These are the study's
       --canvas-stripe / --canvas-lite values VERBATIM. The study quieted the
       stripe to 0.014 in its V6-4 pass — deliberately subtle, sized to sit
       under the noise field and never fight text on the raw canvas — and that
       subtle pinstripe is the intended reading.

       REVERSION NOTED: an earlier library pass (cortex-g8kexss) raised the ink
       to 0.05 to "make it visible", reading the study's stripe as flat. That
       was drift, not a fix — the founder's 1:1 instruction reverts it. The
       pinstripe goes subtle again, on purpose. It sits on the graphite
       --ev-bg #c9c9c9 bench now (not the near-white #ececec the raise was
       measured against), where the study's subtle grain reads correctly as the
       machined tooth of the stock. */
    --ev-pinstripe-ink:   rgba(28, 28, 28, 0.014);
    --ev-pinstripe-lite:  rgba(250, 250, 250, 0.11);
    --ev-pinstripe-pitch: 3px;

    /* The composed two-layer grain. Layer 1: a 1px ink line on the pitch.
       Layer 2: a 1px lit line offset by ~half a pitch (starts at 1px, runs to
       2px), so the groove reads milled rather than ruled. Both are vertical
       (90deg). Consumers stack this ABOVE a surface colour in `background`. */
    --ev-pinstripe:
        repeating-linear-gradient(90deg,
            var(--ev-pinstripe-ink) 0px,
            var(--ev-pinstripe-ink) 1px,
            transparent 1px,
            transparent var(--ev-pinstripe-pitch)),
        repeating-linear-gradient(90deg,
            transparent 0px,
            transparent 1px,
            var(--ev-pinstripe-lite) 1px,
            var(--ev-pinstripe-lite) 2px,
            transparent 2px,
            transparent var(--ev-pinstripe-pitch));
}

/* Dark stock: the grain inverts. On a dark bench the tooth is carried by
   LIGHT — a faint scattered sheen — because there is no room to darken. So the
   primary line becomes a near-black groove at higher alpha (a dark floor needs
   more ink to register) and the companion is an almost-invisible lit thread. */
:is([data-ev-theme="dark"], [data-bs-theme="dark"]) {
    /* Dark stock: the grain inverts and is carried mostly by a faint scattered
       LIGHT sheen. 1:1 WITH THE v16 STUDY (cortex-r3qtun9): these are the
       study's dark --canvas-stripe / --canvas-lite VERBATIM — the groove at
       0.24 (the study's V6-4 quieted value) and the lit companion thread at the
       study's near-invisible 0.011.

       REVERSION NOTED: the same "make it visible" pass (cortex-g8kexss) had
       raised these to 0.30 / 0.045; the 1:1 instruction reverts both to the
       study's subtle values. */
    --ev-pinstripe-ink:  rgba(0, 0, 0, 0.24);
    --ev-pinstripe-lite: rgba(245, 245, 245, 0.011);
}

/* ---- utilities ---------------------------------------------------------- */

/* PAGE surface. The environment: the un-worked bench. Lay the pinstripe over
   the element's own page canvas (--ev-bg). Apply to body or a full-bleed app
   shell. */
.ev-pinstripe {
    /* 1:1 WITH THE v16 STUDY (cortex-r3qtun9): the page environment is THREE
       composited layers, exactly as the study's <body>:
         1. the pinstripe grain (scrolls with content — a page texture)      here
         2. the material NOISE tooth  (fixed underlay)          -> ::before
         3. the diagonal ATMOSPHERE (fixed environment light)    -> ::after
       The stripe scrolls (study V8-5 perf lesson: never background-attachment:
       fixed on a full-viewport gradient); the noise + atmosphere are viewport-
       anchored fixed layers that composite once and cost nothing per scroll
       frame — the study's exact split. */
    position: relative;
    /* Founder option E: this utility establishes the universal bench
       substrate. Any cut component below it consumes this single floor unless
       a raised material container resets the channel. */
    --ev-direct-carve-floor: var(--ev-bench-floor);
    background-color: var(--ev-bg);
    background-image: var(--ev-pinstripe);
    background-attachment: scroll;
}
/* 2. The material NOISE tooth — a fixed full-viewport underlay so its alpha is
   theme-controlled by --ev-noise-alpha rather than baked into the data URI. An
   inline SVG feTurbulence (self-contained, no external asset, no JS): baseFreq
   0.9 = fine tooth, ~180px tile, desaturated (feColorMatrix saturate 0) so every
   pixel is R=G=B and the achromatic invariant survives. Two orders of magnitude
   coarser than the 3px stripe and aperiodic, so the two textures cannot beat. */
.ev-pinstripe::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: var(--ev-noise-alpha);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 180px 180px;
}
/* 3. The CANVAS ATMOSPHERE — environment light, not the surface-finish swoop.
   This fixed, viewport-anchored luminance sweep deliberately shares the stable
   public --ev-swoop-angle token so page and parts agree on one angle. Renaming
   that token would break consumers without clarifying the channel split.
   Pure luminance, zero hue shift: the study's --amb-hi -> transparent ->
   --amb-lo at 0% / 58% / 100%. */
.ev-pinstripe::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image:
        linear-gradient(var(--ev-swoop-angle),
            var(--ev-amb-hi)  0%,
            transparent      58%,
            var(--ev-amb-lo) 100%);
}
/* Everything real sits above the environment layers. A full-bleed .ev-pinstripe
   page should give its own top-level content z-index:1 (the study does this on
   its .chrome/.page/.footer); we hoist direct children so the common case (the
   gallery's <body class="ev-pinstripe"> wrapping one content div) Just Works. */
.ev-pinstripe > * {
    position: relative;
    z-index: 1;
}

/* There is deliberately NO panel modifier and NO in-carve modifier here. Both
   shipped once and are gone (see DOCTRINE above): a worked face — cast or cut —
   does not carry the mill grain of the raw bar, so the grain on a card or in a
   pocket draws a fabrication history that never happened. A surface that wants
   the identity is either the page or the chrome; anything else wants its own
   material, not the bench's. */

/* ===== src/components/scribe.css ===== */
/* ==========================================================================
   Evident component — scribe (layout marks on the environment)
   ==========================================================================

   A scribe is a working mark laid into the stock before fabrication. It is a
   HAIRLINE groove with one lit companion edge: no lip, wall, floor, radius or
   shadow. Those belong to a machined cut and would falsely promote a reference
   line into the nesting ladder.

   The marked element supplies geometry only. Both strands are gradient layers
   on pseudo-elements standing outside its box, so the initial HTML is complete
   and no decorative markup or JavaScript is needed.

   SITING IS ENFORCED. The page canvas and app chrome are stock; cards, cuts,
   controls and inserts are finished parts. The final selector suppresses marks
   both on and inside those part surfaces, making the wrong fabrication history
   unexpressible rather than merely discouraged.
   ========================================================================== */

/* Both theme entry points are scopeable. A nested light stock window must
   restore its groove/arris pair instead of retaining the dark page's marks. */
:root,
:is([data-ev-theme="light"], [data-bs-theme="light"]) {
    /* The light stock carries a dark groove and a minute bright arris. The
       pair deliberately follows pinstripe's ink/lite inversion model. */
    --ev-scribe-ink: rgba(28, 28, 28, 0.34);
    --ev-scribe-lite: rgba(250, 250, 250, 0.62);
    --ev-scribe-w: 1px;
    --ev-scribe-standoff: 12px;
    --ev-scribe-len: 24px;
}

:is([data-ev-theme="dark"], [data-bs-theme="dark"]) {
    /* Dark stock needs a firmer black groove and a quieter lit strand, exactly
       the same inversion principle used by --ev-pinstripe-ink and -lite. */
    --ev-scribe-ink: rgba(0, 0, 0, 0.72);
    --ev-scribe-lite: rgba(245, 245, 245, 0.24);
}

.ev-scribe {
    position: relative;
}

.ev-scribe::before,
.ev-scribe::after {
    content: "";
    position: absolute;
    /* The pseudo-box begins one complete mark length beyond the standoff.
       Every inward-running gradient therefore ENDS at the standoff rather
       than crossing the measured element's edge. */
    inset: calc(-1 * (var(--ev-scribe-standoff) + var(--ev-scribe-len)));
    z-index: 0;
    pointer-events: none;
    background-repeat: no-repeat;
}

/* The companion is one hairline inward from the groove. This is a minute
   scribed arris, not directional depth: neither strand casts a shadow. */
.ev-scribe::before {
    --ev-scribe-line: var(--ev-scribe-ink);
}
.ev-scribe::after {
    --ev-scribe-line: var(--ev-scribe-lite);
    transform: translate(var(--ev-scribe-w), var(--ev-scribe-w));
}

/* Four L marks stand off the four corners of the measured element. */
.ev-scribe--brackets::before,
.ev-scribe--brackets::after,
.ev-scribe--full::before,
.ev-scribe--full::after {
    background-image:
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line));
    background-position:
        left top, left top,
        right top, right top,
        left bottom, left bottom,
        right bottom, right bottom;
    background-size:
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len);
}

/* Ticks locate the midpoint of every edge. The two pseudo-elements make each
   dash the required groove/lit pair without adding a wrapper. */
.ev-scribe--ticks::before,
.ev-scribe--ticks::after {
    background-image:
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line));
    background-position:
        center top, center bottom, left center, right center;
    background-size:
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-len) var(--ev-scribe-w);
}

/* Full is additive geometry, not a new treatment: brackets plus ticks. */
.ev-scribe--full::before,
.ev-scribe--full::after {
    background-image:
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line)),
        linear-gradient(var(--ev-scribe-line), var(--ev-scribe-line));
    background-position:
        left top, left top,
        right top, right top,
        left bottom, left bottom,
        right bottom, right bottom,
        center top, center bottom, left center, right center;
    background-size:
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-w) var(--ev-scribe-len),
        var(--ev-scribe-len) var(--ev-scribe-w),
        var(--ev-scribe-len) var(--ev-scribe-w);
}

/* Environment-only enforcement. A scribe on a part, or anywhere within one,
   emits no mark. This is the complete shipped part-carrier vocabulary:
   fabrication planes, controls, material surfaces, value instruments,
   identity parts, indicators and glass inserts. Typography, finish utilities,
   .ev-pinstripe, .ev-scribe and .ev-datum are deliberately absent because
   they do not establish a finished part surface. */
:where(
    .ev-molded,
    .ev-machined,
    .ev-aperture,
    .ev-key,
    .ev-pocket,
    .ev-select,
    .ev-selector,
    .ev-menu-panel,
    .ev-measure,
    .ev-switch,
    .ev-segmented,
    .ev-boss,
    .ev-confirm,
    .ev-dns-hostname,
    .ev-dns-ttl-selector,
    .ev-copyable,
    .ev-copyable-list,
    .ev-pagination,
    .ev-card,
    .ev-well,
    .ev-baseplate,
    .ev-rail,
    .ev-lip,
    .ev-dropzone,
    .ev-file-list,
    .ev-data-list,
    .ev-table,
    .ev-disclosure,
    .ev-empty-state,
    .ev-entity-header,
    .ev-entity-drawer,
    .ev-readout,
    .ev-stat-card,
    .ev-readout-cluster,
    .ev-identity,
    .ev-entity-token,
    .ev-badge,
    .ev-badge-lamp,
    .ev-tooltip,
    .ev-glass,
    .ev-glass-avatar,
    .ev-glass-id,
    .ev-glass-lamp,
    .ev-stamp
).ev-scribe::before,
:where(
    .ev-molded,
    .ev-machined,
    .ev-aperture,
    .ev-key,
    .ev-pocket,
    .ev-select,
    .ev-selector,
    .ev-menu-panel,
    .ev-measure,
    .ev-switch,
    .ev-segmented,
    .ev-boss,
    .ev-confirm,
    .ev-dns-hostname,
    .ev-dns-ttl-selector,
    .ev-copyable,
    .ev-copyable-list,
    .ev-pagination,
    .ev-card,
    .ev-well,
    .ev-baseplate,
    .ev-rail,
    .ev-lip,
    .ev-dropzone,
    .ev-file-list,
    .ev-data-list,
    .ev-table,
    .ev-disclosure,
    .ev-empty-state,
    .ev-entity-header,
    .ev-entity-drawer,
    .ev-readout,
    .ev-stat-card,
    .ev-readout-cluster,
    .ev-identity,
    .ev-entity-token,
    .ev-badge,
    .ev-badge-lamp,
    .ev-tooltip,
    .ev-glass,
    .ev-glass-avatar,
    .ev-glass-id,
    .ev-glass-lamp,
    .ev-stamp
).ev-scribe::after,
:where(
    .ev-molded,
    .ev-machined,
    .ev-aperture,
    .ev-key,
    .ev-pocket,
    .ev-select,
    .ev-selector,
    .ev-menu-panel,
    .ev-measure,
    .ev-switch,
    .ev-segmented,
    .ev-boss,
    .ev-confirm,
    .ev-dns-hostname,
    .ev-dns-ttl-selector,
    .ev-copyable,
    .ev-copyable-list,
    .ev-pagination,
    .ev-card,
    .ev-well,
    .ev-baseplate,
    .ev-rail,
    .ev-lip,
    .ev-dropzone,
    .ev-file-list,
    .ev-data-list,
    .ev-table,
    .ev-disclosure,
    .ev-empty-state,
    .ev-entity-header,
    .ev-entity-drawer,
    .ev-readout,
    .ev-stat-card,
    .ev-readout-cluster,
    .ev-identity,
    .ev-entity-token,
    .ev-badge,
    .ev-badge-lamp,
    .ev-tooltip,
    .ev-glass,
    .ev-glass-avatar,
    .ev-glass-id,
    .ev-glass-lamp,
    .ev-stamp
) .ev-scribe::before,
:where(
    .ev-molded,
    .ev-machined,
    .ev-aperture,
    .ev-key,
    .ev-pocket,
    .ev-select,
    .ev-selector,
    .ev-menu-panel,
    .ev-measure,
    .ev-switch,
    .ev-segmented,
    .ev-boss,
    .ev-confirm,
    .ev-dns-hostname,
    .ev-dns-ttl-selector,
    .ev-copyable,
    .ev-copyable-list,
    .ev-pagination,
    .ev-card,
    .ev-well,
    .ev-baseplate,
    .ev-rail,
    .ev-lip,
    .ev-dropzone,
    .ev-file-list,
    .ev-data-list,
    .ev-table,
    .ev-disclosure,
    .ev-empty-state,
    .ev-entity-header,
    .ev-entity-drawer,
    .ev-readout,
    .ev-stat-card,
    .ev-readout-cluster,
    .ev-identity,
    .ev-entity-token,
    .ev-badge,
    .ev-badge-lamp,
    .ev-tooltip,
    .ev-glass,
    .ev-glass-avatar,
    .ev-glass-id,
    .ev-glass-lamp,
    .ev-stamp
) .ev-scribe::after {
    content: none;
}

/* ===== src/components/datum.css ===== */
/* ==========================================================================
   Evident component — datum (the current-location mark)
   ==========================================================================

   ITS ONLY MEANING IS "YOU ARE HERE": the current location or section. The
   datum is the one chromatic marking-out component because the position it
   identifies is genuinely live state. It spends the existing accent channel
   on that literal live/active meaning; it is NEVER a decorative crosshair.

   This is its own block, not an .ev-scribe modifier. Scribe geometry is
   achromatic working structure; the datum is chromatic state. Combining them
   would give one selector two meanings and make arbitrary blue layout marks
   look sanctioned.

   The mark is flat information on the environment: no face, no floor, no
   rim, no shadow and no motion. The inner cross has a real centre gap. Four
   short ticks sit at the outer cardinal points, detached from the cross.

   USAGE:

     <span class="ev-datum" aria-hidden="true"></span>

   Keep the semantic current-location state in the surrounding navigation or
   section markup; this visual mark is hidden from assistive technology rather
   than announced as an unexplained graphic.

   DENSITY:
   At most ONE datum may appear in a viewport. CSS cannot count matching
   elements across arbitrary DOM branches or decide which scroll position is
   "a viewport", so it must not pretend to enforce that global rule. The final
   rule below suppresses later sibling datums in the canonical flat placement
   layer; consumers still own the one-per-viewport authoring invariant.
   ========================================================================== */

.ev-datum {
    --ev-datum-size: 3rem;
    --ev-datum-gap: 0.1875rem;
    --ev-datum-tick: 0.3125rem;
    --ev-datum-line: 1px;

    position: relative;
    display: block;
    flex: 0 0 auto;
    inline-size: var(--ev-datum-size);
    block-size: var(--ev-datum-size);
    color: var(--ev-accent);
    pointer-events: none;
    contain: strict;
}

/* The live cross. Its two strokes stop on both sides of the centre instead of
   intersecting, leaving the stock visible through a deliberate square gap. */
.ev-datum::before {
    content: "";
    position: absolute;
    inset: 25%;
    background:
        linear-gradient(to right,
            currentColor 0 calc(50% - var(--ev-datum-gap)),
            transparent calc(50% - var(--ev-datum-gap))
                        calc(50% + var(--ev-datum-gap)),
            currentColor calc(50% + var(--ev-datum-gap)) 100%)
            center / 100% var(--ev-datum-line) no-repeat,
        linear-gradient(to bottom,
            currentColor 0 calc(50% - var(--ev-datum-gap)),
            transparent calc(50% - var(--ev-datum-gap))
                        calc(50% + var(--ev-datum-gap)),
            currentColor calc(50% + var(--ev-datum-gap)) 100%)
            center / var(--ev-datum-line) 100% no-repeat;
}

/* Four detached witness ticks. The empty quarter-size moat between this outer
   ring and the inset cross is load-bearing: ticks must not become long arms. */
.ev-datum::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(currentColor, currentColor)
            center top / var(--ev-datum-line) var(--ev-datum-tick) no-repeat,
        linear-gradient(currentColor, currentColor)
            center bottom / var(--ev-datum-line) var(--ev-datum-tick) no-repeat,
        linear-gradient(currentColor, currentColor)
            left center / var(--ev-datum-tick) var(--ev-datum-line) no-repeat,
        linear-gradient(currentColor, currentColor)
            right center / var(--ev-datum-tick) var(--ev-datum-line) no-repeat;
}

/* Honest partial enforcement of the one-per-viewport rule: the canonical
   placement layer is flat, so a later sibling is always a density violation.
   Arbitrarily nested duplicates remain an authoring error CSS cannot rank. */
.ev-datum ~ .ev-datum {
    display: none;
}

/* ===== src/components/stamp.css ===== */
/* ==========================================================================
   Evident component — stamp (laser-marked fabrication legend)
   ==========================================================================

   A stamp is a small faced pad carrying a permanent fabrication legend. Its
   physical sequence is mill → anodize → laser: the cutter first faces a quiet
   patch that clears the canvas grain, anodizing establishes the part finish,
   and the laser changes only that finish's tone.

   This is neither a pocket nor a raised key. The pad has no wall, arris, rim,
   relief or shadow; its solid face simply keeps small mono lettering off the
   pinstripe. The laser mark is flat, achromatic ink. It darkens natural
   anodize in light mode and lightens black anodize in dark mode, following the
   same physical inversion as the pinstripe rather than adding a status hue.

   USAGE:

     <span class="ev-stamp">EV-241 / REV 03</span>

   Keep legends short and durable: part ids, revisions, ratings or ownership
   marks. This block is base-only; visual variants would invent fabrication
   histories that the component does not represent.
   ========================================================================== */

/* Stamp ink is theme material too: reset it at a nested light boundary rather
   than inheriting the dark ancestor's register. */
:root,
:is([data-ev-theme="light"], [data-bs-theme="light"]) {
    --ev-stamp-face: var(--ev-metal);
    --ev-stamp-mark: #555555;
}

:is([data-ev-theme="dark"], [data-bs-theme="dark"]) {
    --ev-stamp-mark: #aaaaaa;
}

.ev-stamp {
    display: inline-flex;
    align-items: center;
    min-block-size: 1.5rem;
    padding: 0.25rem 0.5rem;
    border: 0;
    border-radius: 0.125rem;
    background-color: var(--ev-stamp-face);
    box-shadow: none;
    color: var(--ev-stamp-mark);
    font-family: var(--ev-font-mono);
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-shadow: none;
    white-space: nowrap;
}

/* ===== src/components/dropzone.css ===== */
/* ==========================================================================
   Evident component — the drop-zone (a tray a loose part is set into)
   ==========================================================================

   A drop-zone is the target area a file manager shows for "drop files here".
   The founder saw the shape in the study's ANTI-PATTERN · RAISED BLOCK INSIDE
   A CUT and asked to repurpose it. That anti-pattern is genuinely forbidden —
   a *molded* (cast) block cannot be poured into a pocket, so it has no
   fabrication story and reads as a sticker (historical v16 record, "The nesting
   rule"). This component is legal for a specific, load-bearing reason:

   THE FABRICATION STORY (coherent — NOT a sanctioned exception)
   -------------------------------------------------------------
   The illegal case is a part that was CAST IN PLACE inside a hole, which never
   happens. But a part that was MANUFACTURED SEPARATELY and then SET DOWN into a
   pocket milled to receive it is completely ordinary — a coin dropped in a
   tray, a chip seated in a socket, a card slid into a slot. Evident already
   sanctions exactly this move: the study's own note says ".btn recessing on
   :active is a sanctioned exception — that is one part travelling into the
   panel it sits on" (CLAUDE.md, invariant "The nesting rule"). A drop-zone is
   that same physics run forward instead of held: an empty machined TRAY, and a
   loose part the user drops INTO it.

   The distinction from the anti-pattern is what makes it honest:
     * IDLE      there is NO raised block. Just the empty recessed tray with a
                 dashed scribe marking where a part should be set. Nothing is
                 depicted that is not there — an empty pocket is an empty pocket.
     * ACTIVE    the tray FLOOR RISES toward the surface (the pocket goes
                 shallow) and the whole cut accent-lights, the way a receiving
                 socket presents itself. The part has not landed yet, so still
                 no block — the invite is a property of the TRAY, not a phantom
                 object.
     * FILLED    now a loose part-plate RESTS in the tray. It is molded (a real
                 cast part) but it sits IN a recess — the sanctioned
                 "part travelling into the panel" case, identical in kind to
                 .btn:active, .ev-key:active and the segmented seat. It seats on
                 a contact ring (the shadow the part casts DOWN into the tray it
                 rests in), never on an outer float — an outer float would claim
                 it hovers above the surface, which is the sticker read the
                 anti-pattern warns about.

   WHY THIS SHAPE, IN THE CHANNEL LANGUAGE (per CLAUDE.md § "The channels")
   -----------------------------------------------------------------------
     Rim / lip weight  → nesting rank. The tray is a rank-1 cut into the host
       face, so it takes the heavy rank-1 lip (--ev-r1-*), the same as any
       machined panel — this is a substantial pocket, not a scribed detail.
     Floor luminance   → nesting depth. Idle tray floor sits at --ev-floor-n1
       (deepest rung) so it reads clearly recessed and inviting. ACTIVE lifts
       the floor to --ev-floor-n3 (shallowest) — the pocket coming UP toward the
       surface to receive the part. Depth is the only channel that legitimately
       means "how ready is this to accept something".
     Finish            → liveness. An idle drop-zone is LIVE (polished): it is
       waiting for input. It never uses the oxidized/read-only finish.
     Hue               → the single accent, and ONLY on the ACTIVE (drag-over)
       state — the one moment the zone is interactive-imminent. Idle and filled
       carry no hue. (Invariant: hue means live/active, nothing else.)

   THE ONE MATERIAL EVENT PER PART (per-side cut audit, required by CLAUDE.md)
     .ev-dropzone            the TRAY. A rank-1 machined pocket cut on all four
                             sides into the host face. Recessed, inset shading.
     .ev-dropzone__mark      the affordance scribe — a dashed inset outline
                             lying ON the tray floor. It is a marking (ink on a
                             floor), not a cut and not a raised edge, so it
                             spends no material channel; it is drawn as an inset
                             so it sits inside the lip, never over the arris.
     .ev-dropzone--active    the tray presenting itself: floor lifts to n3, the
                             lip accent-lights, the scribe goes solid + accent.
     .ev-dropzone__part      the loose part RESTING in the tray (FILLED). Molded
                             plate, seated on a contact ring (casts DOWN), never
                             an outer float. This is the sanctioned recess-part.

   Component is pure CSS. The demo toggles --active via a dragover handler, but
   that JS is a DEMO affordance only — a server-rendered consumer adds/removes
   the class itself, exactly like .is-selected on a nav.

   VISUAL TARGET ⊂ ACTUAL TARGET. The apron marks the ideal landing area on the
   inner floor, but the whole tray accepts the drop — including its outer rim.
   Every decorative layer remains pointer-events:none so none can shrink or
   intercept that full-component target. (cortex-6sfzy4r, cortex-pkx752y)
   ========================================================================== */

/* --------------------------------------------------------------------------
   .ev-dropzone — the empty tray (IDLE). A rank-1 machined pocket.
   The floor sits at --ev-floor-n1 (the deepest rung) so an empty zone reads as
   an obvious recess asking to be filled. It keeps the heavy rank-1 lip — a
   substantial pocket, not a scribe.
   -------------------------------------------------------------------------- */
.ev-dropzone {
    --ev-dropzone-apron-valley: var(--ev-cut-edge);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--ev-radius-sm);
    min-height: 132px;
    padding: var(--ev-btn-pad-y-xl) var(--ev-btn-pad-x-xl);
    text-align: center;
    color: var(--ev-ink-dim);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-radius-lg);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
    position: relative;
    cursor: pointer;
    /* The transparent inner line reserves the hover finish without changing
       geometry; the live line is symmetric, so it preserves axial light. */
    outline: 1px solid transparent;
    outline-offset: -3px;
    /* Depth (floor) + lip both animate when the tray presents itself. No
       transform — the pocket changes depth, it does not slide in space. */
    transition:
        background-color var(--ev-press-out) var(--ev-press-out-ease),
        box-shadow var(--ev-press-out) var(--ev-press-out-ease),
        color var(--ev-press-out) var(--ev-press-out-ease);
}

.ev-dropzone:hover {
    outline-color: var(--ev-edge-glow);
}

/* Content sits above the floor decoration. */
.ev-dropzone > * {
    position: relative;
    z-index: 1;
}

/* The floor's own shallow curvature — a milled floor is not perfectly flat.
   Same construction as .ev-machined::before, kept local so the component does
   not depend on the .ev-machined class being present. */
.ev-dropzone::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(125% 125% at 50% 50%,
            var(--ev-lum-mid) 0%,
            transparent      52%,
            transparent      80%,
            var(--ev-lum-lo) 100%);
}

/* --------------------------------------------------------------------------
   .ev-dropzone::after — the LANDING-PAD APRON.
   Fine diagonal strips milled into the INNER FLOOR at the bottom of the tray,
   fading away upward — the machined equivalent of a parachute landing pad's
   marked apron. The apron is only the IDEAL landing area; the whole tray,
   including its outer rim, remains the actual drop target. The founder saw the
   shape in a production file-manager dropzone
   (src/css/file_manager.css .file-dropzone::before), which paints a single
   repeating-linear-gradient(-45deg) hazard field. Two things are re-cut for
   Evident:

     1. ACHROMATIC / MATERIAL, not painted hazard. CC uses a blue tint
        (rgba(43,179,243,…)); Evident forbids hue except on the live/active
        state (Invariant L4). So the strips are carved from the floor's own
        LUMINANCE tokens — a light rung (--ev-lum-hi) paired with a dark rung
        (--ev-lum-lo) offset half a period, so each strip reads as a milled
        ridge (lit top edge, shaded valley), NOT a coloured band. R=G=B, and it
        flips correctly in the dark theme because the lum tokens are per-theme.

     2. SYMMETRIC. CC's single -45deg field all skews one way — the exact
        asymmetry the brief calls out. Evident's light is axial and symmetric
        (Invariant L1), so the apron must mirror left↔right. It is built as TWO
        mirrored half-fields: the LEFT half leans +45deg, the RIGHT half leans
        -45deg, each masked to its own half and meeting at the centre vertical
        axis → a herringbone chevron pointing to centre. Mirror the screenshot
        and the two halves match exactly; the tray keeps its axial symmetry.

   The whole apron is then bounded inside the landing scribe's inner rounded
   rectangle and mask-faded (opaque at the bottom edge → transparent ~part way
   up). It is floor texture, not a hazard field: a tight 20px period, a thin
   3px ridge pair and reduced opacity keep it subordinate. It spends no material
   CHANNEL beyond the floor it already lives on — no cut, no lip, no hue.
   pointer-events:none; it is decoration.
   -------------------------------------------------------------------------- */
.ev-dropzone::after {
    content: '';
    position: absolute;
    left: var(--ev-radius-md);
    right: var(--ev-radius-md);
    bottom: var(--ev-radius-md);
    height: 62%;
    border-radius: var(--ev-radius-md);
    pointer-events: none;
    z-index: 0;
    /* Two mirrored half-fields. Each is a no-repeat layer sized to half the
       width; the left leans +45deg, the right -45deg, so they are exact mirror
       images meeting at the centre axis. Within each field a light ridge-top
       (--ev-edge-glow) sits just above a dark valley. The active state changes
       only --ev-dropzone-apron-valley, so both states inherit this one geometry
       and cannot jump between periods. */
    background-image:
        repeating-linear-gradient( 45deg,
            transparent            0,
            transparent            12px,
            var(--ev-edge-glow)   12px,
            var(--ev-edge-glow)   13px,
            var(--ev-dropzone-apron-valley) 13px,
            var(--ev-dropzone-apron-valley) 15px,
            transparent           15px,
            transparent           20px),
        repeating-linear-gradient(-45deg,
            transparent            0,
            transparent            12px,
            var(--ev-edge-glow)   12px,
            var(--ev-edge-glow)   13px,
            var(--ev-dropzone-apron-valley) 13px,
            var(--ev-dropzone-apron-valley) 15px,
            transparent           15px,
            transparent           20px);
    background-size: 50% 100%, 50% 100%;
    background-position: left bottom, right bottom;
    background-repeat: no-repeat, no-repeat;
    /* Fade the apron away toward the top of the tray. Opaque at the bottom edge,
       gone by ~62% up its own height — the landing-pad apron the founder asked
       for. */
    -webkit-mask-image: linear-gradient(to top, #000 0%, #000 22%, transparent 92%);
            mask-image: linear-gradient(to top, #000 0%, #000 22%, transparent 92%);
    opacity: 0.55;
    transition:
        opacity var(--ev-press-out) var(--ev-press-out-ease);
}

/* --------------------------------------------------------------------------
   .ev-dropzone__mark — the "set a part here" affordance.
   A dashed scribe lying ON the tray floor: a marking, not a cut and not a
   raised edge. Drawn as an INSET dashed outline so it sits inside the lip and
   never paints over the pocket's own arris. Ink on a floor spends no material
   channel (CLAUDE.md § "The channels" — finish/hue/rim all untouched).
   -------------------------------------------------------------------------- */
.ev-dropzone__mark {
    position: absolute;
    inset: var(--ev-radius-md);
    border-radius: var(--ev-radius-md);
    border: 1.5px dashed var(--ev-cut-edge);
    pointer-events: none;
    /* Above the landing-pad apron (.ev-dropzone::after, z-index:0) so the scribe
       ink reads on top of the milled strips, not under them. */
    z-index: 1;
    transition:
        border-color var(--ev-press-out) var(--ev-press-out-ease);
    opacity: 0.7;
}

/* The label + hint text block. Mono is reserved for machine values, so the
   prompt is IBM Plex Sans; a byte-count/hint can opt into mono at the call
   site by adding its own .ev-readout, not baked in here. */
.ev-dropzone__label {
    font: 600 var(--ev-btn-font-md)/1.3 var(--ev-font-sans);
    color: var(--ev-ink);
}
/* The hint steps DOWN from the label at the dim rung, not the faint one. It
   sits on --ev-floor-n1 at rest and --ev-floor-n3 when active; faint ink fails
   AA on both (cortex-g2j0rmv — see the ink-ladder note in tokens.css). The
   hint is already subordinate by size and by sitting under the label. */
.ev-dropzone__hint {
    font: 400 var(--ev-btn-font-sm)/1.4 var(--ev-font-sans);
    color: var(--ev-ink-dim);
}

/* --------------------------------------------------------------------------
   .ev-dropzone--active — DRAG-OVER. The tray presents itself to receive.
   The floor LIFTS from n1 to n3 (the pocket comes up toward the surface), the
   lip accent-lights, and the scribe goes solid + accent. This is the one
   moment the zone is interactive-imminent, so it is the one moment hue is
   allowed (hue = live/active, nothing else). Instant IN (press-in), like a key.
   -------------------------------------------------------------------------- */
.ev-dropzone--active {
    --ev-dropzone-apron-valley: var(--ev-accent-edge);
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n3));
    color: var(--ev-ink);
    /* Rank-1 lip kept for the cut, plus an accent-lit inner ring stating the
       tray is now armed. The accent ring is INSET (it is the lit inner wall of
       the pocket catching the accent), never an outer glow — glow is banned
       (Invariant L4). */
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        inset 0 0 0 1px var(--ev-accent-edge),
        inset 0 0 12px -2px var(--ev-accent-edge);
    transition:
        background-color var(--ev-press-in) var(--ev-press-in-ease),
        box-shadow var(--ev-press-in) var(--ev-press-in-ease),
        color var(--ev-press-in) var(--ev-press-in-ease);
}

.ev-dropzone--active .ev-dropzone__mark {
    border-style: solid;
    border-color: var(--ev-accent-edge);
    opacity: 1;
}

/* ACTIVE landing-pad apron — the strips light up. This is the one moment hue is
   allowed (hue = live/active, Invariant L4): the component-local valley carrier
   above switches to the accent edge. Geometry, symmetry, clipping, density and
   mask-fade all remain inherited from the one base ::after rule. */

.ev-dropzone--active .ev-dropzone__hint {
    color: var(--ev-ink-dim);
}

/* --------------------------------------------------------------------------
   .ev-dropzone--filled — a loose part is set in the tray.
   The zone still IS a tray (keeps its recessed lip); it now holds a part. Use
   this modifier when the drop-zone has content; render one or more
   .ev-dropzone__part plates inside. The empty-state affordance (__mark) should
   be omitted from the markup when filled (nothing to invite).
   -------------------------------------------------------------------------- */
.ev-dropzone--filled {
    justify-content: flex-start;
    align-items: stretch;
    color: var(--ev-ink);
}

/* A filled tray holds a resting part; the landing-pad invite is spent, so the
   apron recedes (it is an empty-state affordance, like __mark). */
.ev-dropzone--filled::after {
    opacity: 0;
}

/* .ev-dropzone__part — the loose part RESTING in the tray.
   A molded (cast) plate, but it sits INSIDE the recess it was set into — the
   sanctioned "one part travelling into the panel" move (identical in kind to
   .ev-key:active / the segmented seat). It therefore seats on a CONTACT ring
   (the shadow it casts DOWN into the tray floor it rests on) and a light
   shoulder-lite dome — NOT an outer ambient float. An outer float would lift it
   above the surface and reintroduce the sticker read the anti-pattern warns of;
   the contact ring says "resting in", the ambient float would say "hovering
   above". That single shadow choice is what keeps this legal. */
.ev-dropzone__part {
    --ev-direct-carve-floor: initial;
    display: flex;
    align-items: center;
    gap: var(--ev-radius-sm);
    padding: var(--ev-btn-pad-y-sm) var(--ev-btn-pad-x-md);
    border-radius: var(--ev-radius-md);
    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    font: 500 var(--ev-btn-font-sm)/1.2 var(--ev-font-sans);
    /* seated part: interior dome + contact ring cast DOWN. No --ev-ambient-*. */
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1);
}
.ev-dropzone__part + .ev-dropzone__part {
    margin-top: var(--ev-radius-sm);
}

/* ===== src/components/file-list.css ===== */
/* ==========================================================================
   Evident component — file list
   ==========================================================================

   A file list is a RECORD TRAY: structured machine records laid on the floor
   of an existing machined well. Author `.ev-file-list` together with
   `.ev-well`; the well owns the one rank-2 cut into the host and this component
   owns only the records inside it. This deliberate composition avoids drawing
   a second, contradictory well around the same material.

     .ev-file-list                    the record layout, composed with .ev-well
     .ev-file-list__head              captions on the well floor
     .ev-file-list__row               one flat record, separated by a scribe
     .ev-file-list__row--selected     a rank-3 selection detent
     .ev-file-list__row--phantom      an inert pending record
     .ev-file-list__select            checkbox column
     .ev-file-list__name              icon + filename
     .ev-file-list__icon              achromatic type aperture
     .ev-file-list__size              right-aligned machine value
     .ev-file-list__date              machine timestamp
     .ev-file-list__actions           right-aligned action slot
     .ev-file-list__menu              row-action overlay anchor
     .ev-file-list__sort              flat sortable caption
     .ev-table__action                shared compact round row action

   MATERIAL EVENTS / PER-SIDE CUT AUDIT
   ------------------------------------
   WELL: `.ev-well` alone removes material on all four outer sides. This block
   adds no outer background, rim or shadow.

   ORDINARY ROW: no material is removed on any outer side. It is ink on the
   well floor, with one horizontal scribe between records. There is therefore
   no raised row, no hover lift and no false clickable-card signal.

   SELECTED ROW: one rank-3 detent is cut on all four sides. The inset line,
   lip and wall are symmetric and zero-offset; a single accent scribe at the
   left states live selection without flooding the floor with hue.

   TYPE APERTURE: one small rank-3 cut on all four sides holds a flat,
   achromatic glyph. File type is carried by GLYPH SHAPE, never colour. Within
   a selected detent this is the clamped deepest nesting rung, as required once
   the three-rank ladder is exhausted.

   A production file manager informed the useful columns and states:
   selection · name/type · size · modified · actions, selected rows, pending
   phantom rows, sortable headers and an empty state. Its Bootstrap table paint
   is not ported. The empty state remains `.ev-dropzone`: an empty file list is
   already a drop target, so a second empty-list component would duplicate one
   meaning across two shapes.
   ========================================================================== */

.ev-file-list {
    --ev-file-list-columns: 2.75rem minmax(12rem, 1fr) 6rem 9.5rem max-content;
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: var(--ev-file-list-columns);
    min-width: 0;
    padding: 0;
    overflow: visible;
}

.ev-file-list__head,
.ev-file-list__row {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    align-items: center;
    min-width: 0;
}

/* The header is a caption register on the existing floor, not another part.
   Its bottom scribe separates labels from records without boxing it in. */
.ev-file-list__head {
    min-height: 2rem;
    border-bottom: 1px solid var(--ev-cut-edge);
    color: var(--ev-ink-dim);
    font: 600 0.6875rem/1.2 var(--ev-font-sans);
    letter-spacing: 0.055em;
    text-transform: uppercase;
}

.ev-file-list__row {
    min-height: 3.25rem;
    color: var(--ev-ink);
    font: 400 0.875rem/1.35 var(--ev-font-sans);
    position: relative;
}

/* The tray cannot clip its records: row-hosted menus and tooltips are allowed
   to leave both their row and the well. Preserve the well's silhouette on the
   records themselves instead. This is a corner treatment, not a clip, so an
   overlay from the first or last record remains fully paintable. */
.ev-file-list > :first-child {
    border-start-start-radius: var(--ev-radius-lg);
    border-start-end-radius: var(--ev-radius-lg);
}

.ev-file-list > :last-child {
    border-end-start-radius: var(--ev-radius-lg);
    border-end-end-radius: var(--ev-radius-lg);
}

/* One scribe BETWEEN records. No outside rectangle: an ordinary row is not a
   fabricated part and no material was removed around its four sides. */
.ev-file-list__row + .ev-file-list__row {
    border-top: 1px solid var(--ev-cut-edge);
}

.ev-file-list__head > *,
.ev-file-list__row > * {
    min-width: 0;
    padding: 0.5rem 0.625rem;
}

.ev-file-list__select {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding-inline: 0.875rem 0.375rem;
}

.ev-file-list__select .ev-pocket--check {
    margin: 0;
}

.ev-file-list__name {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-width: 0;
    font-weight: 500;
}

.ev-file-list__filename {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Type is glyph shape in an achromatic aperture. The aperture is a real small
   cut; the glyph stays flat (L3) and inherits neutral ink (L4). */
.ev-file-list__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.875rem;
    block-size: 1.875rem;
    border-radius: var(--ev-radius-sm);
    color: var(--ev-ink-dim);
    background-color: var(--ev-floor-n3);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

.ev-file-list__icon svg {
    display: block;
    inline-size: 1rem;
    block-size: 1rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.ev-file-list__row .ev-file-list__size,
.ev-file-list__row .ev-file-list__date {
    color: var(--ev-ink-dim);
    font: 400 0.75rem/1.35 var(--ev-font-mono);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ev-file-list__size,
.ev-file-list__actions {
    text-align: right;
    justify-self: stretch;
}

/* Placement belongs to the row action that opens the shared menu material.
   Keep the anchor out of a private stacking context: the menu's z-index can
   then compare with later records instead of being trapped below them. */
.ev-file-list__menu {
    position: relative;
    display: inline-flex;
    vertical-align: middle;
}

.ev-file-list__menu > summary {
    list-style: none;
    cursor: pointer;
}

.ev-file-list__menu > summary::-webkit-details-marker {
    display: none;
}

.ev-file-list__menu[open] > summary {
    color: var(--ev-accent-text);
}

.ev-file-list__menu > .ev-menu-panel {
    position: absolute;
    z-index: 110;
    inset-block-start: calc(100% + 0.35rem);
    inset-inline-end: 0;
    min-width: min(12rem, calc(100vw - 2rem));
    max-width: min(18rem, calc(100vw - 2rem));
}

/* The compact row action is one shared public part, so its wake cannot depend
   on an `.ev-table` ancestor. On a fine pointer the file record is merely the
   scope that raises its real controls; the row itself gains no paint, lift or
   false whole-row affordance. Safe and destructive ink continue to come from
   the action's own hover/focus contract in table.css. */
@media (hover: hover) and (pointer: fine) {
    .ev-file-list__row:is(:hover, :focus-within) .ev-table__action.ev-key {
        box-shadow:
            var(--ev-contact-1),
            var(--ev-ambient-1);
    }
}

.ev-file-list__sort {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    max-width: 100%;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    cursor: pointer;
}

.ev-file-list__sort:hover,
.ev-file-list__sort:focus-visible {
    color: var(--ev-accent-text);
}

.ev-file-list__sort:focus-visible {
    outline: 1px solid var(--ev-accent-edge);
    outline-offset: 3px;
    border-radius: 2px;
}

.ev-file-list__sort-mark {
    font-family: var(--ev-font-mono);
    font-size: 0.8em;
    line-height: 1;
}

/* Selection is the only full-row material state: a rank-3 detent cut on every
   side, plus one live accent SCRIBE at the left. The accent is a line, not a
   fill, so hue continues to mean selected/live and nothing else. */
.ev-file-list__row--selected {
    background-color: var(--ev-floor-n3);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall);
}

.ev-file-list__row--selected::before {
    content: '';
    position: absolute;
    inset-block: 0.375rem;
    inset-inline-start: 2px;
    inline-size: 2px;
    border-radius: 0 2px 2px 0;
    background: var(--ev-accent);
    pointer-events: none;
}

/* A phantom is a future record, not a new state channel: preserve geometry,
   quiet every content slot together, and block interaction. */
.ev-file-list__row--phantom {
    opacity: 0.58;
    pointer-events: none;
}

/* Narrow trays keep name + selection. Machine metadata is progressive context,
   not the identity of the file, so it may leave before the filename truncates. */
@media (max-width: 720px) {
    .ev-file-list {
        --ev-file-list-columns: 2.75rem minmax(10rem, 1fr) 6rem max-content;
    }
    .ev-file-list__date {
        display: none;
    }
}

@media (max-width: 520px) {
    .ev-file-list {
        --ev-file-list-columns: 2.75rem minmax(8rem, 1fr) max-content;
    }
    .ev-file-list__size {
        display: none;
    }
    .ev-file-list__head > *,
    .ev-file-list__row > * {
        padding-inline: 0.4rem;
    }
}

/* ===== src/components/data-list.css ===== */
/* ==========================================================================
   Evident component — data list
   ==========================================================================

   NAVIGATION, never tabular data. `.ev-data-list` is a stack of discrete
   compact molded strips. Each item is one whole semantic link, so each item is
   one physical part and earns the one sanctioned row lift on hover.

     .ev-data-list
       a.ev-data-list__item[href]
         .ev-data-list__primary
         .ev-aux                       optional; the one auxiliary fact

   The supported-item selector is the component's structural enforcement:
   exactly one primary, at most one auxiliary, no third direct child, and an
   actual `<a href>`. Invalid markup stays an ordinary unstyled link instead of
   quietly becoming a fake table or advertising a click it cannot perform.
   There is deliberately no `__secondary`, cells array, column marker, action
   slot, non-clickable variant, or alignment contract. Wanting one means
   `.ev-table`.
   ========================================================================== */

.ev-data-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 560px;
}

/* Keep this selector as one compound expression: whitespace between its
   structural pseudo-classes would turn them into descendant selectors and
   silently remove the two-information gate. */
.ev-data-list > :where(a.ev-data-list__item[href]:has(> .ev-data-list__primary:first-child):not(:has(> :nth-child(3))):not(:has(> .ev-data-list__primary:nth-child(2))):not(:has(> :not(.ev-data-list__primary):not(.ev-aux))):not(:has(> .ev-aux:first-child))) {
    /* Raised stock owns the ordinary nested floor ladder, so an entity token
       inside takes its n3 cut floor instead of the bench's direct carve. */
    --ev-direct-carve-floor: initial;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 9px 14px;
    color: var(--ev-ink);
    font-size: 13.5px;
    text-decoration: none;
    background: var(--ev-metal-hi);
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
    transition: var(--ev-transition-fast);
}

.ev-data-list > :where(a.ev-data-list__item[href]:has(> .ev-data-list__primary:first-child):not(:has(> :nth-child(3))):not(:has(> .ev-data-list__primary:nth-child(2))):not(:has(> :not(.ev-data-list__primary):not(.ev-aux))):not(:has(> .ev-aux:first-child))) > .ev-data-list__primary {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* THE LIFT — legal because the supported item is one whole part and one whole
   link. It is the same elevation as `.ev-card--clickable`; the list does not
   invent a second hover language. */
.ev-data-list > :where(a.ev-data-list__item[href]:has(> .ev-data-list__primary:first-child):not(:has(> :nth-child(3))):not(:has(> .ev-data-list__primary:nth-child(2))):not(:has(> :not(.ev-data-list__primary):not(.ev-aux))):not(:has(> .ev-aux:first-child))):hover {
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-2),
        var(--ev-contact-2),
        var(--ev-ambient-2);
    transition: none;
}

/* A link presents as one thing, so the auxiliary fact keeps the link's ink in
   every state. Hierarchy rides on register instead: `.ev-aux` supplies the
   smaller face and `.ev-aux--mono` is available when the fact is a genuine
   machine value. It has no cross-row alignment; each link lays out its own two
   facts independently. */
.ev-data-list > a.ev-data-list__item[href] > .ev-aux {
    flex: 0 1 auto;
    min-width: 0;
    text-align: end;
    color: inherit;
}

/* ===== src/components/table.css ===== */
/* ==========================================================================
   Evident component — data table
   ==========================================================================

   A table is selectable, copyable data. Ordinary rows are never navigation.
   One explicit exception is a row that expands an adjacent detail row: a real
   button inside the row owns activation and accessibility state while pointer
   delegation may make the row's whole surface operate that same button. A
   grouped table is a run of independently collapsible record planes on one visual
   SPINE: Name is anchored left; TTL and Actions are anchored right; the
   type-specific middle columns use only the space their real data needs.

     .ev-table-group              grouped tables sharing the outer spine
     .ev-table-group__item        one titled/collapsible group
     .ev-table-group__summary     native details control
     .ev-table-group__title       group identity
     .ev-table-group__count       quiet record count
     .ev-table-group__marker      disclosure chevron
     .ev-table-group__footer      full-width group action
     .ev-table-viewport           the one horizontal overflow boundary
     .ev-table-viewport--sticky-identity
                                  opt-in pinned Name column
     .ev-table-viewport__guidance screen-reader-only continuation guidance
     .ev-table                    one semantic data table
     .ev-table__head/__body       row groups
     .ev-table__row               inert selectable record
     .ev-table__row-toggle        native control owning an expandable row
     .ev-table__detail-row        adjacent row controlled by that button
     .ev-table__detail            full-width expanded detail cell
     .ev-table__cell              header or data cell
     .ev-table__row--selected     selected-record wash + accent scribe
     .ev-table--embedded          table inside an existing group plane
     .ev-table__actions           right action cell
     .ev-table__action-set        compact control group
     .ev-table__action            round icon-only key; compose with .ev-key
     .ev-table__action--danger    neutral-rest destructive action

   THE VIEWPORT — ONE BOUNDARY, AND IT CLAIMS NOTHING
   --------------------------------------------------
   .ev-table-viewport is the ONLY Evident-owned horizontal overflow boundary a
   semantic table has. It replaces .ev-table-group__scroll, which was
   grouped-only: a standalone .ev-table had no boundary at all, so a consumer
   invented one — .nete-table-scroll, a script, and a literal visible sentence,
   `More columns to the right ->`.

   That sentence is why the replacement says nothing on screen. The script
   deriving it was not wrong; `scrollWidth > clientWidth` was true. The CLAIM
   was wrong, and structurally so: .ev-table below declares
   `min-width: max-content`, so a table always claims its content width and ANY
   bounded frame overflows the moment ONE cell is wide — three columns or
   thirty. A three-column table with one wide repeated IP value therefore
   announced hidden columns that did not exist. So this frame reports nothing
   about columns; a non-verbal per-edge affordance for material that really does
   continue is a separate part (cortex-m9ne2e9), and it is a claim about
   CONTINUATION, never about columns.

   THE FRAME IS THE PART; THE TABLE IS WHAT TRAVELS THROUGH IT
   -----------------------------------------------------------
   The viewport carries the plate — face, radius and the four shadow layers —
   and the table inside it goes flat. It is the same fabrication story the
   entity header's rail already tells: one fixed part, contents travelling
   through it. The alternative was measured against the tokens and rejected: a
   transparent frame around a table that keeps its own plate must clip that
   plate's outer shadow in the block axis, because `overflow-x: auto` computes
   `overflow-y: auto` and a scroll container clips at its padding box. That
   erases --ev-contact-1 (`0 0 3px` at 0.85 alpha in dark) and --ev-ambient-1
   (`0 0 16px` at 0.55), which is the entire seating of the part — a plate with
   no contact shadow reads as a sticker, the one failure this language is built
   to avoid. Padding the frame to give the shadow room only moves the defect:
   pad the block axis alone and the corners go asymmetric; pad both and the
   plate is inset from its column or the frame overhangs its neighbours.

   Consequences for an author:
   - The FRAME owns the width. Constrain .ev-table-viewport, never the table
     inside it — a max-width on the table leaves the plate at full column width
     with the data floating in it.
   - A table that already sits in an existing plane keeps .ev-table--embedded,
     and the viewport derives its own material from that same marker rather
     than from a second class the author has to remember.

   THE CONTINUATION CUE — A CLAIM ABOUT MATERIAL, MADE BY GEOMETRY
   ---------------------------------------------------------------
   Four background layers on the frame, and no state anywhere. Two SHADES sit
   on the frame's own edges (`background-attachment: scroll`, so they do not
   move); two COVERS sit on the travelling content's edges (`local`, so they
   do). A cover is the ground colour, so where it lands on a shade the shade
   is gone. Content's start edge coincides with the frame's start edge exactly
   when nothing is hidden that way — so the start cover lands on the start
   shade exactly then, and only then. Same at the end. A table that fits has
   both coincidences at once and shows neither cue.

   That is the whole mechanism: the cue is not computed from the geometry, it
   IS the geometry. Nothing observes scroll position, nothing measures
   scrollWidth, and there is no state to fall out of sync after a resize, a
   font load, a row insertion or a theme change — the covers are attached to
   the content, so they are already wherever the content is on the next paint.
   The consumer sentence this component deleted failed at precisely the point
   a derived claim can fail; a cue that cannot be derived cannot be derived
   wrongly.

   It says MATERIAL, not COLUMNS, and that distinction is the bead. A shade is
   the frame's edge occluding what passes beneath it. A three-column table with
   one wide cell really does hide material past the frame, so it really does
   show the cue — and the cue is true there, where `More columns to the right`
   was false.

   WHAT IT IS MADE OF. --ev-contact-tint is the contact falloff as a raw colour,
   declared for exactly this case: a part's shadow that must be drawn as a
   gradient because the part is not its own element. The shade is a linear
   falloff across the inline axis only, so it is INVARIANT along the block axis
   — symmetric about every horizontal axis there is, and offset toward neither
   side of the boundary it describes. L1 holds structurally, as it does for the
   entity-header rail's overflow shades: no box-shadow is involved and nothing
   here carries a light direction. The one thing the shade states is where
   material is.

   The rail's exact form — `radial-gradient(farthest-side at <edge> 50%)` — was
   tried first, on the reasoning that copying a shipped precedent needs no
   argument. It was wrong here and the crop said so. `farthest-side` on a 20px
   band inside a 113px-tall frame gives ry = 56px, so the shade collapses into
   a lens: darkest at the frame's vertical middle, gone at both corners. It
   reads as a smudge on the data rather than as an edge, and it depicts a
   fabrication event nothing performed — an occlusion that varies down the
   length of a straight edge. The rail gets away with it because it is 40px
   tall and a lens that tall IS an edge. A table frame is not.

   WHAT WAS MEASURED, AND WHY THE OTHER TWO WERE NOT SHIPPED (cortex-m9ne2e9).
   The open question was not whether the local/scroll pair is truthful — it is,
   by construction — but whether it is VISIBLE THROUGH the plate this frame
   carries. Measured on the showcase, Chromium 149, 1440px, both branches:

     plated frame, 420px over 613px of content, light theme, luminance profile
     across the last 20 CSS px of each edge —
       scroll 0    start flat 234-238 (no cue) · end 236 -> 201 (cue)
       scroll mid  start 199 -> 236 (cue)      · end 236 -> 201 (cue)
       scroll end  start 199 -> 236 (cue)      · end flat 234-239 (no cue)
     embedded frame, transparent face, 420px over 916px, scroll mid —
       start 181 -> 231 (cue) · end 231 -> 183 (cue)

   Six states, six correct verdicts, and a ~35-tone step where a cue is present
   against ≤5 tones where it is not. So it is visible, and option 1 carries the
   affordance.

   Option 2, `animation-timeline: scroll(self inline)` driving a registered
   `<number>` through the shade alpha, was built and measured too, and it also
   works: 0 / 1 / 1-1 / 1-0 at start / mid / end, and it survives
   `data-ev-motion="off"` because the motion gate's `animation-duration` clamp
   does not apply to a progress-based timeline. It is rejected anyway, on two
   measurements. It needs `@supports (animation-timeline: scroll())` — so on an
   engine without it the cue is not degraded, it is ABSENT, while
   `background-attachment: local` is supported everywhere this library ships.
   And its no-overflow case is decided by a fallback (an inactive timeline
   leaves the registered property at its initial value) rather than by the same
   geometry as every other case; option 1 has one code path and one argument
   for all four states. Two mechanisms doing one job is the thing not to ship,
   and this is the one that needs an engine gate to do it.

   Option 3, a bounded enhancement asset, was not reached. It is the correct
   shape only when the static baseline cannot be correct, and the numbers above
   are that baseline being correct. Note what a script would have to do here to
   match: observe layout, scroll, resize, font load and row mutation, and get
   every one of them right. The geometry gets all five for free by never
   knowing about any of them.

   REACHABLE, NAMED, AND SILENT
   ----------------------------
   The frame is a real destination: `tabindex="0"`, `role="region"` and an
   accessible name saying what data it frames, so a keyboard reader can reach
   the scroller and drive it with the arrow keys, and a screen reader announces
   entering it. .ev-table-viewport__guidance is the one piece of continuation
   guidance, and it is screen-reader-only: it states how to reach anything past
   the frame without asserting that anything IS past it. Nothing visible in the
   frame instructs.

   WRAP OR STACK BEFORE YOU REACH FOR THIS
   ---------------------------------------
   Horizontal travel is the right answer for a genuinely wide record — the
   seven-column SRV row below is one. It is the WRONG answer for a cell that is
   merely long, and `min-width: max-content` is what makes that distinction
   matter: a cell can never wrap its way out of trouble, so one long run inside
   it becomes horizontal travel for every reader of every row. Before wrapping a
   table in a viewport, ask what the wide cell holds:
   - A SET of values (addresses, aliases, IPs) — stack them, one block-level
     element per value. The cell's max-content width then becomes the widest
     single value instead of the whole concatenation, and the table stops being
     wide at all. This is the reported false-positive case; that content wanted
     stacking, not scrolling.
   - PROSE or a long free-text field — it does not belong in a spine column.
     Move it to an expandable .ev-table__detail row, where it has the full width
     and may wrap.
   - ONE unbreakable machine value that is genuinely that long — then the table
     is genuinely wide, and travelling through the frame is honest.

   Stacked rows (cortex-9wqxyaj) are the other half of this and are NOT
   implemented here. What that variant will need from this frame, recorded now
   so it is not rediscovered: the frame must be able to stop being a boundary.
   When rows stack there is no horizontal overflow left to contain, so the
   scroller, the tab stop, the region role and the guidance all have to go
   together — a focusable, named region announcing how to reach material past an
   edge that cannot exist is worse than no region at all. Only half of that is
   reachable from here: a media-query branch on this block can retire the
   scroller and take the guidance out of the accessibility tree, but `tabindex`
   and `role` are markup, and no CSS removes them. So stacking has to decide the
   other half at the markup layer — a stacked variant the consumer authors
   without the frame, or a documented pairing. That call belongs to that bead.

   COLUMN SCHEMA
   -------------
   Put data-ev-column="name|numeric|ttl|actions" on each HEADER cell. It is
   the one schema: selectors below project each marker onto the same nth-child
   in the body, so alignment and tabular figures cannot drift between th/td.
   Unmarked middle columns flex. Do not emit empty cells to make unlike groups
   line up; the Name / TTL / Actions widths are the shared spine.

   STICKY IDENTITY — THE SAME SCHEMA, AND THE ROW'S REAL MATERIAL
   ---------------------------------------------------------------
   Add .ev-table-viewport--sticky-identity to the FRAME when a genuinely wide
   record needs to retain its name during horizontal travel. There is no cell
   marker: the bounded selectors below project the existing header
   data-ev-column="name" onto the same body position, exactly as the numeric
   schema already does. A table with no modifier has no sticky cells.

   A sticky cell has to paint. Transparency would let the cells travelling
   beneath it show through; a flat face colour would be just as false once the
   row is selected or an expandable row wakes. The projected cell therefore
   paints the frame's declared opaque ground, then composes the SAME --ev-wash
   over it through --ev-table-pinned-wash. Selected and expandable-row states
   already own that wash, so they set the carrier while their ordinary
   background continues to serve every non-pinned cell. The selected scribe is
   moved from the physical first cell to the projected identity cell inside
   this opt-in branch. Spanning detail and empty cells are excluded: one
   full-width plane cannot truthfully become one column merely because its
   first grid slot is the Name slot.

   MATERIAL AND INTERACTION
   ------------------------
   A group containing .ev-table__actions becomes one raised molded plane via
   :has(). That is the additive rule expressed structurally: raised controls
   sit on a raised face. A group without actions gains no false elevation.

   Ordinary rows remain flat data regions: no hover wash, cursor, transform or
   lift; their text stays selectable. An expandable row is recognizable from
   the native .ev-table__row-toggle it contains, so :has() can give only that
   row a pointer cursor and wash. Keyboard focus stays on the button and wakes
   the same row treatment through :focus-within; the tr keeps native table
   semantics and never receives role, tabindex or aria-expanded.

   On fine pointers, compact action keys sit flush
   until their row is hovered or contains keyboard focus, then the real keys
   become proud. Only their falloff changes — the ring is the sole wake
   channel. The no-query floor is a proud 44px target, so touch and engines
   that under-report pointer capability never lose access to the actions.
   ========================================================================== */

.ev-table-group {
    display: grid;
    gap: 1rem;
    min-width: 0;
}

.ev-table-group__item {
    --ev-direct-carve-floor: initial;
    min-width: 0;
    overflow: hidden;
    color: var(--ev-ink);
    border-radius: var(--ev-radius-md);
}

.ev-table-group__item:has(.ev-table__actions) {
    background: var(--ev-metal-hi);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

.ev-table-group__summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 2.75rem;
    padding: 0.625rem 0.875rem;
    cursor: pointer;
    list-style: none;
    font: 600 0.8125rem/1.35 var(--ev-font-sans);
    letter-spacing: 0.04em;
}

.ev-table-group__summary::-webkit-details-marker {
    display: none;
}

.ev-table-group__title {
    min-width: 0;
}

.ev-table-group__count {
    color: var(--ev-ink-dim);
    font-weight: 400;
    letter-spacing: 0;
}

.ev-table-group__marker {
    inline-size: 1.125rem;
    block-size: 1.125rem;
    margin-inline-start: auto;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform var(--ev-transition-fast);
}

.ev-table-group__item:not([open]) .ev-table-group__marker {
    transform: rotate(-90deg);
}

.ev-table-group__item[open] .ev-table-group__summary {
    border-bottom: 1px solid var(--ev-rule);
}

.ev-table-group__footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.5625rem 0.875rem;
    border-top: 1px solid var(--ev-rule);
    color: var(--ev-ink-dim);
    font: 500 0.78125rem/1.35 var(--ev-font-sans);
    text-decoration: none;
}

.ev-table-group__footer:is(:hover, :focus-visible) {
    color: var(--ev-ink);
    background: var(--ev-wash);
}

.ev-table-group__footer svg {
    inline-size: 0.9375rem;
    block-size: 0.9375rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
}

/* The frame. It is the part: the plate that was on the table now lives here,
   so the shadow that seats it is never inside the clip that contains the
   travel. overscroll-behavior-inline keeps a trackpad swipe that runs out of
   table from turning into page or history navigation.

   The four background layers are the continuation cue; see the block comment
   above the token declarations below for why they are shaped this way. */
.ev-table-viewport {
    /* The opaque face the covers are cut from. It must be the colour the
       reader sees BEHIND the travelling table, which for a plated frame is
       this element's own face and for an embedded frame is the host plane —
       measured as --ev-metal-hi in every shipped case, plated and embedded
       alike (nine frames, cortex-m9ne2e9). A consumer that seats an embedded
       table on some other face sets this token there and nothing else.

       Getting that wrong is the one authoring mistake this mechanism can make,
       and it is quiet: a cover cut from the wrong colour does not vanish at
       rest, it paints a band of the wrong colour exactly where the shade was
       meant to be hidden. It fails in the direction that LOOKS calm, so
       scripts/probe_table_edge_cue.py tests the resting edge in absolute value
       and reports a lighter-than-ground edge as COVER MISMATCH rather than as
       the "no cue" a one-sided threshold would have called it. */
    --ev-table-viewport-ground: var(--ev-metal-hi);
    /* The cover's opaque run must EXCEED the shade it hides, or a sliver of
       shade survives at rest and the frame claims continuation that is not
       there. 36px * 60% = 21.6px opaque against a 20px shade. */
    --ev-table-viewport-cover: 36px;
    --ev-table-viewport-shade: 20px;

    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    color: var(--ev-ink);
    background-color: var(--ev-metal-hi);
    background-image:
        linear-gradient(to right, var(--ev-table-viewport-ground) 60%, transparent),
        linear-gradient(to left, var(--ev-table-viewport-ground) 60%, transparent),
        linear-gradient(to right, var(--ev-contact-tint), transparent),
        linear-gradient(to left, var(--ev-contact-tint), transparent);
    background-position: left center, right center, left center, right center;
    background-repeat: no-repeat;
    background-size:
        var(--ev-table-viewport-cover) 100%,
        var(--ev-table-viewport-cover) 100%,
        var(--ev-table-viewport-shade) 100%,
        var(--ev-table-viewport-shade) 100%;
    background-attachment: local, local, scroll, scroll;
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

/* The frame is reachable, so it shows the same boundary every other Evident
   focus target shows. Offset outward: the ring belongs to the frame's outer
   silhouette, not to the travelling content it clips. */
.ev-table-viewport:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

/* One boundary means one plate. The framed table keeps its structure, its
   spine and its max-content claim, and gives up the face, the radius and the
   seating shadow it can no longer honestly carry — the frame draws those now.
   Its own clip goes too: a table clipping to a radius it no longer has would
   cut the sticky identity column (cortex-qqmvogj) off at the frame's edge. */
.ev-table-viewport > .ev-table {
    overflow: visible;
    background: transparent;
    border-radius: 0;
    box-shadow: none;
}

/* A framed table that declares itself embedded is stating that a plane already
   exists around it — the group item, a card, a swatch. The frame reads that
   same marker rather than asking the author for a second one, and adds no
   second face inside the first.

   background-COLOR, not the background shorthand. The shorthand would reset
   background-image to none and take the continuation cue with it, which is
   exactly what happened the first time this branch was measured: the embedded
   frame reported `background-image: none` and showed no cue at any scroll
   position while the plated frame beside it showed both. The face is what an
   embedded frame gives up; the cue is not a face. */
.ev-table-viewport:has(> .ev-table--embedded) {
    background-color: transparent;
    border-radius: 0;
    box-shadow: none;
}

/* The one continuation instruction, and it is never drawn. It says how to
   reach material past the frame; it does not assert that any exists, and it
   says nothing about columns. */
.ev-table-viewport__guidance {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.ev-table {
    --ev-direct-carve-floor: initial;
    width: 100%;
    min-width: max-content;
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    border-radius: var(--ev-radius-md);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

.ev-table--embedded {
    --ev-direct-carve-floor: inherit;
    min-width: 100%;
    overflow: visible;
    background: transparent;
    border-radius: 0;
    box-shadow: none;
}

.ev-table__cell,
.ev-table__actions {
    padding: 0.5625rem 0.875rem;
    text-align: left;
    vertical-align: middle;
    font: 400 0.84375rem/1.35 var(--ev-font-sans);
}

.ev-table__head .ev-table__cell,
.ev-table__head .ev-table__actions {
    border-bottom: 1px solid var(--ev-rule);
    color: var(--ev-ink-dim);
    font-weight: 600;
}

.ev-table__body .ev-table__row + .ev-table__row > * {
    border-top: 1px solid var(--ev-rule);
}

/* A hidden or revealed detail row remains real table structure between two
   summaries, so restore the ordinary divider on the following summary. */
.ev-table__body .ev-table__detail-row + .ev-table__row > * {
    border-top: 1px solid var(--ev-rule);
}

/* The shared outer spine. Name, TTL and Actions are fixed anchors; numeric is
   a middle-field semantic whose 5.5rem width is a floor, not a cap. That keeps
   short figures aligned while allowing a descriptive heading to size the real
   column instead of breaking words inside an artificial box. Other unmarked
   middle columns likewise flex with their actual schema; no placeholder cell
   is needed in a shorter group. */
.ev-table__head [data-ev-column="name"] {
    width: 17rem;
    min-width: 17rem;
    max-width: 17rem;
}

.ev-table__head [data-ev-column="numeric"] {
    width: 5.5rem;
    min-width: 5.5rem;
    white-space: nowrap;
}

.ev-table__head [data-ev-column="ttl"] {
    width: 6.5rem;
    min-width: 6.5rem;
    max-width: 6.5rem;
}

.ev-table__head [data-ev-column="actions"] {
    width: 7.75rem;
    min-width: 7.75rem;
    max-width: 7.75rem;
}

/* One header marker projects numeric semantics onto header AND body. The
   bounded seven-column contract covers the shipped grouped record surface;
   extending it is an explicit component change, not an ad-hoc cell class. */
.ev-table:has(.ev-table__head :nth-child(1)[data-ev-column="numeric"], .ev-table__head :nth-child(1)[data-ev-column="ttl"]) :is(th, td):nth-child(1),
.ev-table:has(.ev-table__head :nth-child(2)[data-ev-column="numeric"], .ev-table__head :nth-child(2)[data-ev-column="ttl"]) :is(th, td):nth-child(2),
.ev-table:has(.ev-table__head :nth-child(3)[data-ev-column="numeric"], .ev-table__head :nth-child(3)[data-ev-column="ttl"]) :is(th, td):nth-child(3),
.ev-table:has(.ev-table__head :nth-child(4)[data-ev-column="numeric"], .ev-table__head :nth-child(4)[data-ev-column="ttl"]) :is(th, td):nth-child(4),
.ev-table:has(.ev-table__head :nth-child(5)[data-ev-column="numeric"], .ev-table__head :nth-child(5)[data-ev-column="ttl"]) :is(th, td):nth-child(5),
.ev-table:has(.ev-table__head :nth-child(6)[data-ev-column="numeric"], .ev-table__head :nth-child(6)[data-ev-column="ttl"]) :is(th, td):nth-child(6),
.ev-table:has(.ev-table__head :nth-child(7)[data-ev-column="numeric"], .ev-table__head :nth-child(7)[data-ev-column="ttl"]) :is(th, td):nth-child(7) {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The Name marker is the identity schema. Project it through the bounded
   seven-column surface instead of asking authors to mark the same fact twice.
   :not([colspan]) is load-bearing: a detail or empty-state cell is one plane
   spanning the record and must travel as one plane, never masquerade as the
   identity column because it occupies that column's first grid slot. */
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(1)[data-ev-column="name"]) :is(th, td):nth-child(1):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(2)[data-ev-column="name"]) :is(th, td):nth-child(2):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(3)[data-ev-column="name"]) :is(th, td):nth-child(3):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(4)[data-ev-column="name"]) :is(th, td):nth-child(4):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(5)[data-ev-column="name"]) :is(th, td):nth-child(5):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(6)[data-ev-column="name"]) :is(th, td):nth-child(6):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(7)[data-ev-column="name"]) :is(th, td):nth-child(7):not([colspan]) {
    position: sticky;
    inset-inline-start: 0;
    z-index: 1;
    background-color: var(--ev-table-viewport-ground);
    background-image: linear-gradient(
        var(--ev-table-pinned-wash, transparent),
        var(--ev-table-pinned-wash, transparent)
    );
}

/* The header owns the upper paint order if a consumer also gives the frame a
   block-axis constraint. This does not make the header sticky vertically; it
   only keeps the Name heading above body identity cells at an intersection. */
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(1)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(1):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(2)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(2):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(3)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(3):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(4)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(4):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(5)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(5):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(6)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(6):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(7)[data-ev-column="name"]) .ev-table__head :is(th, td):nth-child(7):not([colspan]) {
    z-index: 2;
}

.ev-table__row--selected > * {
    --ev-table-pinned-wash: var(--ev-wash);
    background: var(--ev-wash);
}

.ev-table__row--selected > *:first-child {
    box-shadow: inset 3px 0 0 var(--ev-accent);
}

/* In the opt-in branch identity may not be the physical first column. Retire
   that cell's scribe and put the one selected-record mark on the projected
   pinned cell, where it remains visible throughout travel. */
.ev-table-viewport--sticky-identity .ev-table__row--selected > *:first-child {
    box-shadow: none;
}

.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(1)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(1):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(2)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(2):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(3)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(3):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(4)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(4):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(5)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(5):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(6)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(6):not([colspan]),
.ev-table-viewport--sticky-identity > .ev-table:has(.ev-table__head :nth-child(7)[data-ev-column="name"]) .ev-table__row--selected > :nth-child(7):not([colspan]) {
    box-shadow: inset 3px 0 0 var(--ev-accent);
}

/* WHOLE-ROW EXPANSION
   -------------------
   The real button is the structural proof that the row is interactive. This
   avoids a literal row modifier that can drift away from behavior, and keeps
   inert rows free of a false affordance. The wash is flat interaction paint:
   no lift or fabricated relief appears on a table row. */
.ev-table__row:has(.ev-table__row-toggle) {
    cursor: pointer;
}

.ev-table__row:has(.ev-table__row-toggle):is(:hover, :focus-within) > * {
    --ev-table-pinned-wash: var(--ev-wash);
    background: var(--ev-wash);
}

.ev-table__row-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    min-block-size: 2.75rem;
    margin: -0.375rem -0.5rem -0.375rem 0;
    padding: 0.375rem 0.5rem;
    border: 0;
    border-radius: var(--ev-radius-sm);
    color: var(--ev-ink-dim);
    background: transparent;
    font: 600 0.78125rem/1.35 var(--ev-font-sans);
    cursor: pointer;
}

.ev-table__row-toggle::after {
    inline-size: 0.45rem;
    block-size: 0.45rem;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    content: "";
    transform: rotate(45deg) translateY(-0.1rem);
    transition: transform var(--ev-transition-fast);
}

.ev-table__row-toggle[aria-expanded="true"]::after {
    transform: rotate(225deg) translate(-0.05rem, -0.05rem);
}

.ev-table__row-toggle:is(:hover, :focus-visible) {
    color: var(--ev-ink);
}

.ev-table__row-toggle:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 1px;
}

.ev-table__detail-row[hidden] {
    display: none;
}

.ev-table__detail {
    padding: 0.75rem 0.875rem;
    border-top: 1px solid var(--ev-rule-strong);
    color: var(--ev-ink-dim);
    background: var(--ev-floor-n1);
    font: 400 0.8125rem/1.5 var(--ev-font-sans);
}

.ev-table__actions {
    text-align: right;
    white-space: nowrap;
}

.ev-table__action-set {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* Reachable baseline: touch-sized and proud. Fine pointer is a progressive
   compaction below, never the condition that makes actions available. */
.ev-table__action.ev-key {
    inline-size: 2.75rem;
    min-inline-size: 2.75rem;
    block-size: 2.75rem;
    padding: 0;
    border-radius: 50%;
    color: var(--ev-ink-dim);
    transition: none;
}

.ev-table__action svg {
    inline-size: 1.125rem;
    block-size: 1.125rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.55;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Every row action wakes on its own hover or keyboard focus; only the carrier
   ink differs. Safe is the DEFAULT and needs no modifier — an action is
   destructive or it is not. A safe action that stayed inert did not read as
   "danger is special"; it read as a broken hover, and that is what sent a
   consumer reaching for the lit accent face .ev-key--primary. Ink is the whole
   channel: --ev-accent-text, the accent walked a luminance step down for use as
   ink on a neutral ground, exactly as .ev-key--ghost:hover takes it. Never
   --ev-accent, which is a FACE value and misses the text floor in light. */
.ev-table__action.ev-key:not(:disabled):not(.ev-key--disabled):is(:hover, :focus-visible) {
    color: var(--ev-accent-text);
}

/* Destructive identity remains in glyph + accessible name. Warm ink is direct
   interaction feedback only; at rest the action is the same neutral stock.
   The .ev-key in the interaction selector below is load-bearing, not decoration:
   the safe default above computes (0,5,0), so a bare
   .ev-table__action--danger:not():not():is() at (0,4,0) would LOSE and paint the
   trash glyph accent. Matched at (0,5,0) and later in source order, the marked
   exception holds. */
.ev-table__action--danger {
    color: var(--ev-ink-dim);
}

.ev-table__action--danger.ev-key:not(:disabled):not(.ev-key--disabled):is(:hover, :focus-visible) {
    color: var(--ev-danger-action-ink);
}

@media (hover: hover) and (pointer: fine) {
    .ev-table__action-set {
        gap: 0.375rem;
    }

    .ev-table__action.ev-key {
        inline-size: 2rem;
        min-inline-size: 2rem;
        block-size: 2rem;
        box-shadow: none;
    }

    .ev-table__action svg {
        inline-size: 0.9375rem;
        block-size: 0.9375rem;
    }

    /* A2: only a real control rises. The row is merely the scope of the wake;
       it receives no paint or geometry of its own. Ink deliberately does not
       change — the ring is the sole channel. */
    .ev-table__body .ev-table__row:is(:hover, :focus-within) .ev-table__action.ev-key {
        box-shadow:
            var(--ev-contact-1),
            var(--ev-ambient-1);
    }
}

/* ===== src/components/lip.css ===== */
/* ==========================================================================
   Evident component — lip (the lip progression)
   ==========================================================================

   The founder-flagged demonstrative primitive: "Magnified — the lip
   progression." It shows Evident's single most load-bearing correction — the
   INVERTED nesting weight — as a standalone, type-free object so the only thing
   left to judge is the edge.

   THE RULE IT DEMONSTRATES (Invariant 2 / the channels map):
     Rim / lip weight carries NESTING RANK. The weight runs OUTWARD: rank-1 is
     the OUTERMOST cut and the heaviest (a substantial, machined lip); each cut
     nested inside it is finer, until rank-3 is a delicate scribe line rather
     than a trench. This inverted from an earlier version — the intuitive
     direction (heavier as you go deeper) was wrong, and it was read backwards
     three times before it stuck. A real part is fabricated the same way: you
     rough a pocket with a large endmill and detail inside it with smaller
     tools, so a smaller tool = a smaller corner radius = a finer lip.

   WHY THIS IS A SEPARATE PRIMITIVE FROM .ev-machined--{shallow,medium,deep}
     The rank modifiers on .ev-machined DROP the lit-burr rim (--ev-rN-rim) on
     their inner ranks, because there they compose INSIDE a real panel and the
     parent's own rim already states the outer boundary. The lip progression is
     the opposite job: an isolated teaching object where every rank must carry
     its FULL {line, lip, wall, rim} stack so the burr decay (0.88 -> 0.52 ->
     0.30 alpha in light) is visible as the same channel stepping down. So
     .ev-lip__rank{1,2,3} restate the whole stack rather than reuse the panel
     modifiers.

   MOST-REFINED PROVENANCE (why these exact values)
     These are the V9-3 tokens — "the outermost lip, measured not asserted."
     The study demonstrates a v6->v16 progression of the lip; the canonical
     form is V9-3, where the rank-1 lip was measured (lipprobe.py) rather than
     guessed: 6px blur at alpha 0.42 gives a 5px-wide lip reading 14/255 deeper
     through the middle of the band than the v8 5px/0.40 it replaced, while
     ranks 2 and 3 were left unchanged so the inverted progression WIDENED. The
     study's earlier "ramp up with depth" lips (v6/v7: 3/4/5px climbing) are
     the SUPERSEDED direction and are NOT canonical. All values below reference
     the shared --ev-rN-* tokens (defined in tokens.css), so this primitive
     invents no numbers of its own — it only composes and magnifies them, and
     it tracks both themes automatically because those tokens are per-theme.

   Class naming (ev- BEM, cortex-q29li00): the block is .ev-lip; the three cut
   levels are elements .ev-lip__rank1 / __rank2 / __rank3 (rank1 outermost).
   ========================================================================== */

/* The block: an oversized machined pocket carrying rank-1's full stack.
   Magnified (a large radius, and padding a step above the compact components)
   so the edge is legible at a glance and the corner fillet has room to read.
   Floor is n1 (the deepest rung) because this is a demonstration object, not a
   panel composed into a page — there is nothing cut into it that needs a rung
   left in reserve.

   PADDING IS THE LABEL GAP, at all four levels. Every rank carries a label that
   names it, so its top padding IS the air above that label and must equal the
   air below it — one value, read from --ev-carve-label-gap by both halves so
   they cannot drift (cortex-4fg3ps6). It was a hard-coded 34px against a
   label margin of 8px, which is why the rank texts read as headings for the
   carve below them.

   Each rank DECLARES that value rather than only reading it. --ev-carve-label-gap
   is a custom property and therefore INHERITS, so a carve that consumed an
   ancestor's value would silently take that ancestor's inset — drop a .ev-lip
   inside a .ev-baseplate__pocket and its 20px padding would collapse to the
   pocket's 10.5px. Declaring makes every carve authoritative for its own inset
   and the nesting inert. Same reason .ev-well and .ev-baseplate declare theirs. */
.ev-lip {
    /* This is a SLAB holding nested cuts, not a direct bench carve — reset the
       bench-floor override so the block + its ranks use the floor ladder, or the
       whole progression flattens to the near-black bench floor on the bench
       (regression fix, cortex-a2ca9mx). Same reset every other slab declares. */
    --ev-direct-carve-floor: initial;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    color: var(--ev-ink);
    border-radius: var(--ev-radius-lg);
    /* Declared, not merely consumed — see the block comment. */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);
    padding: var(--ev-carve-label-gap);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
    position: relative;
}

/* rank-1 element: an explicit alias of the block face, for markup that wants
   to name the outermost cut alongside its children. Same stack as .ev-lip. */
.ev-lip__rank1 {
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-radius-lg);
    /* Declared, not merely consumed — see the block comment. */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);
    padding: var(--ev-carve-label-gap);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
}

/* rank-2: a cut inside rank-1. Noticeably finer — 3px lip, half the rim burr.
   Floor steps DARKER (n2 is below n1? no — n1 is the deepest; a cut inside the
   deepest floor cannot go deeper, so the ceiling clamps and the floor holds at
   n1). We keep it at n1 and let the RIM, not the floor, carry the rank step —
   which is the whole point: rank lives on lip/rim weight, depth lives on floor
   luminance, and here the depth axis is intentionally pinned so the rim step is
   the only variable. */
.ev-lip__rank2 {
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-radius-md);
    /* Declared, not merely consumed — see the block comment. */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);
    padding: var(--ev-carve-label-gap);
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
}

/* rank-3: a cut inside rank-2. A delicate scribe line — 2px lip, faintest rim.
   This is the finest the language goes; nesting past rank-3 clamps here. */
.ev-lip__rank3 {
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    border-radius: var(--ev-radius-sm);
    /* Declared, not merely consumed — see the block comment. */
    --ev-carve-label-gap: var(--ev-btn-pad-x-md);
    padding: var(--ev-carve-label-gap);
    box-shadow:
        var(--ev-r3-line),
        var(--ev-r3-lip),
        var(--ev-r3-wall),
        var(--ev-r3-rim);
}

/* When the ranks are nested inside each other (the canonical use), rank-3 is
   the innermost and holds no children, so give it a minimum body so the cut
   has an area to read rather than collapsing to a line of padding. */
.ev-lip__rank3:empty {
    min-height: 74px;
    padding: 0;
}

/* ===== src/components/disclosure.css ===== */
/* ==========================================================================
   Evident component — disclosure (the quiet, animated <details>)
   ==========================================================================

   A styled, SHIPPED disclosure built on the native <details>/<summary> pair.
   It is the settled promotion of the gallery's ad-hoc `.ev-doc-notes` /
   `.ev-doc-css` blocks (cortex-kuj9vht) into a real, reusable component so
   consumers get "a bit of extra detail hides
   behind a quiet toggle" without re-authoring the pattern.

   THE REGISTER
     A disclosure is a QUIET affordance, not primary UI. The summary is a small
     muted mono eyebrow — a little caret plus a lowercase-feeling label — never
     a heavy button. Collapsed by default; opening it reveals a recessed,
     ink-dim body. It reads as "there is more here if you want it", not "click
     me".

   THE MARKER (a named component element)
     `.ev-disclosure__marker` is the triangle. It is a real element in the DOM
     (span), not a pseudo, so it is nameable, restyleable, and rotates on its
     own transform channel. Closed → points right; open → points down. The
     rotation eases (~0.16s) so the affordance turns rather than snaps.

   THE BODY ANIMATION — CSS-ONLY, NO JS (Evident ships no language JS)
     Native <details> toggles instantly, and Evident carries no JavaScript, so
     the open/close animation is done two ways at once, so it degrades cleanly:

       1) THE RELIABLE PATH (opens smoothly EVERYWHERE): the body is a
          grid whose single row animates `grid-template-rows: 0fr → 1fr`, with
          an inner wrapper at `overflow:hidden`. A 0fr→1fr grid row is one of
          the few height-from-nothing transitions the engine will actually
          interpolate, so the body slides open on every current engine. (Native
          <details> keeps `display:none` while closed, so this reveal runs on
          the frame the element is un-hidden — an OPEN animation everywhere.)

       2) THE MODERN PATH (adds a smooth CLOSE where supported): with
          `interpolate-size: allow-keywords` on :root and
          `transition-behavior: allow-discrete`, `::details-content` can
          transition its own `content-visibility`/`block-size`, so the close is
          animated too. Engines without `::details-content` simply ignore this
          layer and fall back to an instant close — no breakage.

     Both paths are fast + subtle (~0.15–0.18s ease). Token-driven, so both
     themes re-tint the summary, marker, and the machined well the body sits in.
   ========================================================================== */

/* The modern smooth-CLOSE path keys on keyword interpolation being allowed at
   the root. Harmless on engines that don't understand it (declaration dropped);
   the reliable grid path above does not depend on it. */
:root {
    interpolate-size: allow-keywords;
}

.ev-disclosure {
    margin: 14px 0 0;
    max-width: 68ch;
}

/* The summary: a quiet muted-mono eyebrow toggle. Small caret + muted label,
   deliberately NOT a heavy button. */
.ev-disclosure__summary {
    list-style: none;                    /* drop the native disclosure triangle */
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font: var(--ev-weight-semibold) 10.5px/1 var(--ev-font-mono);
    text-transform: uppercase;
    letter-spacing: var(--ev-tracking-eyebrow, 0.10em);
    color: var(--ev-ink-dim);
    padding: 3px 0;
    user-select: none;
    -webkit-user-select: none;
}
.ev-disclosure__summary::-webkit-details-marker { display: none; }
.ev-disclosure__summary:hover { color: var(--ev-ink); }

/* The marker — a named triangle element (not a pseudo), so it is a real
   component part that turns on its own transform channel. Closed points right;
   open points down. */
.ev-disclosure__marker {
    flex: none;
    width: 0;
    height: 0;
    border-left: 4px solid currentColor;
    border-top: 3.5px solid transparent;
    border-bottom: 3.5px solid transparent;
    opacity: 0.7;
    transform: rotate(0deg);
    transform-origin: 30% 50%;
    transition: transform 0.16s ease;
}
.ev-disclosure[open] > .ev-disclosure__summary .ev-disclosure__marker {
    transform: rotate(90deg);
}

/* THE BODY — the reliable grid path (opens smoothly everywhere).
   A 0fr row collapsed → 1fr open, with the inner wrapper clipped, is a height
   transition the engine will actually interpolate. */
.ev-disclosure__body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.17s ease;
}
.ev-disclosure[open] > .ev-disclosure__body {
    grid-template-rows: 1fr;
}
/* The clipped inner wrapper: the single grid row. Its min-height:0 lets the row
   actually shrink to zero, and overflow:hidden keeps the content from spilling
   during the slide. Consumers put their content inside this wrapper. */
.ev-disclosure__inner {
    min-height: 0;
    overflow: hidden;
}

/* THE MODERN PATH — smooth CLOSE where ::details-content exists. Layered so
   engines without it simply ignore these rules (instant close, no breakage).
   This animates the native content box itself, which the grid path can't reach
   on close because <details> flips display:none synchronously. */
.ev-disclosure::details-content {
    block-size: 0;
    overflow: clip;
    opacity: 0;
    transition:
        block-size 0.17s ease,
        content-visibility 0.17s ease allow-discrete,
        opacity 0.15s ease;
}
.ev-disclosure[open]::details-content {
    block-size: auto;
    opacity: 1;
}

/* ===== src/components/hierarchy.css ===== */
/* ==========================================================================
   Evident component — hierarchy (nested native disclosures)
   ==========================================================================

   A hierarchy is the dense, scan-first sibling of `.ev-disclosure`. Disclosure
   hides optional prose; hierarchy exposes parent/child structure. Branches are
   native <details>/<summary> pairs, leaves are links, and nesting is literal in
   the DOM. The browser therefore owns expand/collapse and keyboard activation;
   the correct tree needs no JavaScript and no invented ARIA tree behavior.

   THE MATERIAL STORY
     The outer tray is one rank-1 cut. Descendants do not become successively
     boxed wells: that would spend relief on every generation and make deep
     data look like stacked cards. Instead, a quiet continuation groove records
     ancestry while indentation records depth. Branch and leaf rows are flat
     marks on the same machined floor.

   THE CURRENT LEAF
     Location is drawn, not tinted. The current leaf keeps neutral ink and is
     recognized by a wash, semibold weight, and one live selection scribe down
     its leading edge — the same vocabulary `.ev-table__row--selected` already
     ships. Accent survives here as geometry, which spends no face budget; it
     is not spent as label colour, because `--ev-accent` is a face/emission
     value and only 1.43:1 on the light canvas. Hover paints the same wash, so
     the scribe and the weight — not a second, heavier wash — are what separate
     “you are here” from “your pointer is here.” See docs/interactive-ink.md.

   THE ROW CONTRACT
     A branch summary owns its whole row, so the row may highlight on hover. A
     leaf link also owns its whole row. Do not put buttons or links inside a
     branch summary and do not add secondary controls inside a leaf row: mixed
     targets would make the full-row feedback dishonest.
   ========================================================================== */

.ev-hierarchy {
    margin: 0;
    padding: 7px;
    color: var(--ev-ink);
    background: var(--ev-floor-n1);
    border-radius: var(--ev-radius-sm);
    box-shadow:
        var(--ev-r1-line),
        var(--ev-r1-lip),
        var(--ev-r1-wall),
        var(--ev-r1-rim);
    font: 13px/1.35 var(--ev-font-sans);
}

.ev-hierarchy__branch,
.ev-hierarchy__children {
    margin: 0;
}

.ev-hierarchy__children {
    position: relative;
    margin-left: 10px;
    padding-left: 12px;
}

/* One continuous machined groove says “these rows descend from this branch”.
   It is ancestry geometry, not a new nesting rank or a decorative connector. */
.ev-hierarchy__children::before {
    content: "";
    position: absolute;
    inset: 0 auto 3px 0;
    width: 1px;
    background: var(--ev-rule-strong);
    box-shadow: 1px 0 0 var(--ev-rule);
}

.ev-hierarchy__summary,
.ev-hierarchy__leaf {
    box-sizing: border-box;
    min-height: 32px;
    width: 100%;
    border-radius: var(--ev-radius-xs, 2px);
    color: inherit;
    text-decoration: none;
}

.ev-hierarchy__summary {
    list-style: none;
    cursor: pointer;
    display: grid;
    grid-template-columns: 12px minmax(0, 1fr) auto;
    align-items: center;
    gap: 7px;
    padding: 6px 9px;
    user-select: none;
    -webkit-user-select: none;
}
.ev-hierarchy__summary::-webkit-details-marker { display: none; }

.ev-hierarchy__leaf {
    display: grid;
    grid-template-columns: 12px minmax(0, 1fr) auto;
    align-items: center;
    gap: 7px;
    padding: 6px 9px;
}

/* Flat interaction paint on the shared floor, exactly as a table row wakes. The
   superseded figure here was `--oxide-veil` (rgba(28,28,28,0.085) in the frozen
   v16 study), a token this package never shipped: the var() had no fallback, so
   it computed to `initial` and the row in fact woke to nothing at all. */
.ev-hierarchy__summary:hover,
.ev-hierarchy__leaf:hover {
    background: var(--ev-wash);
}

/* Keyboard boundary uses the edge channel, never the face value. */
.ev-hierarchy__summary:focus-visible,
.ev-hierarchy__leaf:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: -2px;
}

.ev-hierarchy__marker {
    width: 0;
    height: 0;
    border-left: 4px solid currentColor;
    border-top: 3.5px solid transparent;
    border-bottom: 3.5px solid transparent;
    opacity: 0.72;
    transform: rotate(0deg);
    transform-origin: 30% 50%;
    transition: transform 0.16s ease;
}
.ev-hierarchy__branch[open] > .ev-hierarchy__summary .ev-hierarchy__marker {
    transform: rotate(90deg);
}

/* Leaves reserve the marker column with a small laser-marked stop. Branch and
   leaf silhouettes remain distinguishable without importing an icon family. */
.ev-hierarchy__stop {
    width: 4px;
    height: 4px;
    margin-left: 1px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.38;
}

.ev-hierarchy__label {
    min-width: 0;
    overflow-wrap: anywhere;
}

.ev-hierarchy__meta {
    color: var(--ev-ink-dim);
    font: 10.5px/1 var(--ev-font-mono);
    letter-spacing: var(--ev-tracking-eyebrow, 0.10em);
    text-transform: uppercase;
    white-space: nowrap;
}

/* The neutral ink is stated rather than inherited so the contract survives a
   consumer that recolours the tray, and so the guard can assert it. */
.ev-hierarchy .ev-hierarchy__leaf[aria-current] {
    color: var(--ev-ink);
    background: var(--ev-wash);
    box-shadow: inset 3px 0 0 var(--ev-accent);
    font-weight: var(--ev-weight-semibold);
}
/* The meta lifts out of --ev-ink-dim with its row: the current row's status
   reads at full strength, which is the recognition the old accent tint was
   carrying badly. */
.ev-hierarchy .ev-hierarchy__leaf[aria-current] .ev-hierarchy__meta { color: currentColor; }

@media (max-width: 520px) {
    .ev-hierarchy__children { margin-left: 7px; padding-left: 9px; }
    .ev-hierarchy__meta { display: none; }
}

/* ===== src/components/tooltip.css ===== */
/* ==========================================================================
   Evident component — tooltip (the lifted annotation plate)
   ==========================================================================

   A tooltip is a SMALL, TEMPORARY annotation plate lifted above the surface it
   explains. It is not a dialog, a menu, or a second interaction target:
   nothing inside it is clickable and it never takes focus. The trigger remains
   the only control.

     .ev-tooltip                 the achromatic molded annotation bubble

   The block stays a single leaf, as reserved in docs/reserved-names.md. The
   trigger is whatever focusable element immediately precedes it and carries
   aria-describedby="<tooltip-id>". Put the pair in a positioned inline host:

     <span style="position:relative;display:inline-flex">
       <button aria-describedby="why">?</button>
       <span class="ev-tooltip" id="why" role="tooltip">...</span>
     </span>

   CSS reveals the bubble for BOTH pointer hover and keyboard focus. A consumer
   that needs click/touch persistence may set data-open="true"; that is state
   input, not a positioning runtime. The initial HTML is complete and correctly
   associated without JavaScript.

   MATERIAL:
   - The bubble is molded, not machined: information has been ADDED beside the
     control, so it is a small cast plate above the bench.
   - The centered nib is part of that plate, not a directional-light arrow. It
     points to the trigger while every shadow remains axial (zero x/y offset).
   - It is fully achromatic. A tooltip explains; it carries no status channel.

   POSITIONING:
   The default seats below the trigger, centered. Placement is deliberately
   bounded to that one stable recipe: consumers may progressively enhance the
   physical coordinates when viewport collision demands it, but no JS is
   required for the correct initial render.
   ========================================================================== */

.ev-tooltip {
    position: absolute;
    z-index: 100;
    inset-block-start: calc(100% + 0.625rem);
    inset-inline-start: 50%;
    width: max-content;
    max-width: min(28ch, calc(100vw - 2rem));
    padding: 0.5rem 0.6875rem;

    background: var(--ev-metal-hi);
    color: var(--ev-ink);
    border: 1px solid var(--ev-rule);
    border-radius: var(--ev-radius-sm);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);

    font: 500 0.75rem/1.4 var(--ev-font-sans);
    letter-spacing: 0;
    text-align: start;
    white-space: normal;

    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translate(-50%, -0.2rem);
    transition:
        opacity 0.12s ease,
        transform 0.12s ease,
        visibility 0s linear 0.12s;
}

/* The molded nib is an integral square turned 45deg. Its upper and left edges
   use the same neutral boundary as the plate; no x/y shadow direction is
   added. */
.ev-tooltip::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset-block-start: -0.3125rem;
    inset-inline-start: 50%;
    width: 0.625rem;
    height: 0.625rem;
    background: inherit;
    border-block-start: 1px solid var(--ev-rule);
    border-inline-start: 1px solid var(--ev-rule);
    transform: translateX(-50%) rotate(45deg);
}

/* The trigger is author-owned; Evident only reads the explicit relationship.
   :focus covers programmatic focus and older engines, while :focus-visible
   remains the keyboard-intent path. Hover is an addition, never the only path. */
[aria-describedby]:is(:hover, :focus, :focus-visible) + .ev-tooltip,
.ev-tooltip[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition-delay: 0s;
}

/* A tooltip is descriptive content, not a popover the pointer can enter. Hide
   any accidentally nested control outright: pointer-events alone would still
   leave a tabindex in the keyboard order, turning the leaf into a broken
   non-modal. This makes the interaction ban self-enforcing. */
.ev-tooltip :is(a, button, input, select, textarea, [tabindex]) {
    display: none !important;
}

/* ===== src/components/copyable.css ===== */
/* ==========================================================================
   Evident component — copyable (flat value + copy key)
   ==========================================================================

   A copyable value is still TEXT. The value remains flat, selectable and
   readable when JavaScript is absent; copying is an optional action beside it,
   represented by a small real key:

     <span class="ev-copyable-list">
       <span class="ev-copyable ev-copyable--mono">
       <span class="ev-copyable__value">mysql.example.org</span>
       <button class="ev-key ev-key--xs ev-copyable__copy" ... hidden>Copy</button>
       <span class="ev-copyable__feedback"
             aria-live="polite" aria-atomic="true"></span>
       </span>
     </span>

   The key starts hidden. dist/evident-copyable.js reveals it only when the
   Clipboard API is available in a secure context, so an unenhanced component
   never advertises an action it cannot perform. The initial HTML therefore
   remains complete without JavaScript: the value can always be selected and
   copied manually.

   FEEDBACK:
   The key itself carries the visible result at the locus of action: Copy
   becomes Copied on success or Retry on failure. Its fixed inline size makes
   that state change inert to surrounding sentence and table-cell layout.
   The adjacent polite live region carries the fuller non-visual result but is
   permanently clipped out of layout rather than conditionally display:none;
   assistive technology can therefore announce every update without a third
   inline child moving the host composition.

   Icon-only feedback composes the existing .ev-tooltip plate as
   .ev-copyable__tip. It is a result, not an annotation: hover and focus never
   reveal it, it takes no focus, and pointer, keyboard and touch activation all
   use the same click path. Success remains for 1.6s while the checkmark is the
   durable confirmation. Failure is actionable feedback, so its Retry plate
   persists until another copy attempt or Escape. Only the latest activation
   in a document may own a confirmation; stale asynchronous results are inert.

   MODIFIERS:
   --mono      genuine machine values: ids, keys, addresses and hostnames
   --truncate  one-line ellipsis; the full value remains in the DOM and copy
               source, and authors should provide it as the value's title too
   ========================================================================== */

.ev-copyable {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    max-inline-size: 100%;
    color: var(--ev-ink);
    font: 400 var(--ev-text-small) / var(--ev-leading-snug) var(--ev-font-sans);
    vertical-align: middle;
}

/* A repeated value list owns one common action edge. Each value remains a
   complete copyable component; the carrier only gives its keys a shared datum
   so a scan does not zig-zag between different value lengths. */
.ev-copyable-list {
    display: grid;
    gap: 0.875rem;
    inline-size: 100%;
}

.ev-copyable-list > .ev-copyable {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    inline-size: 100%;
}

.ev-copyable__value {
    min-inline-size: 0;
    overflow-wrap: anywhere;
    user-select: text;
    cursor: text;
}

.ev-copyable--mono .ev-copyable__value {
    font-family: var(--ev-font-mono);
}

.ev-copyable--truncate {
    inline-size: 100%;
}

.ev-copyable--truncate .ev-copyable__value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow-wrap: normal;
}

/* The copy action keeps an XS key's 31px pointer target, but sheds the raised
   cast face: this is a secondary instrument beside the value, not a peer to
   it. The readable button text remains in the accessibility tree while the
   visual state is a compact 14px glyph. Copy/Copied/Retry therefore share one
   inert footprint and consumers need no extra icon markup. */
.ev-copyable__copy {
    --ev-copyable-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='6.5' y='6.5' width='9' height='9' rx='1.5'/%3E%3Cpath d='M4.5 13.5h-1A1.5 1.5 0 0 1 2 12V3.5A1.5 1.5 0 0 1 3.5 2H12a1.5 1.5 0 0 1 1.5 1.5v1'/%3E%3C/svg%3E");
    flex: 0 0 auto;
    box-sizing: border-box;
    inline-size: var(--ev-btn-height-xs);
    min-inline-size: var(--ev-btn-height-xs);
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    font-size: 0;
    line-height: 0;
    background: transparent;
    color: var(--ev-ink-dim);
    box-shadow: none;
}

.ev-copyable__copy::before {
    content: "";
    inline-size: 0.875rem;
    block-size: 0.875rem;
    background: currentColor;
    -webkit-mask: var(--ev-copyable-icon) center / contain no-repeat;
    mask: var(--ev-copyable-icon) center / contain no-repeat;
    pointer-events: none;
}

.ev-copyable__copy:not(:disabled):not(.ev-key--disabled):hover {
    background: transparent;
    color: var(--ev-accent-text);
    box-shadow: none;
}

.ev-copyable__copy:active {
    box-shadow: none;
}

.ev-copyable__copy[data-copy-state="pending"] {
    opacity: 0.55;
}

.ev-copyable__copy[data-copy-state="copied"] {
    --ev-copyable-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 10.5 3.5 3.5L16 5.5'/%3E%3C/svg%3E");
    color: var(--ev-success);
}

.ev-copyable__copy[data-copy-state="failed"] {
    --ev-copyable-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15.5 7V3.5H12'/%3E%3Cpath d='M15 4.5a6.5 6.5 0 1 0 1.2 7.2'/%3E%3C/svg%3E");
    color: var(--ev-danger);
}

.ev-copyable__copy[hidden] {
    display: none;
}

.ev-copyable__feedback {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* The result plate is fixed to coordinates measured from the action key. That
   takes it out of every sentence/table layout and permits the enhancement to
   clamp its centre to the viewport before choosing above/below placement.
   The base .ev-tooltip supplies the material; these rules only specialize the
   result interaction and physical locus. */
.ev-copyable__tip.ev-tooltip {
    position: fixed;
    inset-block-start: var(--ev-copyable-tip-block, 0);
    inset-inline-start: var(--ev-copyable-tip-inline, 0);
    max-inline-size: min(24ch, calc(100vw - 1rem));
    transform: translate(-50%, -0.2rem);
}

.ev-copyable__tip.ev-tooltip[data-open="true"] {
    transform: translate(-50%, 0);
}

.ev-copyable__tip.ev-tooltip[data-placement="above"] {
    transform: translate(-50%, calc(-100% + 0.2rem));
}

.ev-copyable__tip.ev-tooltip[data-placement="above"][data-open="true"] {
    transform: translate(-50%, -100%);
}

.ev-copyable__tip.ev-tooltip[data-placement="above"]::before {
    inset-block-start: auto;
    inset-block-end: -0.3125rem;
    border-block-start: 0;
    border-inline-start: 0;
    border-block-end: 1px solid var(--ev-rule);
    border-inline-end: 1px solid var(--ev-rule);
}

@media (prefers-reduced-motion: reduce) {
    .ev-copyable__tip.ev-tooltip {
        transition: none;
    }
}

/* ===== src/components/glass.css ===== */
/* ==========================================================================
   Evident component — glass (the content-aperture insert material)
   ==========================================================================

   Glass is a third INSERT material (after molded metal and machined cuts). It
   is a transparent PART set into a machined aperture (bezel/gasket). Its JOB is
   to give CONTENT a material home: a glowing LED readout or a coloured avatar
   sits BEHIND an achromatic glass window in the panel, so the panel stays pure
   achromatic machined metal and content-colour earns its place. Promoted from
   the standalone study (demos/glass-study.html) — cortex-t8w48yi.

   THE INVARIANTS glass holds:
     1. ONE MEANING — glass is used ONLY for content/display apertures (LED
        readout, avatar, status lens). Never a generic glossy finish. FROSTED is
        likewise gated to APERTURES only — never a generic surface finish
        (founder ruling B).
     2. GLASS IS ACHROMATIC — every glass surface token is white / neutral ALPHA
        (--ev-glass-*, in tokens.css). All colour comes from the CONTENT behind
        the glass.
     3. OPTICAL SIGNATURE = its channel — a small AXIAL specular glint
        (symmetric, near the top; a glint, NOT a light direction, so L1 holds), a
        bright inner bevel/refraction rim + a slight dark outer contact where the
        glass meets the aperture wall, and it reveals what is behind (content
        sits BELOW the glass surface).

   FOUNDER RULING A — LED glow is ALLOWED as emission from LIT CONTENT behind
   glass: a sanctioned carve-out of the flat-text (L3) invariant. The panel's own
   labels stay flat; ONLY the lit display content (the glowing value) emits. The
   glow is CONTENT (accent hue), not decoration on panel ink.

   PACKAGING — the pure-CSS box-shadow-rim path below is the BASE (works
   standalone, no JS, all engines). The Chromium `feDisplacementMap` edge
   refraction is an ENHANCEMENT layer, gated behind
   `@supports (backdrop-filter: url(#ev-glass-refract-96))`. The SVG <filter>
   defs + the canvas displacement-map generator cannot live in a .css file, so
   they ship as an OPTIONAL asset, dist/evident-glass-refract.js: consumers
   include that ONE script to activate refraction; without it they get the CSS
   fallback rim. A `backdrop-filter: url(#missing)` degrades cleanly (the base
   box-shadow rim still renders) when the JS is absent.
   ========================================================================== */

/* ==========================================================================
   THE GLASS PART — the shared insert primitive.

   A glass insert is TWO nested things:
     .ev-aperture  — a machined CUT in the panel (bezel/gasket). A real recess:
                     lip, wall, inset shadow. This is ordinary Evident machining.
     .ev-glass     — the transparent PART seated in that cut. It sits ON TOP of
                     the content but reveals it — the content shows through.

   The optical signature is built from THREE stacked pseudo/box layers, all
   achromatic:
     (a) box-shadow: the bevel rim (bright, inside) + the contact seam (dark, at
         the aperture wall). Two parts meeting.
     (b) ::before  — the AXIAL top glint: a soft symmetric white ellipse near the
         top, horizontally centred (zero x-bias — a glint, not a light).
     (c) ::after   — the under-glass scrim: a hair of neutral darkening + a very
         faint vertical falloff so the content reads as sitting BELOW a surface.
   ========================================================================== */

/* The machined aperture — the cut the glass seats into. Plate is n2, so the
   aperture floor is n1 (one rung deeper); its own rank-2 cut shading reads the
   recess before any glass or content lands in it. */
.ev-aperture {
    position: relative;
    background-color: var(--ev-direct-carve-floor, var(--ev-floor-n1));
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
    overflow: hidden;
}

/* The glass part itself — fills the aperture, sits over the content. It draws
   nothing but light: the content behind is what carries colour. */
.ev-glass {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    /* (a) the bevel rim (bright, just inside) + the outer contact seam (dark, at
       the aperture wall). Both achromatic; this is where two PARTS meet. */
    box-shadow:
        var(--ev-glass-bevel),
        var(--ev-glass-bevel-soft),
        var(--ev-glass-contact),
        var(--ev-glass-contact-2);
    /* (c-base) the whole pane carries a hair of neutral darkening so even before
       the glint, content reads as BELOW a surface. A grey scrim, never a hue. */
    background: var(--ev-glass-underscrim);
}

/* (b) the AXIAL specular glint — a soft symmetric white ellipse near the top.
   Horizontally CENTRED (50%): a glint on a curved pane, not a directional light,
   so Invariant L1 holds. Fades out well before mid-height. */
.ev-glass::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        radial-gradient(60% 42% at 50% -6%,
            var(--ev-glass-glint) 0%,
            var(--ev-glass-glint-soft) 40%,
            transparent 72%);
}

/* (c-falloff) a very faint top-to-bottom darkening — the content dims a touch
   toward the bottom of the pane, the way real content behind glass loses a
   little light with depth. Achromatic. */
.ev-glass::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        linear-gradient(180deg,
            transparent 0%,
            transparent 55%,
            var(--ev-glass-underscrim) 100%);
}

/* ---- CLEAR vs FROSTED ---------------------------------------------------
   Clear = sharp/live (default). Frosted = soft/ambient: a milky white-alpha veil
   laid over the content to DIFFUSE it. The veil is achromatic; it dims and
   softens the content's colour without tinting it. (backdrop-filter blurs the
   content behind where supported; the veil is the guaranteed floor.)
   FROSTED IS GATED TO APERTURES ONLY (founder ruling B) — it is a lens finish,
   never a generic surface treatment. */
.ev-glass--frosted {
    background:
        var(--ev-glass-frost),
        var(--ev-glass-underscrim);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}
.ev-glass--frosted::before {
    /* a frosted pane scatters the glint into a broader, softer bloom */
    background:
        radial-gradient(80% 60% at 50% -10%,
            var(--ev-glass-glint) 0%,
            var(--ev-glass-glint-soft) 50%,
            transparent 85%);
}

/* ==========================================================================
   PIECE 1 — the LIT READOUT CLUSTER (.ev-readout-cluster--lit).

   A machined instrument panel whose digits GLOW (accent) as if lit behind a
   clear glass cover.

   THIS IS A MODIFIER, NOT A BLOCK. The plate is `.ev-readout-cluster`
   (src/components/readout.css) — the same molded faceplate, the same swoop, the
   same radius, the same three-layer shadow, the same milled-pocket grid. What
   the lit treatment actually changes is the CELL, and only the CELL:

     flat  (.ev-readout-cluster)        a shallow milled POCKET, flat ink.
     lit   (.ev-readout-cluster--lit)   a milled APERTURE with a GLASS insert
                                        over a smoked display substrate, and a
                                        value that LUMINATES.

   One block, two cell treatments. This section therefore carries no block-level
   rule at all — there is nothing about the plate that differs, so there is
   nothing to override. Until cortex-v41smw1 this shipped as a separate
   "instrument" block whose plate rule was a verbatim copy of the cluster's (its
   own comment said so: "molded faceplate — same as the readout cluster's
   plate"). That block and its five element names were REMOVED, cleanly and
   without an alias, per cortex-qairdc1. All six removed names, and what to use
   instead, are in docs/removed-names.tsv.

   MARKUP:

     <div class="ev-readout-cluster ev-readout-cluster--lit">
       <div class="ev-readout-cluster__cell">
         <span class="ev-readout-cluster__value">14</span>
         <span class="ev-readout-cluster__label">DOMÆNER</span>
         <span class="ev-glass"></span>
       </div>
       ...
     </div>

   The trailing `.ev-glass` span is the pane itself — the lit cell is an
   aperture, and an aperture without its glass is just a dark hole.

   The glow is the CONTENT (accent) — colour behind the achromatic glass. The
   panel, bezel and glint stay pure grey. LED emission is sanctioned by founder
   ruling A; the panel's own labels stay flat.

   INTERACTION (cortex-g8own7f)
   ----------------------------
   Glass sits ABOVE its content, so an instrument pane may itself be clickable.
   An `<a>` or `<button>` cell opts in by native semantics; a custom interactive
   host may opt in with `.ev-readout-cluster__cell--interactive` (and must supply
   its own keyboard semantics). Static cells do not react.

   Hover/focus lights the DISPLAY CONTENT behind the pane, never the achromatic
   metal panel. One registered intensity driver, `--inst-lit` (0..1), controls
   the LED bloom, under-glass phosphor bloom and neutral screen texture. The
   transition is motion-gated globally; with motion off the same state snaps on,
   so motion never carries the meaning.
   ========================================================================== */

/* Registered so the 0→1 instrument-light driver interpolates instead of
   changing discretely. Browsers without @property still get the complete
   hover/focus state; they simply snap, the same truthful fallback as the
   library's forced reduced-motion mode. */
@property --inst-lit {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}

/* The cell becomes a milled APERTURE with a glass cover over a glowing readout,
   in place of the flat cluster's shallow pocket. Geometry (min-height, padding,
   margin, radius, the column flex with space-between) belongs to the block and
   is NOT restated here — only the material changes. */
.ev-readout-cluster--lit .ev-readout-cluster__cell {
    /* rest value of the instrument-light driver, stated ONCE for every surface
       that seats content behind glass — the lit cell and the identity
       instrument share this aperture material, so they share its driver. */
    --inst-lit: 0;
    /* the .ev-glass pane is absolutely positioned; this is what it seats against */
    position: relative;
    /* the display substrate behind the glass — a smoked instrument screen. Dark
       in BOTH themes: content (the glow) needs a dark ground to bloom on. This
       is CONTENT-side material (the screen), not the achromatic panel. */
    background-color: #14171b;
    /* machined APERTURE shading (rank-2 cut) — the cut the glass seats into,
       one rung deeper than the flat cell's rank-3 pocket. */
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
    overflow: hidden;
}

/* RETRO DISPLAY SUBSTRATE — both layers sit behind the content and glass.
   ::before is a fine achromatic scanline texture; ::after is a symmetric
   phosphor vignette plus the interactive emitter bloom. No directional light,
   no panel colour and no outer halo: the screen itself warms under its pane. */
.ev-readout-cluster--lit .ev-readout-cluster__cell::before,
.ev-readout-cluster--lit .ev-readout-cluster__cell::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: 0;
}

.ev-readout-cluster--lit .ev-readout-cluster__cell::before {
    background:
        repeating-linear-gradient(
            0deg,
            rgba(255, 255, 255, calc(0.022 + 0.012 * var(--inst-lit))) 0,
            rgba(255, 255, 255, calc(0.022 + 0.012 * var(--inst-lit))) 1px,
            transparent 1px,
            transparent 3px);
}

.ev-readout-cluster--lit .ev-readout-cluster__cell::after {
    background:
        radial-gradient(
            82% 94% at 50% 42%,
            color-mix(in srgb,
                var(--ev-accent) calc(var(--inst-lit) * 16%),
                transparent) 0%,
            color-mix(in srgb,
                var(--ev-accent) calc(var(--inst-lit) * 6%),
                transparent) 46%,
            transparent 72%),
        radial-gradient(
            120% 120% at 50% 45%,
            transparent 54%,
            rgba(0, 0, 0, calc(0.34 + 0.04 * var(--inst-lit))) 100%);
    box-shadow:
        inset 0 0 calc(20px + 18px * var(--inst-lit))
        color-mix(in srgb,
            var(--ev-accent) calc(var(--inst-lit) * 18%),
            transparent);
}

/* Content is above the display texture; the transparent lens is the top part.
   Stating the stack explicitly prevents a later pseudo-element from silently
   drawing scanlines over the physical glass surface. */
.ev-readout-cluster--lit .ev-readout-cluster__value,
.ev-readout-cluster--lit .ev-readout-cluster__label {
    z-index: 1;
}
.ev-readout-cluster--lit .ev-readout-cluster__cell > .ev-glass {
    z-index: 2;
}

/* the glowing value — CONTENT. Accent hue, with a bloom (text-shadow is the
   LED's own emission, on the content layer behind glass — NOT decoration on
   panel ink; the flat-text invariant holds because the panel's own labels stay
   flat and only the lit display emits — founder ruling A). Tracking opens a
   half-step against the flat value's -0.02em so the bloom does not smear
   adjacent glyphs into each other. */
.ev-readout-cluster--lit .ev-readout-cluster__value {
    position: relative;
    z-index: 0;
    letter-spacing: -0.01em;
    color: var(--ev-accent);
    text-shadow:
        0 0 calc(2px + 2px * var(--inst-lit))
            color-mix(in srgb,
                var(--ev-accent) calc(90% + 8% * var(--inst-lit)),
                transparent),
        0 0 calc(10px + 8px * var(--inst-lit))
            color-mix(in srgb,
                var(--ev-accent) calc(62% + 18% * var(--inst-lit)),
                transparent),
        0 0 calc(22px + 16px * var(--inst-lit))
            color-mix(in srgb,
                var(--ev-accent) calc(38% + 20% * var(--inst-lit)),
                transparent);
}
.ev-readout-cluster--lit .ev-readout-cluster__unit {
    /* The mix partner desaturates the lit accent for the unit suffix. It was
       #7f8a90, a slate; an achromatic grey of the same luminance (0.2463 vs
       0.2470) desaturates identically without putting a second hue in the file
       — the mix result shifts by well under a tone. (cortex-yzjllwa) */
    color: color-mix(in srgb, var(--ev-accent) 72%, #888888);
    text-shadow:
        0 0 calc(6px + 6px * var(--inst-lit))
        color-mix(in srgb,
            var(--ev-accent) calc(40% + 18% * var(--inst-lit)),
            transparent);
}
/* the caption — a silk-screened label on the display, dim luminous grey. It is
   CONTENT on the screen (printed on the display), so it may glow faintly; it
   stays achromatic. Mono and wider-tracked than the flat caption: it is printed
   ON the instrument screen, not set on the panel. */
.ev-readout-cluster--lit .ev-readout-cluster__label {
    position: relative;
    z-index: 0;
    font-family: var(--ev-font-mono);
    letter-spacing: 0.1em;
    font-weight: 500;
    /* Was rgba(198,208,214) — a slate, where the comment above already calls
       this a "dim luminous grey". The content carve-out lets CONTENT carry hue
       (a lit value, an avatar); a silk-screened monochrome caption is not that,
       so it takes the equal-luminance grey. (cortex-yzjllwa) */
    color: rgba(206, 206, 206, calc(0.62 + 0.16 * var(--inst-lit)));
}
/* a dimmed / inert reading — an off LED segment: the same digits, no emission.
   Shows the glow is a LIVENESS reading (accent = live), not baked into glass. */
.ev-readout-cluster--lit .ev-readout-cluster__value--off {
    /* achromatic: an UNLIT segment emits nothing, so it carries no content
       colour to justify a hue. Was rgba(150,160,168). (cortex-yzjllwa) */
    color: rgba(159, 159, 159, 0.42);
    text-shadow: none;
}

/* A lit cell is a sealed aperture, not a milled pocket, so it has no
   polished-finish hover and no deeper-cut press. Hold the screen's MATERIAL
   through every interaction state; only the content-side --inst-lit driver
   changes. This overrides the flat cluster's inherited link hover/press rules.

   :focus-visible joins :hover and :active here because the flat register now
   gives a keyboard arrival the same polished finish it gives a pointer one
   (cortex-pmctr5c). Before that the omission was harmless — the flat register
   had no focus treatment to hold off. */
.ev-readout-cluster--lit .ev-readout-cluster__cell:where(a):is(:hover, :active, :focus-visible),
.ev-readout-cluster--lit .ev-readout-cluster__cell:where(button):is(:hover, :active, :focus-visible),
.ev-readout-cluster--lit .ev-readout-cluster__cell--interactive:is(:hover, :active, :focus-visible) {
    background-color: #14171b;
    box-shadow:
        var(--ev-r2-line),
        var(--ev-r2-lip),
        var(--ev-r2-wall),
        var(--ev-r2-rim);
}

/* The lit register does NOT take the flat register's resting ACCENT mark.
   The flat pocket marks an interactive cell by putting the accent on its
   caption at rest (readout.css, "The INTERACTIVE cell"); here the VALUE
   already emits the accent as lit content, so a second accent on the
   silk-screened caption would put two live readings in one cell and the mark
   would stop reading as a mark. The caption holds its dim luminous grey.

   Stated as a rule rather than left to specificity: the flat mark and the
   block-level caption rule weigh the same, so source order must not decide
   which register speaks. */
.ev-readout-cluster--lit
    .ev-readout-cluster__cell:is(a, button, .ev-readout-cluster__cell--interactive)
    .ev-readout-cluster__label {
    color: rgba(206, 206, 206, calc(0.62 + 0.16 * var(--inst-lit)));
}

/* The lit register's own RESTING mark is a neutral silk-screened index diamond
   beside the caption. It belongs to the printed legend on the display, not to
   the emitting value, glass or bezel: currentColor keeps it achromatic and one
   0.32rem square keeps it at indicator scale. A diamond states "this legend is
   a control" without claiming that every control navigates in one direction;
   links, buttons and custom keyboard controls therefore share the same mark.

   Static lit cells have no pseudo-element. Hover/focus may still raise
   --inst-lit from 0 to 1, but neither motion nor a pointer is needed to read
   the interactive form at rest. */
.ev-readout-cluster--lit
    .ev-readout-cluster__cell:is(a, button, .ev-readout-cluster__cell--interactive)
    .ev-readout-cluster__label::after {
    display: inline-block;
    inline-size: 0.32rem;
    block-size: 0.32rem;
    margin-inline-start: 0.5rem;
    border: 1px solid currentColor;
    content: "";
    transform: rotate(45deg);
    vertical-align: 0.08em;
}

/* Native links/buttons opt in by semantics; the modifier supports a custom
   focusable host. The pointer + flat link reset carry no material claim. */
.ev-readout-cluster--lit
    .ev-readout-cluster__cell:is(a, button, .ev-readout-cluster__cell--interactive) {
    cursor: pointer;
    text-decoration: none;
    transition:
        --inst-lit 360ms ease,
        box-shadow var(--ev-press-out) var(--ev-press-out-ease),
        background-color var(--ev-press-out) var(--ev-press-out-ease);
}
.ev-readout-cluster--lit .ev-readout-cluster__cell:where(button) {
    appearance: none;
    border: 0;
    font: inherit;
    text-align: inherit;
}

.ev-readout-cluster--lit
    .ev-readout-cluster__cell:is(a, button, .ev-readout-cluster__cell--interactive):is(:hover, :focus-visible) {
    --inst-lit: 1;
}

.ev-readout-cluster--lit
    .ev-readout-cluster__cell:is(a, button, .ev-readout-cluster__cell--interactive):focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

/* Preserve the existing accent content reading against the flat cluster's
   anchor-hover ink override. Its intensity already rides the driver above; no
   colour channel changes on interaction.

   The matching caption rule that used to sit here is gone: the resting rule
   above already holds the caption's grey for the SAME three hosts at every
   state, so a hover-scoped copy only added a third site for one literal to
   drift at. */
.ev-readout-cluster--lit
    .ev-readout-cluster__cell:is(a, button, .ev-readout-cluster__cell--interactive):is(:hover, :focus-visible)
    .ev-readout-cluster__value {
    color: var(--ev-accent);
}

/* ==========================================================================
   PIECE 2 — the CLICKABLE IDENTITY INSTRUMENT (.ev-glass-id).

   Founder review 2026-07-28 (cortex-pxe4904): a clickable user avatar is not a
   coloured disc sitting in another carved ridge. It is a compact instrument
   that PROJECTS the rounded portrait on its left and EMITS identity data on
   its right. The whole instrument is an <a> to the user.

   The shell shares the lit-cell material rule above verbatim: one smoked
   display substrate in a rank-2 aperture. The existing `.ev-glass-avatar`
   provides the 56px projection lens, including its bezel, refraction and CSS
   fallback. No new lens size means no new JS refraction map.

   Typography keeps L5 honest:
     NAME    human prose -> IBM Plex Sans, pale screen ink, no glow.
     META    @handle / user id -> IBM Plex Mono, emitted accent content.

   `--inst-lit` and `--gav-sheen` rise together on hover/focus, so the readout
   emission and lens catch respond as ONE instrument. Motion is never the state:
   the variables still snap to their lit values when the motion gate removes
   transitions.

   MARKUP:

     <a class="ev-glass-id" href="/users/mikkel-krog">
       <span class="ev-glass-id__lens ev-glass-avatar ev-glass-avatar--interactive"
             style="--gav-size:56px; --gav-tile:#c0392b;">
         <span class="ev-glass-avatar__initials">MK</span>
         <span class="ev-glass"></span>
       </span>
       <span class="ev-glass-id__body">
         <span class="ev-glass-id__name">Mikkel Krog</span>
         <span class="ev-glass-id__meta">@mikkel · u-0417</span>
       </span>
     </a>
   ========================================================================== */

.ev-glass-id {
    /* --inst-lit rests at 0 via the shared aperture block above. */
    --gav-sheen: 0;

    display: inline-flex;
    align-items: center;
    gap: 14px;
    min-width: 226px;
    padding: 12px 16px;
    border-radius: var(--ev-radius-md);
    position: relative;
    color: var(--ev-ink);
    background: var(--ev-metal-hi);
    box-shadow:
        var(--ev-shoulder-lite),
        var(--ev-shoulder-1),
        var(--ev-contact-1),
        var(--ev-ambient-1);
    font-family: var(--ev-font-sans);
    text-decoration: none;
    cursor: pointer;
    isolation: isolate;
    transition: box-shadow 320ms ease;
}

/* Emission spill from the machine-value readout. This sits behind both content
   columns and carries no independent state: opacity is only --inst-lit. */
.ev-glass-id::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    pointer-events: none;
    box-shadow:
        inset 0 0 18px
            color-mix(in srgb, var(--ev-accent) 18%, transparent);
    opacity: var(--inst-lit);
    transition: opacity 320ms ease;
}

.ev-glass-id > * {
    position: relative;
    z-index: 1;
}

.ev-glass-id > .ev-glass-id__lens {
    flex: 0 0 auto;
}

.ev-glass-id__body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
    gap: 3px;
    padding: 0.55rem 0.7rem;
    border-radius: calc(var(--ev-radius-sm) - 1px);
    background-color: #14171b;
    box-shadow: var(--ev-r2-line), var(--ev-r2-lip), var(--ev-r2-wall);
}

.ev-glass-id__name {
    color: rgba(226, 226, 226, 0.88);
    font: 600 0.95rem/1.2 var(--ev-font-sans);
    letter-spacing: 0.005em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The handle/id is genuine machine data, so mono is earned. Its glow is
   emitted CONTENT behind glass — founder ruling A — not decoration on the
   human name or on panel ink. */
.ev-glass-id__meta {
    color: color-mix(in srgb, var(--ev-accent) 82%, #888888);
    font: 500 0.72rem/1.25 var(--ev-font-mono);
    letter-spacing: 0.07em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-shadow:
        0 0 2px color-mix(in srgb, var(--ev-accent) 56%, transparent),
        0 0 8px color-mix(in srgb, var(--ev-accent) 28%, transparent);
    transition: text-shadow 320ms ease, color 320ms ease;
}

.ev-glass-id:hover,
.ev-glass-id:focus-visible {
    --inst-lit: 1;
    --gav-sheen: 1;
}

.ev-glass-id:hover .ev-glass-id__meta,
.ev-glass-id:focus-visible .ev-glass-id__meta {
    color: var(--ev-accent);
    text-shadow:
        0 0 2px color-mix(in srgb, var(--ev-accent) 88%, transparent),
        0 0 10px color-mix(in srgb, var(--ev-accent) 52%, transparent);
}

/* Parent hover/focus brightens the existing projection lens even when the
   pointer is over the readout half, preserving the "one instrument" reading. */
.ev-glass-id:hover .ev-glass-avatar > .ev-glass,
.ev-glass-id:focus-visible .ev-glass-avatar > .ev-glass {
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.48),
        inset 0 0 7px   rgba(255, 255, 255, 0.20),
        inset 0 0 0 2px rgba(20, 20, 20, 0.06),
        inset 0 0 7px   rgba(20, 20, 20, 0.08);
}

.ev-glass-id:hover .ev-glass-avatar > .ev-glass::before,
.ev-glass-id:focus-visible .ev-glass-avatar > .ev-glass::before {
    opacity: 1.35;
}

.ev-glass-id:focus-visible {
    outline: 2px solid var(--ev-accent-edge);
    outline-offset: 2px;
}

/* ==========================================================================
   ROUND GLASS = A LENS SEATED IN A CARVED METAL APERTURE
   (.ev-glass-avatar / .ev-glass-lamp)

   An honest LAYER STACK, outer -> inner (both lamp & avatar share it). Each ring
   is a real fabrication event, so the surface can be READ:

     1. BEZEL   — the container itself IS panel metal (--ev-metal-hi) with a
                  subtle RAISED/molded finish (outer shadow). A real ring of metal
                  (--rr-bezel wide) surrounds the hole. This is the panel the
                  aperture is cut INTO.
     2. WALL    — the container ::before is the CUT: an inset ring at the bezel
                  line carrying a crisp dark contact at the inner rim + a soft
                  wall falloff down to the floor. Material was removed here.
     3. FLOOR   — the content (lit disc / photo / monogram), inset by the bezel
                  width, sits at the BOTTOM of the aperture.
     4. LENS    — .ev-glass, inset by the bezel width, seated just below the bezel
                  lip: one soft AXIAL glint (top, centred), a bright refractive
                  rim where glass meets wall, a faint grey scrim.

   Bezel, wall, glass, glint and scrim are ALL ACHROMATIC. Colour comes ONLY from
   the content. Symmetric axial light (glint centred; edge shades ringed). Every
   round edge is feathered (radial mask) so no stair-stepped circle.

   --rr-size is the outer diameter; --rr-bezel is the metal ring width (~8.5% of
   the diameter, min 3px, so a 40px lamp gets ~3px and a 64px lamp ~5px).
   ========================================================================== */
.ev-glass-avatar,
.ev-glass-lamp {
    --ev-direct-carve-floor: initial;
    --rr-bezel: max(3px, calc(var(--rr-size) * 0.085));
    position: relative;
    width: var(--rr-size);
    height: var(--rr-size);
    border-radius: 50%;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    /* --rr-size is set per component below (avatar -> --gav-size, lamp ->
       --lamp-size), each with its own historical default. */
    /* LAYER 1 — the raised metal BEZEL. The container is panel metal with a
       shallow radial shoulder (brighter toward the top-centre, achromatic) and
       an OUTER molded shadow so the ring reads as raised material the hole is cut
       into. No overflow clip here: the ring must stay visible; the inner parts
       are inset by --rr-bezel and feather their own edges.

       OPEN-FACE RULING (cortex-cen2d0x): this outer cast belongs to the bezel,
       not to the lens seated inside its aperture. The cut begins at ::before's
       --rr-bezel inset; outside the container, the bezel stands on the host's
       wide bench with more than the 14px ambient runway available in every
       gallery specimen. Contact + ambient therefore has real surrounding land
       to fall across. Replacing it with --ev-seat-contact would incorrectly
       depict the whole raised bezel as another part trapped inside its cut. */
    background-color: var(--ev-metal-hi);
    background-image:
        radial-gradient(72% 62% at 50% 34%,
            var(--ev-lum-hi)  0%,
            var(--ev-lum-mid) 46%,
            transparent       72%,
            var(--ev-lum-lo)  100%);
    box-shadow:
        /* raised molded finish: a soft outer drop + a bright top shoulder line
           and a faint bottom contact — symmetric ambient, achromatic */
        var(--ev-shoulder-lite),
        var(--ev-contact-1),
        var(--ev-ambient-1);
}

/* LAYER 2 — the carved WALL. An inset ring exactly at the bezel line: a crisp
   dark contact where the wall meets the floor + a soft wall falloff, so the eye
   sees material was milled out down to the recessed floor. All achromatic. The
   feathered mask kills the aliased inner circle. */
.ev-glass-avatar::before,
.ev-glass-lamp::before {
    content: '';
    position: absolute;
    inset: var(--rr-bezel);
    border-radius: 50%;
    pointer-events: none;
    z-index: 3;
    box-shadow:
        var(--ev-glass-contact),      /* crisp dark contact at the aperture wall */
        var(--ev-glass-contact-2),    /* the wall falls off softly inward */
        inset 0 0 0 1px rgba(20, 20, 20, 0.10),  /* the milled arris, symmetric */
        inset 0 0 6px   rgba(20, 20, 20, 0.22);  /* depth down to the floor */
    -webkit-mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 0.8px), transparent 100%);
            mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 0.8px), transparent 100%);
}

/* the avatar content — a photo or a coloured monogram disc — sits on the FLOOR,
   inset by the bezel width, feathered so its edge is anti-aliased. Its colour is
   its own (the content exemption). */
.ev-glass-avatar__img,
.ev-glass-avatar__initials {
    position: absolute;
    inset: var(--rr-bezel);
    border-radius: 50%;
    z-index: 1;
    -webkit-mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 1px), transparent 100%);
            mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 1px), transparent 100%);
}
.ev-glass-avatar__img {
    width: calc(100% - 2 * var(--rr-bezel));
    height: calc(100% - 2 * var(--rr-bezel));
    object-fit: cover;
    display: block;
}
.ev-glass-avatar__initials {
    display: grid;
    place-items: center;
    /* content colour — a neutral slate DEFAULT so an un-themed monogram still
       reads; consumers override --gav-tile per user. Deliberately NOT
       achromatic: this is CONTENT behind the lens, and glass's own rule is
       "colour only from content" — L4 governs the panel, not what sits under
       the glass. Mirrors .ev-identity__tile. Do not "fix" in an L4 sweep. */
    background: var(--gav-tile, #5b6673);
    color: var(--gav-tile-ink, #f4f6f8);
    font: 600 calc(var(--rr-size) * 0.32)/1 var(--ev-font-sans);
    letter-spacing: 0.01em;
    text-transform: uppercase;
    user-select: none;
}

/* ==========================================================================
   PIECE 3 — the LAMP as a proper glass LENS (.ev-glass-lamp).

   Same carved-aperture stack as the avatar; the FLOOR is a lit LED behind glass,
   not a spherical marble. Dark housing ground so the glow blooms; a FLAT-ish
   single emission (no central second highlight -> no 3D-ball read). Hue set per
   lamp via --lamp-c (content colour), drawn from the semantic palette.
   ========================================================================== */
.ev-glass-avatar { --rr-size: var(--gav-size, 72px); }
.ev-glass-lamp {
    --rr-size: var(--lamp-size, 40px);
    --lamp-c: var(--ev-accent);
}
/* the lamp housing FLOOR — the dark recess the LED sits in. Inset by the bezel
   width so the metal ring shows, feathered so the edge is anti-aliased. Dark in
   both themes: the glow needs a dark ground to bloom on (content-side material,
   like the instrument screen). */
.ev-glass-lamp__core {
    position: absolute;
    inset: var(--rr-bezel);
    border-radius: 50%;
    z-index: 1;
    /* a FLAT lit disc: a bloom that peaks a touch above centre and falls to a
       dark housing ground at the rim. NO white centre spike -> reads as a lit
       LED under glass, not a glossy sphere.

       FIX A (cortex-iw9ii7e) — the dark housing ring is a GRADUAL fade, not a
       hard #0c0e11 slam at 100%. The old profile jumped from lit hue to
       near-black across the last ~14% of radius, giving the glass a hard dark
       ring to refract into dashed white arcs at the rim. Now the darkening
       starts earlier and eases into a housing ground that is itself only
       moderately dark, so the displacement filter has no sharp edge to smear.
       The lamp core is inset by the bezel, so this darker ground still hides
       under the metal ring — the visible lit area is unchanged.

       LIT-GATED CENTRE (cortex-m24c054) — the first two stops mix WHITE into the
       hue by `calc(var(--lamp-lit) * N%)`. At --lamp-lit: 0 that resolves to a
       0% white mix, i.e. plain `var(--lamp-c)` — byte-for-byte the OFF profile
       FIX A settled, with no white spike and no glossy-ball read. At
       --lamp-lit: 1 the emitter core goes hot, which is what a driven LED does
       and what "ON" has to look like. The gate is the whole point: do NOT
       hoist the white into the unconditional profile. */
    background:
        radial-gradient(circle at 50% 50%,
            color-mix(in srgb, #fff calc(var(--lamp-lit) * 32%), var(--lamp-c)) 0%,
            color-mix(in srgb, #fff calc(var(--lamp-lit) * 13%), var(--lamp-c)) 32%,
            var(--lamp-c) 58%,
            color-mix(in srgb, var(--lamp-c) 88%, #000) 72%,
            color-mix(in srgb, var(--lamp-c) 66%, #000) 82%,
            color-mix(in srgb, var(--lamp-c) 42%, #000) 90%,
            color-mix(in srgb, var(--lamp-c) 30%, #000) 96%,
            color-mix(in srgb, var(--lamp-c) 24%, #000) 100%);
    /* Feather the outer edge over ~2.5px (was a hard 1px slam) so the dark
       housing ground eases into transparency instead of presenting a crisp
       luminance ring. A sharp ring is exactly what the displacement filter
       smears into a bright arc on the refracting (right) side; a soft boundary
       gives it nothing to catch, so the lamp keeps a clean rim all the way
       around, both themes. */
    -webkit-mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 2.5px), transparent 100%);
            mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 2.5px), transparent 100%);
    transition: opacity 420ms ease;
}

/* ==========================================================================
   LAYER 4 — the glass LENS (shared).  MODERN GLASS: real edge refraction.

   The .ev-glass part is round, inset by the bezel so it seats just below the
   bezel lip, and it stacks ABOVE the content (floor / photo / lit core) so the
   content sits IN the lens's backdrop. Two mechanisms build the glass:

     (A) REAL EDGE REFRACTION (Chromium, ENHANCEMENT) — an SVG
         `feDisplacementMap` driven by a BEZEL-PROFILE radial displacement field
         (generated per lens size by canvas, injected by the OPTIONAL
         dist/evident-glass-refract.js as the filter's <feImage>). Displacement is
         ~ZERO across the flat centre and rises to a strong RADIAL push at the RIM
         (falling back to 0 AT the very rim so nothing clips), so the lens edge
         BENDS the content behind it (a real glass lip) while the centre stays
         clear. Applied as
         `backdrop-filter: url(#ev-glass-refract-<size>) blur() saturate()`.
         Achromatic: a geometric pixel shift, no channel split, no tint.
     (B) CRISP SPECULAR RIM — a hairline achromatic gradient border (via
         border-image, background-clip padding/border-box) giving one clean bright
         lip, plus a single soft axial glint. No box-shadow "rim".

   FALLBACK (BASE — non-Chromium / @supports not / evident-glass-refract.js not
   loaded): the pre-refraction box-shadow rim + axial glint below is the base
   layer, so every engine still renders a lens. When the JS is absent, the SVG
   <filter> does not exist; a `backdrop-filter: url(#missing)` is simply ignored
   and the base rim shows — clean degradation.
   ========================================================================== */
.ev-glass-avatar > .ev-glass,
.ev-glass-lamp > .ev-glass {
    inset: var(--rr-bezel);
    border-radius: 50%;
    z-index: 2;
    /* FALLBACK base: a refractive rim (bright, just inside where glass meets
       wall) + the glass under-scrim so content reads as BELOW a surface. This is
       what shows on engines without SVG-backdrop-filter. Achromatic. */
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.30),  /* bright refractive rim */
        inset 0 0 5px   rgba(255, 255, 255, 0.12),  /* rim bleeds inward */
        inset 0 0 0 2px rgba(20, 20, 20, 0.08),     /* thin contact under the lip */
        inset 0 0 7px   rgba(20, 20, 20, 0.10);     /* symmetric edge shade */
    background: var(--ev-glass-underscrim);
    -webkit-mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 1px), transparent 100%);
            mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 1px), transparent 100%);
}
/* the single soft AXIAL glint — a symmetric white ellipse near the top,
   horizontally centred. A glint on a flat pane catching the axial light, NOT a
   directional light and NOT a dome spike. Kept in BOTH modes. */
.ev-glass-avatar > .ev-glass::before,
.ev-glass-lamp > .ev-glass::before {
    background:
        radial-gradient(52% 34% at 50% 16%,
            var(--ev-glass-glint) 0%,
            var(--ev-glass-glint-soft) 44%,
            transparent 74%);
}
/* just the faint depth scrim (no dome sheen) — content dims a hair toward the
   bottom, achromatic. */
.ev-glass-avatar > .ev-glass::after,
.ev-glass-lamp > .ev-glass::after {
    background:
        linear-gradient(180deg,
            transparent 0%,
            transparent 62%,
            var(--ev-glass-underscrim) 100%);
}

/* ---- MODERN GLASS: real SVG edge refraction (Chromium-only ENHANCEMENT) ----
   Where SVG filters are accepted as backdrop-filter AND the filter defs have
   been injected (by evident-glass-refract.js), we DROP the heavy box-shadow rim
   (the displacement field IS the refraction now) and instead:
     - refract the backdrop through the per-size bezel-profile filter,
     - lens the content with a small blur + gentle saturate,
     - draw ONE crisp achromatic gradient-border specular lip.
   The @supports probe keys on url(#ev-glass-refract-96): if the JS never runs,
   Chromium still reports the property valid (the id is resolved at paint), so
   the branch is taken but the missing filter is a no-op and the padding-box
   under-scrim + the gradient-border rim keep the lens looking right. */
@supports (backdrop-filter: url(#ev-glass-refract-96)) {
    .ev-glass-avatar > .ev-glass,
    .ev-glass-lamp > .ev-glass {
        /* the displacement filter is applied per-size via the --refract var set
           on each host below; blur() lenses, saturate() lifts content colour a
           hair (achromatic op on the content, not a tint on the glass). */
        -webkit-backdrop-filter: var(--refract) blur(0.6px) saturate(1.08);
                backdrop-filter: var(--refract) blur(0.6px) saturate(1.08);
        /* the crisp specular RIM — a hairline achromatic gradient border. The
           padding-box fill carries the faint under-scrim; the border-box paints
           the bright top-lip + a dim lower contact, one meaning (a lit lip). */
        box-shadow: none;
        border: 1px solid transparent;
        background:
            radial-gradient(circle at 50% 50%,
                var(--ev-glass-underscrim), var(--ev-glass-underscrim)) padding-box,
            linear-gradient(180deg,
                rgba(255, 255, 255, 0.62) 0%,
                rgba(255, 255, 255, 0.14) 22%,
                rgba(255, 255, 255, 0.02) 50%,
                rgba(20, 20, 20, 0.12) 88%,
                rgba(20, 20, 20, 0.20) 100%) border-box;
        /* the round border needs the round clip; mask both box and border. */
        -webkit-mask:
            radial-gradient(circle at 50% 50%, #000 calc(100% - 0.5px), transparent 100%);
                mask:
            radial-gradient(circle at 50% 50%, #000 calc(100% - 0.5px), transparent 100%);
    }
    /* frosted: more blur for the ambient/diffused read */
    .ev-glass-avatar > .ev-glass.ev-glass--frosted,
    .ev-glass-lamp > .ev-glass.ev-glass--frosted {
        -webkit-backdrop-filter: var(--refract) blur(3px) saturate(1.04);
                backdrop-filter: var(--refract) blur(3px) saturate(1.04);
    }
    /* per outer-diameter refraction filter (dims must match the lens box). */
    .ev-glass-avatar[style*="--gav-size:40px"] > .ev-glass,
    .ev-glass-lamp[style*="--lamp-size:40px"] > .ev-glass,
    .ev-glass-lamp:not([style*="--lamp-size"]) > .ev-glass { --refract: url(#ev-glass-refract-40); }
    .ev-glass-avatar[style*="--gav-size:56px"] > .ev-glass { --refract: url(#ev-glass-refract-56); }
    .ev-glass-lamp[style*="--lamp-size:64px"] > .ev-glass { --refract: url(#ev-glass-refract-64); }
    .ev-glass-avatar[style*="--gav-size:96px"] > .ev-glass { --refract: url(#ev-glass-refract-96); }
}

/* status hues for the lamps — CONTENT colours, drawn from the semantic palette
   (defined in badge.css, which concatenates before glass.css). */
.ev-glass-lamp--info    { --lamp-c: var(--ev-info); }
.ev-glass-lamp--success { --lamp-c: var(--ev-success); }
.ev-glass-lamp--warning { --lamp-c: var(--ev-warning); }
.ev-glass-lamp--danger  { --lamp-c: var(--ev-danger); }

/* ==========================================================================
   THE LIVE LANGUAGE — a shared "this is alive" vocabulary (cortex-lpxi69r /
   cortex-nhcsuj4 / cortex-lf0ji9b).

   ONE meaning, ONE motion, spelled the same everywhere:
     - a glass lamp turns ON (its lit content brightens behind the lens);
     - a glass avatar lights up on HOVER (the lens catches more light);
     - a live BADGE breathes (an achromatic glow rides its rim).
   All three share the SAME calm, achromatic breathing curve below
   (`ev-live-breathe`, ~2.6s ease-in-out): liveness is LIGHT rising and
   falling, never a new hue and never a strobe. The lit CONTENT keeps its hue
   (a lamp's status colour); the "aliveness" itself is achromatic — a lens
   brightening, so it reads identically on any colour and stays achromatic-safe.
   Motion is gated by the platform motion gate (src/components/motion.css) via
   the [data-ev-motion] override; with motion off, the ON state still reads lit
   (brighter), it simply does not breathe.
   ========================================================================== */

/* The shared breathing curve. Drives a 0..1 "live intensity" via opacity on a
   lit overlay; consumers place their own glow. Calm: a long ease-in-out, never
   fully dark at the trough (an LED gently breathing, still clearly ON). */
@keyframes ev-live-breathe {
    0%, 100% { opacity: 0.42; }
    50%      { opacity: 1; }
}
/* Optional faster/attention variant — still a breathe, not a strobe. */
@keyframes ev-live-blink {
    0%, 100% { opacity: 0.30; }
    50%      { opacity: 1; }
}

/* ---- LAMP: OFF vs ON (cortex-lpxi69r) -----------------------------------
   The bare lamp reads dim/inert (an unlit indicator). `--on` lights it: a lit
   halo of the content hue blooms behind the lens and the lit core brightens,
   so it reads as a real ON indicator. `--pulse` makes that ON glow breathe.

   OFF is the default: dim the lit core toward the dark housing ground so it
   reads clearly unlit (a status lamp that is currently off), and drop the glint
   so no false "lit" catch remains.

   THREE STATES, THREE READINGS (cortex-m24c054). The founder's review found the
   old two-state model collapsed two different facts into one picture: an OFF
   lamp and a DISABLED lamp both rendered as "a heavily dimmed coloured disc",
   which reads as *broken/inert* rather than *powered but not lit*. They are now
   split across the channels the language already owns:

     OFF (default, and `--off`)  the lamp is ENABLED and simply not lit. Its
                                 coloured lens plastic is still plainly there —
                                 a real unlit LED still shows its own colour —
                                 it just emits nothing. HUE present, LIGHT absent.
     `--disabled`                the lamp is not powered at all. FINISH carries
                                 it: the hue drains to an achromatic grey (dead
                                 plastic) and the oxide veil goes on. Finish is
                                 the LIVENESS channel, which is exactly the
                                 channel "not powered" belongs in.
     `--on` / `--pulse`          emitting. See the spill layer below.

   So OFF vs DISABLED differ in HUE + FINISH, not merely in how dim they are —
   one channel, one meaning, and neither state has to be learned. */
.ev-glass-lamp {
    /* the lit-halo layer sits under the glass; a lamp draws it only when ON */
    --lamp-lit: 0;
    /* the UNLIT core alpha — how visible the lens plastic is with no light
       behind it. The OFF default keeps the coloured lens clearly present
       (off-but-enabled); `--disabled` drops it toward the housing (inert). */
    --lamp-core-a: 0.58;
}
.ev-glass-lamp__core {
    /* interpolate from the unlit floor up to full brightness when lit. The disc
       is masked to the aperture floor, so this is the LED going dark, not the
       bezel. */
    opacity: calc(var(--lamp-core-a) + (1 - var(--lamp-core-a)) * var(--lamp-lit));
}
/* the ON lit-halo — a soft content-hue bloom rising off the lit core, drawn as
   a dedicated layer between core and glass so its brightness can breathe
   without touching the disc geometry. Achromatic-safe: it is the CONTENT's own
   hue blooming (a lit LED spilling light), exactly like the instrument glow
   (founder ruling A), NOT decoration on achromatic panel ink. */
.ev-glass-lamp__glow {
    position: absolute;
    inset: var(--rr-bezel);
    border-radius: 50%;
    z-index: 1;              /* same stratum as the core, under the glass (z:2) */
    pointer-events: none;
    opacity: 0;              /* OFF: no halo */
    background:
        radial-gradient(circle at 50% 46%,
            color-mix(in srgb, var(--lamp-c) 88%, #fff) 0%,
            var(--lamp-c) 30%,
            color-mix(in srgb, var(--lamp-c) 55%, transparent) 62%,
            transparent 82%);
    -webkit-mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 1px), transparent 100%);
            mask: radial-gradient(circle at 50% 50%, #000 calc(100% - 1px), transparent 100%);
    transition: opacity 420ms ease;
}
/* ---- THE SPILL — light that actually leaves the lamp (cortex-m24c054) -----

   The bug the founder named as "ON looks OFF" was structural, not a matter of
   turning a number up. Every lit layer above (`__core`, `__glow`) is
   `inset: var(--rr-bezel)` AND radially masked to the aperture floor, so 100% of
   the emission was trapped UNDER the lens. A lamp whose light stops dead at the
   glass is a coloured disc, not a light source: nothing in the picture says
   photons left the part, so nothing reads as emission.

   This layer is the light that escapes — a soft content-hue bloom over the
   bezel metal and onto the surrounding panel. It is drawn ON TOP (z:4, above
   bezel, wall and lens) because that is what it physically is: emitted light
   falling on material in front of it, not a surface finish underneath.

   Ruling A, extended. Founder ruling A already sanctions LED glow as emission
   from LIT CONTENT behind glass (the `.ev-readout-cluster--lit` value's
   text-shadow); this
   is the same carve-out on the same content layer — the lamp's own lit core
   spilling its own hue. L4's no-glow rule still fully binds ACHROMATIC PANEL
   surfaces: this bloom is `--lamp-c` (content colour), never a neutral, and it
   exists only where lit content is behind it. A neutral glow on panel ink stays
   forbidden.

   L1 holds: the gradient is `circle at 50% 50%` on a symmetrically-inset
   pseudo-element — zero x/y bias, no box-shadow offsets added anywhere. */
.ev-glass-lamp::after {
    content: '';
    position: absolute;
    /* reach well past the bezel so the light lands on the panel around the
       lamp — the spill IS the emission cue */
    inset: calc(var(--rr-size) * -0.38);
    border-radius: 50%;
    pointer-events: none;
    z-index: 4;
    /* alpha rides --lamp-lit: an OFF or DISABLED lamp spills exactly nothing,
       structurally, whatever the opacity channel is doing. */
    background:
        radial-gradient(circle at 50% 50%,
            color-mix(in srgb, var(--lamp-c) calc(var(--lamp-lit) * 42%), transparent) 0%,
            color-mix(in srgb, var(--lamp-c) calc(var(--lamp-lit) * 34%), transparent) 22%,
            color-mix(in srgb, var(--lamp-c) calc(var(--lamp-lit) * 18%), transparent) 42%,
            color-mix(in srgb, var(--lamp-c) calc(var(--lamp-lit) *  6%), transparent) 60%,
            transparent 80%);
    opacity: 0;              /* OFF: nothing emitted */
    transition: opacity 420ms ease;
}

.ev-glass-lamp--on { --lamp-lit: 1; }
.ev-glass-lamp--on .ev-glass-lamp__glow { opacity: 1; }
.ev-glass-lamp--on::after { opacity: 1; }
/* the lit disc also brightens at the centre — a white-mixed core stop GATED on
   --lamp-lit (see __core's gradient), so the OFF profile keeps no white spike
   and the glossy-ball read FIX A removed does not come back. */

/* OFF — explicit spelling of the default. Off-but-ENABLED: the coloured lens is
   still visible (--lamp-core-a stays at the 0.58 default), there is simply no
   light. Distinct from --disabled below, which drains the hue instead. */
.ev-glass-lamp--off { --lamp-lit: 0; }
.ev-glass-lamp--off .ev-glass-lamp__glow { opacity: 0; }
.ev-glass-lamp--off::after { opacity: 0; }

/* ---- LAMP: soothing pulse / breathing (cortex-lpxi69r) -------------------
   `--pulse` breathes the ON halo (calm, ~2.6s). `--blink` is the faster
   attention variant. Both imply ON. The breathe/blink animations are declared
   unconditionally; the platform motion gate (src/components/motion.css)
   disables them for reduced-motion users (unless `data-ev-motion="on"` forces
   them on), leaving the steady ON glow. --pulse & --blink always read ON
   (steady) even with motion off. */
.ev-glass-lamp--pulse,
.ev-glass-lamp--blink { --lamp-lit: 1; }
.ev-glass-lamp--pulse .ev-glass-lamp__glow,
.ev-glass-lamp--blink .ev-glass-lamp__glow { opacity: 1; }
.ev-glass-lamp--pulse::after,
.ev-glass-lamp--blink::after { opacity: 1; }

/* WHY PULSE WAS INVISIBLE (cortex-m24c054) — measured, not guessed.
   Probed on the live DOM with the gallery motion switch ON:
   `getComputedStyle(glow).animationName` = "ev-live-breathe",
   `glow.getAnimations()` = [["ev-live-breathe", "running", 2600]].
   The animation was RUNNING the whole time. The motion gate was NOT the cause
   (`data-ev-motion="on"`, OS prefers-reduced-motion = false).

   It was invisible because it had nowhere to be seen. `__glow` sat directly on
   top of a `__core` already at full `--lamp-c` saturation, and BOTH were masked
   to the aperture floor — so breathing the halo 0.42 -> 1 composited hue over
   near-identical hue inside the same small disc. Screenshotting the lamp pinned
   at the trough (currentTime 0) and at the peak (currentTime 1300) and diffing
   the pixels measured a MAX CHANNEL DELTA OF 11/255 over the whole lamp region
   (mean 0.19/255). Technically animating; perceptually a still image. Founder's
   "no visible effect" was an accurate report of a running animation.

   The fix is dynamic range, not a bigger number: breathe the SPILL — which
   rides over ACHROMATIC bezel metal and panel, where the same 0.42 -> 1 swing
   is a large, obvious luminance change — from the SAME shared curve, in lockstep
   with the under-lens halo. One meaning, one motion, still spelled once. */
.ev-glass-lamp--pulse .ev-glass-lamp__glow,
.ev-glass-lamp--pulse::after {
    animation: ev-live-breathe 2.6s ease-in-out infinite;
}
.ev-glass-lamp--blink .ev-glass-lamp__glow,
.ev-glass-lamp--blink::after {
    animation: ev-live-blink 1.1s ease-in-out infinite;
}

/* ---- LAMP: DISABLED — not powered (cortex-m24c054) -----------------------
   The reading the OLD bare/off state accidentally had, now given its own name
   and its own channel. Two things change, and neither is "more dim":

     HUE drains.    --lamp-c becomes an achromatic grey mixed from the panel's
                    own material tokens, so it is R=G=B in BOTH themes and
                    theme-flips for free (a mid grey on light metal, a mid grey
                    on dark metal). Dead plastic has no colour to show.
     FINISH goes.   The oxide veil — the same saturate/brightness idiom
                    `.ev-switch--disabled` uses — plus a low core alpha. Finish
                    is the LIVENESS channel; "not powered" is a liveness fact.

   Declared AFTER the on/pulse/blink rules at equal specificity, so --disabled
   wins over a stale --on/--pulse left on the element: a lamp that is disabled
   is inert regardless of what state it was holding. It emits nothing — no halo,
   no spill, no motion.

   `cursor: not-allowed` is deliberately NOT set here: a status lamp is a
   readout, not a control. Interactive consumers set it themselves. */
.ev-glass-lamp--disabled {
    --lamp-lit: 0;
    --lamp-core-a: 0.30;
    /* achromatic, from existing tokens — no new hex, R=G=B in both themes */
    --lamp-c: color-mix(in srgb, var(--ev-metal) 62%, var(--ev-ink-dim));
}
/* the oxide veil goes on the CONTENT (the core), never on .ev-glass-lamp
   itself: a `filter` on the lamp element would establish a new backdrop root
   and change what the lens's `backdrop-filter` refraction samples. Same
   saturate/brightness idiom as .ev-switch--disabled, applied where it is inert. */
.ev-glass-lamp--disabled .ev-glass-lamp__core {
    filter: saturate(0.85) brightness(0.94);
}
.ev-glass-lamp--disabled .ev-glass-lamp__glow {
    opacity: 0;
    animation: none;
}
.ev-glass-lamp--disabled::after {
    opacity: 0;
    animation: none;
}

/* ---- AVATAR: hover light-up (cortex-nhcsuj4) -----------------------------
   A clickable/interactive glass avatar's LENS lights up on hover: the glass
   catches more light (a brighter glint + a soft achromatic sheen) and the
   content lifts a hair. ACHROMATIC — the glass brightens; the content colour
   is unchanged (no hue added). Motion-gated transition. The avatar opts in with
   `--interactive` (so static identity avatars do not react); it also lights on
   keyboard focus for parity. */
.ev-glass-avatar--interactive { cursor: pointer; }
.ev-glass-avatar--interactive > .ev-glass {
    transition:
        box-shadow 420ms ease,
        background 420ms ease;
}
.ev-glass-avatar--interactive > .ev-glass::before {
    transition: opacity 420ms ease,
                transform 420ms ease;
}
/* the hover sheen — a dedicated achromatic bloom layer over the lens, off by
   default, easing up on hover/focus. White alpha only: this is LIGHT catching
   the glass, never a tint on the content. */
.ev-glass-avatar--interactive > .ev-glass::after {
    /* keep the existing depth scrim AND add a controllable sheen on top; the
       sheen alpha rides --gav-sheen (0 at rest). */
    background:
        radial-gradient(60% 42% at 50% 30%,
            rgba(255, 255, 255, calc(0.22 * var(--gav-sheen, 0))) 0%,
            rgba(255, 255, 255, calc(0.06 * var(--gav-sheen, 0))) 46%,
            transparent 72%),
        linear-gradient(180deg,
            transparent 0%,
            transparent 62%,
            var(--ev-glass-underscrim) 100%);
    transition: background 420ms ease;
}
/* The lens lights up on hover/focus unconditionally — this is a state, not
   motion, so it holds even for reduced-motion users. The platform motion gate
   (src/components/motion.css) strips the eased TRANSITION when motion is off
   (unless `data-ev-motion="on"` forces it), so the sheen snaps rather than
   fades. */
.ev-glass-avatar--interactive:hover,
.ev-glass-avatar--interactive:focus-visible { --gav-sheen: 1; }
/* on hover the lens catches a brighter refractive rim + a stronger glint —
   achromatic (white alpha), the "more light" read. Works in both the fallback
   (box-shadow rim) and the modern (gradient-border) branch: we lift the glint
   and add a soft outer/inner white sheen via the ::after above + a rim bump. */
.ev-glass-avatar--interactive:hover > .ev-glass,
.ev-glass-avatar--interactive:focus-visible > .ev-glass {
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.48),
        inset 0 0 7px   rgba(255, 255, 255, 0.20),
        inset 0 0 0 2px rgba(20, 20, 20, 0.06),
        inset 0 0 7px   rgba(20, 20, 20, 0.08);
}
.ev-glass-avatar--interactive:hover > .ev-glass::before,
.ev-glass-avatar--interactive:focus-visible > .ev-glass::before {
    opacity: 1.35;   /* brighter axial catch (clamped by the gradient) */
}

/* ===== src/components/motion.css ===== */
/* ==========================================================================
   MOTION GATE — the library-level reduced-motion override (cortex-6zoor4d)
   ==========================================================================

   Evident's animated affordances (the glass lamp breathe, the badge/lamp
   breathe, the segmented seat slide, the interactive-avatar / entity-token
   hover, and every eased press/hover transition) are declared UNCONDITIONALLY
   in their component files — NOT behind `@media (prefers-reduced-motion:
   no-preference)`. This one file is the single place that decides whether that
   motion actually runs, so the decision can be overridden per-page.

   The override is a `data-ev-motion` attribute on the root <html>. It accepts
   FOUR values, which are TWO synonym pairs plus the unset default:

       (unset)                — respect the OS. This is the default and matches
                                the historic behaviour: motion runs unless the
                                OS asks for reduced motion.
       "on" / "no-preference" — FORCE motion on, even on a reduced-motion OS (a
                                preview mode for designers / the gallery motion
                                switch).
       "off" / "reduce"       — FORCE motion off, regardless of the OS.

   WHY the aliases exist: "no-preference" and "reduce" are the two values of the
   `prefers-reduced-motion` media feature itself. A consumer that already HOLDS
   a motion preference — read off `matchMedia`, stored on an account, handed
   down by an OS bridge — can pipe that value straight into the attribute with
   no translation table in between. "on"/"off" is the SWITCH vocabulary, the
   spelling a two-state control writes; "no-preference"/"reduce" is the MEDIA
   QUERY vocabulary, the spelling the platform already gave the caller. Two
   meanings, each spelled the way its caller already spells it.

   Any OTHER value (a typo, a future spelling) matches neither pair and falls
   through to the unset behaviour — respect the OS. That is the safe direction
   to fail: an unrecognised attribute never traps a reduced-motion user in
   motion, it just stops overriding them.

   Truth table (motion RUNS when):
       data-ev-motion = "on"  or "no-preference"    -> always
       data-ev-motion = "off" or "reduce"           -> never
       (unset) + OS prefers-reduced-motion: reduce  -> no
       (unset) + OS no-preference                   -> yes

   So motion is DISABLED exactly when:
       (OS = reduce  AND  not forced-on)   OR   forced-off

   Both disabling conditions strip `animation` and `transition` from everything
   under the root. Killing them at the root (rather than re-listing every
   animated selector) keeps this gate in one place and means new animated
   components inherit the contract for free — the fix-by-removal alternative to
   sprinkling a guard into each component. State that is carried by a class or a
   custom property (a lit lamp, a hover sheen, the selected seat) is untouched:
   only the movement is removed, so every affordance still READS correctly
   without motion — it simply snaps instead of easing.
   -------------------------------------------------------------------------- */

/* forced-off: never move, whatever the OS says. Both spellings of forced-off
   are matched with `:is()`, which takes the specificity of its most specific
   argument — both arms are plain attribute selectors, so accepting the synonym
   costs exactly nothing over the single-value form this replaces. */
:root:is([data-ev-motion="off"], [data-ev-motion="reduce"]) *,
:root:is([data-ev-motion="off"], [data-ev-motion="reduce"]) *::before,
:root:is([data-ev-motion="off"], [data-ev-motion="reduce"]) *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
}

/* respect-the-OS (unset) on a reduced-motion OS: same kill, but ONLY when not
   forced on. The chained `:not()`s are what let a forced-on override win over
   the OS preference — and BOTH spellings of forced-on have to be excused here,
   or "no-preference" would silently lose to the OS on exactly the machines the
   override exists to preview. Any other attribute value matches neither
   exclusion, so it lands in this block and respects the OS, as documented. */
@media (prefers-reduced-motion: reduce) {
    :root:not([data-ev-motion="on"]):not([data-ev-motion="no-preference"]) *,
    :root:not([data-ev-motion="on"]):not([data-ev-motion="no-preference"]) *::before,
    :root:not([data-ev-motion="on"]):not([data-ev-motion="no-preference"]) *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}
