/* Exis kit v4. Colour arrives through currentColor; the signal dot through .node.
   Iris (#8a84ff) is reserved for the mark and never appears in kit assets. */

.ex-kit { --ex-page: #050505; --ex-ink: #f2f2f0; --ex-signal: #3fd9a4; color: var(--ex-ink); background: var(--ex-page); }
.ex-kit.ex-ledger, .ex-ledger .ex-kit, .ex-ledger { --ex-page: #ece9e1; --ex-ink: #2b2740; --ex-signal: #1d8f69; }
.ex-kit .node { fill: var(--ex-signal); }
.ex-kit .ex-ring { stroke: var(--ex-signal); }

/* Icons: inline SVG or <svg><use href="icons/exis-kit-icons.svg#ex-root-tip"/></svg> */
.ex-icon { width: 24px; height: 24px; flex: none; display: inline-block; vertical-align: middle; }
.ex-icon--16 { width: 16px; height: 16px; }
.ex-icon--48 { width: 48px; height: 48px; }

/* Dividers: full width, fixed 24 px tall. Keep 48 px of space above and below. */
.ex-divider { display: block; width: 100%; height: 24px; margin: 48px 0; color: var(--ex-ink); opacity: .5; }

/* List markers as CSS masks (monochrome). For the mint station dot, inline the SVG instead. */
.ex-list { list-style: none; padding: 0; }
.ex-list > li { position: relative; padding-left: 28px; }
.ex-list > li::before { content: ""; position: absolute; left: 0; top: .35em; width: 12px; height: 12px; background: currentColor; opacity: .6;
  -webkit-mask: var(--ex-marker, url(elements/marker-root-tip.svg)) center / contain no-repeat; mask: var(--ex-marker, url(elements/marker-root-tip.svg)) center / contain no-repeat; }
.ex-list--station { --ex-marker: url(elements/marker-station-node.svg); }
.ex-list--tally { --ex-marker: url(elements/marker-tally-notch.svg); }
.ex-list--root { --ex-marker: url(elements/marker-root-tip.svg); }

/* Corner ticks on any framed panel */
.ex-corners { position: relative; }
.ex-corners::before { content: ""; position: absolute; inset: -8px; pointer-events: none; background: currentColor; opacity: .45;
  -webkit-mask: url(elements/mask/corner-tl.svg) top left no-repeat, url(elements/mask/corner-tr.svg) top right no-repeat, url(elements/mask/corner-br.svg) bottom right no-repeat, url(elements/mask/corner-bl.svg) bottom left no-repeat;
  mask: url(elements/mask/corner-tl.svg) top left no-repeat, url(elements/mask/corner-tr.svg) top right no-repeat, url(elements/mask/corner-br.svg) bottom right no-repeat, url(elements/mask/corner-bl.svg) bottom left no-repeat; }

/* Numeral frames: frame SVG behind, numeral set in Plex Mono on top */
.ex-numeral { position: relative; display: inline-grid; place-items: center; width: 48px; height: 56px; font: 600 18px/1 "IBM Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.ex-numeral > svg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: .55; }
.ex-numeral > span { position: relative; transform: translateY(-6px); }

/* Graphics: a stack of same-viewBox layers. 2 or 3 layers per section, never behind body text. */
.ex-stack { position: relative; width: 100%; aspect-ratio: 1200 / 720; overflow: hidden; color: var(--ex-ink); isolation: isolate; }
.ex-stack > svg, .ex-stack > .ex-layer { position: absolute; inset: 0; width: 100%; height: 100%; }
.ex-stack > .ex-tex { top: 23.34%; } /* headroom: y 0 to 168 of 720 stays clear for the heading */
.ex-stack--band { aspect-ratio: auto; height: clamp(240px, 42vh, 480px); }

/* Textures: tiles are masks; colour from currentColor, strength from --ex-tex-o.
   Documented ranges are in README.md. Never place a texture behind body text. */
.ex-tex { position: absolute; inset: 0; pointer-events: none; background: currentColor; opacity: var(--ex-tex-o, .08);
  -webkit-mask: var(--ex-tex) repeat; mask: var(--ex-tex) repeat; }
.ex-tex--paper { --ex-tex: url(textures/paper-ruling-24.svg); --ex-tex-o: .08; }
.ex-tex--hatch-o { --ex-tex: url(textures/hatch-o-16.svg); --ex-tex-o: .1; }
.ex-tex--hatch-a { --ex-tex: url(textures/hatch-a-8.svg); --ex-tex-o: .08; }
.ex-tex--hatch-b { --ex-tex: url(textures/hatch-b-10.svg); --ex-tex-o: .07; }
.ex-tex--hatch-c { --ex-tex: url(textures/hatch-c-14.svg); --ex-tex-o: .14; }
.ex-tex--hairs { --ex-tex: url(textures/root-hair-stipple-96.svg); --ex-tex-o: .12; }
.ex-tex--grid { --ex-tex: url(textures/survey-grid-64.svg); --ex-tex-o: .07; }

/* Motion hooks: .ex-live (living) and .ex-rule (measured) classes are on every path.
   Living lines may draw in once (set pathLength="1" on them in JS, then animate stroke-dashoffset 1 to 0).
   Measured lines never move. Respect prefers-reduced-motion. */

/* ===================================================================== v4.1: Ledger of the Field
   Rules, entries, numeral column, folio rail, Perspective ledger, form fields, plates, figure textures.
   Muted text uses --ex-mute (#a3a3a0, about 8:1 on #050505); never dimmer than --n-50 for small text. */
.ex-kit { --ex-mute: #a3a3a0; --ex-line: color-mix(in srgb, currentColor 22%, transparent); --ex-line-2: color-mix(in srgb, currentColor 12%, transparent); }
.ex-ledger { --ex-mute: #5d5970; }

/* Ledger rules as CSS (no SVG request). Single, double (accountant's total), ruled off, margin, column. */
.ex-lrule { display: block; height: 1px; border: 0; margin: 0; background: var(--ex-line); }
.ex-lrule--double { height: 6px; background: linear-gradient(var(--ex-line), var(--ex-line)) top / 100% 1px no-repeat, linear-gradient(var(--ex-line-2), var(--ex-line-2)) bottom / 100% 1px no-repeat; }
.ex-lrule--total { height: 20px; background: linear-gradient(var(--ex-line-2), var(--ex-line-2)) top / 100% 1px no-repeat, linear-gradient(var(--ex-line), var(--ex-line)) 0 14px / 100% 1px no-repeat, linear-gradient(var(--ex-line-2), var(--ex-line-2)) bottom / 100% 1px no-repeat; }
.ex-margin-rule { width: 6px; align-self: stretch; background: linear-gradient(var(--ex-line-2), var(--ex-line-2)) left / 1px 100% no-repeat, linear-gradient(var(--ex-line), var(--ex-line)) right / 1px 100% no-repeat; }
.ex-colrule { border-left: 1px solid var(--ex-line); }

/* Entry: margin symbol, the ruled line, and the posted marker. The root tip arrives at the left end (engine or ledger-curl.svg). */
.ex-entry { display: grid; grid-template-columns: 36px minmax(0, 1fr) 12px; align-items: end; column-gap: 12px; }
.ex-entry > .ex-sym { width: 36px; height: 36px; opacity: .8; }
.ex-entry > .ex-entry__line { align-self: end; height: 1px; background: var(--ex-line); margin-bottom: 5px; }
.ex-entry > .ex-entry__mark { width: 12px; height: 12px; }
.ex-sym { width: 32px; height: 32px; flex: none; display: inline-block; }
.ex-sym--tag { width: 120px; height: 32px; }

/* Numeral column: Plex Mono, tabular, right aligned, behind a column rule. Folio style: f.01 */
.ex-numcol { font: 400 13px/24px "IBM Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; text-align: right; color: var(--ex-mute); padding: 0 10px 0 12px; border-left: 1px solid var(--ex-line); white-space: nowrap; }
.ex-numcol--lead { color: var(--ex-ink); font-weight: 600; }
.ex-folio { font: 400 11px/1 "IBM Plex Mono", ui-monospace, monospace; letter-spacing: .08em; color: var(--ex-mute); font-variant-numeric: tabular-nums; }
.ex-tally { display: inline-block; width: 20px; height: 12px; vertical-align: -1px; }

/* Section rail (folio rail): <ol class="ex-rail"><li class="is-read">...</li><li aria-current="true">...</li><li>...</li></ol> */
.ex-rail { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.ex-rail > li { display: flex; align-items: center; gap: 8px; white-space: nowrap; font: 400 11px/1 "IBM Plex Mono", ui-monospace, monospace; letter-spacing: .06em; color: var(--ex-mute); }
.ex-rail > li::before { content: ""; width: 24px; height: 12px; flex: none; background: currentColor; opacity: .6; -webkit-mask: var(--ex-tick, url(elements/rail/rail-tick.svg)) center / contain no-repeat; mask: var(--ex-tick, url(elements/rail/rail-tick.svg)) center / contain no-repeat; }
.ex-rail > li.is-read { --ex-tick: url(elements/rail/rail-tick-read.svg); }
.ex-rail > li[aria-current="true"] { --ex-tick: url(elements/rail/rail-tick-current.svg); color: var(--ex-ink); }
.ex-rail > li[aria-current="true"]::before { opacity: 1; }
.ex-rail a { color: inherit; text-decoration: none; }

/* Perspective claim ledger: three ruled lines, marker at the left, text on the line. */
.ex-claims { list-style: none; margin: 0; padding: 0; }
.ex-claims > li { display: grid; grid-template-columns: 24px minmax(0, 1fr); column-gap: 12px; align-items: end; padding: 10px 0 8px; border-bottom: 1px solid var(--ex-line); }
.ex-claims > li > svg { width: 24px; height: 24px; }
.ex-claims b { display: block; font: 600 11px/1.3 "IBM Plex Mono", ui-monospace, monospace; letter-spacing: .08em; text-transform: uppercase; color: var(--ex-mute); margin-bottom: 4px; }

/* Form field: a ledger line, not a box. States: focus, filled, invalid (misclosure, no red), disabled, posted. */
.ex-field { display: grid; gap: 6px; margin: 0 0 24px; }
.ex-field > label { font: 500 11px/1.3 "IBM Plex Mono", ui-monospace, monospace; letter-spacing: .08em; text-transform: uppercase; color: var(--ex-mute); }
.ex-field > input, .ex-field > textarea { font: 400 16px/1.5 "IBM Plex Sans", system-ui, sans-serif; color: var(--ex-ink); background: transparent; border: 0; border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent); border-radius: 0; padding: 8px 0 7px; outline: none; }
.ex-field > textarea { resize: vertical; min-height: 72px; background: linear-gradient(transparent 31px, var(--ex-line-2) 31px) 0 7px / 100% 32px; line-height: 32px; padding-top: 0; }
.ex-field > input::placeholder, .ex-field > textarea::placeholder { color: var(--ex-mute); opacity: 1; }
.ex-field > input:focus-visible, .ex-field > textarea:focus-visible { border-bottom: 2px solid var(--ex-ink); padding-bottom: 6px; }
.ex-field:focus-within > label { color: var(--ex-ink); }
.ex-field.is-invalid > input, .ex-field.is-invalid > textarea { border-bottom: 3px double var(--ex-ink); padding-bottom: 5px; }
.ex-field__msg { display: flex; gap: 8px; align-items: center; font: 400 13px/1.4 "IBM Plex Sans", system-ui, sans-serif; color: var(--ex-ink); }
.ex-field__msg > svg { width: 16px; height: 16px; flex: none; }
.ex-field > input:disabled { color: var(--ex-mute); border-bottom-style: dotted; }
.ex-form-posted { display: grid; grid-template-columns: 12px minmax(0, 1fr); gap: 12px; align-items: start; padding: 16px 0 22px; position: relative; }
.ex-form-posted::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 6px; background: linear-gradient(var(--ex-line), var(--ex-line)) top / 100% 1px no-repeat, linear-gradient(var(--ex-line-2), var(--ex-line-2)) bottom / 100% 1px no-repeat; }
.ex-choice { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 10px; align-items: center; padding: 14px 16px; border: 1px solid var(--ex-line); cursor: pointer; }
.ex-choice:has(input:checked) { border-color: var(--ex-ink); }
.ex-choice:has(input:focus-visible) { outline: 2px solid var(--ex-ink); outline-offset: 3px; }
.ex-choice input { position: absolute; opacity: 0; pointer-events: none; }

/* Plates and figures: one per section, captioned in Plex Serif italic, never behind text. */
.ex-plate { margin: 0; display: grid; gap: 10px; color: var(--ex-ink); }
.ex-plate > svg { width: 100%; height: auto; display: block; }
.ex-plate > figcaption { font: italic 400 14px/1.45 "IBM Plex Serif", Georgia, serif; color: var(--ex-mute); }
.ex-plate--focus { max-width: 240px; }
@media (max-width: 600px) { .ex-plate--focus { max-width: 180px; } }

/* Figure textures (dark ground, figures only). */
.ex-tex--ledger { --ex-tex: url(textures/ledger-paper-96.svg); --ex-tex-o: .08; }
.ex-tex--soil { --ex-tex: url(textures/soil-hatch-12.svg); --ex-tex-o: .1; }
