/*
 * core-ui.css — the whole front end of this platform, in one file.
 *
 * ONE FILE, NO BUILD STEP. Properties are server-rendered Blade on a small
 * box; a bundler would put a node toolchain, a lockfile and a CI step in
 * front of every property that wants to change a colour, and the deploy
 * engine ships a git archive, not a dist/ directory. Adding a bundler is
 * the integrator's decision — this file is what it would have to beat.
 *
 * A PROPERTY RE-SKINS BY REDEFINING TOKENS, NEVER BY COPYING MARKUP. Every
 * value a designer would want to change is a custom property in :root
 * below; a property ships its own stylesheet after this one that redefines
 * the handful it cares about. Copying a component's markup into the
 * property is the failure mode this file exists to end: the copy stops
 * getting the accessibility fixes, and nobody finds out until an audit.
 *
 * THREE THEME STATES, NOT TWO. A viewer either chose light, chose dark, or
 * chose nothing — and "nothing" is the common case, where only
 * prefers-color-scheme separates the two. So: the complete light palette is
 * defined on bare :root (never inside a media query — a token whose only
 * definition lives in a @media block is undefined for everyone outside it,
 * which renders as black-on-black the first time somebody toggles), the
 * dark palette is defined twice, once under prefers-color-scheme guarded
 * against an explicit light choice and once under [data-theme="dark"] so an
 * explicit choice wins in both directions.
 *
 * CONTRAST IS CHECKED BY THE CONTRACT TEST, NOT BY EYE. UIContractTest
 * parses the token blocks below and computes WCAG contrast for every
 * text-carrying pair in BOTH themes. Changing a colour here to something
 * that fails AA turns the suite red with the ratio printed. That is the
 * only reason the numbers in this file can be trusted six months from now.
 */

/* Author display rules (notably .ui-btn) override the browser's user-agent
   [hidden] rule. Preserve the HTML hidden contract for every reusable
   component, including ineligible utility actions. */
[hidden] { display: none !important; }

/* ── Tokens: light, and the floor for everything ─────────────────────── */
:root {
  /* Colour. Semantic good/warn/critical are SEPARATE from the accent on
     purpose: a property whose brand colour is green must still be able to
     say "this failed" in red, and a design system that derives its danger
     colour from its accent cannot. */
  --ui-color-surface: #ffffff;
  --ui-color-surface-sunken: #f4f4f2;
  --ui-color-surface-raised: #ffffff;
  --ui-color-ink: #16161a;
  --ui-color-muted: #5c5c66;
  --ui-color-border: #dcdcd6;
  /* Borders that CARRY MEANING — an input's outline, a focus ring — need
     3:1 against their background to be perceivable; a hairline divider does
     not. Two tokens rather than one, because using the divider colour on a
     text field is the single most common way a form fails a contrast
     audit while looking fine to the person who built it. */
  --ui-color-border-strong: #82828a;
  --ui-color-accent: #1f5f46;
  --ui-color-accent-ink: #ffffff;
  --ui-color-accent-tint: #eaf3ee;
  --ui-color-good: #1b6b3f;
  --ui-color-good-tint: #eef5f1;
  --ui-color-warn: #7a4a00;
  --ui-color-warn-tint: #fdf3e3;
  --ui-color-critical: #a3231b;
  --ui-color-critical-tint: #fceceb;
  --ui-color-info: #5c5c66;
  --ui-color-info-tint: #eef2f7;
  --ui-color-focus: #1f5f46;

  /* Type scale. A ratio, not a pile of one-off sizes: every step is
     reachable by name, so "make this a bit bigger" cannot become a 17px
     that exists nowhere else. */
  --ui-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ui-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ui-text-xs: 0.78rem;
  --ui-text-sm: 0.875rem;
  --ui-text-base: 1rem;
  --ui-text-lg: 1.125rem;
  --ui-text-xl: 1.375rem;
  --ui-text-2xl: 1.75rem;
  --ui-leading: 1.55;
  --ui-leading-tight: 1.25;

  /* Spacing. */
  --ui-space-1: 0.25rem;
  --ui-space-2: 0.5rem;
  --ui-space-3: 0.75rem;
  --ui-space-4: 1rem;
  --ui-space-5: 1.5rem;
  --ui-space-6: 2rem;
  --ui-space-7: 3rem;

  /* Radius, shadow, and the one width that decides what a page feels
     like. --ui-container is the token a property most often changes. */
  --ui-radius-sm: 5px;
  --ui-radius-md: 8px;
  --ui-radius-lg: 12px;
  --ui-radius-pill: 999px;
  --ui-shadow-1: 0 1px 2px rgba(15, 15, 20, 0.06);
  --ui-shadow-2: 0 8px 28px rgba(15, 15, 20, 0.16);
  --ui-container: 64rem;
}

/* Dark, for a viewer who chose nothing. Guarded so an explicit light
   choice is not overridden by the operating system. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ui-color-surface: #131316;
    --ui-color-surface-sunken: #1b1b21;
    --ui-color-surface-raised: #1b1b21;
    --ui-color-ink: #ececee;
    --ui-color-muted: #a3a3ad;
    --ui-color-border: #33333c;
    --ui-color-border-strong: #75757f;
    --ui-color-accent: #7fd3ac;
    --ui-color-accent-ink: #08130e;
    --ui-color-accent-tint: #10241b;
    --ui-color-good: #6fd39a;
    --ui-color-good-tint: #12241a;
    --ui-color-warn: #e7b45a;
    --ui-color-warn-tint: #26200f;
    --ui-color-critical: #ff9a90;
    --ui-color-critical-tint: #2a1614;
    --ui-color-info: #a3a3ad;
    --ui-color-info-tint: #1b1b21;
    --ui-color-focus: #7fd3ac;
    --ui-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5);
    --ui-shadow-2: 0 8px 28px rgba(0, 0, 0, 0.6);
  }
}

/* Dark, chosen. Same values, second block — deliberately duplicated
   rather than factored into a shared class, because the two selectors
   answer different questions and CSS has no way to say "this rule, under
   either of these conditions" that also survives a viewer with no
   preference at all. */
:root[data-theme="dark"] {
  --ui-color-surface: #131316;
  --ui-color-surface-sunken: #1b1b21;
  --ui-color-surface-raised: #1b1b21;
  --ui-color-ink: #ececee;
  --ui-color-muted: #a3a3ad;
  --ui-color-border: #33333c;
  --ui-color-border-strong: #75757f;
  --ui-color-accent: #7fd3ac;
  --ui-color-accent-ink: #08130e;
  --ui-color-accent-tint: #10241b;
  --ui-color-good: #6fd39a;
  --ui-color-good-tint: #12241a;
  --ui-color-warn: #e7b45a;
  --ui-color-warn-tint: #26200f;
  --ui-color-critical: #ff9a90;
  --ui-color-critical-tint: #2a1614;
  --ui-color-info: #a3a3ad;
  --ui-color-info-tint: #1b1b21;
  --ui-color-focus: #7fd3ac;
  --ui-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5);
  --ui-shadow-2: 0 8px 28px rgba(0, 0, 0, 0.6);
}

/* Tell the browser which form-control palette to paint: without this, a
   dark page renders a white native select and a white scrollbar. */
:root { color-scheme: light; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; } }
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

/* ── Reduced motion ──────────────────────────────────────────────────
   Honoured globally rather than per-component. A vestibular trigger is
   not a component's problem to remember; the one property that has ever
   caused harm here is a transition somebody added later without reading
   this file. Near-zero rather than zero so transitionend listeners still
   fire — a 0s transition silently breaks any code waiting for one. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Page ────────────────────────────────────────────────────────────── */
.ui-page {
  margin: 0;
  background: var(--ui-color-surface);
  color: var(--ui-color-ink);
  font: var(--ui-text-base) / var(--ui-leading) var(--ui-font);
  -webkit-text-size-adjust: 100%;
}

.ui-container {
  max-width: var(--ui-container);
  margin: 0 auto;
  padding: 0 var(--ui-space-4);
}

.ui-main { padding: var(--ui-space-6) 0 var(--ui-space-7); }

.ui-header {
  border-bottom: 1px solid var(--ui-color-border);
  padding: var(--ui-space-4) 0;
}

.ui-footer {
  border-top: 1px solid var(--ui-color-border);
  padding: var(--ui-space-5) 0;
  color: var(--ui-color-muted);
  font-size: var(--ui-text-sm);
}

/* FOCUS IS VISIBLE, ALWAYS, AND IT IS NOT THE ACCENT ALONE. A ring drawn
   only in the brand colour disappears the moment a property re-skins the
   accent to something close to its surface, so the ring carries its own
   token and an offset that keeps it off the control's own edge. Never
   `outline: none` anywhere in this file: a keyboard user with no visible
   focus cannot use the page at all, and "we add it back in JS" has never
   once survived a refactor. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ui-color-focus);
  outline-offset: 2px;
  border-radius: var(--ui-radius-sm);
}

.ui-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The skip link is the first thing in the tab order and the only thing
   that makes a keyboard user's twentieth page view bearable. Visible only
   when focused — hiding it with display:none would take it out of the tab
   order, which is the same as not shipping it. */
.ui-skip {
  position: absolute;
  left: var(--ui-space-3);
  top: calc(var(--ui-space-3) * -10);
  z-index: 100;
  background: var(--ui-color-surface-raised);
  color: var(--ui-color-ink);
  border: 1px solid var(--ui-color-border-strong);
  border-radius: var(--ui-radius-sm);
  padding: var(--ui-space-2) var(--ui-space-3);
  transition: top 0.15s ease;
}
.ui-skip:focus { top: var(--ui-space-3); }

/* ── Nav ─────────────────────────────────────────────────────────────── */
.ui-nav {
  display: flex;
  align-items: center;
  gap: var(--ui-space-1);
  flex-wrap: wrap;
}

.ui-nav__link {
  text-decoration: none;
  color: var(--ui-color-muted);
  padding: var(--ui-space-1) var(--ui-space-3);
  border-radius: var(--ui-radius-sm);
  font-size: var(--ui-text-sm);
}
.ui-nav__link:hover { color: var(--ui-color-ink); }
/* The current page is marked by weight and background AS WELL AS colour:
   colour alone is invisible to a colour-blind reader and to anyone in
   forced-colours mode. aria-current does the rest for a screen reader. */
.ui-nav__link.is-current {
  background: var(--ui-color-surface-sunken);
  color: var(--ui-color-ink);
  font-weight: 600;
}
.ui-nav__end { margin-inline-start: auto; }

/* ── Button ──────────────────────────────────────────────────────────── */
.ui-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--ui-space-2);
  font: inherit;
  font-size: var(--ui-text-sm);
  line-height: var(--ui-leading-tight);
  padding: 0.5rem 1rem;
  border: 1px solid var(--ui-color-border-strong);
  border-radius: var(--ui-radius-sm);
  background: var(--ui-color-surface-raised);
  color: var(--ui-color-ink);
  text-decoration: none;
  cursor: pointer;
  /* 44px is the touch target everyone forgets; a 30px button is a button
     only for people with a mouse. */
  min-height: 2.4rem;
}
.ui-btn:hover { background: var(--ui-color-surface-sunken); }

.ui-btn--accent {
  background: var(--ui-color-accent);
  border-color: var(--ui-color-accent);
  color: var(--ui-color-accent-ink);
}
.ui-btn--accent:hover { filter: brightness(1.08); background: var(--ui-color-accent); }

.ui-btn--danger { border-color: var(--ui-color-critical); color: var(--ui-color-critical); }
.ui-btn--danger:hover { background: var(--ui-color-critical-tint); }

/* A quiet button is still a button: it keeps the padding and the target
   size, and loses only the box. A bare <a> styled as an action is how a
   destructive control ends up with a 14px hit area. */
.ui-btn--quiet {
  border-color: transparent;
  background: none;
  color: var(--ui-color-muted);
  text-decoration: underline;
}
.ui-btn--quiet:hover { background: none; color: var(--ui-color-ink); }

.ui-btn[disabled],
.ui-btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Busy is not a spinner, it is a STATE. aria-busy tells a screen reader,
   the dots tell everyone else, and the component disables the control —
   a "submitting…" label on a button that still submits is a double
   charge waiting to happen. */
.ui-btn[aria-busy="true"]::after {
  content: "";
  width: 0.7em;
  height: 0.7em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: ui-spin 0.7s linear infinite;
}
@keyframes ui-spin { to { transform: rotate(360deg); } }

/* ── Link ────────────────────────────────────────────────────────────── */
.ui-link {
  color: var(--ui-color-accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.ui-link:hover { color: var(--ui-color-ink); }
.ui-link--plain { color: inherit; text-decoration: none; }
.ui-link--plain:hover { text-decoration: underline; }

/* ── Card ────────────────────────────────────────────────────────────── */
.ui-card {
  border: 1px solid var(--ui-color-border);
  border-radius: var(--ui-radius-lg);
  background: var(--ui-color-surface-raised);
  box-shadow: var(--ui-shadow-1);
  padding: var(--ui-space-5);
}
.ui-card--flush { padding: 0; overflow: hidden; }
.ui-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--ui-space-4);
  flex-wrap: wrap;
  margin-bottom: var(--ui-space-3);
}
.ui-card__title { font-size: var(--ui-text-lg); margin: 0; }
.ui-card__sub { color: var(--ui-color-muted); font-size: var(--ui-text-sm); margin: 0; }

/* ── Form ────────────────────────────────────────────────────────────── */
.ui-field { display: block; margin-bottom: var(--ui-space-4); }
.ui-label {
  display: block;
  font-weight: 600;
  font-size: var(--ui-text-sm);
  margin-bottom: var(--ui-space-1);
}
.ui-label__optional { font-weight: 400; color: var(--ui-color-muted); }
.ui-hint { color: var(--ui-color-muted); font-size: var(--ui-text-sm); margin: 0 0 var(--ui-space-1); }
.ui-error { color: var(--ui-color-critical); font-size: var(--ui-text-sm); margin: var(--ui-space-1) 0 0; }

.ui-control {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: var(--ui-text-base);
  padding: 0.5rem 0.6rem;
  color: var(--ui-color-ink);
  background: var(--ui-color-surface);
  border: 1px solid var(--ui-color-border-strong);
  border-radius: var(--ui-radius-sm);
  min-height: 2.4rem;
}
.ui-control[aria-invalid="true"] { border-color: var(--ui-color-critical); }
.ui-control[disabled] { background: var(--ui-color-surface-sunken); color: var(--ui-color-muted); }
textarea.ui-control { min-height: 6rem; resize: vertical; }

.ui-check {
  display: flex;
  align-items: flex-start;
  gap: var(--ui-space-2);
  margin-bottom: var(--ui-space-2);
  font-size: var(--ui-text-sm);
}
.ui-check input { margin-top: 0.2rem; width: 1rem; height: 1rem; accent-color: var(--ui-color-accent); }

/* ── Table ───────────────────────────────────────────────────────────── */
/* The scroller is not decoration. A table wider than the viewport that
   cannot scroll inside its own box makes the WHOLE PAGE scroll sideways,
   and on a phone that means every paragraph on the page is half off
   screen. */
.ui-table-scroll { overflow-x: auto; }
.ui-table { width: 100%; border-collapse: collapse; font-size: var(--ui-text-sm); }
.ui-table th,
.ui-table td {
  padding: var(--ui-space-2) var(--ui-space-3);
  text-align: start;
  border-bottom: 1px solid var(--ui-color-border);
}
.ui-table th {
  font-size: var(--ui-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ui-color-muted);
  font-weight: 600;
}
.ui-table .ui-num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ui-table__empty { padding: var(--ui-space-6) var(--ui-space-3); text-align: center; color: var(--ui-color-muted); }

/* ── Badge ───────────────────────────────────────────────────────────── */
.ui-badge {
  display: inline-block;
  font-size: var(--ui-text-xs);
  line-height: 1.6;
  padding: 0 var(--ui-space-2);
  border-radius: var(--ui-radius-pill);
  background: var(--ui-color-surface-sunken);
  color: var(--ui-color-muted);
}
.ui-badge--good { background: var(--ui-color-good-tint); color: var(--ui-color-good); }
.ui-badge--warn { background: var(--ui-color-warn-tint); color: var(--ui-color-warn); }
.ui-badge--critical { background: var(--ui-color-critical-tint); color: var(--ui-color-critical); }
.ui-badge--accent { background: var(--ui-color-accent-tint); color: var(--ui-color-accent); }

/* ── Notice ──────────────────────────────────────────────────────────── */
.ui-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--ui-space-3);
  border: 1px solid var(--ui-color-border);
  border-inline-start-width: 3px;
  border-radius: var(--ui-radius-md);
  background: var(--ui-color-info-tint);
  padding: var(--ui-space-3) var(--ui-space-4);
  margin-bottom: var(--ui-space-4);
  font-size: var(--ui-text-sm);
}
.ui-notice__body { flex: 1; }
.ui-notice__title { font-weight: 650; margin: 0 0 var(--ui-space-1); }
.ui-notice--info { border-inline-start-color: var(--ui-color-info); background: var(--ui-color-info-tint); }
.ui-notice--good { border-inline-start-color: var(--ui-color-good); background: var(--ui-color-good-tint); }
.ui-notice--warn { border-inline-start-color: var(--ui-color-warn); background: var(--ui-color-warn-tint); }
.ui-notice--critical { border-inline-start-color: var(--ui-color-critical); background: var(--ui-color-critical-tint); }

/* ── Empty state ─────────────────────────────────────────────────────── */
.ui-empty {
  border: 1px dashed var(--ui-color-border-strong);
  border-radius: var(--ui-radius-lg);
  padding: var(--ui-space-6) var(--ui-space-4);
  text-align: center;
  color: var(--ui-color-muted);
}
.ui-empty__title { color: var(--ui-color-ink); font-size: var(--ui-text-lg); margin: 0 0 var(--ui-space-2); }

/* ── Pagination ──────────────────────────────────────────────────────── */
.ui-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ui-space-3);
  margin-top: var(--ui-space-5);
  font-size: var(--ui-text-sm);
}
.ui-pagination__position { color: var(--ui-color-muted); }

/* ── Definition list ─────────────────────────────────────────────────── */
.ui-dl { margin: 0; display: grid; gap: var(--ui-space-3); }
@media (min-width: 34rem) {
  .ui-dl { grid-template-columns: minmax(8rem, 14rem) 1fr; gap: var(--ui-space-2) var(--ui-space-4); }
}
.ui-dl dt { color: var(--ui-color-muted); font-size: var(--ui-text-sm); }
.ui-dl dd { margin: 0; }
/* An unknown value is an em dash with a screen-reader word behind it, and
   it is a DIFFERENT thing from a zero. The platform's fourth law lives in
   this rule: null means could-not-know, and a detail page that prints 0
   for a figure nobody could take is the confident lie the law exists to
   forbid. */
.ui-dl dd .ui-unknown { color: var(--ui-color-muted); }

/* ── Modal ───────────────────────────────────────────────────────────── */
/* :target, not JavaScript. The modal opens because the URL says so, which
   means it works with JS off, survives a back button, and can be linked
   to. The script beside it only adds Escape-to-close and focus movement —
   if it never runs, every modal still opens and still closes. */
.ui-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 50;
  align-items: center;
  justify-content: center;
  padding: var(--ui-space-4);
  background: rgba(16, 16, 20, 0.5);
}
.ui-modal:target { display: flex; }
/* Set by Escape and by a backdrop click, cleared on the next in-page
   navigation. See partials/behaviour.blade.php for why the URL is left
   alone: rewriting it does not reliably recompute :target, and clearing
   the hash pushes a history entry that makes Back reopen the dialog. */
.ui-modal.is-closed { display: none; }
.ui-modal__panel {
  background: var(--ui-color-surface-raised);
  color: var(--ui-color-ink);
  border: 1px solid var(--ui-color-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-2);
  max-width: 34rem;
  width: 100%;
  max-height: 80vh;
  overflow-y: auto;
  padding: var(--ui-space-5);
}
.ui-modal--wide .ui-modal__panel { max-width: 46rem; }
.ui-modal__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--ui-space-4);
  margin-bottom: var(--ui-space-3);
}
.ui-modal__title { margin: 0; font-size: var(--ui-text-lg); }
.ui-modal__actions {
  display: flex;
  gap: var(--ui-space-2);
  justify-content: flex-end;
  margin-top: var(--ui-space-4);
  flex-wrap: wrap;
}

/* ── Small helpers the layouts lean on ───────────────────────────────── */
.ui-stack > * + * { margin-top: var(--ui-space-4); }
.ui-actions { display: flex; gap: var(--ui-space-2); align-items: center; flex-wrap: wrap; }
.ui-mono { font-family: var(--ui-font-mono); font-size: 0.9em; }
.ui-muted { color: var(--ui-color-muted); }
.ui-h1 { font-size: var(--ui-text-2xl); line-height: var(--ui-leading-tight); margin: 0; }
.ui-h2 { font-size: var(--ui-text-xl); line-height: var(--ui-leading-tight); margin: var(--ui-space-6) 0 var(--ui-space-3); }
.ui-h3 { font-size: var(--ui-text-lg); line-height: var(--ui-leading-tight); margin: 0; }
.ui-grid { display: grid; gap: var(--ui-space-4); }
@media (min-width: 40rem) {
  .ui-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .ui-grid--3 { grid-template-columns: repeat(3, 1fr); }
}

/* ── Utility workbench ── */
.ui-utility-workbench { display: grid; gap: var(--ui-space-5); }
.ui-utility-input__control { min-height: 14rem; font-family: var(--ui-font-mono); }
.ui-utility-input__meter {
  display: flex;
  justify-content: flex-end;
  gap: var(--ui-space-4);
  margin-top: var(--ui-space-1);
  color: var(--ui-color-muted);
  font-size: var(--ui-text-sm);
  font-variant-numeric: tabular-nums;
}
.ui-utility-profile { display: flex; gap: var(--ui-space-2); flex-wrap: wrap; margin: 0; }
.ui-utility-profile span { color: var(--ui-color-muted); }
.ui-utility-profile output { font-weight: 650; }
.ui-utility-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ui-space-3);
  flex-wrap: wrap;
}
.ui-utility-actions__controls { display: flex; gap: var(--ui-space-2); flex-wrap: wrap; }
.ui-utility-actions__status { color: var(--ui-color-muted); }
.ui-utility-export-control {
  display: inline-flex;
  align-items: flex-start;
  flex-direction: column;
}
.ui-utility-export-control[hidden],
.ui-utility-export-control > .ui-btn[hidden] { display: none; }
.ui-utility-export-too-large {
  display: block;
  max-width: 28rem;
  margin-top: var(--ui-space-1);
  white-space: normal;
  font-size: var(--ui-text-sm);
  font-weight: 400;
  text-align: start;
}
.ui-utility-export-too-large[hidden] { display: none; }
.ui-utility-progress { display: grid; gap: var(--ui-space-2); }
.ui-utility-progress progress { width: 100%; accent-color: var(--ui-color-accent); }
.ui-utility-progress__label { font-weight: 650; }
.ui-utility-summary {
  border: 1px solid var(--ui-color-border);
  border-inline-start: 0.3rem solid var(--ui-color-info);
  border-radius: var(--ui-radius-md);
  padding: var(--ui-space-4);
}
.ui-utility-summary--good { border-inline-start-color: var(--ui-color-good); }
.ui-utility-summary--warn { border-inline-start-color: var(--ui-color-warn); }
.ui-utility-summary--critical { border-inline-start-color: var(--ui-color-critical); }
.ui-utility-summary__title { margin: 0 0 var(--ui-space-3); font-size: var(--ui-text-xl); }
.ui-utility-summary__facts { display: grid; gap: var(--ui-space-2); margin: 0; }
.ui-utility-summary__facts > div { display: flex; justify-content: space-between; gap: var(--ui-space-3); }
.ui-utility-summary__facts dt { color: var(--ui-color-muted); }
.ui-utility-summary__facts dd { margin: 0; font-weight: 650; }
.ui-utility-coverage__list { list-style: none; padding: 0; display: grid; gap: var(--ui-space-2); }
.ui-utility-coverage__list li { display: flex; align-items: flex-start; gap: var(--ui-space-2); }
.ui-utility-coverage__state {
  flex: 0 0 0.75rem;
  width: 0.75rem;
  height: 0.75rem;
  margin-top: 0.35rem;
  border: 2px solid currentColor;
  border-radius: 50%;
}
.ui-utility-coverage__state[data-state="inspected"],
.ui-utility-coverage__state[data-state="not_present"] { color: var(--ui-color-good); background: currentColor; }
.ui-utility-coverage__state[data-state="partially_inspected"] { color: var(--ui-color-warn); background: currentColor; }
.ui-utility-coverage__state[data-state="unsupported"],
.ui-utility-coverage__state[data-state="not_inspected"],
.ui-utility-coverage__state[data-state="not_applicable"] { color: var(--ui-color-muted); }
.ui-utility-coverage__state[data-state="failed"] { color: var(--ui-color-critical); }
.ui-utility-findings { display: grid; gap: var(--ui-space-3); }
.ui-utility-finding {
  border: 1px solid var(--ui-color-border);
  border-inline-start: 0.25rem solid var(--ui-color-info);
  border-radius: var(--ui-radius-md);
  padding: var(--ui-space-4);
}
.ui-utility-finding--review { border-inline-start-color: var(--ui-color-warn); }
.ui-utility-finding--high { border-inline-start-color: var(--ui-color-critical); }
.ui-utility-finding__head { display: flex; justify-content: space-between; gap: var(--ui-space-3); flex-wrap: wrap; }
.ui-utility-evidence,
.ui-utility-before-after pre {
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--ui-color-surface-sunken);
  border-radius: var(--ui-radius-sm);
  padding: var(--ui-space-3);
}
.ui-utility-before-after { display: grid; gap: var(--ui-space-3); }
.ui-utility-receipt__list { display: grid; gap: var(--ui-space-2); }
.ui-utility-receipt__list li { padding-inline-start: var(--ui-space-1); }
.ui-utility-receipt__list span { display: block; color: var(--ui-color-muted); }
.ui-utility-limitations {
  border: 1px solid var(--ui-color-border);
  border-radius: var(--ui-radius-md);
  background: var(--ui-color-surface-sunken);
  padding: var(--ui-space-4);
}
.ui-utility-result { display: grid; gap: var(--ui-space-4); min-width: 0; }
.ui-utility-result:empty { display: none; }
.ui-utility-result [data-utility-view] { min-width: 0; }
/* An evidence excerpt is a <pre>, so it does not wrap by default and a long
   line — a base64 run, a URL, a pasted paragraph — pushes the whole document
   sideways. `pre-wrap` keeps the excerpt's own whitespace, which is part of
   the evidence, while `anywhere` breaks a run that has nowhere else to break. */
.ui-utility-visible-excerpt {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.ui-utility-result [data-utility-view="summary"] {
  border: 1px solid var(--ui-color-border);
  border-inline-start: 0.3rem solid var(--ui-color-info);
  border-radius: var(--ui-radius-md);
  padding: var(--ui-space-4);
}
.ui-utility-result [data-utility-view="summary"] > p { margin-top: 0; font-weight: 650; }
.ui-utility-result [data-utility-view="summary"] dl { display: grid; gap: var(--ui-space-2); margin: 0; }
.ui-utility-result [data-utility-view="summary"] dl > div {
  display: flex;
  justify-content: space-between;
  gap: var(--ui-space-3);
  flex-wrap: wrap;
}
.ui-utility-result [data-utility-view="summary"] dt { color: var(--ui-color-muted); }
.ui-utility-result [data-utility-view="summary"] dd { margin: 0; font-weight: 650; }
.ui-utility-result [data-utility-view="coverage"] ul,
.ui-utility-result [data-utility-view="limitations"] ul,
.ui-utility-result [data-utility-view="receipt"] ul { display: grid; gap: var(--ui-space-2); }
.ui-utility-result [data-utility-view="findings"] article {
  border: 1px solid var(--ui-color-border);
  border-inline-start: 0.25rem solid var(--ui-color-info);
  border-radius: var(--ui-radius-md);
  padding: var(--ui-space-4);
  margin-block: var(--ui-space-3);
}
.ui-utility-result [data-utility-view="findings"] article[data-severity="review"] {
  border-inline-start-color: var(--ui-color-warn);
}
.ui-utility-result [data-utility-view="findings"] article[data-severity="high"] {
  border-inline-start-color: var(--ui-color-critical);
}
.ui-utility-result pre {
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--ui-color-surface-sunken);
  border-radius: var(--ui-radius-sm);
  padding: var(--ui-space-3);
}
.ui-utility-visible-token {
  unicode-bidi: isolate;
  direction: ltr;
  white-space: nowrap;
  border: 1px solid currentColor;
  border-radius: var(--ui-radius-sm);
  padding-inline: 0.15em;
  color: var(--ui-color-info);
  background: var(--ui-color-surface);
  font: inherit;
  font-size: 0.92em;
}
.ui-utility-result [data-utility-view="changes"] > div {
  border-top: 1px solid var(--ui-color-border);
  padding-block: var(--ui-space-3);
}
.ui-utility-result [data-utility-view="changes"] > div > div { display: grid; gap: var(--ui-space-2); }
.ui-utility-result [data-utility-view="limitations"] {
  border: 1px solid var(--ui-color-border);
  border-radius: var(--ui-radius-md);
  background: var(--ui-color-surface-sunken);
  padding: var(--ui-space-4);
}
@media (min-width: 48rem) {
  .ui-utility-before-after { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ui-utility-result [data-utility-view="changes"] > div > div {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (forced-colors: active) {
  .ui-utility-summary,
  .ui-utility-finding,
  .ui-utility-limitations,
  .ui-utility-result [data-utility-view="summary"],
  .ui-utility-result [data-utility-view="findings"] article,
  .ui-utility-result [data-utility-view="limitations"] { border-width: 2px; }
}
