/* mod design system — the single source. Hand-written, no build.
   Edit here, copy into each app's vendor dir (Forgejo, mod-books, Authelia, mod-trust).
   Themes switch on prefers-color-scheme or [data-theme]; palette switches on [data-palette]. */

:root {
  /* app signal colors — one per browsable app, named for the app it marks.
     mod-chrome.js reads these by name off each APPS entry, so a mark cannot be
     spelled one way in a template and another in a vendor patch. */
  --color-mod-accent: #4166d8;
  --color-mod-app-trust: #c69a63;
  --color-mod-app-books: #a96cca;
  --color-mod-app-report: #d4856a;
  --color-mod-app-code: #7b82e0;
  --color-mod-app-docs: #3fb0a0;
  --color-mod-app-id: #e08768;
  --color-mod-app-status: #7fb84e;

  /* ledger signal colors — money semantics for mod-books */
  --color-mod-ledger-native: #b47b1e;
  --color-mod-ledger-foreign: #22714f;
  --color-mod-ledger-deduct: #a8412a;
  --color-mod-ledger-bonus: #205dc2;
  --color-mod-ledger-base: #77818e;

  /* motion */
  --motion-easing-main: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --motion-easing-shadow: cubic-bezier(0, .65, .35, 1);
  --motion-easing-rotate: cubic-bezier(.28, 1.92, .39, .56);
  --motion-easing-clock: cubic-bezier(.35, 2.1, .79, .71);
  --motion-duration-fast: 0.15s;
  --motion-duration-base: 0.2s;
  --motion-duration-slow: 0.3s;

  /* shadows */
  --shadow-popover-x: 0;
  --shadow-popover-y: 0.5rem;
  --shadow-popover-blur: 0.75rem;
  --shadow-popover-spread: 0;
  --shadow-modal-x: 0;
  --shadow-modal-y: 1.5rem;
  --shadow-modal-blur: 1.5rem;
  --shadow-modal-spread: 0.25rem;
  --shadow-composite-popup: rgb(0 0 0 / 50%) 0px 4px 24px;
  --shadow-composite-popup-panel: rgb(0 0 0 / 55%) 0px 7px 24px;
  --shadow-composite-popup-aside: rgb(0 0 0 / 25%) 0px 8px 16px;
  --shadow-composite-card: rgb(0 0 0 / 50%) 0px 16px 70px;
  --shadow-composite-button: rgb(0 0 0 / 15%) 0px 1px 1px 1px;
  --shadow-composite-primary: rgb(0 0 0 / 25%) 0px 1px 2px;
  --shadow-composite-accent: rgb(0 0 0 / 10%) 0px 2px 4px;
  --shadow-composite-popup-simple: 0 0 .5rem rgba(0, 0, 0, .2);

  /* spacing scale (rem) */
  --space-0-25: 0.125rem;
  --space-0-5: 0.25rem;
  --space-0-75: 0.375rem;
  --space-1: 0.5rem;
  --space-1-25: 0.625rem;
  --space-1-5: 0.75rem;
  --space-1-75: 0.875rem;
  --space-2: 1rem;
  --space-2-25: 1.125rem;
  --space-2-5: 1.25rem;
  --space-2-75: 1.375rem;
  --space-3: 1.5rem;
  --space-3-25: 1.625rem;
  --space-3-5: 1.75rem;
  --space-4: 2rem;
  --space-4-5: 2.25rem;
  --space-5: 2.5rem;
  --space-5-5: 2.75rem;
  --space-6: 3rem;
  --space-6-5: 3.5rem;
  --space-7: 4rem;
  --space-8: 5rem;
  --space-9: 6rem;
  --space-10: 7.5rem;

  /* control sizes */
  --size-min: 1rem;
  --size-extra-small: 1.5rem;
  --size-small: 2rem;
  --size-medium: 2.5rem;
  --size-large: 3rem;
  --size-extra-large: 3.5rem;
  --size-max: 4rem;

  /* typography */
  --font-family-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto;
  --font-family-mono: 'IBM Plex Mono', monospace;
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --font-size-11: 0.6875rem;
  --font-size-12: 0.75rem;
  --font-size-13: 0.8125rem;
  --font-size-14: 0.875rem;
  --font-size-16: 1rem;
  --font-size-18: 1.125rem;
  --font-size-20: 1.25rem;
  --font-size-body: 0.875rem;
  --font-display-1: clamp(2.125rem, 6vw, 3.75rem);
  --font-display-2: clamp(1.875rem, 5vw, 2.75rem);
  --font-display-3: clamp(1.5rem, 4vw, 2.125rem);
  --font-display-4: clamp(1.375rem, 3vw, 1.75rem);
  --font-line-height-16: 1rem;
  --font-line-height-18: 1.125rem;
  --font-line-height-20: 1.25rem;
  --font-line-height-24: 1.5rem;
  --font-line-height-compact: 1rem;

  /* z-index — harvested map plus the app-shell layers, tokenized from the literals
     each app was already using. Upstream defines no formal ramp; this is not one. */
  --z-index-table-selection: 100;
  --z-index-table-handlers: 120;
  --z-index-table-drag-and-drop: 130;
  --z-index-list-header: 450;
  --z-index-list-header-raised: 460;
  --z-index-panel: 500;
  --z-index-overlay: 599;
  --z-index-sidebar: 600;
  --z-index-appbar: 700;
  --z-index-toast: 800;
  --z-index-popover: 900;
  --z-index-print: 9999;

  /* measure — spacing named for the relationship it expresses, not the size it
     happens to be. --gutter is the one page edge: the appbar and .mod-main both
     inset by it, so the brand mark and every heading below it share a left edge.
     The three breakpoints re-declare these four and every consumer follows. */
  --gutter: 1.5rem;
  --rhythm-section: 2.5rem;
  --rhythm-block: 1.5rem;
  --gap-grid: 1.5rem;
  --measure: 68rem;

  /* layout primitives */
  --appbar-h: 48px;
  --appbar-control: 28px;
  --border-width: 1px;
  --grid-unit: 8px;
  --grid-field: calc(var(--gutter) * 2);
  --point-size: 6px;
  --tick-size: 8px;
  --tick-weight: 1.5px;
  --range-track-size: 4px;
  --range-thumb-size: 14px;

  /* control geometry — every clickable thing lands on one of three heights, and
     its padding and label follow from that height instead of being chosen per
     component: padding-x is 0.45x the height, so the label fills the box. */
  --control-height-sm: 2rem;
  --control-height-md: 2.25rem;
  --control-height-lg: 2.75rem;
  --control-pad-sm: 0.875rem;
  --control-pad-md: 1rem;
  --control-pad-lg: 1.25rem;
  --control-font-sm: var(--font-size-12);
  --control-font-md: var(--font-size-13);
  --control-touch: 2.75rem;
  --control-press: 1px;
  --control-press-tint: rgb(0 0 0 / 22%);
  --control-edge: color-mix(in srgb, var(--color-palette-accent) 20%, #AAB2BE);

  /* component variables (drive buttons/cards/inputs across apps) */
  --button-primary-bg: var(--color-accent-strong);
  --button-primary-bg-hover: color-mix(in srgb, var(--color-accent-strong) 82%, #000000);
  --button-primary-text: var(--color-text-on-accent);
  --button-primary-radius: 0;
  --button-primary-padding-x: var(--space-1-5);
  --button-primary-padding-y: var(--space-0-75);
  --button-primary-font-size: var(--font-size-14);
  --button-primary-font-weight: var(--font-weight-medium);
  --button-primary-shadow: var(--shadow-composite-primary);
  --button-secondary-bg: var(--color-bg-raised);
  --button-secondary-text: var(--color-text-primary);
  --button-secondary-border: var(--color-border);
  --card-bg: var(--color-bg-raised);
  --card-border: var(--color-border);
  --card-radius: 0;
  --card-padding: var(--space-3);
  --card-shadow: var(--shadow-composite-card);
  --card-text: var(--color-text-primary);
  --card-muted: var(--color-text-secondary);
  --input-bg: var(--color-bg-raised);
  --input-text: var(--color-text-primary);
  --input-placeholder: var(--color-text-muted);
  --input-border: var(--color-border-ui);
  --input-border-focus: var(--color-border-focus);
  --input-radius: 0;
  --input-padding-x: var(--space-1);
  --input-padding-y: var(--space-0-75);
  --input-font-size: var(--font-size-14);

  /* active palette (default cobalt) — override via :root[data-palette] */
  --color-palette-accent: #4F74E4;
  --color-palette-accent-hi: #8AA4F2;

  /* semantic layer (light) — accent resolves to the active palette; neutrals are tinted */
  --color-bg-surface: color-mix(in srgb, var(--color-palette-accent) 5%, #E7E9ED);
  --color-bg-raised: color-mix(in srgb, var(--color-palette-accent) 3%, #FFFFFF);
  --color-bg-sunken: color-mix(in srgb, var(--color-palette-accent) 7%, #DDE0E5);
  --color-bg-overlay: rgba(0, 0, 0, .2);
  --color-bg-popup: color-mix(in srgb, var(--color-palette-accent) 3%, #FFFFFF);
  --color-text-primary: #14161B;
  --color-text-secondary: #4C5464;
  --color-text-muted: #525762;
  --color-text-disabled: #AAB1BD;
  --color-text-on-accent: #FFFFFF;
  --color-accent: var(--color-palette-accent);
  --color-accent-text: color-mix(in srgb, var(--color-palette-accent) 55%, #000000);
  --color-accent-hover: var(--color-palette-accent);
  --color-accent-strong: color-mix(in srgb, var(--color-palette-accent) 66%, #000000);
  --color-border: color-mix(in srgb, var(--color-palette-accent) 26%, #C4C9D2);
  --color-border-subtle: color-mix(in srgb, var(--color-palette-accent) 15%, #D8DBE2);
  --color-border-ui: color-mix(in srgb, var(--color-palette-accent) 15%, #D8DBE2);
  --color-border-focus: var(--color-palette-accent);
  --color-grid-line: color-mix(in srgb, var(--color-palette-accent) 12%, #CFD3DB);
  --color-state-error: #A3312C;
  --color-state-error-strong: var(--color-state-error);
  --color-state-warn: #725221;
  --color-state-ok: #1D6445;
  --color-state-info: color-mix(in srgb, var(--color-palette-accent) 55%, #000000);
}

/* palette variants — set [data-palette] on :root to reskin the accent */
:root[data-palette="amber"]  { --color-palette-accent: #D69A3C; --color-palette-accent-hi: #EFBF63; }
:root[data-palette="cobalt"] { --color-palette-accent: #4F74E4; --color-palette-accent-hi: #8AA4F2; }
:root[data-palette="coral"]  { --color-palette-accent: #E0716E; --color-palette-accent-hi: #F29A97; }
:root[data-palette="lime"]   { --color-palette-accent: #7FB84E; --color-palette-accent-hi: #A7D97A; }
:root[data-palette="teal"]   { --color-palette-accent: #2FB1A4; --color-palette-accent-hi: #5FD6C9; }
:root[data-palette="violet"] { --color-palette-accent: #8A6FE0; --color-palette-accent-hi: #B098F2; }

/* dark theme — apply via [data-theme="dark"] (or wire prefers-color-scheme to set it) */
[data-theme="dark"] {
  --color-bg-surface: color-mix(in srgb, var(--color-palette-accent) 5%, #0C0E12);
  --color-bg-raised: color-mix(in srgb, var(--color-palette-accent) 6%, #13161B);
  --color-bg-sunken: color-mix(in srgb, var(--color-palette-accent) 4%, #070809);
  --color-bg-overlay: rgba(0, 0, 0, .3);
  --color-bg-popup: color-mix(in srgb, var(--color-palette-accent) 6%, #13161B);
  --color-text-primary: #EEF1F6;
  --color-text-secondary: #A6AEBC;
  --color-text-muted: #868C98;
  --color-text-disabled: #454B57;
  --color-text-on-accent: #FFFFFF;
  --color-accent: var(--color-palette-accent);
  --color-accent-text: var(--color-palette-accent-hi);
  --color-accent-hover: var(--color-palette-accent-hi);
  --color-accent-strong: color-mix(in srgb, var(--color-palette-accent) 66%, #000000);
  --color-border: color-mix(in srgb, var(--color-palette-accent) 22%, #2B303A);
  --color-border-subtle: color-mix(in srgb, var(--color-palette-accent) 12%, #1B1F26);
  --color-border-ui: color-mix(in srgb, var(--color-palette-accent) 12%, #1B1F26);
  --color-border-focus: var(--color-palette-accent);
  --color-grid-line: color-mix(in srgb, var(--color-palette-accent) 16%, #14181F);
  --color-state-error: #E8635C;
  --color-state-error-strong: color-mix(in srgb, var(--color-state-error) 80%, #000000);
  --color-state-warn: #E0A040;
  --color-state-ok: #35B57E;
  --color-state-info: var(--color-palette-accent-hi);
  --control-press-tint: rgb(0 0 0 / 50%);
  --control-edge: rgb(0 0 0 / 55%);
}

/* skip link — first focusable element; jumps keyboard users past the chrome */
.mod-skip-link {
  position: absolute; left: var(--space-1); top: calc(var(--space-1) * -10);
  z-index: var(--z-index-popover);
  padding: var(--space-1) var(--space-2);
  background: var(--color-accent-strong); color: var(--color-text-on-accent);
  font-family: var(--font-family-mono); font-size: var(--font-size-12);
  text-decoration: none;
  transition: top var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-skip-link:focus { top: var(--space-1); color: var(--color-text-on-accent); }

/* responsive layout — sidebar + main shell, collapsible nav, responsive grid */
.mod-shell { display: flex; min-height: calc(100vh - var(--appbar-h)); }
.mod-sidebar {
  width: 220px; flex-shrink: 0;
  border-right: var(--border-width) solid var(--color-border);
  background: var(--color-bg-raised);
  transition: transform var(--motion-duration-base) var(--motion-easing-main);
}
.mod-main {
  flex: 1; min-width: 0;
  padding: var(--rhythm-section) var(--gutter);
  max-width: var(--measure); margin-inline: auto;
}
.mod-nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: var(--appbar-h); height: var(--appbar-h);
  background: none; border: 0; color: var(--color-text-primary);
  cursor: pointer; font-size: var(--font-size-18); flex-shrink: 0;
}
.mod-nav-toggle:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.mod-overlay {
  display: none; position: fixed; inset: 0; z-index: var(--z-index-overlay);
  background: var(--color-bg-overlay);
  opacity: 0;
  transition: opacity var(--motion-duration-base) var(--motion-easing-main),
              display var(--motion-duration-base) allow-discrete;
}
.mod-overlay[data-open] { display: block; opacity: 1; }
@starting-style { .mod-overlay[data-open] { opacity: 0; } }
.mod-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--mod-grid-min, 280px), 1fr));
  gap: var(--gap-grid);
}
.mod-grid > *, .mod-cols > * { min-width: 0; }
.mod-stack {
  display: flex; flex-direction: column;
  gap: var(--rhythm-block);
  max-width: clamp(320px, 100%, 560px);
}
.mod-cols {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: var(--gap-grid);
  align-items: start;
}

/* narrower viewports move the four measure tokens, not the components. One
   declaration per breakpoint keeps the appbar and the content on one edge all
   the way down instead of each rule drifting on its own. */
@media (max-width: 1024px) {
  :root { --gutter: 1.25rem; --rhythm-section: 2rem; }
  .mod-cols { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
  .mod-nav-toggle { display: flex; }
  .mod-sidebar {
    position: fixed; top: var(--appbar-h); left: 0; bottom: 0;
    z-index: var(--z-index-sidebar); width: 260px;
    transform: translateX(-100%);
    border-right: var(--border-width) solid var(--color-border);
    overflow-y: auto;
  }
  .mod-sidebar[data-open] { transform: translateX(0); }
}
/* touch — every control grows to the 44px target under 640px, and text inputs
   go to 16px so iOS stops zooming the page on focus. This lives here, not in one
   app's stylesheet, because a thumb is the same size in all three apps. */
@media (max-width: 640px) {
  :root {
    --gutter: 1rem; --rhythm-section: 1.5rem; --rhythm-block: 1.25rem; --gap-grid: 1.25rem;
    --control-height-sm: var(--control-touch);
    --control-height-md: var(--control-touch);
  }
  .mod-grid { grid-template-columns: 1fr; }
  .mod-input, .mod-input--small { font-size: var(--font-size-16); }
}

/* .mod-appbar — the shared app header. Every surface ships an empty
   <header class="mod-appbar" data-app="…"> and mod-chrome.js fills it: brand,
   title, theme control, app switcher, identity, in that order, on all seven.
   The box is pinned to --appbar-h so nothing shifts while it is still empty.
   Consumes --color-* only — a vendor app that maps its own theme onto our
   semantic layer gets this bar for free instead of a copy of it. */
.mod-appbar {
  display: flex; align-items: center; height: var(--appbar-h);
  border-bottom: var(--border-width) solid var(--color-border);
  background: var(--color-bg-surface); padding: 0 var(--gutter); gap: var(--space-2);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .05em; text-transform: uppercase; color: var(--color-text-muted);
  position: sticky; top: 0; z-index: var(--z-index-appbar);
}
.mod-appbar__brand { display: flex; align-items: center; gap: var(--space-1); flex-shrink: 0; }
.mod-appbar__word {
  font-weight: var(--font-weight-bold); font-size: var(--font-size-13);
  letter-spacing: -.02em; text-transform: none; color: var(--color-text-primary);
}
.mod-appbar .mod-signal {
  inline-size: var(--point-size); block-size: var(--point-size);
  background: var(--sig, var(--color-accent)); flex-shrink: 0;
}
.mod-appbar__title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mod-appbar__tools { display: flex; align-items: center; }
.mod-appbar__apps  { display: flex; align-items: center; flex-shrink: 0; }
.mod-appbar__meta  { display: flex; align-items: center; flex-shrink: 0; position: relative; }
.mod-appbar__user  { display: flex; align-items: center; gap: var(--space-1); flex-shrink: 0; }
.mod-identity-chip { text-transform: none; letter-spacing: .04em; }

/* one control box for the whole bar: --appbar-control of visible square inside a
   44px hit area made of padding. WCAG 2.5.8 asks 24px minimum — the six 12px
   swatches this replaces were half of it, six times over. */
.mod-appbar__control {
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
  inline-size: var(--control-touch); block-size: var(--control-touch);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--color-text-muted); flex-shrink: 0;
}
.mod-appbar__control-mark {
  inline-size: var(--appbar-control); block-size: var(--appbar-control);
  display: grid; place-content: center;
  border: var(--border-width) solid transparent;
  transition: color var(--motion-duration-fast) var(--motion-easing-main),
              border-color var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-appbar__control:hover { color: var(--color-text-primary); }
.mod-appbar__control:hover .mod-appbar__control-mark { border-color: var(--color-accent); }
.mod-appbar__control:focus-visible { outline: none; }
.mod-appbar__control:focus-visible .mod-appbar__control-mark {
  outline: 2px solid var(--color-accent); outline-offset: -2px;
}
.mod-appbar__control[aria-expanded="true"] .mod-appbar__control-mark { border-color: var(--color-accent); }
.mod-appbar__control .mod-icon-sun,
.mod-appbar__control .mod-icon-moon { display: none; }
.mod-appbar__control[data-mode="dark"] .mod-icon-sun { display: block; }
.mod-appbar__control[data-mode="light"] .mod-icon-moon { display: block; }

/* the palette is one control that opens the six, not six controls in the bar */
.mod-palette-swatch {
  inline-size: calc(var(--appbar-control) - var(--space-1-25));
  block-size: calc(var(--appbar-control) - var(--space-1-25));
  background: var(--color-palette-accent);
}
/* Closed has to be spelled out here. The browser's own rule for a closed popover
   is a user-agent rule, and any author declaration outranks it, so a bare
   display:flex on this class beat it: the menu was never hidden, the [popover]
   block below made it position:fixed with no offsets, and an invisible strip of
   six swatches sat over the bar eating the click meant for the control that
   opens it. Open is the exception now, named once per path — :popover-open where
   the platform runs it, :not([hidden]) where the script does. */
.mod-palette-menu {
  display: none; gap: var(--space-0-5); padding: var(--space-1);
  background: var(--color-bg-popup);
  border: var(--border-width) solid var(--color-border);
  box-shadow: var(--shadow-composite-popup);
}
.mod-palette-menu:popover-open { display: flex; }
.mod-palette-menu:not([popover]):not([hidden]) { display: flex; }
.mod-palette-menu button {
  appearance: none; border: 0; padding: var(--space-1); background: none;
  inline-size: var(--control-touch); block-size: var(--control-touch);
  display: grid; place-content: center; cursor: pointer;
}
.mod-palette-menu button > span {
  inline-size: var(--appbar-control); block-size: var(--appbar-control);
  border: 2px solid transparent;
}
.mod-palette-menu button[aria-pressed="true"] > span { border-color: var(--color-text-primary); }
.mod-palette-menu button:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -4px; }

.mod-appbar__app {
  display: inline-flex; align-items: center; gap: var(--space-0-75);
  padding: var(--space-1) var(--space-1-25); text-decoration: none;
  color: var(--color-text-muted); border: var(--border-width) solid transparent;
  font-size: var(--font-size-11); letter-spacing: .05em; text-transform: uppercase;
  font-family: var(--font-family-mono);
}
.mod-appbar__app:hover {
  border-color: var(--sig); color: var(--color-text-primary); text-decoration: none;
}
.mod-appbar__app:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* small screens drop the appbar's optional zones. This block lives after the zone
   definitions on purpose — same specificity, so the later rule is the one that wins;
   in the responsive block above it lost silently and the app links overflowed. */
@media (max-width: 768px) {
  .mod-appbar__apps { display: none; }
  .mod-appbar__meta { display: none; }
  .mod-appbar__user > span:not(.mod-pill) { display: none; }
}

/* top layer — anything transient (explain panels, menus) opens as a native popover so it
   escapes every ancestor's overflow and stacking context, and gets outside-click plus
   Escape dismissal from the platform instead of hand-rolled listeners. Placement is set
   by script on open; these rules only undo the UA dialog styling. */
[popover] {
  position: fixed; inset: auto; margin: 0; padding: 0; border: 0;
  overflow: visible; background: transparent; color: inherit;
  width: max-content; max-width: min(30rem, calc(100vw - var(--space-4)));
}
[popover]::backdrop { background: transparent; }

@media (prefers-reduced-motion: no-preference) {
  [popover] {
    opacity: 0; translate: 0 calc(var(--space-0-5) * -1);
    transition:
      opacity var(--motion-duration-fast) var(--motion-easing-main),
      translate var(--motion-duration-fast) var(--motion-easing-shadow),
      overlay var(--motion-duration-fast) allow-discrete,
      display var(--motion-duration-fast) allow-discrete;
  }
  [popover]:popover-open { opacity: 1; translate: 0 0; }
  @starting-style {
    [popover]:popover-open { opacity: 0; translate: 0 calc(var(--space-0-5) * -1); }
  }
}

/* autosave indicator — a lasting mark beside any [data-autosave] field. Persistent
   by design: the panel states what happened and leaves it on screen, never a flash
   the eye can miss (UI principle: save state is persistent, not a flash). Behaviour
   lives in design/mod-htmx.js. */
.save-state {
  display: inline-block;
  margin-top: var(--space-1);
  font-family: var(--font-family-mono);
  font-size: var(--font-size-11);
  color: var(--color-text-secondary);
  line-height: 1.4;
}
.save-state--saved { color: var(--color-state-ok); }
.save-state--dirty { color: var(--color-state-warn); }
.save-state--error { color: var(--color-state-error); }

/* ============================================================================
   COMPONENTS — the one shared UI vocabulary. Every app consumes these by class.
   Spacing lives in the component, never in a utility class. Renamed out of the
   old per-app c-/dc-/p-/m- prefixes into a single mod- namespace. Where two apps
   carried the same component, the richer rule won: mod-trust for controls, frame
   and nav; mod-books for table hover and stat-tile numerals.
   ============================================================================ */

/* button — every clickable verb. Text always names the action it performs.
   Flat like every other square in the system: no raised lip, no travel on press.
   Press is a fast background and border shift plus a one-pixel inset, so the
   feedback is the same colour language the rest of the system already speaks. */
.mod-button {
  --mod-button-bg: var(--color-bg-raised);
  --mod-button-text: var(--color-text-primary);
  --mod-button-border: var(--color-border);
  --mod-button-bg-hover: var(--color-bg-sunken);
  --mod-button-text-hover: var(--color-text-primary);
  --mod-button-border-hover: var(--color-accent);
  --mod-button-bg-press: color-mix(in srgb, var(--mod-button-bg-hover) 88%, #000000);

  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-0-75);
  height: var(--control-height-md); padding: 0 var(--control-pad-md);
  font-family: var(--font-family-mono); font-size: var(--control-font-md);
  font-weight: var(--font-weight-medium); letter-spacing: .07em; text-transform: uppercase;
  line-height: 1; white-space: nowrap; text-decoration: none;
  color: var(--mod-button-text); background: var(--mod-button-bg);
  border: var(--border-width) solid var(--mod-button-border); border-radius: 0;
  cursor: pointer; overflow: hidden;
  transition:
    background var(--motion-duration-fast) var(--motion-easing-main),
    border-color var(--motion-duration-fast) var(--motion-easing-main),
    color var(--motion-duration-fast) var(--motion-easing-main),
    box-shadow var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-button:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--mod-button-bg-hover); color: var(--mod-button-text-hover); border-color: var(--mod-button-border-hover);
}
.mod-button:active:not(:disabled):not([aria-disabled="true"]) {
  background: var(--mod-button-bg-press); border-color: var(--mod-button-border-hover);
  box-shadow: inset 0 var(--control-press) 0 var(--control-press-tint);
}
.mod-button:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.mod-button:disabled, .mod-button[aria-disabled="true"] {
  opacity: .4; cursor: not-allowed; box-shadow: none;
}
.mod-button--primary {
  --mod-button-bg: var(--button-primary-bg);
  --mod-button-text: var(--button-primary-text);
  --mod-button-border: var(--button-primary-bg);
  --mod-button-bg-hover: var(--button-primary-bg-hover);
  --mod-button-text-hover: var(--button-primary-text);
  --mod-button-border-hover: var(--button-primary-bg-hover);
  font-weight: var(--font-weight-semibold);
}
.mod-button--ghost {
  --mod-button-bg: transparent;
  --mod-button-text: var(--color-text-secondary);
  --mod-button-border: var(--color-border-subtle);
  --mod-button-text-hover: var(--color-accent-text);
}
.mod-button--danger {
  --mod-button-bg: transparent;
  --mod-button-text: var(--color-state-error);
  --mod-button-border: color-mix(in srgb, var(--color-state-error) 45%, transparent);
  --mod-button-bg-hover: var(--color-state-error-strong);
  --mod-button-text-hover: var(--color-text-on-accent);
  --mod-button-border-hover: var(--color-state-error-strong);
}
.mod-button--small { height: var(--control-height-sm); padding: 0 var(--control-pad-sm); font-size: var(--control-font-sm); }
.mod-button--large { height: var(--control-height-lg); padding: 0 var(--control-pad-lg); }
/* icon-only — a square on the same three heights. The label lives in aria-label,
   so the box stays square at every size instead of inheriting a text button's
   padding and drifting into a rectangle. */
.mod-button--icon {
  width: var(--control-height-md); padding: 0; gap: 0; flex-shrink: 0;
}
.mod-button--icon.mod-button--small { width: var(--control-height-sm); }
.mod-button--icon.mod-button--large { width: var(--control-height-lg); }
.mod-button--icon > svg { inline-size: 1rem; block-size: 1rem; }
.mod-button--full-width { display: flex; width: 100%; }

/* a control inside a table cell, or in an inline cluster, stands on the small
   box: there the row is the unit, and a medium button breaks the line the row
   makes. One redefinition of the medium tokens carries height, padding and
   label together, so nothing re-states geometry per app. */
.mod-table :is(td, th), .mod-inline-controls {
  --control-height-md: var(--control-height-sm);
  --control-pad-md: var(--control-pad-sm);
  --control-font-md: var(--control-font-sm);
}

/* button in flight — keep the label readable, run a scan bar underneath */
.mod-button.htmx-request { cursor: wait; pointer-events: none; }
.mod-button.htmx-request::after {
  content: ""; position: absolute; left: 0; bottom: 0; z-index: 1;
  width: 40%; height: 2px; background: currentColor; opacity: .8;
  animation: mod-button-scan .85s var(--motion-easing-main) infinite;
}
@keyframes mod-button-scan { from { translate: -100% 0; } to { translate: 250% 0; } }
tr.htmx-request { opacity: .65; transition: opacity var(--motion-duration-base) var(--motion-easing-main); }
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { display: inline-block; }

/* input — placeholder never substitutes for a label; invalid gets an error bar */
.mod-input {
  width: 100%; height: var(--control-height-md);
  font-family: var(--font-family-sans); font-size: var(--font-size-14); color: var(--color-text-primary);
  background: var(--color-bg-raised); border: var(--border-width) solid var(--color-border);
  border-radius: 0; padding: 0 var(--space-1-25);
  transition: border-color var(--motion-duration-fast) var(--motion-easing-main),
              box-shadow var(--motion-duration-fast) var(--motion-easing-main),
              background var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-input::placeholder { color: var(--color-text-muted); }
.mod-input:hover:not(:disabled) { border-color: var(--color-border-focus); }
.mod-input:focus {
  outline: 2px solid transparent; outline-offset: -2px;
  border-color: var(--color-accent); background: var(--color-bg-surface);
  box-shadow: inset 3px 0 0 var(--color-accent);
}
.mod-input:disabled { opacity: .5; cursor: not-allowed; }
.mod-input:user-invalid {
  border-color: var(--color-state-error); box-shadow: inset 3px 0 0 var(--color-state-error);
}
select.mod-input { cursor: pointer; }
/* the dense variant — for table-like rows where an input sits beside segments,
   ranges and icon buttons, all of which stand on the small control box. */
.mod-input--small {
  height: var(--control-height-sm); padding: 0 var(--space-1);
  font-size: var(--font-size-14);
}

/* input-group — input with a visible, non-editable unit suffix inside its border */
.mod-input-group {
  display: flex; align-items: stretch; width: 100%;
  background: var(--color-bg-raised); border: var(--border-width) solid var(--color-border);
  transition: border-color var(--motion-duration-fast) var(--motion-easing-main),
              box-shadow var(--motion-duration-fast) var(--motion-easing-main),
              background var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-input-group:hover { border-color: var(--color-border-focus); }
.mod-input-group:focus-within {
  outline: 2px solid transparent; outline-offset: -2px;
  border-color: var(--color-accent); background: var(--color-bg-surface);
  box-shadow: inset 3px 0 0 var(--color-accent);
}
.mod-input-group .mod-input {
  border: 0; background: transparent; box-shadow: none; flex: 1 1 auto; min-width: 0;
}
.mod-input-group .mod-input:focus { border: 0; background: transparent; box-shadow: none; }
.mod-input-group__unit {
  display: inline-flex; align-items: center; padding: 0 var(--space-1-25);
  font-family: var(--font-family-mono); font-size: var(--font-size-12); color: var(--color-text-muted);
  border-left: var(--border-width) solid var(--color-border-subtle); white-space: nowrap; flex-shrink: 0;
}

/* hint — help text under a form element, connected via aria-describedby */
.mod-hint {
  display: block; margin-top: var(--space-0-5);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  color: var(--color-text-muted); line-height: 1.4;
}

/* checkbox — square, accent fill, focus ring */
.mod-checkbox {
  -webkit-appearance: none; appearance: none;
  width: var(--space-2); height: var(--space-2);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-bg-raised);
  border-radius: 0; display: inline-grid; place-content: center;
  cursor: pointer; vertical-align: middle; flex-shrink: 0;
  transition: border-color var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-checkbox:checked { border-color: var(--color-accent); }
.mod-checkbox:checked::before { content: ""; width: var(--space-1); height: var(--space-1); background: var(--color-accent); }
.mod-checkbox:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* pill (status, with signal dot) + tag (category, no dot) + badge (count) */
.mod-tag, .mod-pill, .mod-badge {
  display: inline-flex; align-items: center; gap: var(--space-0-5);
  font-family: var(--font-family-mono); font-size: var(--font-size-11); letter-spacing: .08em;
  text-transform: uppercase; padding: 2px var(--space-0-75);
  border: var(--border-width) solid var(--color-border);
  color: var(--color-text-secondary); border-radius: 0;
}
.mod-pill::before { content: ""; width: var(--point-size); height: var(--point-size); background: currentColor; flex-shrink: 0; }
.mod-pill--ok     { color: var(--color-state-ok);    border-color: color-mix(in srgb, var(--color-state-ok) 45%, transparent); }
.mod-pill--warn   { color: var(--color-state-warn);  border-color: color-mix(in srgb, var(--color-state-warn) 45%, transparent); }
.mod-pill--error  { color: var(--color-state-error); border-color: color-mix(in srgb, var(--color-state-error) 45%, transparent); }
.mod-pill--accent { color: var(--color-accent);      border-color: color-mix(in srgb, var(--color-accent) 45%, transparent); }
.mod-pill--muted  { color: var(--color-text-muted);  border-color: var(--color-border); opacity: .5; }
.mod-pill--small, .mod-tag--small { font-size: 10px; padding: 1px var(--space-0-5); }
.mod-badge { min-width: var(--space-2); justify-content: center; }

/* alert — 3px left border + tinted background, consistent margin inside frames */
.mod-alert {
  display: flex; gap: var(--space-1-5);
  padding: var(--space-1-5) var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-left-width: 3px;
  background: var(--color-bg-raised);
  font-size: var(--font-size-14); color: var(--color-text-primary);
  overflow-wrap: anywhere;
}
.mod-alert--ok    { border-left-color: var(--color-state-ok);    background: color-mix(in srgb, var(--color-state-ok) 8%, var(--color-bg-raised)); }
.mod-alert--warn  { border-left-color: var(--color-state-warn);  background: color-mix(in srgb, var(--color-state-warn) 8%, var(--color-bg-raised)); }
.mod-alert--error { border-left-color: var(--color-state-error); background: color-mix(in srgb, var(--color-state-error) 8%, var(--color-bg-raised)); }
.mod-alert--info  { border-left-color: var(--color-accent);      background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg-raised)); }

/* empty state — every list/table that can be empty says what would be here */
.mod-empty-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-1);
  text-align: center; padding: var(--space-4) var(--space-2);
  color: var(--color-text-muted); font-size: var(--font-size-14); line-height: 1.5;
}
.mod-empty-state .mod-signal-dot { margin-bottom: var(--space-0-5); }

/* table — accent-tinted hover (mod-books), warn/critical rows (mod-trust) */
.mod-table-container {
  overflow-x: auto; border: var(--border-width) solid var(--color-border);
  background:
    linear-gradient(to right, var(--color-bg-raised) 30%, transparent) left center / 24px 100% no-repeat,
    linear-gradient(to left, var(--color-bg-raised) 30%, transparent) right center / 24px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.18), transparent) left center / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.18), transparent) right center / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.mod-scroll-indicator {
  background:
    linear-gradient(to right, var(--color-bg-raised) 30%, transparent) left center / 24px 100% no-repeat,
    linear-gradient(to left, var(--color-bg-raised) 30%, transparent) right center / 24px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.18), transparent) left center / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.18), transparent) right center / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.mod-table { width: 100%; border-collapse: collapse; font-size: var(--font-size-14); }
.mod-table th { text-align: left; padding: var(--space-1) var(--space-1-5); }
.mod-table thead th {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-11); font-weight: var(--font-weight-medium); letter-spacing: .12em;
  text-transform: uppercase; color: var(--color-text-muted); background: var(--color-bg-sunken);
  border-bottom: var(--border-width) solid var(--color-border); white-space: nowrap;
}
.mod-table td, .mod-table--key-value th {
  padding: var(--space-1) var(--space-1-5);
  border-bottom: var(--border-width) solid var(--color-border-subtle);
}
.mod-table td { vertical-align: middle; overflow-wrap: anywhere; }
.mod-table--key-value th {
  width: 160px; color: var(--color-text-muted); font-weight: var(--font-weight-regular);
  font-size: var(--font-size-14); vertical-align: top;
}
.mod-table tbody tr { transition: background var(--motion-duration-fast) var(--motion-easing-main); }
.mod-table tbody tr:hover { background: color-mix(in srgb, var(--color-accent) 4%, transparent); }
.mod-table tbody tr:last-child > :is(td, th) { border-bottom: 0; }
.mod-table tfoot th { font-weight: var(--font-weight-semibold); }
.mod-table__row--warning {
  background: color-mix(in srgb, var(--color-state-warn) 8%, var(--color-bg-raised));
  box-shadow: inset 3px 0 0 var(--color-state-warn);
}
.mod-table__row--warning:hover { background: color-mix(in srgb, var(--color-state-warn) 14%, var(--color-bg-raised)); }
.mod-table__row--critical {
  background: color-mix(in srgb, var(--color-state-error) 8%, var(--color-bg-raised));
  box-shadow: inset 3px 0 0 var(--color-state-error);
}
.mod-table__row--critical:hover { background: color-mix(in srgb, var(--color-state-error) 14%, var(--color-bg-raised)); }

/* frame — bordered card with corner ticks + coordinate label; linkable variant lifts */
.mod-frame {
  position: relative;
  background: var(--card-bg);
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--card-radius);
  padding: var(--card-padding);
}
.mod-frame--soft { background: var(--color-bg-sunken); border-color: var(--color-border-subtle); }
.mod-frame--drift {
  border-color: color-mix(in srgb, var(--color-state-warn) 40%, var(--color-border));
  box-shadow: inset 3px 0 0 var(--color-state-warn);
}
.mod-frame__coordinate {
  position: absolute; top: calc(var(--tick-weight) * -4); left: var(--space-1-5);
  padding: 0 var(--space-0-5); background: inherit;
  font-family: var(--font-family-mono); font-size: var(--font-size-12);
  letter-spacing: .14em; text-transform: uppercase; color: var(--color-accent);
}
.mod-frame__tick { display: block; height: 0; font-size: 0; line-height: 0; }
.mod-frame::before, .mod-frame::after,
.mod-frame__tick::before, .mod-frame__tick::after {
  content: ""; position: absolute; width: var(--tick-size); height: var(--tick-size);
}
.mod-frame::before {
  top: calc(var(--border-width) * -1); left: calc(var(--border-width) * -1);
  border-top: var(--tick-weight) solid var(--color-accent);
  border-left: var(--tick-weight) solid var(--color-accent);
}
.mod-frame::after {
  bottom: calc(var(--border-width) * -1); left: calc(var(--border-width) * -1);
  border-bottom: var(--tick-weight) solid var(--color-accent);
  border-left: var(--tick-weight) solid var(--color-accent);
}
.mod-frame__tick::before {
  top: calc(var(--border-width) * -1); right: calc(var(--border-width) * -1);
  border-top: var(--tick-weight) solid var(--color-accent);
  border-right: var(--tick-weight) solid var(--color-accent);
}
.mod-frame__tick::after {
  bottom: calc(var(--border-width) * -1); right: calc(var(--border-width) * -1);
  border-bottom: var(--tick-weight) solid var(--color-accent);
  border-right: var(--tick-weight) solid var(--color-accent);
}
.mod-frame :is(a, button, input, select, textarea):focus-visible {
  outline: 2px solid var(--color-accent); outline-offset: 2px;
}
a.mod-frame {
  text-decoration: none; color: inherit; display: block;
  transition: background var(--motion-duration-fast) var(--motion-easing-main),
              border-color var(--motion-duration-fast) var(--motion-easing-main),
              translate var(--motion-duration-base) var(--motion-easing-shadow),
              box-shadow var(--motion-duration-base) var(--motion-easing-shadow);
}
a.mod-frame:hover {
  background: var(--color-bg-sunken); border-color: var(--color-accent);
  translate: 0 -2px; box-shadow: 0 2px 0 var(--control-edge);
}
a.mod-frame:active { translate: 0 0; box-shadow: none; }
a.mod-frame:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* stat grid + tile — big mono numeral, inset state bar */
.mod-stat-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--gap-grid); margin-bottom: var(--rhythm-section);
}
.mod-stat-tile { box-shadow: inset 3px 0 0 var(--color-border); }
.mod-stat-tile--ok    { box-shadow: inset 3px 0 0 var(--color-state-ok); }
.mod-stat-tile--warn  { box-shadow: inset 3px 0 0 var(--color-state-warn); }
.mod-stat-tile--error { box-shadow: inset 3px 0 0 var(--color-state-error); }
a.mod-frame.mod-stat-tile:hover { box-shadow: inset 3px 0 0 var(--color-accent), 0 2px 0 var(--control-edge); }
.mod-stat-tile__value {
  margin-top: var(--space-0-5);
  font-family: var(--font-family-mono); font-size: var(--font-size-20);
  font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.mod-stat-tile__label {
  margin-top: var(--space-0-5);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .08em; text-transform: uppercase; color: var(--color-text-muted); line-height: 1.4;
}

/* background grid — fixed field lines behind the shell (2-direction composite mask) */
.mod-background-grid {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--color-grid-line) var(--border-width), transparent var(--border-width)),
    linear-gradient(to bottom, var(--color-grid-line) var(--border-width), transparent var(--border-width));
  background-size: var(--grid-field) var(--grid-field);
  opacity: .45;
  -webkit-mask-image:
    linear-gradient(180deg, #000 0%, rgba(0,0,0,.45) 32%, rgba(0,0,0,.1) 58%, rgba(0,0,0,.4) 84%, transparent 100%),
    linear-gradient(90deg, #000 0%, rgba(0,0,0,.22) 28%, rgba(0,0,0,.22) 72%, #000 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(180deg, #000 0%, rgba(0,0,0,.45) 32%, rgba(0,0,0,.1) 58%, rgba(0,0,0,.4) 84%, transparent 100%),
    linear-gradient(90deg, #000 0%, rgba(0,0,0,.22) 28%, rgba(0,0,0,.22) 72%, #000 100%);
  mask-composite: intersect;
}
[data-theme="dark"] .mod-background-grid { opacity: .52; }

/* signal dot — small state mark for headings, lists, empty states */
.mod-signal-dot {
  display: inline-block; width: var(--point-size); height: var(--point-size);
  background: var(--color-state-ok); flex-shrink: 0;
}
.mod-signal-dot--ok     { background: var(--color-state-ok); }
.mod-signal-dot--warn   { background: var(--color-state-warn); }
.mod-signal-dot--error  { background: var(--color-state-error); }
.mod-signal-dot--accent { background: var(--color-accent); }
.mod-signal-dot--muted  { background: var(--color-text-muted); }
.mod-signal-dot--node   { background: var(--color-text-muted); }

/* focus indicator — left accent bar scales in on focus-within */
.mod-focus-indicator { position: relative; display: block; }
.mod-focus-indicator::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: calc(var(--point-size) / 2);
  background: var(--color-accent);
  transform: scaleY(0); transform-origin: center;
  transition: transform var(--motion-duration-fast) var(--motion-easing-main);
  z-index: 1;
}
.mod-focus-indicator:focus-within { outline: 2px solid transparent; outline-offset: -2px; }
.mod-focus-indicator:focus-within::before { transform: scaleY(1); }

/* divider — subtle horizontal rule */
.mod-divider { border: 0; border-top: var(--border-width) solid var(--color-border-subtle); margin: 0; }

/* navigation — vertical list with an animated accent bar (mod-trust) */
.mod-navigation {
  display: flex; flex-direction: column;
  border: var(--border-width) solid var(--color-border);
  background: var(--color-bg-raised);
}
.mod-navigation__item {
  display: flex; align-items: center; gap: var(--space-1-5); position: relative;
  padding: var(--space-1) var(--space-1-5) var(--space-1) calc(var(--space-1-5) + 3px);
  font-family: var(--font-family-mono); font-size: var(--font-size-14);
  color: var(--color-text-secondary); text-decoration: none; cursor: pointer;
  transition: background var(--motion-duration-fast) var(--motion-easing-main),
              color var(--motion-duration-fast) var(--motion-easing-main),
              padding-left var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-navigation__item::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--color-accent);
  transform: scaleY(0); transform-origin: center;
  transition: transform var(--motion-duration-base) var(--motion-easing-shadow);
}
.mod-navigation__item:hover {
  background: var(--color-bg-sunken); color: var(--color-text-primary);
  padding-left: calc(var(--space-2) + 3px);
}
.mod-navigation__item:hover::before { transform: scaleY(.4); background: var(--color-text-muted); }
.mod-navigation__item[aria-current="page"] {
  background: var(--color-bg-sunken); color: var(--color-text-primary);
  font-weight: var(--font-weight-medium);
}
.mod-navigation__item[aria-current="page"]::before { transform: scaleY(1); background: var(--color-accent); }
.mod-navigation__item:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.mod-navigation__separator {
  padding: var(--space-0-75) var(--space-1-5);
  margin-top: var(--space-2);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-muted);
  border-top: var(--border-width) solid var(--color-border-subtle);
}
.mod-navigation__separator:first-child { border-top: 0; margin-top: 0; }

/* form — vertical field stack; the field wrapper enforces label→input association */
.mod-form {
  display: flex; flex-direction: column; gap: var(--rhythm-block);
  max-width: clamp(320px, 100%, 560px); margin-top: var(--space-1);
}
.mod-form__field { display: flex; flex-direction: column; gap: var(--space-0-75); }
.mod-form__label {
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-muted);
}
.mod-form__actions {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-1-5);
  margin-top: var(--space-1-5);
}
.mod-form__options { display: flex; flex-direction: column; gap: var(--space-1-25); }
.mod-form__options label {
  display: flex; align-items: center; gap: var(--space-1);
  font-family: var(--font-family-mono); font-size: var(--font-size-12);
  color: var(--color-text-secondary); cursor: pointer;
}
@media (min-width: 641px) {
  .mod-form__options--grid { display: grid; grid-template-columns: 1fr 1fr; }
}

/* tab bar — horizontal tabs, accent underline on the active one, wraps on mobile */
.mod-tab-bar {
  display: flex; flex-wrap: wrap; gap: var(--space-0-5);
  margin-bottom: var(--rhythm-block);
  border-bottom: var(--border-width) solid var(--color-border-subtle);
}
.mod-tab-bar__tab {
  display: inline-flex; align-items: center; gap: var(--space-0-5);
  padding: var(--space-1) var(--space-1-5); margin-bottom: -1px;
  font-family: var(--font-family-mono); font-size: var(--font-size-12);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--color-text-muted); text-decoration: none; cursor: pointer;
  background: none; border: 0; border-bottom: 2px solid transparent;
  transition: color var(--motion-duration-fast) var(--motion-easing-main),
              border-color var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-tab-bar__tab:hover { color: var(--color-text-primary); }
.mod-tab-bar__tab[aria-current="page"] { color: var(--color-text-primary); border-bottom-color: var(--color-accent); }
.mod-tab-bar__tab:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* toggle — two-state button (interactive) or read-only mark (span) */
.mod-toggle {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-0-5);
  min-width: var(--control-height-sm); height: var(--control-height-sm); padding: 0 var(--space-1);
  font-family: var(--font-family-mono); font-size: var(--font-size-14); line-height: 1;
  color: var(--color-text-muted); background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border); cursor: pointer;
  transition: border-color var(--motion-duration-fast) var(--motion-easing-main),
              background var(--motion-duration-fast) var(--motion-easing-main),
              color var(--motion-duration-fast) var(--motion-easing-main);
}
button.mod-toggle:hover { border-color: var(--color-accent); background: var(--color-bg-sunken); }
button.mod-toggle:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.mod-toggle[aria-pressed="true"] { color: var(--color-state-ok); border-color: color-mix(in srgb, var(--color-state-ok) 45%, transparent); }
span.mod-toggle, .mod-toggle--readonly { cursor: default; }

/* action group — safe buttons left, destructive pushed right past a divider */
.mod-action-group {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-0-75);
}
.mod-action-group__divider {
  align-self: stretch; width: var(--border-width);
  background: var(--color-border-subtle); margin: 0 var(--space-0-5);
}
@media (min-width: 641px) {
  .mod-action-group__spacer { margin-left: auto; }
  .mod-action-group--split > .mod-button--danger:last-child { margin-left: auto; }
}

/* breadcrumb — page context path, / separated, mono uppercase */
.mod-breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-0-5);
  margin-bottom: var(--space-2);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .08em; text-transform: uppercase;
}
.mod-breadcrumb a { color: var(--color-text-muted); text-decoration: none; }
.mod-breadcrumb a:hover { color: var(--color-accent-text); }
.mod-breadcrumb__separator { color: var(--color-text-disabled); }
.mod-breadcrumb__current { color: var(--color-text-primary); }

/* section nav — in-page anchor links, sticky below the appbar on long pages */
.mod-section-nav {
  position: sticky; top: var(--appbar-h); z-index: var(--z-index-list-header);
  display: flex; flex-wrap: wrap; gap: var(--space-0-5);
  padding: var(--space-1) 0; margin-bottom: var(--rhythm-block);
  background: var(--color-bg-surface);
  border-bottom: var(--border-width) solid var(--color-border-subtle);
}
.mod-section-nav__link {
  padding: var(--space-0-5) var(--space-1);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--color-text-muted); text-decoration: none;
  border-bottom: 2px solid transparent;
}
.mod-section-nav__link:hover { color: var(--color-text-primary); }
.mod-section-nav__link:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* progress line — one hairline at the top edge acknowledges every fetch */
.mod-progress-line {
  position: fixed; top: 0; left: 0; right: 0; height: 2px;
  z-index: var(--z-index-toast); pointer-events: none;
  background: var(--color-accent);
  transform: scaleX(0); transform-origin: left; opacity: 0;
  transition: transform var(--motion-duration-slow) var(--motion-easing-main),
              opacity var(--motion-duration-fast) linear;
}
.mod-progress-line[data-run] { opacity: 1; transform: scaleX(.75); }
.mod-progress-line[data-done] { opacity: 0; transform: scaleX(1); }

/* toast — bottom-right stack. Non-error auto-dismisses with a countdown bar;
   error toasts persist until clicked (behaviour in mod-toast.js). */
.mod-toast-container {
  position: fixed; bottom: var(--space-3); right: var(--space-3);
  z-index: var(--z-index-toast); display: flex; flex-direction: column-reverse;
  gap: var(--space-1); max-width: min(28rem, calc(100vw - var(--space-4)));
}
.mod-toast {
  position: relative; overflow: hidden; cursor: pointer;
  box-shadow: var(--shadow-composite-popup);
  animation: mod-toast-in var(--motion-duration-base) var(--motion-easing-shadow);
  transition: opacity var(--motion-duration-base) var(--motion-easing-main),
              translate var(--motion-duration-base) var(--motion-easing-main);
}
.mod-toast::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  background: var(--color-state-ok); transform-origin: left;
  animation: mod-toast-life 3.5s linear forwards;
}
.mod-toast--persist::after { animation: none; display: none; }
.mod-alert--error.mod-toast::after { background: var(--color-state-error); }
.mod-alert--warn.mod-toast::after { background: var(--color-state-warn); }
.mod-toast--out { opacity: 0; translate: var(--space-2) 0; }
@keyframes mod-toast-in { from { opacity: 0; translate: var(--space-2) 0; } }
@keyframes mod-toast-life { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@media (max-width: 640px) {
  .mod-toast-container { left: var(--space-2); right: var(--space-2); bottom: var(--space-2); max-width: none; }
}

/* dialog — destructive verbs get a named panel, never a browser alert */
.mod-dialog {
  margin: auto; padding: 0; border: 0; background: transparent; color: inherit;
  width: min(30rem, calc(100vw - var(--space-4)));
}
.mod-dialog::backdrop { background: var(--color-bg-overlay); backdrop-filter: blur(2px); }
.mod-dialog__panel {
  position: relative;
  background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border);
  border-left: 3px solid var(--color-state-warn);
  padding: var(--space-3);
  box-shadow: var(--shadow-composite-card);
}
.mod-dialog__panel--danger { border-left-color: var(--color-state-error); }
.mod-dialog__title {
  display: block; font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}
.mod-dialog__body { font-size: var(--font-size-14); color: var(--color-text-primary); line-height: 1.55; }
.mod-dialog__actions {
  display: flex; gap: var(--space-1); justify-content: flex-end; margin-top: var(--rhythm-block);
}
@media (prefers-reduced-motion: no-preference) {
  .mod-dialog[open] { animation: mod-dialog-in var(--motion-duration-base) var(--motion-easing-shadow); }
  @keyframes mod-dialog-in { from { opacity: 0; translate: 0 calc(var(--space-1) * -1); } }
}

/* reveal + grid-draw animations — staggered fade-in on first paint */
@media (prefers-reduced-motion: no-preference) {
  .mod-animate-grid { animation: mod-grid-draw var(--motion-duration-slow) var(--motion-easing-main) both; }
  @keyframes mod-grid-draw { from { opacity: 0; } }
  .mod-animate-reveal {
    animation: mod-reveal-rise var(--motion-duration-slow) var(--motion-easing-main) both;
    animation-delay: var(--mod-reveal-delay, 0ms);
  }
  @keyframes mod-reveal-rise { from { opacity: 0; transform: translateY(var(--space-1)); } }
}
[hx-get] .mod-animate-reveal { animation: none; }
.mod-animate-reveal:nth-child(1) { --mod-reveal-delay: 0ms; }
.mod-animate-reveal:nth-child(2) { --mod-reveal-delay: 50ms; }
.mod-animate-reveal:nth-child(3) { --mod-reveal-delay: 100ms; }
.mod-animate-reveal:nth-child(4) { --mod-reveal-delay: 150ms; }
.mod-animate-reveal:nth-child(5) { --mod-reveal-delay: 200ms; }
.mod-animate-reveal:nth-child(6) { --mod-reveal-delay: 250ms; }
.mod-animate-reveal:nth-child(7) { --mod-reveal-delay: 300ms; }
.mod-animate-reveal:nth-child(8) { --mod-reveal-delay: 350ms; }

@media (prefers-reduced-motion: reduce) {
  .mod-toast { animation: none; }
  .mod-toast::after { animation: none; }
  .mod-button.htmx-request { opacity: .6; }
  .mod-button.htmx-request::after { display: none; }
  .mod-progress-line[data-run] { opacity: 1; transform: scaleX(1); }
}

.mod-meter {
  position: relative; height: var(--space-0-5); width: 100%;
  background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border-subtle);
}
.mod-meter__fill {
  position: absolute; inset-block: 0; inset-inline-start: 0;
  background: var(--color-accent);
  transition: inline-size var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-status-light {
  display: inline-flex; align-items: center; gap: var(--space-0-5);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-muted);
}
.mod-status-light::before {
  content: ""; inline-size: var(--space-0-75); block-size: var(--space-0-75);
  border-radius: 50%; background: transparent;
  border: var(--border-width) solid var(--color-text-muted);
}
.mod-status-light--on { color: var(--color-accent-text); }
.mod-status-light--on::before { background: var(--color-accent); border-color: var(--color-accent); }
.mod-media-tile {
  position: relative; display: block; inline-size: 100%; aspect-ratio: 16 / 10;
  overflow: hidden; background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border);
}
.mod-media-tile img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.mod-media-tile__duration {
  position: absolute; inset-block-end: var(--space-0-5); inset-inline-end: var(--space-0-5);
  padding: 0 var(--space-0-5); background: var(--color-bg-popup);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
}
.mod-date-switch { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-0-5); }
.mod-date-switch__link {
  padding: var(--space-0-25) var(--space-1); font-family: var(--font-family-mono);
  font-size: var(--font-size-12); color: var(--color-text-muted); text-decoration: none;
  border-block-end: var(--border-width) solid transparent;
}
.mod-date-switch__link:hover { color: var(--color-text-primary); border-block-end-color: var(--color-border); }
.mod-date-switch__link--active { color: var(--color-accent); border-block-end-color: var(--color-accent); }
.mod-disclosure { border-block-start: var(--border-width) solid var(--color-border-subtle); }
.mod-disclosure__summary {
  cursor: pointer; padding: var(--space-1) 0; list-style: none;
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-secondary);
}
.mod-disclosure__summary::-webkit-details-marker { display: none; }
.mod-disclosure__summary::before { content: "+ "; color: var(--color-accent); }
.mod-disclosure[open] > .mod-disclosure__summary::before { content: "− "; }

/* completeness gate — a contract the eye cannot miss. One per thing a surface
   needs before it counts as done. Pending stays quiet, met goes green, missed
   goes red: a surface that closed without being met reads as closed, never as
   broken. Bigger than .mod-status-light on purpose — the light annotates, the
   gate is the verdict. */
.mod-gate {
  display: flex; align-items: flex-start; gap: var(--space-1-25); min-width: 0;
  padding: var(--space-1-25) var(--space-1-5);
  background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border-subtle);
  box-shadow: inset 3px 0 0 var(--color-border);
  transition: box-shadow var(--motion-duration-base) var(--motion-easing-main),
              border-color var(--motion-duration-base) var(--motion-easing-main);
}
.mod-gate__mark {
  inline-size: var(--space-2); block-size: var(--space-2); flex-shrink: 0;
  margin-block-start: 2px; display: grid; place-content: center;
  border: var(--border-width) solid var(--color-text-muted);
  transition: border-color var(--motion-duration-base) var(--motion-easing-main);
}
.mod-gate__mark::before {
  content: ""; inline-size: var(--space-1); block-size: var(--space-1);
  background: transparent;
  transition: background var(--motion-duration-base) var(--motion-easing-main);
}
.mod-gate__body { display: flex; flex-direction: column; gap: var(--space-0-25); min-width: 0; }
.mod-gate__label {
  font-family: var(--font-family-mono); font-size: var(--font-size-12);
  font-weight: var(--font-weight-medium); letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-secondary);
}
.mod-gate__detail { font-size: var(--font-size-12); color: var(--color-text-muted); line-height: 1.45; }
.mod-gate--met {
  border-color: color-mix(in srgb, var(--color-state-ok) 35%, var(--color-border-subtle));
  box-shadow: inset 3px 0 0 var(--color-state-ok);
}
.mod-gate--met .mod-gate__mark { border-color: var(--color-state-ok); }
.mod-gate--met .mod-gate__mark::before { background: var(--color-state-ok); }
.mod-gate--met .mod-gate__label { color: var(--color-state-ok); }
.mod-gate--missed {
  border-color: color-mix(in srgb, var(--color-state-error) 35%, var(--color-border-subtle));
  box-shadow: inset 3px 0 0 var(--color-state-error);
}
.mod-gate--missed .mod-gate__mark { border-color: var(--color-state-error); }
.mod-gate--missed .mod-gate__label { color: var(--color-state-error); }

/* state row — a bordered box that carries its verdict as an inset left bar. The
   same three pixels .mod-frame--drift, .mod-gate and .mod-alert already draw, made
   a component because mod-report hand-wrote it eight times in one stylesheet: work
   rows, post drafts, media stages, the day bar and the chosen issue. Pending keeps
   the bar transparent, so a row that has not been judged yet reads as untouched
   rather than as neutral-good. */
.mod-state-row {
  --mod-state: transparent;
  position: relative;
  background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border-subtle);
  box-shadow: inset 3px 0 0 var(--mod-state);
  transition: box-shadow var(--motion-duration-fast) var(--motion-easing-main),
              border-color var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-state-row:focus-within {
  outline: 2px solid transparent; outline-offset: -2px;
  --mod-state: var(--color-accent); border-color: var(--color-border);
}
.mod-state-row--accent { --mod-state: var(--color-accent); }
.mod-state-row--ok     { --mod-state: var(--color-state-ok); }
.mod-state-row--muted  { --mod-state: var(--color-text-muted); }
.mod-state-row--warn {
  --mod-state: var(--color-state-warn);
  border-color: color-mix(in srgb, var(--color-state-warn) 40%, var(--color-border-subtle));
}
.mod-state-row--error {
  --mod-state: var(--color-state-error);
  border-color: color-mix(in srgb, var(--color-state-error) 35%, var(--color-border-subtle));
}
.mod-state-row--blank { border-style: dashed; }

/* media stage — one queued file between the drop zone and the post it belongs to.
   State lives on data-state, not a class, because the uploader owns the value and
   the stylesheet only reads it. */
.mod-media-stages {
  list-style: none; display: grid; gap: var(--space-1-25);
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}
.mod-media-stages:empty { display: none; }
.mod-media-stage {
  display: flex; flex-direction: column; gap: var(--space-0-5);
  padding: var(--space-0-75);
}
.mod-media-stage[data-state="ready"]  { --mod-state: var(--color-state-ok); }
.mod-media-stage[data-state="failed"] {
  --mod-state: var(--color-state-error);
  border-color: color-mix(in srgb, var(--color-state-error) 40%, var(--color-border-subtle));
}
.mod-media-stage__name {
  font-size: var(--font-size-12); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mod-media-stage__state {
  margin: 0; font-family: var(--font-family-mono); font-size: var(--font-size-11);
  color: var(--color-text-muted); overflow-wrap: anywhere; line-height: 1.4;
}
.mod-media-stage__state--warn { color: var(--color-state-error); }
.mod-media-stage__actions { display: flex; flex-wrap: wrap; gap: var(--space-0-5); }

/* combobox — a text input that filters a list of real records. The listbox is
   positioned against the input rather than the page, so it stays with the field
   inside a scrolling panel; state is carried on aria-expanded and aria-activedescendant,
   never on a class the screen reader cannot see. */
.mod-combobox { position: relative; }
.mod-combobox__results {
  position: absolute; inset-inline: 0; top: calc(100% + 2px); z-index: var(--z-index-popover);
  max-height: 17rem; overflow-y: auto; list-style: none;
  background: var(--color-bg-popup); border: var(--border-width) solid var(--color-border);
  box-shadow: var(--shadow-composite-popup);
}
.mod-combobox__results[hidden] { display: none; }
.mod-combobox__option {
  display: flex; flex-direction: column; gap: var(--space-0-25); cursor: pointer;
  padding: var(--space-0-75) var(--space-1-25);
  border-inline-start: 3px solid transparent;
}
.mod-combobox__option--active { background: var(--color-bg-raised); border-inline-start-color: var(--color-accent); }
.mod-combobox__option-context {
  font-family: var(--font-family-mono); font-size: var(--font-size-11); letter-spacing: .04em;
  color: var(--color-text-muted);
}
.mod-combobox__option--active .mod-combobox__option-context { color: var(--color-accent-text); }
.mod-combobox__option-title {
  font-size: var(--font-size-14); color: var(--color-text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mod-combobox__status {
  display: block; margin-top: var(--space-0-75);
  font-size: var(--font-size-12); color: var(--color-text-muted);
}
.mod-combobox__status[hidden] { display: none; }
.mod-combobox__status--warn  { color: var(--color-state-warn); }
.mod-combobox__status--error { color: var(--color-state-error); }

/* segmented control — two or three mutually exclusive options where the choice
   is part of the sentence the row makes, so a select would hide it. State lives
   on aria-pressed, never on a class the screen reader cannot see. */
.mod-segment {
  display: inline-flex; flex-shrink: 0;
  block-size: var(--control-height-sm);
  background: var(--color-bg-raised);
  border: var(--border-width) solid var(--color-border);
}
.mod-segment__option {
  appearance: none; cursor: pointer; background: transparent; border: 0;
  height: 100%; padding: 0 var(--space-1-25);
  font-family: var(--font-family-mono); font-size: var(--font-size-11);
  font-weight: var(--font-weight-medium); letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-muted); white-space: nowrap;
  transition: background var(--motion-duration-fast) var(--motion-easing-main),
              color var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-segment__option + .mod-segment__option { border-inline-start: var(--border-width) solid var(--color-border-subtle); }
.mod-segment__option:hover:not(:disabled) { color: var(--color-text-primary); background: var(--color-bg-sunken); }
.mod-segment__option[aria-pressed="true"] { background: var(--color-accent-strong); color: var(--color-text-on-accent); }
.mod-segment__option:disabled { opacity: .4; cursor: not-allowed; }
.mod-segment__option:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* range — the one slider. Square track, square thumb: the native control is the only
   round thing the platform would give us, and nothing else in the system is round.
   Sits on the small control box so it lines up with inputs and buttons in a row. */
.mod-range {
  -webkit-appearance: none; appearance: none;
  inline-size: 100%; min-inline-size: 0; block-size: var(--control-height-sm);
  margin: 0; padding: 0; background: transparent; cursor: pointer;
  accent-color: var(--color-accent);
}
.mod-range::-webkit-slider-runnable-track {
  block-size: var(--range-track-size); background: var(--color-bg-sunken);
  border: var(--border-width) solid var(--color-border-subtle);
}
.mod-range::-moz-range-track {
  block-size: var(--range-track-size); background: var(--color-bg-sunken);
  border: var(--border-width) solid var(--color-border-subtle);
}
.mod-range::-moz-range-progress { block-size: var(--range-track-size); background: var(--color-accent); }
.mod-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  inline-size: var(--range-thumb-size); block-size: var(--range-thumb-size);
  margin-block-start: calc((var(--range-track-size) + var(--border-width) * 2 - var(--range-thumb-size)) / 2);
  background: var(--color-accent); border: 2px solid var(--color-bg-raised); cursor: pointer;
}
.mod-range::-moz-range-thumb {
  inline-size: var(--range-thumb-size); block-size: var(--range-thumb-size); border-radius: 0;
  background: var(--color-accent); border: 2px solid var(--color-bg-raised); cursor: pointer;
}
.mod-range:disabled { accent-color: var(--color-text-disabled); cursor: not-allowed; }
.mod-range:disabled::-webkit-slider-thumb { background: var(--color-text-disabled); }
.mod-range:disabled::-moz-range-thumb { background: var(--color-text-disabled); }
.mod-range:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* meter states — a fill that means trouble stops being accent-coloured */
.mod-meter__fill--ok    { background: var(--color-state-ok); }
.mod-meter__fill--warn  { background: var(--color-state-warn); }
.mod-meter__fill--error { background: var(--color-state-error); }

/* drop zone — a file target that is also the file button, so keyboard and touch
   reach it without a separate control. The input stays focusable, never hidden
   from the accessibility tree. */
.mod-drop-zone {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: var(--space-0-5); text-align: center;
  padding: var(--space-2-5) var(--space-1-5);
  background: var(--color-bg-sunken);
  border: var(--border-width) dashed var(--color-border);
  color: var(--color-text-muted); font-size: var(--font-size-12); cursor: pointer;
  transition: background var(--motion-duration-fast) var(--motion-easing-main),
              border-color var(--motion-duration-fast) var(--motion-easing-main),
              color var(--motion-duration-fast) var(--motion-easing-main);
}
.mod-drop-zone:hover, .mod-drop-zone:focus-within { border-color: var(--color-accent); color: var(--color-text-secondary); }
.mod-drop-zone[data-dragging] {
  border-color: var(--color-accent); color: var(--color-text-primary);
  background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg-sunken));
}
.mod-drop-zone__verb {
  font-family: var(--font-family-mono); font-size: var(--font-size-12);
  font-weight: var(--font-weight-medium); letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-secondary);
}
.mod-drop-zone__input {
  position: absolute; inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* read-only region — a surface that is closed, not broken. Accent drains to a
   neutral so ticks, meters, links and focus bars stop inviting input; nothing
   inside turns red, because being closed is not a fault. */
.mod-readonly {
  --color-accent: var(--color-text-muted);
  --color-accent-text: var(--color-text-muted);
  --color-accent-hover: var(--color-text-secondary);
}

/* forced colors — Windows High Contrast and friends replace the whole palette and
   drop box-shadow, background-image and most backgrounds outright. Everything this
   system says with a three-pixel inset bar, a tinted row or a filled square
   therefore says nothing at all there. These rules restate each of those marks as a
   border, which the forced palette does repaint, so a warning row still reads as a
   warning and a ticked checkbox still reads as ticked. */
@media (forced-colors: active) {
  .mod-state-row,
  .mod-gate,
  .mod-stat-tile,
  .mod-frame--drift,
  .mod-table__row--warning,
  .mod-table__row--critical {
    border-inline-start: 3px solid CanvasText;
  }
  .mod-state-row--ok, .mod-state-row--accent,
  .mod-gate--met,
  .mod-stat-tile--ok,
  .mod-media-stage[data-state="ready"] { border-inline-start-color: Highlight; }
  .mod-state-row--warn, .mod-state-row--error,
  .mod-gate--missed,
  .mod-stat-tile--warn, .mod-stat-tile--error,
  .mod-frame--drift,
  .mod-media-stage[data-state="failed"],
  .mod-table__row--warning,
  .mod-table__row--critical { border-inline-start-color: LinkText; }
  .mod-state-row--blank { border-inline-start-style: dashed; }

  .mod-focus-indicator::before { background: CanvasText; }
  .mod-checkbox:checked::before { background: Highlight; forced-color-adjust: none; }
  .mod-signal, .mod-signal-dot, .mod-pill::before { forced-color-adjust: none; }
  .mod-meter__fill, .mod-palette-swatch, .mod-palette-menu button > span { forced-color-adjust: none; }
  .mod-progress-line { background: Highlight; forced-color-adjust: none; }

  .mod-input:focus,
  .mod-input-group:focus-within,
  .mod-state-row:focus-within,
  .mod-focus-indicator:focus-within { outline-color: Highlight; }
}
