/* ---------------------------------------------------------------------------
 * Tokens — ported from the Conduit design system (Meridian).
 *
 * Two layers, and the split is the whole point:
 *
 *   1. THE SOURCE OF TRUTH — brand ramps and semantic roles, named exactly as
 *      the design system names them (`--foreground`, `--primary`, `--sev-high`).
 *      New work should reach for these.
 *   2. THE COMPATIBILITY LAYER — the short names the page templates already
 *      use (`--ink`, `--mut`, `--crit`), re-pointed at the semantic roles.
 *      Every existing page therefore adopts the palette without being
 *      rewritten, and pages can migrate to the real names one at a time.
 *
 * Colour discipline, carried over: severity is the only hue that means
 * urgency. The action colour is teal, the brand accent terracotta, and the
 * severity ramp is a single terracotta intensity climb — so a busy queue
 * reads as one instrument rather than a rainbow.
 * ------------------------------------------------------------------------- */
:root {
  /* ---- brand ramps ---- */
  --ink-50:#f4f4f1; --ink-100:#e6e7e3; --ink-200:#c9cac5; --ink-300:#a3a49f;
  --ink-400:#7c7d7a; --ink-500:#63645f; --ink-600:#50514f; --ink-700:#3d3e3c;
  --ink-800:#2b2c2a; --ink-900:#22231f; --ink-950:#1b1c1a;
  --sage-50:#f1f4ef; --sage-100:#e3e9df; --sage-200:#cbd4c2; --sage-300:#b0bda5;
  --sage-500:#708464; --sage-600:#5a6c52; --sage-700:#45533f;
  --paper:#fffcff;
  --orange-50:#fdf1ec; --orange-100:#f9ded1; --orange-200:#f0b99f; --orange-300:#e58f6c;
  --orange-400:#d76c46; --orange-500:#c1502b; --orange-600:#a13f21; --orange-700:#7c301a;
  --orange-800:#571f11; --orange-900:#3a1309;
  --teal-50:#eaf6f7; --teal-100:#cfeaec; --teal-200:#9dd4d8; --teal-300:#66b8c0;
  --teal-400:#3d9aa5; --teal-500:#2b7e8c; --teal-600:#226675; --teal-700:#1a4f5b;
  --teal-800:#123840; --teal-900:#0b2429;
  --amber-50:#fdf5e6; --amber-100:#f9e7c2; --amber-300:#e0ae42; --amber-500:#916a0f;
  --amber-700:#5e440a; --amber-800:#3f2d07;

  /* ---- semantic roles, light ---- */
  --background:var(--paper);
  --foreground:var(--ink-900);
  --surface:#fbf9f7;
  --card:var(--paper);
  --muted:var(--sage-50);
  --muted-foreground:var(--ink-500);
  --border:var(--ink-100);
  --border-strong:var(--ink-200);
  --ring:var(--teal-600);
  --primary:var(--teal-600);
  --primary-foreground:var(--paper);
  --primary-hover:var(--teal-700);
  --primary-subtle:var(--teal-50);
  --accent:var(--orange-600);
  --accent-subtle:var(--orange-50);
  --destructive:#a81d3c;
  --destructive-subtle:#fdeaee;
  --warning:var(--amber-500);
  --warning-subtle:var(--amber-50);
  --success:var(--sage-600);
  --success-subtle:var(--sage-50);
  --info:var(--teal-700);
  --info-subtle:var(--teal-50);

  /* Severity: one terracotta intensity ramp, low falling back to ink. */
  --sev-critical:var(--orange-700); --sev-critical-soft:var(--orange-50);
  --sev-high:var(--orange-500);     --sev-high-soft:var(--orange-100);
  --sev-medium:var(--orange-300);   --sev-medium-soft:var(--orange-50);
  --sev-low:var(--ink-300);         --sev-low-soft:var(--ink-50);
  --limited:var(--info);            --limited-soft:var(--info-subtle);

  /* ---- elevation ---- */
  --shadow-tint:80 81 79;
  --elevation-1:0 1px 2px rgb(var(--shadow-tint)/.08);
  --elevation-2:0 2px 4px rgb(var(--shadow-tint)/.08),0 1px 2px rgb(var(--shadow-tint)/.06);
  --elevation-3:0 6px 12px rgb(var(--shadow-tint)/.1),0 2px 4px rgb(var(--shadow-tint)/.06);
  --elevation-4:0 12px 24px rgb(var(--shadow-tint)/.12),0 4px 8px rgb(var(--shadow-tint)/.06);
  --elevation-5:0 24px 48px rgb(var(--shadow-tint)/.16),0 8px 16px rgb(var(--shadow-tint)/.08);

  /* ---- type, radii, spacing, motion ---- */
  --font-display:"Space Grotesk",ui-sans-serif,system-ui,sans-serif;
  --font-sans:"DM Sans",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,monospace;
  --radius-sm:2px; --radius-md:4px; --radius-lg:6px; --radius-xl:10px;
  /* Used five times (pills, the avatar, the toggle knob) and never defined,
   * so every one of them rendered square: an undefined custom property makes
   * the whole declaration invalid, and `border-radius` silently falls to 0. */
  --radius-full:999px;
  --duration-fast:140ms; --duration-base:200ms; --duration-slow:320ms;
  --ease-standard:cubic-bezier(.2,0,0,1);
  --ease-entrance:cubic-bezier(.05,.7,.1,1);
  --shell-max:1220px; --shell-gutter:24px;

  /* ---- overlays + chrome ---- */
  --scrim:rgb(34 35 31/.42);
  --header-surface:var(--paper);
  --header-translucent:color-mix(in srgb,var(--paper) 78%,transparent);
  --ops-header-surface:var(--ink-900);
  --ops-header-foreground:var(--paper);

  /* ---- compatibility layer: the names the templates already use ---- */
  --bg:var(--surface);
  --panel:var(--card);
  --ink:var(--foreground);
  --mut:var(--muted-foreground);
  --faint:var(--ink-400);
  --line:var(--border);
  --line2:var(--border-strong);
  --blue:var(--primary);
  --blue2:var(--primary-hover);
  --bluebg:var(--primary-subtle);
  --crit:var(--sev-critical);   --critbg:var(--sev-critical-soft);
  --hi:var(--sev-high);         --hibg:var(--sev-high-soft);
  --med:var(--sev-medium);      --medbg:var(--sev-medium-soft);
  --lo:var(--sev-low);          --lobg:var(--sev-low-soft);
  --ok:var(--success);          --okbg:var(--success-subtle);
  --green:var(--success);
  --sh:var(--elevation-1);
  --sh2:var(--elevation-3);
  --crit-line:color-mix(in oklab,var(--sev-critical) 30%,var(--border));
  --hdr-h:56px;
}

/* Dark. Designed, not inverted: the ramps re-point at legible weights and the
   teal action colour lifts so it still reads as the one thing you can press. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --background:var(--ink-950); --foreground:var(--paper);
    --surface:#232421; --card:#232421;
    --muted:var(--ink-800); --muted-foreground:var(--ink-300);
    --border:#3a3b38; --border-strong:#4a4b48; --ring:var(--teal-300);
    --primary:var(--teal-300); --primary-foreground:var(--teal-900);
    --primary-hover:var(--teal-200); --primary-subtle:var(--teal-800);
    --accent:var(--orange-300); --accent-subtle:var(--orange-800);
    --destructive:#f4b3c0; --destructive-subtle:#4a1c27;
    --warning:var(--amber-300); --warning-subtle:var(--amber-800);
    --success:var(--sage-300); --success-subtle:#2c322a;
    --info:var(--teal-200); --info-subtle:var(--teal-800);
    --sev-critical:var(--orange-300); --sev-critical-soft:var(--orange-900);
    --sev-high:var(--orange-400);     --sev-high-soft:var(--orange-800);
    --sev-medium:var(--orange-500);   --sev-medium-soft:var(--orange-900);
    --sev-low:var(--ink-300);         --sev-low-soft:var(--ink-800);
    --shadow-tint:0 0 0;
    --scrim:rgb(0 0 0/.64);
    --header-surface:#1f201d;
    --header-translucent:color-mix(in srgb,#1f201d 78%,transparent);
    --faint:var(--ink-400);
    --bg:var(--background); --panel:var(--card);
  }
}
:root[data-theme="dark"] {
  --background:var(--ink-950); --foreground:var(--paper);
  --surface:#232421; --card:#232421;
  --muted:var(--ink-800); --muted-foreground:var(--ink-300);
  --border:#3a3b38; --border-strong:#4a4b48; --ring:var(--teal-300);
  --primary:var(--teal-300); --primary-foreground:var(--teal-900);
  --primary-hover:var(--teal-200); --primary-subtle:var(--teal-800);
  --accent:var(--orange-300); --accent-subtle:var(--orange-800);
  --destructive:#f4b3c0; --destructive-subtle:#4a1c27;
  --warning:var(--amber-300); --warning-subtle:var(--amber-800);
  --success:var(--sage-300); --success-subtle:#2c322a;
  --info:var(--teal-200); --info-subtle:var(--teal-800);
  --sev-critical:var(--orange-300); --sev-critical-soft:var(--orange-900);
  --sev-high:var(--orange-400);     --sev-high-soft:var(--orange-800);
  --sev-medium:var(--orange-500);   --sev-medium-soft:var(--orange-900);
  --sev-low:var(--ink-300);         --sev-low-soft:var(--ink-800);
  --shadow-tint:0 0 0;
  --scrim:rgb(0 0 0/.64);
  --header-surface:#1f201d;
  --header-translucent:color-mix(in srgb,#1f201d 78%,transparent);
  --faint:var(--ink-400);
  --bg:var(--background); --panel:var(--card);
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  /* The design system's DM Sans figures: `cv05` for the single-storey a,
     `ss01` for the alternate g. Silently ignored where the face is missing. */
  font-feature-settings: "cv05", "ss01";
  font-size: 14px;
  line-height: 1.55;
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

/* Headings carry the display face; body text never does. */
h1, h2, h3, h4, h5, h6 { font-family: var(--font-display); font-weight: 600; letter-spacing: 0; }

/* Colour eases on a theme change; layout never does. */
.theme-turning * {
  transition: background-color var(--duration-base) var(--ease-standard),
              border-color var(--duration-base) var(--ease-standard),
              color var(--duration-base) var(--ease-standard),
              fill var(--duration-base) var(--ease-standard) !important;
}

/* ---------------------------------------------------------------------------
 * The three type utilities that do most of the work.
 * ------------------------------------------------------------------------- */

/* Micro-label: mono, wide, quiet. The editorial spine of the interface. */
.label-caps {
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
/* Money, reference ids and dates: mono and column-aligned. */
.tabular { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }
/* Figures that stay in the body face but still line up. */
.num { font-variant-numeric: tabular-nums; }

/* Alpine strips x-cloak once it boots. Now that a stylesheet exists this is the
 * proper way to hide a panel pre-boot; the realm selector's Variant C keeps its
 * inline `style="display: none"` instead, because that survives Alpine failing
 * to load at all — which would otherwise leave its panel permanently open. */
[x-cloak] { display: none !important; }

/* ---------------------------------------------------------------------------
 * Skip link — first focusable element on the page.
 * ------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 10px 16px;
  border-radius: 0 0 8px 0;
  background: var(--blue);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* ---------------------------------------------------------------------------
 * Header shell.
 * ------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  /* Above page content, below the menu panels this header owns (z-index 60). */
  z-index: 50;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(20, 25, 40, .04);
  font-size: 13px;
}

/* The signed-out landing page renders its own full-bleed hero and suppresses the
 * header entirely (body_class in pages/home.html.jinja). */
body.landing-signedout .site-header { display: none; }

.hdr-inner {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--hdr-h);
  /* Full-bleed bar; 24px matches the horizontal padding of every page's .wrap so
   * the brand lines up with page content. */
  padding: 0 24px;
}

.hdr-div {
  flex: none;
  width: 1px;
  height: 22px;
  margin: 0 4px;
  background: var(--line);
}

/* The header carries four forms (sign-out, realm switch, realm remove, and the
 * no-JS realm select). None of them should contribute layout margin. */
.site-header form { margin: 0; }

/* Right-hand cluster: company switcher + account menu. */
.hdr-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  min-width: 0;
}

/* ---------------------------------------------------------------------------
 * Brand + environment badge.
 * ------------------------------------------------------------------------- */
.hdr-brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: none;
  padding: 6px 6px 6px 0;
  color: var(--ink);
  font-size: 15px;
  font-weight: 750;
  letter-spacing: -.3px;
  text-decoration: none;
}
.hdr-brand:hover { color: var(--blue2); }

.hdr-mark {
  flex: none;
  width: 23px;
  height: 23px;
  color: var(--blue);
}

.env-badge {
  display: inline-flex;
  align-items: center;
  flex: none;
  height: 20px;
  padding: 0 7px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--lobg);
  color: var(--mut);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .7px;
  text-transform: uppercase;
}
/* Staging is the one non-production env that holds real-looking data, so it gets
 * a warning colour rather than the neutral one. */
.env-badge-staging {
  border-color: #f0d6bd;
  background: var(--hibg);
  color: var(--hi);
}

/* ---------------------------------------------------------------------------
 * Primary navigation.
 * ------------------------------------------------------------------------- */
.mainnav {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
}

.mainnav-link {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 11px;
  border-radius: 7px;
  color: var(--mut);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.mainnav-link:hover { background: var(--bg); color: var(--ink); }
.mainnav-link[aria-current="page"] { background: var(--bluebg); color: var(--blue2); }

/* The internal Ops console is not part of the product surface — keep it legible
 * but visually secondary to the four product destinations. */
.mainnav-link.ops-link { color: var(--faint); }
.mainnav-link.ops-link:hover,
.mainnav-link.ops-link[aria-current="page"] { color: var(--blue2); }

/* On a client's or a portfolio's page the item here is only the SECTION that
 * holds the page (the page itself is a tab in the strip below): lit, but not as
 * the page. WAI-ARIA's own value for the ancestor. */
.mainnav-link[aria-current="location"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--blue2); border-radius: 7px 7px 0 0; }

/* Admin is service-provider tooling, not org scope: a divider sets it apart. */
.mainnav-div {
  flex: none;
  width: 1px;
  height: 18px;
  margin: 0 6px;
  background: var(--line);
}
.mainnav-link.admin-link { color: var(--faint); }
.mainnav-link.admin-link:hover,
.mainnav-link.admin-link[aria-current="page"] { color: var(--blue2); }

/* ---------------------------------------------------------------------------
 * The context strip — tier two (docs/plans/two-tier-navigation.md).
 *
 * The second row of the sticky header, rendered only on a client's or a
 * portfolio's own pages: a crumb back to the section's list, the name as the
 * switcher, and (for a client) the tabs that are its pages. The header grows
 * by --strip-h when it is present, and everything that sticks beneath the
 * header (the queue dock, the tuning rail) reads --hdr-h, so that token grows
 * with it.
 * ------------------------------------------------------------------------- */
:root { --strip-h: 42px; }
:root:has(.context-strip) { --hdr-h: calc(56px + var(--strip-h)); }

.context-strip {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: var(--strip-h);
  padding: 0 24px;
  border-top: 1px solid var(--line);
  background: var(--bg);
}

.strip-crumb {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  min-width: 0;
  font-size: 13px;
}
.strip-crumb-root {
  color: var(--mut);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.strip-crumb-root:hover { color: var(--ink); }
.strip-crumb-sep { color: var(--faint); }
/* The switcher's toggle sits a little tighter here than it did in the header. */
.strip-crumb .hdr-menu-toggle,
.strip-crumb .realm-selector-toggle { height: 30px; font-weight: 700; }
/* The shared panels anchor to their right edge, which suited the header's
 * right-hand cluster. In the crumb, at the left of the row, they open to the
 * right of their toggle instead — otherwise they run off the viewport. */
.strip-crumb .hdr-menu-panel,
.strip-crumb .realm-selector-panel { left: 0; right: auto; }
.hdr-menu-item-current { color: var(--blue2); font-weight: 700; }

.strip-tabs {
  display: flex;
  align-items: stretch;
  gap: 2px;
  min-width: 0;
  align-self: stretch;
}
.strip-tab {
  display: inline-flex;
  align-items: center;
  padding: 0 11px;
  color: var(--mut);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.strip-tab:hover { color: var(--ink); }
.strip-tab[aria-current="page"] { color: var(--blue2); border-bottom-color: var(--blue2); }
.strip-tab.diag-tab { color: var(--faint); }
.strip-tab.diag-tab:hover,
.strip-tab.diag-tab[aria-current="page"] { color: var(--blue2); }

/* ---------------------------------------------------------------------------
 * Dropdown menus.
 *
 * Two mechanisms, one appearance. The account menu and the single-company
 * switcher are native <details>/<summary> — no JavaScript, native keyboard
 * support, and the enclosed remove form still works with JS disabled. The
 * multi-company switcher (Variant C) is an Alpine combobox whose DOM is pinned
 * by contract tests, so its class names are matched alongside rather than
 * changed.
 * ------------------------------------------------------------------------- */
.hdr-menu,
.realm-selector { position: relative; }

.hdr-menu-toggle,
.realm-selector-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  max-width: 280px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  /* <summary> shows a disclosure triangle by default; we draw our own caret. */
  list-style: none;
}
.hdr-menu-toggle::-webkit-details-marker { display: none; }
.hdr-menu-toggle::marker { content: ""; }

.hdr-menu-toggle:hover,
.realm-selector-toggle:hover,
.hdr-menu[open] > .hdr-menu-toggle {
  background: var(--bg);
  border-color: var(--line2);
}

.hdr-caret,
.realm-selector-toggle .chevron {
  flex: none;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4.5px solid var(--faint);
}

.hdr-menu-icon {
  flex: none;
  width: 15px;
  height: 15px;
  color: var(--mut);
}

.hdr-menu-panel,
.realm-selector-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 60;
  min-width: 268px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  box-shadow: var(--sh2);
  /* Never set `display` here — Alpine's x-show owns that property on Variant C's
   * panel, and a declaration would fight it. */
}

/* `.realm-add-more` is matched by descendant rather than given the
 * `.hdr-menu-item` class, because the render-contract tests match the literal
 * string `class="realm-add-more"` — a second class name there breaks them. */
.hdr-menu-item,
.hdr-menu-panel .realm-add-more,
.realm-selector-panel .realm-add-more {
  display: flex;
  align-items: center;
  gap: 8px;
  box-sizing: border-box;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.hdr-menu-item:hover,
.hdr-menu-panel .realm-add-more:hover,
.realm-selector-panel .realm-add-more:hover { background: var(--bg); }

.hdr-menu-sep {
  height: 1px;
  margin: 5px 4px;
  background: var(--line);
}

.hdr-menu-label {
  margin: 0;
  padding: 7px 10px 3px;
  color: var(--faint);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .6px;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------------------
 * Account menu.
 * ------------------------------------------------------------------------- */
.hdr-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .4px;
}
.hdr-avatar-lg { width: 36px; height: 36px; font-size: 13px; }
/* An invitation waiting for this address: a dot on the avatar's shoulder.
   The account menu's "N invitations waiting" line is the accessible signal;
   this is the glance (docs/plans/org-invitations-and-email.md, decision 10). */
.hdr-account-toggle { position: relative; }
.hdr-invite-dot {
  position: absolute;
  top: 2px;
  left: 24px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--crit);
  border: 2px solid var(--panel);
  box-sizing: content-box;
}
.hdr-menu-invites { font-weight: 700; color: var(--blue2); }

/* The active organization — a header link to /organizations, not a widget. */
.hdr-org {
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--mut);
  text-decoration: none;
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.hdr-org:hover { color: var(--ink); background: var(--bg); }
.hdr-org-none { color: var(--blue2); border-color: var(--bluebg); }

.hdr-account-toggle { padding-left: 5px; }

.hdr-account-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 150px;
}

.hdr-account-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px 10px;
}

.hdr-account-id {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.hdr-account-id .signin-marker {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 700;
}
.hdr-account-email {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--mut);
  font-size: 12px;
}

.role-badge {
  align-self: flex-start;
  margin-top: 5px;
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--lobg);
  color: var(--mut);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .5px;
  text-transform: uppercase;
}
.role-operator { background: var(--bluebg); color: var(--blue2); }
.role-superadmin { background: var(--okbg); color: var(--ok); }

/* ---------------------------------------------------------------------------
 * Company switcher — shared by Variant B (<details>) and Variant C (Alpine).
 * ------------------------------------------------------------------------- */
.realm-current,
.realm-selector-current-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 190px;
}

/* Variant A: no companies yet — the one call to action in the header. */
.realm-add-first {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  border-radius: 8px;
  background: var(--blue);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.realm-add-first:hover { background: var(--blue2); }

/* "Add another QuickBooks company" — a menu item inside both panels; the base
 * item styling is applied by the descendant rules above. */
.hdr-menu-panel .realm-add-more,
.realm-selector-panel .realm-add-more { color: var(--blue2); }

.realm-selector-typeahead {
  box-sizing: border-box;
  width: 100%;
  height: 32px;
  margin: 2px 0 6px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
}
.realm-selector-typeahead:focus {
  outline: 2px solid var(--blue);
  outline-offset: -1px;
  background: var(--panel);
}

#realm-list {
  margin: 0;
  padding: 0;
  max-height: 264px;
  overflow-y: auto;
  list-style: none;
}

.realm-selector-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 7px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.realm-selector-option:hover,
.realm-selector-option-highlighted { background: var(--bg); }
.realm-selector-option-current { background: var(--bluebg); color: var(--blue2); }

.realm-selector-no-matches {
  padding: 10px;
  color: var(--mut);
  font-size: 12.5px;
  list-style: none;
}

/* Per-company remove, nested inside each Variant C option row. Quiet until
 * hovered — it sits inside a row whose primary action is "switch to this one". */
.realm-selector-option .realm-remove { flex: none; margin: 0; }
.realm-selector-option .realm-remove button {
  padding: 3px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: var(--faint);
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
}
.realm-selector-option .realm-remove button:hover {
  border-color: var(--crit-line);
  background: var(--critbg);
  color: var(--crit);
}

.realm-selector-nojs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  font-size: 12.5px;
}

/* Variant B's remove affordance: a checkbox-gated danger region at the foot of
 * the panel, replacing the bare checkbox + button that used to sit in the bar. */
.hdr-menu-danger {
  margin: 0;
  padding: 9px 10px;
  border-radius: 7px;
  background: var(--critbg);
}
.hdr-menu-danger-title {
  margin: 0 0 7px;
  color: var(--crit);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .5px;
  text-transform: uppercase;
}
.hdr-menu-danger label {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 8px;
  color: var(--crit);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.hdr-menu-danger button {
  box-sizing: border-box;
  width: 100%;
  height: 30px;
  border: 1px solid var(--crit-line);
  border-radius: 7px;
  background: var(--panel);
  color: var(--crit);
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.hdr-menu-danger button:hover {
  border-color: var(--crit);
  background: var(--crit);
  color: #fff;
}

/* ---------------------------------------------------------------------------
 * Signed-out header.
 * ------------------------------------------------------------------------- */
.signin-link {
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 14px;
  border-radius: 8px;
  background: var(--blue);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.signin-link:hover { background: var(--blue2); }

/* ---------------------------------------------------------------------------
 * Focus visibility — scoped to the header so page styles keep their own rules.
 * ------------------------------------------------------------------------- */
.site-header a:focus-visible,
.site-header button:focus-visible,
.site-header summary:focus-visible,
.site-header input[type="checkbox"]:focus-visible,
.site-header select:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * Theme switch — three states in one control.
 * ------------------------------------------------------------------------- */
.theme-switch {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg);
}
.theme-switch button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 24px;
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--faint);
  cursor: pointer;
  padding: 0;
}
.theme-switch button:hover { color: var(--ink); }
.theme-switch button[aria-pressed="true"] {
  background: var(--panel);
  color: var(--ink);
  box-shadow: var(--elevation-1);
}
/* Visually hidden, still announced. */
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * Drawer shell — the sliding right-hand panel.
 *
 * Here rather than in a page's <style> because it is the visual half of
 * `/static/js/drawer.js`, which every page loads. Two surfaces open a drawer
 * (the audit catalog's configuration panel, the queue's finding detail) and a
 * third would otherwise copy these rules a third time. Only the shell lives
 * here — what a drawer *contains* stays the owning page's vocabulary, the same
 * arrangement every other fragment already has with the page that renders it.
 * ------------------------------------------------------------------------- */
.drawer { position: fixed; inset: 0; z-index: 60; visibility: hidden; pointer-events: none; }
.drawer.open { visibility: visible; pointer-events: auto; }
.drawer-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 20, 28, .34);
  opacity: 0;
  transition: opacity .22s ease;
}
.drawer.open .drawer-backdrop { opacity: 1; }
.drawer-panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: min(480px, 92vw);
  background: var(--panel);
  border-left: 1px solid var(--line);
  box-shadow: -14px 0 40px rgba(15, 20, 28, .16);
  transform: translateX(100%);
  transition: transform .24s cubic-bezier(.4, 0, .2, 1);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.drawer.open .drawer-panel { transform: translateX(0); }
/* A drawer that reads like a workpaper rather than a form needs the room. */
.drawer.wide .drawer-panel { width: min(680px, 96vw); }
.drawer-x {
  position: absolute;
  top: 12px;
  right: 14px;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--mut);
  font-size: 14px;
  cursor: pointer;
  line-height: 1;
  z-index: 2;
}
.drawer-x:hover { color: var(--ink); background: var(--lobg); }
.drawer-loading { padding: 40px 22px; color: var(--faint); font-size: 13px; }

/* ---------------------------------------------------------------------------
 * The finding record — one audit result, wherever it is read.
 *
 * Two surfaces render the same partials: the queue's slide-over drawer and the
 * record page at /audit/{id}. The vocabulary therefore lives here rather than in
 * either page, for the same reason the drawer shell does — a second copy is a
 * second thing to keep in step, and the two are meant to be indistinguishable.
 *
 * ONE RULE GOVERNS THE PALETTE: severity is the only coloured signal. A page
 * where confidence, status, roles and links all compete in colour is a page where
 * a reviewer cannot find the one number that says how much this costs. Certainty
 * is grey on purpose. The single exception is the pale wash on matched comparison
 * cells, which is doing the work of a symbol rather than of an alarm.
 * ------------------------------------------------------------------------- */

/* Cards ------------------------------------------------------------------- */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 13px;
  box-shadow: var(--sh);
  padding: 17px 22px 18px;
  margin-bottom: 14px;
}
/* Inside the drawer the panel is already a surface: cards there are separators,
   not floating objects. */
.card.flush,
.fd .card {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  border-top: 1px solid var(--line);
}
/* `.fd-scroll` already insets the panel by 18px, so a card adding its own 22px
   put the Overview tab's content and every other tab's content on two different
   left edges. That is invisible while you read one tab and obvious as a sideways
   jump when you switch — which is how it reached production. The vertical
   padding matches `.fd-sec + .fd-sec` so the two section shapes, which this
   file is otherwise stuck with, at least share a rhythm. */
.fd .card { padding: 16px 0; }
.fd .card:first-of-type { border-top: 0; padding-top: 0; }
.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.card-head h2 {
  margin: 0;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--faint);
}
.card-note { font-size: 11.5px; color: var(--faint); text-align: right; max-width: 46ch; }
.card-foot {
  margin: 13px 0 0;
  padding-top: 11px;
  border-top: 1px solid var(--line);
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--faint);
}
.card-foot a { color: var(--blue2); font-weight: 700; }
.card-foot a:hover { text-decoration: underline; }
.card p { margin: 0; font-size: 13px; line-height: 1.6; }
.card .muted { color: var(--mut); }
/* A heading *inside* a card — one tier below `.card-head h2`, and it has to look
   it. At 10px caps against the head's 10.5px caps the two were indistinguishable,
   so "Basis" read as a peer of "What it rests on" rather than as part of it, and
   the panel became one flat list. Sentence case rather than a third uppercase
   label: an eyebrow competes with the section label above it instead of sitting
   under it.

   `.fd-h` lands here when it appears inside a card, where it is a subsection. In
   `.fd-sec` the same class is a section heading and is styled as one — see the
   drawer's panel furniture. One class, two jobs, which is why both rules have to
   say which job they mean. */
.card h3.sub,
.fd .card .fd-h {
  margin: 16px 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--mut);
}
.card h3.sub:first-child,
.fd .card .fd-h:first-child { margin-top: 0; }
/* The one action the result asks for. A rule, not a colour block — it is the
   conclusion of the page, not an alarm. */
.card.next { border-left: 3px solid var(--ink); }
.mono { font-family: ui-monospace, Menlo, Consolas, monospace; }
.tscroll { overflow-x: auto; }

/* Severity, certainty, and the signal strip ------------------------------- */
.sev {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .03em;
  padding: 3px 8px;
  border-radius: 6px;
  text-transform: uppercase;
}
.sev.sev-Critical { color: #fff; background: var(--crit); }
.sev.sev-High { color: var(--crit); background: var(--critbg); }
.sev.sev-Medium { color: var(--med); background: var(--medbg); }
.sev.sev-Low { color: var(--lo); background: var(--lobg); }
.meter { display: inline-flex; gap: 2px; }
.meter i { width: 4px; height: 12px; border-radius: 1px; background: var(--line); }
/* Grey, not green: a confident wrong answer and an uncertain right one must not
   be told apart by colour. */
.meter i.f { background: var(--mut); }
.newb {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .06em;
  padding: 2px 6px;
  border-radius: 5px;
  background: var(--lobg);
  color: var(--mut);
}
.reflag {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--hi);
  background: var(--hibg);
  border-radius: 5px;
  padding: 2px 6px;
}

.fs-strip {
  display: flex;
  align-items: center;
  gap: 30px;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  margin: 0 -22px;
  padding: 13px 22px;
}
.fs-sig { display: flex; align-items: center; gap: 9px; }
.fs-label {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--faint);
}
.fs-val { font-size: 12.5px; font-weight: 700; }
.fs-val .fs-pct { color: var(--faint); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Thin history is the one place this signal raises its voice — the audit judged
   on less past than it wants, and the reviewer should weigh it accordingly. */
.fs-val.thin { color: var(--hi); }
.fs-status {
  margin-left: auto;
  font-size: 11px;
  font-weight: 750;
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 3px 11px;
  color: var(--mut);
}

/* Side-by-side comparison ------------------------------------------------- */
table.cmp { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.cmp th, table.cmp td {
  padding: 9px 11px;
  border: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
table.cmp thead th { border-top: 0; background: var(--panel); }
table.cmp thead th:first-child { border-left: 0; }
table.cmp .cmp-doc {
  display: block;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 700;
}
table.cmp .cmp-sub { display: block; font-size: 11px; color: var(--faint); margin-top: 2px; }
.cmp-field {
  width: 132px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--faint);
  border-left: 0 !important;
}
table.cmp td { font-family: ui-monospace, Menlo, Consolas, monospace; }
table.cmp tr.same td { background: rgba(33, 122, 75, .06); }
.cmp-mark {
  display: inline-block;
  width: 17px;
  height: 17px;
  line-height: 16px;
  text-align: center;
  border-radius: 50%;
  font-size: 11px;
  font-weight: 700;
  margin-right: 8px;
  border: 1px solid var(--line2);
  color: var(--mut);
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
tr.same .cmp-mark { border-color: rgba(33, 122, 75, .4); color: var(--ok); }

/* Source records ---------------------------------------------------------- */
table.recs { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.recs th {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--faint);
  text-align: left;
  padding: 7px 9px;
  border-bottom: 1px solid var(--line);
}
table.recs td { padding: 9px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.recs tr:last-child td { border-bottom: 0; }
table.recs .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.recs td.num, table.recs td.mono { font-family: ui-monospace, Menlo, Consolas, monospace; }
.rec-doc { font-weight: 700; font-family: ui-monospace, Menlo, Consolas, monospace; }
.rec-sub { color: var(--faint); font-size: 11px; margin-top: 2px; line-height: 1.4; }
.rec-missing { margin-left: 6px; font-size: 10.5px; font-weight: 700; color: var(--mut); }
/* Roles are a taxonomy, not a severity: they are told apart by weight and border,
   so the only colour on the page stays the one that means money. */
.role {
  display: inline-block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase;
  border-radius: 5px;
  padding: 2px 6px;
  white-space: nowrap;
  background: var(--lobg);
  color: var(--mut);
}
.role-subject { background: var(--ink); color: #fff; }
.role-expected { background: var(--panel); color: var(--mut); border: 1px dashed var(--line2); }
.role-offsetting { background: var(--panel); color: var(--mut); border: 1px solid var(--line2); }
tr.rr-expected td { background: #fcfcfd; }
.cites code, .fields code {
  background: var(--lobg);
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 11px;
  margin-right: 5px;
  display: inline-block;
}
.fields { margin-top: 5px; }

/* Calculation ------------------------------------------------------------- */
.measures { display: flex; gap: 22px; flex-wrap: wrap; margin: 13px 0 4px; }
.measure .mv { font-size: 14px; font-weight: 750; font-variant-numeric: tabular-nums; }
.measure .mv.key { color: var(--ink); }
.measure .ml {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--faint);
  text-transform: uppercase;
  margin-top: 2px;
}
.steps { margin: 0; padding-left: 18px; font-size: 12.5px; line-height: 1.6; color: var(--mut); }
.steps li { margin-bottom: 3px; }
.conds { list-style: none; margin: 0; padding: 0; }
.cond {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 6px 0;
  border-top: 1px dashed var(--line);
  font-size: 12.5px;
}
.cond:first-child { border-top: 0; }
.cond-mark { color: var(--mut); font-size: 11px; }
.cond.fail .cond-mark { color: var(--crit); }
.cond-name { font-weight: 700; min-width: 150px; }
.cond-val { color: var(--mut); font-variant-numeric: tabular-nums; }
/* Which config layer set the bound. "Their 15% or our 10%?" decides whether a
   result is worth arguing with, and it should not need a trip to the settings. */
.cond-src {
  margin-left: auto;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--faint);
}
.rows { margin: 11px 0 0; }
.row2 { display: grid; grid-template-columns: 160px 1fr; gap: 12px; padding: 6px 0;
  border-top: 1px dashed var(--line); }
.row2:first-child { border-top: 0; }
.row2 dt {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--faint);
}
.row2 dd { margin: 0; font-size: 12.5px; line-height: 1.5; }
.stale {
  margin-top: 11px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--hi);
  background: var(--hibg);
  border-radius: 8px;
  padding: 9px 11px;
}
.wp { margin-top: 15px; }
.wp summary { cursor: pointer; font-size: 12px; font-weight: 700; color: var(--blue2); list-style: none; }
.wp summary::-webkit-details-marker { display: none; }
.wp summary::before { content: "▸ "; color: var(--faint); }
.wp[open] summary::before { content: "▾ "; }
.stamp {
  margin-top: 11px;
  font-size: 10.5px;
  color: var(--faint);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  word-break: break-all;
}
.note {
  margin-top: 10px;
  font-size: 12px;
  color: var(--mut);
  background: var(--bg);
  border-radius: 7px;
  padding: 8px 10px;
}

/* Review controls — the same three forms on the row, the drawer and the page -- */
.wfield { margin-bottom: 8px; }
.wlabel {
  display: block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 3px;
}
.inline-edit { display: flex; gap: 5px; align-items: center; margin: 0; }
.inline-edit select,
.inline-edit input[type=date] {
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 7px;
  padding: 4px 7px;
  font-size: 11.5px;
  font-weight: 650;
  color: var(--ink);
  width: 100%;
  min-width: 0;
  max-width: 100%;
}
.inline-edit select:hover,
.inline-edit input[type=date]:hover { border-color: var(--line2); }
.inline-edit select.unassigned { color: var(--faint); }
.due-input.overdue { border-color: var(--crit-line); color: var(--crit); background: var(--critbg); }
.due-flag {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--crit);
  margin-top: 3px;
}
/* The no-JS submit button. With scripting the select self-submits, so the button
   is redundant; without it, it is the only way to save. */
.nojs-go {
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 7px;
  padding: 4px 8px;
  font-size: 11px;
  font-weight: 700;
  color: var(--mut);
  cursor: pointer;
}
@media (scripting: enabled) { .nojs-go { display: none; } }
.htmx-request .inline-edit select,
.htmx-request .inline-edit input { opacity: .5; }

/* The drawer's own frame -------------------------------------------------- */
/* An earlier drawer design used to live here: pills, a figure row, an "open"
   link, and its own copies of the head, title, meta, sub and dot rules. Its
   markup went years ago; the rules did not, and because they sat *after* the
   current ones in source order they kept winning whichever properties the live
   rules happened not to restate. That is a bad way to hold a design — nobody
   chose those values, and editing the rule you can find does nothing.

   `.fd .card { padding: 16px 22px }` was the expensive one. It quietly reinstated
   the 22px inset that put the Overview tab's content on a different left edge
   from every other tab's, and it would have overridden the fix for that from
   four hundred lines away.

   The declarations that were genuinely still doing work are folded into the live
   rules below — `border-bottom` on the head, `font-weight` on the title and sub,
   `margin-top` on the meta line, `color` on the dot — so this deletion changes
   what the stylesheet *says*, not what it draws. */
#finding-drawer-body { padding: 0 0 40px; }
.fd .fs-strip { margin: 0; }

/* ---------------------------------------------------------------------------
 * Responsive. Two steps, no framework.
 * ------------------------------------------------------------------------- */

/* Tablet: drop the two most redundant labels — the wordmark (the mark carries
 * the brand) and the account name (it repeats inside the open panel). */
@media (max-width: 1023px) {
  .hdr-wordmark { display: none; }
  .hdr-account-name { display: none; }
  .realm-current,
  .realm-selector-current-label { max-width: 130px; }
}

/* Phone: nav moves to its own scrollable row beneath the brand/actions row. */
@media (max-width: 767px) {
  .hdr-inner {
    flex-wrap: wrap;
    padding: 0 14px;
  }
  .hdr-div { display: none; }
  .hdr-actions { order: 2; }
  .mainnav {
    order: 3;
    width: 100%;
    margin: 0 -14px;
    padding: 0 14px 8px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .mainnav::-webkit-scrollbar { display: none; }
  .hdr-menu-panel,
  .realm-selector-panel {
    min-width: 0;
    width: min(320px, calc(100vw - 28px));
  }
  /* The strip: crumb and tabs on one scrollable row, no page-level overflow. */
  .context-strip {
    gap: 12px;
    padding: 0 14px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .context-strip::-webkit-scrollbar { display: none; }
  .strip-crumb .realm-current,
  .strip-crumb .realm-selector-current-label { max-width: 130px; }
}

/* ---------------------------------------------------------------------------
 * The result drawer — three tabs, a pinned dock, and the trust band between them.
 *
 * Laid out as a column with two fixed ends: the header block and the action dock
 * never scroll, because the decision has to stay reachable from every tab. Only
 * the panel between them moves. The tab rail is vertical on anything wide enough
 * to hold it and collapses to a strip above the panel below that, which is the
 * one breakpoint in here.
 *
 * Colour is spent on severity and on pass/fail, and nowhere else — the panels are
 * dense enough that a second accent would compete with the one signal that has to
 * carry.
 * ------------------------------------------------------------------------- */
.drawer.finding .drawer-panel { width: min(1080px, 98vw); padding: 0; }
.fd { display: flex; flex-direction: column; height: 100%; min-height: 0; }

/* --- the bar: where you are, and the ways out ---------------------------- */
.fd-bar {
  display: flex; align-items: center; gap: 12px; flex: none;
  padding: 9px 14px; border-bottom: 1px solid var(--line); background: var(--bg);
}
.fd-pos { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--mut); }
.fd-pos .mono { color: var(--ink); }
.fd-bar-sub { font-size: 12px; color: var(--mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-bar-acts { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.fd-ibtn {
  width: 26px; height: 26px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 5px; background: var(--bg);
  color: var(--mut); font-size: 13px; cursor: pointer;
}
.fd-ibtn:hover:not(:disabled) { color: var(--ink); border-color: var(--line2); }
.fd-ibtn:disabled { opacity: .35; cursor: default; }
.fd-full { font-size: 12px; color: var(--mut); text-decoration: none; padding: 0 4px; }
.fd-full:hover { color: var(--ink); }
.fd-close {
  font-size: 12px; color: var(--mut); background: none; border: 0; cursor: pointer;
  display: flex; align-items: center; gap: 5px;
}
.fd-close:hover { color: var(--ink); }
.fd-close kbd, .btn kbd {
  font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase;
  border: 1px solid currentColor; border-radius: 3px; padding: 0 3px; opacity: .6;
}

/* --- the head: what it is, and what it is worth -------------------------- */
/* `border-bottom`, `margin-top` and the dot's `color` are folded in from the
   superseded block that used to sit above — they were in effect, so they stay. */
.fd-head { flex: none; padding: 14px 18px 12px; border-bottom: 1px solid var(--line); }
.fd-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 7px; font-size: 12px; color: var(--mut);
}
.fd-audit { font-weight: 600; color: var(--ink); }
.fd-dot { opacity: .45; color: var(--line2); }
.fd-flag {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--med); background: var(--medbg);
  border: 1px solid color-mix(in oklab, var(--med) 30%, var(--border)); border-radius: 3px; padding: 1px 5px;
}
.fd-headline { display: flex; align-items: flex-start; gap: 20px; margin-top: 8px; }
.fd-title {
  flex: 1; min-width: 0; margin: 0;
  font-size: 19px; font-weight: 800; line-height: 1.28; letter-spacing: -.01em;
}
.fd-impact { text-align: right; flex: none; }
.fd-impactv { font-size: 19px; font-weight: 600; line-height: 1; }
.fd-impactl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mut); margin-top: 5px; }
/* Who the result is about, and where it stands. Severity / certainty / history
   are NOT here — the trust strip immediately below states all three with hints,
   and stating them twice is what made this header hard to read. */
.fd-subject { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-top: 12px; }
.fd-entity { font-size: 13.5px; font-weight: 600; }
.fd-subject .fd-sub { display: inline; margin-top: 0; }
.fd-status {
  margin-left: auto; font-size: 11.5px; color: var(--mut);
  border: 1px solid var(--line); border-radius: 999px; padding: 2px 9px;
}

/* --- the trust band: three axes, never one score ------------------------- */
.fd-trust { flex: none; border-block: 1px solid var(--line); background: var(--muted); }
.fd-trustbar { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px 26px; padding: 11px 18px; }
.fd-axis { min-width: 0; }
.fd-axisl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mut); }
.fd-axisv { font-size: 13px; font-weight: 600; margin-top: 2px; }
.fd-axisv.thin { color: var(--med); }
.fd-axish { font-size: 11.5px; color: var(--mut); margin-top: 1px; max-width: 34ch; }
.fd-trustx {
  margin-left: auto; align-self: center; background: none; border: 0; cursor: pointer;
  font-size: 12px; font-weight: 500; color: var(--primary);
}
.fd-trustd { padding: 0 18px 14px; }
.fd-legend { display: grid; gap: 10px; margin: 0; }
.fd-legend dt { font-size: 11px; text-transform: uppercase; letter-spacing: .07em; color: var(--mut); }
.fd-legend dd { margin: 2px 0 0; font-size: 12.5px; line-height: 1.5; max-width: 76ch; }

/* --- rail + panel -------------------------------------------------------- */
.fd-body { display: flex; flex: 1; min-height: 0; }
.fd-rail {
  flex: none; display: flex; border-bottom: 1px solid var(--line2);
  background: var(--muted); overflow-x: auto;
}
.fd-raill { display: none; }
.fd-tab {
  position: relative; flex: 1; display: flex; align-items: center; justify-content: center;
  gap: 8px; height: 44px; padding: 0 12px; border: 0; background: none; cursor: pointer;
  font-size: 13px; font-weight: 500; color: var(--mut); white-space: nowrap;
}
.fd-tab:hover { color: var(--ink); }
.fd-tab.on { background: var(--bg); color: var(--primary); font-weight: 700; }
.fd-tab.on::after {
  content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 3px;
  background: var(--primary);
}
.fd-tabi {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 4px;
  font-size: 12px; color: var(--mut);
}
.fd-tab.on .fd-tabi { background: var(--primary); color: #fff; }
.fd-scroll { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 22px; }
.fd-scroll > div > * + * { margin-top: 14px; }

@media (min-width: 860px) {
  .fd-rail {
    flex-direction: column; width: 158px; border-bottom: 0;
    border-inline-end: 1px solid var(--line2); overflow-x: visible;
  }
  .fd-raill {
    display: block; padding: 12px 14px; border-bottom: 1px solid var(--line);
    font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em; color: var(--mut); font-weight: 600;
  }
  .fd-tab { flex: none; justify-content: flex-start; height: 46px; padding: 0 14px; }
  .fd-tab.on::after { inset: 0 0 0 auto; width: 3px; height: auto; }
}

/* --- panel furniture ----------------------------------------------------- */
/* 14px rather than 16px so a `.fd-sec` boundary and a `.fd .card` boundary are
   the same gap: the cards take their 14px from `.fd-scroll > div > * + *` above,
   and both then add the same 16px of padding under the rule. */
.fd-sec + .fd-sec { margin-top: 14px; padding-top: 16px; border-top: 1px solid var(--line); }
.fd-h { margin: 0; font-size: 13px; font-weight: 600; }

/* A section heading, and the reason `.fd-h` above is not the whole story: the
   Overview tab built its sections from `.fd-sec` while every other tab built
   them from `.card`, so peer sections rendered at 13px sentence case on one tab
   and 10.5px caps on the next. Same tier, two looks. This settles it on the
   card's treatment because that is the app's established section label, used on
   the standalone pages too — the alternative would have been restyling every
   page to match the drawer. */
.fd-sec > .fd-h {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--faint);
  /* Matches `.card-head`'s 10px, so the gap between a section's label and its
     first line is the same in both shapes. It collapses with `.fd-p`'s 7px
     rather than adding to it. */
  margin-bottom: 10px;
}
.fd-p { margin: 7px 0 0; font-size: 13.5px; line-height: 1.6; max-width: 76ch; }
.fd-hint { font-size: 12px; color: var(--mut); }
/* `font-weight` folded in from the superseded frame block; see the note there. */
.fd-sub { display: block; font-size: 11.5px; font-weight: 700; color: var(--mut); margin-top: 1px; }
.fd-caveat {
  font-size: 12.5px; line-height: 1.55; color: var(--med);
  background: var(--medbg); border: 1px solid color-mix(in oklab, var(--med) 30%, var(--border));
  border-radius: 5px; padding: 9px 12px; margin-top: 10px;
}
.fd-facts { display: grid; gap: 10px 20px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); margin: 10px 0 0; }
.fd-facts.bordered { border-top: 1px solid var(--line); padding-top: 12px; margin-top: 12px; }
.fd-facts.tight { gap: 6px 18px; margin-top: 8px; }
.fd-facts dt { font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--mut); }
.fd-facts dd { margin: 2px 0 0; font-size: 13px; }
.fd-next { margin-top: 12px; border: 1px solid var(--line2); border-radius: 6px; padding: 10px 13px; background: var(--muted); }
.fd-nextl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mut); }
.fd-next p, .fd-note p { margin: 4px 0 0; font-size: 13px; line-height: 1.55; }
.fd-note { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
.fd-wgrid { display: flex; flex-wrap: wrap; gap: 14px 22px; margin-top: 12px; }

/* --- Overview: read on the left, decide on the right --------------------- */
/* The two halves answer different questions and are read in parallel, so they
   sit side by side once there is room. The drawer is min(1080px, 98vw) less a
   158px rail, so the breakpoint is on the viewport rather than the panel. */
.fd-cols { display: grid; gap: 16px; align-items: start; }
.fd-cols > .fd-sec + .fd-sec { margin-top: 0; padding-top: 0; border-top: 0; }
@media (min-width: 1040px) {
  .fd-cols { grid-template-columns: minmax(0, 1fr) minmax(300px, 360px); gap: 24px; }
  .fd-cols > .fd-col + .fd-col {
    border-inline-start: 1px solid var(--line); padding-inline-start: 24px;
  }
}
/* Stacked, because a column is narrower than the three fields laid in a row. */
.fd-wgrid.stacked { flex-direction: column; gap: 12px; }
.fd-wgrid.stacked .wfield { min-width: 0; }

.fd-detector {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--line);
}
.fd-detector .fd-sub { display: inline; margin-top: 0; }
.fd-detectorv { font-size: 12.5px; font-weight: 600; }

/* Reference prose: kept in full, closed by default. */
.fd-more { margin-top: 10px; }
.fd-more > summary {
  cursor: pointer; font-size: 12px; font-weight: 500; color: var(--primary);
  list-style: none;
}
.fd-more > summary::-webkit-details-marker { display: none; }
.fd-more > summary::before { content: "▸ "; font-size: 10px; }
.fd-more[open] > summary::before { content: "▾ "; }
.fd-more > summary:hover { text-decoration: underline; }
.fd-more > p { margin-top: 6px; }
.fd-empty { font-size: 12.5px; color: var(--mut); padding: 10px 0; }

/* --- the scale ----------------------------------------------------------- */
.fd-scale { padding: 18px 2px 6px; }
.fd-scaletrack { position: relative; height: 26px; }
.fd-scaletrack::before { content: ""; position: absolute; inset-inline: 0; top: 12px; height: 1px; background: var(--line2); }
.fd-scalebound { position: absolute; top: 3px; height: 20px; border-left: 1px dashed var(--line2); }
.fd-scalemark { position: absolute; top: 4px; width: 3px; height: 18px; border-radius: 2px; transform: translateX(-1.5px); }
.fd-scalemark.base { background: var(--mut); }

/* The observed mark — "this result", the whole point of the scale — was drawing
   with no background at all. `.fd-scalemark` sets no colour of its own, `.base`
   sets one, and `.obs` never had a rule: the severity class it carries is matched
   only by `.sev.sev-Critical`, which needs a `.sev` class this element does not
   have. So the one mark the reader is actually looking for was invisible, and the
   two ticks on screen were the baseline and the threshold bound.

   The swatches in the key row share this mapping rather than restating it, so the
   legend cannot drift from the thing it describes. */
.fd-scalemark.obs,
.fd-scaleswatch.obs { background: var(--ink); }
.fd-scalemark.obs.sev-Critical,
.fd-scaleswatch.obs.sev-Critical { background: var(--crit); }
.fd-scalemark.obs.sev-High,
.fd-scaleswatch.obs.sev-High { background: var(--hi); }
.fd-scalemark.obs.sev-Medium,
.fd-scaleswatch.obs.sev-Medium { background: var(--med); }
.fd-scalemark.obs.sev-Low,
.fd-scaleswatch.obs.sev-Low { background: var(--lo); }

.fd-scalekeys { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 10px; font-size: 11.5px; color: var(--mut); }

/* The marks are positioned by value; this row is a flex list. So a key never sat
   above the mark it names — "typical" printed a long way left of its own tick, and
   the reader was left to guess the pairing, which is worse than no scale at all.
   Aligning them positionally is not the fix: the positions are data, so two marks
   can land a percent apart and their labels would collide. Each key carries a
   swatch of its own mark instead — the mapping is then by appearance, and the row
   stays readable whatever the values do. */
.fd-scalekey { display: inline-flex; align-items: baseline; gap: 6px; }
.fd-scaleswatch {
  width: 3px; height: 11px; border-radius: 2px;
  flex: none; align-self: center; background: var(--mut);
}
.fd-scaleswatch.bound {
  width: 0; height: 13px; border-radius: 0; background: none;
  border-left: 1px dashed var(--line2);
}
.fd-scalekeys em { font-style: normal; color: var(--ink); font-weight: 600; }
.fd-scalekeys .strong em { font-weight: 700; }
.fd-scalenote { margin: 10px 0 0; font-size: 12px; color: var(--mut); line-height: 1.55; max-width: 76ch; }

/* --- conditions / rules -------------------------------------------------- */
.fd-conds { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.fd-conds th {
  text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--mut); font-weight: 500; padding: 8px 10px 8px 0; border-bottom: 1px solid var(--line2);
}
.fd-conds td { padding: 8px 10px 8px 0; border-bottom: 1px solid var(--line); }
.fd-conds tr:last-child td { border-bottom: 0; }
.fd-conds tr.is-headline td { background: var(--muted); font-weight: 600; }
.fd-conds .num { text-align: right; }
.fd-conds .op { color: var(--mut); text-align: center; }
.fd-conds .src { color: var(--mut); font-size: 11.5px; }
/* The bound as one readable line, under the condition it belongs to. The three
   numeric columns say the same thing precisely; this says it the way a person
   would read it aloud. */
.fd-condv { display: block; font-size: 11.5px; color: var(--mut); margin-top: 2px; }
.fd-conds .ok, .fd-reconok.ok { color: var(--ok); }
.fd-conds .no, .fd-reconok.no { color: var(--crit); font-weight: 600; }

/* --- derivation ----------------------------------------------------------
   The config / rules / suppression lists that used to live here are gone: all
   three were re-renderings of the conditions table's rows, which now carries the
   operator, the bound, the layer that set it and the `override` flag itself. */
.fd-recon, .fd-lineage, .fd-fields, .fd-bands {
  list-style: none; margin: 0; padding: 0;
}
.fd-recon li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px;
  padding: 9px 0; border-bottom: 1px solid var(--line); font-size: 12.5px;
}
.fd-recon li:last-child { border-bottom: 0; }
.fd-reconf { min-width: 168px; font-weight: 500; }
.fd-recond { color: var(--ink); }
.fd-reconp { margin-left: auto; font-size: 11.5px; color: var(--mut); }
.fd-ovr {
  font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--med); background: var(--medbg);
  border: 1px solid color-mix(in oklab, var(--med) 30%, var(--border)); border-radius: 3px; padding: 1px 5px;
  margin-left: 6px;
}
.fd-why { font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--mut); margin-left: 7px; }
.fd-reconok { font-size: 11.5px; }
.fd-stages { list-style: none; margin: 0; padding: 0; }
.fd-stages li { display: flex; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.fd-stages li:last-child { border-bottom: 0; }
.fd-stagen {
  flex: none; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%;
  background: var(--muted); font-size: 11px; color: var(--ink);
}
.fd-staged { min-width: 0; flex: 1; }
.fd-stageh { font-size: 13px; font-weight: 600; }
.fd-stagev { font-size: 13px; margin-top: 2px; }
.fd-stageb { margin: 5px 0 0; font-size: 12px; color: var(--mut); line-height: 1.55; max-width: 76ch; }
.fd-assembly { padding: 4px 0 2px; }
.fd-basis {
  margin: 7px 0 0; font-size: 12px; line-height: 1.55; padding: 8px 11px;
  background: var(--muted); border-radius: 5px; max-width: 76ch;
}
.fd-bands { display: grid; gap: 6px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin-top: 10px; }
.fd-bands li { border: 1px solid var(--line); border-radius: 5px; padding: 7px 10px; }
.fd-bands li.on { border-color: var(--line2); background: var(--muted); }
.fd-bandl { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--mut); }
.fd-bands li.on .fd-bandl { color: var(--ink); }
.fd-bandr { font-size: 12px; }
.fd-map { display: grid; gap: 7px; margin: 10px 0 0; }
.fd-map dt { font-size: 11.5px; font-weight: 600; }
.fd-map dd { margin: 1px 0 0; font-size: 12px; color: var(--mut); line-height: 1.5; }

/* --- the machine's own account, folded away ------------------------------
   Below the argument sits the derivation: how it was calculated, the steps the
   engine ran, how severity resolved, and the self-check. All of it matters when
   a result is challenged and none of it when one is merely read, so it is closed
   by default. `<details>` rather than Alpine so it still opens with no scripting. */
.fd-folds { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 4px; }
.fd-foldl {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--mut); padding: 10px 0 4px;
}
.fd-fold { border-bottom: 1px solid var(--line); }
.fd-fold:last-child { border-bottom: 0; }
.fd-fold > summary {
  cursor: pointer; list-style: none; padding: 11px 0;
  font-size: 13px; font-weight: 600; color: var(--ink);
  display: flex; align-items: baseline; gap: 8px;
}
.fd-fold > summary::-webkit-details-marker { display: none; }
.fd-fold > summary::before { content: "▸"; font-size: 10px; color: var(--mut); }
.fd-fold[open] > summary::before { content: "▾"; }
.fd-fold > summary:hover { color: var(--primary); }
.fd-foldn { margin-left: auto; font-size: 11.5px; font-weight: 400; color: var(--mut); }
.fd-fold > *:not(summary) { padding-bottom: 14px; }
/* The calculation partial brings its own card; inside a fold it would be a box
   in a box. */
.fd-fold > .card { border: 0; box-shadow: none; padding-inline: 0; margin: 0; }
/* ...and its own <h2>, directly under the summary that already names it. The
   fold's summary IS that heading, so the inner one is hidden rather than removed:
   the partial is shared with the record page, where it is the only heading the
   section has. Its card-note (the audit's purpose) still shows. */
.fd-fold > .card > .card-head > h2 { display: none; }

/* --- automation opportunities -------------------------------------------
   Cards, not buttons in a row: each carries a title, a category, a decision and
   a disclosure, and a reviewer reads down them. Styled quietly on purpose —
   these record an intention, and nothing here has fired. */
.fd-autos { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.fd-auto {
  border: 1px solid var(--line); border-radius: 7px; padding: 11px 13px; margin-top: 10px;
}
.fd-auto.on { border-color: color-mix(in oklab, var(--primary) 40%, var(--border)); }
.fd-auto.off { opacity: .62; }
.fd-autohead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.fd-autotitle { font-size: 13px; font-weight: 600; }
.fd-autotag {
  margin-left: auto; font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--mut); background: var(--lobg); border: 1px solid var(--line);
  border-radius: 3px; padding: 1px 6px; white-space: nowrap;
}
.fd-autodesc { margin: 5px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--mut); }
.fd-autostate {
  margin-top: 8px; font-size: 11.5px; color: var(--ink);
  background: var(--muted); border-radius: 4px; padding: 5px 8px;
}
.fd-autoacts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.fd-autoacts .btn[disabled] { opacity: .5; cursor: default; }

/* --- notes & activity ----------------------------------------------------
   The same dot-and-connector rail as the lineage above it, because it answers
   the same shape of question about the same result. */
.fd-activity { list-style: none; margin: 0; padding: 12px 2px 4px; }
.fd-activity li { position: relative; display: flex; gap: 12px; padding-bottom: 14px; }
.fd-activity li:last-child { padding-bottom: 0; }
.fd-actbody { min-width: 0; flex: 1; }
.fd-acthead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.fd-acthead strong { font-size: 12.5px; }
.fd-actwhen { font-size: 11.5px; color: var(--mut); }
.fd-actext { margin: 2px 0 0; font-size: 12.5px; line-height: 1.55; }
/* A generated entry is not somebody's sentence, and should not read like one. */
.fd-activity li.is-event .fd-actext { color: var(--mut); font-style: italic; }

/* --- lineage ------------------------------------------------------------- */
.fd-lineage { padding: 12px 2px 4px; }
.fd-lineage li { position: relative; display: flex; gap: 12px; padding-bottom: 14px; }
.fd-lineage li:last-child { padding-bottom: 0; }
.fd-lin { position: relative; flex: none; width: 8px; }
.fd-lin::before { content: ""; position: absolute; top: 5px; left: 0; width: 7px; height: 7px; border-radius: 50%; background: var(--line2); }
.fd-lin::after { content: ""; position: absolute; top: 14px; left: 3px; bottom: -14px; width: 1px; background: var(--line); }
.fd-lin.last::after { display: none; }
.fd-lineage strong { display: block; font-size: 12.5px; }
.fd-lineage span { font-size: 11.5px; color: var(--mut); }
.fd-provenance { margin: 0; padding: 11px 0 2px; border-top: 1px solid var(--line); font-size: 12px; color: var(--mut); line-height: 1.6; }
.fd-fields { display: flex; flex-wrap: wrap; gap: 5px; padding: 10px 0 2px; }
.fd-fields li { font-size: 11.5px; border: 1px solid var(--line); border-radius: 3px; padding: 2px 7px; color: var(--mut); }

/* --- the dock ------------------------------------------------------------ */
.fd-dock { flex: none; border-top: 1px solid var(--line2); background: var(--bg); }
.fd-dockrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 11px 16px; }
.fd-dockmain { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fd-dockalt { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.fd-closed { font-size: 12px; color: var(--mut); }
.fd-dismiss, .fd-annotate { flex-basis: 100%; border: 1px dashed var(--line2); border-radius: 6px; padding: 12px 13px; background: var(--muted); }
.fd-dismissh { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mut); }
.fd-reasons { display: grid; gap: 6px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); margin-top: 9px; }
.fd-reason {
  display: block; border: 1px solid var(--line); border-radius: 5px; padding: 8px 10px;
  background: var(--bg); cursor: pointer;
}
.fd-reason:hover { border-color: var(--line2); }
.fd-reason:has(input:checked) { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.fd-reason input { position: absolute; opacity: 0; pointer-events: none; }
.fd-reasonl { display: block; font-size: 12.5px; font-weight: 600; }
.fd-reasonh { display: block; font-size: 11.5px; color: var(--mut); line-height: 1.45; margin-top: 2px; }
.fd-dismiss textarea, .fd-annotate textarea {
  width: 100%; margin-top: 9px; resize: vertical; border: 1px solid var(--line);
  border-radius: 5px; padding: 8px 10px; font: inherit; font-size: 12.5px; background: var(--bg); color: var(--ink);
}
.fd-dismissa { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 9px; }
.fd-dismissa .fd-hint { margin-left: auto; max-width: 46ch; }

/* The dock's buttons. Three weights and no more: the one thing to press, the
   things you might press, and the things that leave. `a` and `button` both take
   the class because "Tune this audit" navigates and "Annotate" does not, and a
   reviewer should not have to care which is which. */
.fd-dock .btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 6px; border: 1px solid var(--line2);
  background: var(--bg); color: var(--ink); font: inherit; font-size: 13px;
  font-weight: 500; line-height: 1.2; cursor: pointer; text-decoration: none;
  white-space: nowrap; transition: background .12s, border-color .12s, color .12s;
}
.fd-dock .btn:hover { background: var(--muted); }
.fd-dock .btn.primary {
  background: var(--primary); border-color: var(--primary); color: var(--primary-foreground);
}
.fd-dock .btn.primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.fd-dock .btn.quiet { border-color: transparent; color: var(--mut); padding-inline: 9px; }
.fd-dock .btn.quiet:hover { color: var(--ink); background: var(--muted); }
.fd-dock .btn:focus-visible, .fd-tab:focus-visible, .fd-ibtn:focus-visible,
.fd-trustx:focus-visible, .fd-close:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 2px;
}
/* The forms the dock wraps each action in must not become layout. */
.fd-dockmain .inline-edit, .fd-dockmain form { display: contents; }

/* ---------------------------------------------------------------------------
 * Developer-mode banner.
 *
 * Sticky rather than static, and above the header rather than inside it: the
 * numbers on screen in developer mode are generated, and sooner or later a
 * screenshot of them reaches somebody who did not generate them. A marker that
 * scrolls away is a marker that is absent from most screenshots.
 *
 * Two-tier sticky — the bar pins at 0, the header pins beneath it — so nothing
 * about the header's own layout has to change when the bar is not there.
 * ------------------------------------------------------------------------- */
.devbar {
  --devbar-h: 30px;
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--devbar-h);
  padding: 5px 24px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--warning);
  background: var(--warning-subtle);
  border-bottom: 1px solid color-mix(in oklab, var(--warning) 35%, var(--border));
}
.devbar b { font-weight: 800; letter-spacing: .01em; }
.devbar a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
body[data-dev-mode] .site-header { top: 30px; }

/* ---------------------------------------------------------------------------
 * Superadmin mode (org plan §step 5). Same register and same two-tier sticky
 * as the dev bar, for the same reason: while the sudo window is open every
 * org guard admits this session, and that state must not scroll away. The
 * severity palette (not the warning one) keeps the two bars distinguishable
 * at a glance when both are up in local dev.
 * ------------------------------------------------------------------------- */
.sudobar {
  --sudobar-h: 30px;
  position: sticky;
  top: 0;
  z-index: 59;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--sudobar-h);
  padding: 5px 24px;
  font-size: 12px;
  line-height: 1.4;
  /* The bar carries two links and a button beside its sentence; on a narrow
   * screen they wrap beneath it rather than squeezing it into a column. */
  flex-wrap: wrap;
  row-gap: 2px;
  color: var(--crit);
  background: var(--critbg);
  border-bottom: 1px solid var(--crit-line);
}
.sudobar b { font-weight: 800; letter-spacing: .01em; }

/* ---------------------------------------------------------------------------
 * Access-changed notice (docs/plans/live-access-updates.md). Shown once, on
 * the page the browser lands on after a live signal found the page the user
 * was reading no longer theirs. The warning palette, not the severity one:
 * nothing is wrong, something changed. Not sticky — it is one line of news
 * that can scroll away.
 * ------------------------------------------------------------------------- */
.access-notice {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 30px;
  padding: 5px 24px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--warning);
  background: var(--warning-subtle);
  border-bottom: 1px solid color-mix(in oklab, var(--warning) 30%, var(--border));
}
.access-notice[hidden] { display: none; }
.access-notice b { font-weight: 800; letter-spacing: .01em; }
.access-notice-refresh {
  background: none;
  border: 1px solid color-mix(in oklab, var(--warning) 30%, var(--border));
  border-radius: 7px;
  padding: 2px 9px;
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  color: inherit;
  cursor: pointer;
}
.access-notice-refresh:hover { background: color-mix(in oklab, var(--warning) 12%, transparent); }
/* The two superadmin directories, reachable from every page while the
 * window is open (docs/plans/superadmin-console.md, decision 11). */
.sudobar-link {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.sudobar-link:hover { text-decoration-thickness: 2px; }
.sudobar-off { margin: 0; }
.sudobar-off button {
  background: none;
  border: 1px solid var(--crit-line);
  border-radius: 7px;
  padding: 2px 9px;
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  color: inherit;
  cursor: pointer;
}
.sudobar-off button:hover { background: color-mix(in oklab, var(--crit) 12%, transparent); }
body[data-sudo] .site-header { top: 30px; }
/* Both bars up (dev mode + sudo): stack them, header beneath the pair. */
body[data-dev-mode] .sudobar { top: 30px; }
body[data-dev-mode][data-sudo] .site-header { top: 60px; }

/* ---------------------------------------------------------------------------
 * Impersonation (org plan §step 6). Same two-tier sticky slot as the sudo
 * bar — the two can never render together, because impersonating masks sudo
 * — but deliberately LOUDER: solid critical fill rather than the subtle
 * tint. The failure mode this bar exists for is a superadmin forgetting
 * whose eyes they are looking through.
 * ------------------------------------------------------------------------- */
.impersonation-bar {
  --sudobar-h: 30px;
  position: sticky;
  top: 0;
  z-index: 59;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--sudobar-h);
  padding: 5px 24px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--crit-contrast, #fff);
  background: var(--crit);
  border-bottom: 1px solid var(--crit-line);
}
.impersonation-bar b { font-weight: 800; letter-spacing: .01em; }
.impersonation-bar .sudobar-off button { border-color: currentColor; }
.impersonation-bar .sudobar-off button:hover {
  background: color-mix(in oklab, currentColor 18%, transparent);
}
body[data-impersonating] .site-header { top: 30px; }
/* Dev mode + impersonation: stack, header beneath the pair. */
body[data-dev-mode] .impersonation-bar { top: 30px; }
body[data-dev-mode][data-impersonating] .site-header { top: 60px; }

/* The header's sudo toggle — quiet until pressed; the banner is the loud half. */
.sudo-toggle { margin: 0; }
.sudo-btn {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 9px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--mut);
  cursor: pointer;
}
.sudo-btn:hover { color: var(--crit); border-color: var(--crit-line); }

/* Grant/revoke forms on /admin. */
.superadmin-form { display: flex; gap: 8px; align-items: center; margin: 0 0 8px; }
.superadmin-form input[type="email"] {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  min-width: 240px;
}
.superadmin-form button {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 11px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}
.superadmin-form button:hover { background: var(--bg); }
.superadmin-error { color: var(--crit); font-size: 12.5px; }

/* ---------------------------------------------------------------------------
 * Audit tuning workspace (/settings/audits/{id}/tune).
 *
 * Two columns: parameters on the left, save + version on a sticky right rail.
 * The impact review is a modal because it is a decision, not a panel — it
 * should interrupt, and it should be dismissable without touching anything.
 * ------------------------------------------------------------------------- */
.tn-wrap { max-width: 1180px; }
/* The two-column workspace wants a little more air above it than a
 * single-column reading page: the sticky rail starts at the top edge. */
.tn-wrap { padding-top: 26px; }
.tn-grid { display: grid; gap: 24px; grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
@media (max-width: 980px) { .tn-grid { grid-template-columns: minmax(0, 1fr); } }
.tn-main { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.tn-sticky { position: sticky; top: calc(var(--hdr-h) + 16px); display: flex; flex-direction: column; gap: 14px; }

.tn-hdr { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 22px 24px; }
.tn-hdr h1 { margin: 5px 0 0; font-size: 22px; letter-spacing: -.4px; }
.tn-sub { margin: 6px 0 0; color: var(--mut); font-size: 13px; }
.tn-ver { text-align: right; border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 12px; background: var(--surface); flex: none; }
.tn-ver .n { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tn-ver .w { font-size: 11.5px; color: var(--mut); margin-top: 1px; }

/* In plain language */
.tn-plain { background: var(--panel); border: 1px solid var(--primary); border-radius: 12px;
  padding: 18px 22px; }
.tn-plain.dirty { border-color: var(--warning); background: var(--warning-subtle); }
.tn-plainhd { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.tn-unsaved { font-size: 10px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: var(--warning); border: 1px solid var(--warning); border-radius: 99px; padding: 1px 8px; }
.tn-sent { margin: 0 0 7px; font-size: 13px; line-height: 1.6; color: var(--mut); }
.tn-sent.lead { font-size: 14.5px; color: var(--ink); }
.tn-caveat { margin: 9px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--warning);
  padding-left: 13px; border-left: 2px solid var(--warning); }

/* Parameters */
.tn-params { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.tn-params h2 { margin: 0; font-size: 13.5px; padding: 13px 22px; border-bottom: 1px solid var(--line); }
.tn-field { display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); gap: 24px;
  padding: 16px 22px; border-bottom: 1px solid var(--line); }
.tn-field:last-child { border-bottom: 0; }
@media (max-width: 720px) { .tn-field { grid-template-columns: minmax(0, 1fr); gap: 10px; } }
.tn-flabel label { font-size: 13px; font-weight: 600; }
.tn-fhelp { margin: 3px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--mut); }
.tn-fnote { margin: 4px 0 0; font-size: 11px; color: var(--warning); }
.tn-fmeta { margin-top: 7px; display: flex; gap: 8px; align-items: baseline; font-size: 11px; color: var(--faint); }
.tn-over { color: var(--primary); font-weight: 700; }

.tn-toggle { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: 13px; }
.tn-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.tn-track { position: relative; width: 32px; height: 18px; border-radius: 99px;
  background: var(--surface); border: 1px solid var(--border-strong); transition: background .15s, border-color .15s; }
.tn-knob { position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 99px;
  background: var(--panel); box-shadow: 0 1px 2px rgba(0,0,0,.2); transition: left .15s; }
.tn-toggle input:checked + .tn-track { background: var(--primary); border-color: var(--primary); }
.tn-toggle input:checked + .tn-track .tn-knob { left: 16px; }
.tn-toggle input:focus-visible + .tn-track { outline: 2px solid var(--ring); outline-offset: 2px; }

.tn-slider { max-width: 340px; }
.tn-sval { display: block; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tn-slider input[type=range] { width: 100%; margin-top: 7px; accent-color: var(--primary); }
.tn-ticks { display: flex; justify-content: space-between; font-size: 11px; color: var(--faint); margin-top: 3px; }

.tn-stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden; background: var(--panel); }
.tn-stepper button { border: 0; background: transparent; padding: 0 11px; cursor: pointer;
  color: var(--mut); font-size: 15px; }
.tn-stepper button:hover { background: var(--surface); color: var(--ink); }
.tn-stepper input { border: 0; border-left: 1px solid var(--line); border-right: 1px solid var(--line);
  width: 108px; padding: 7px 9px; font: inherit; font-size: 13px; font-weight: 600;
  font-variant-numeric: tabular-nums; background: transparent; color: var(--ink); text-align: center; }
.tn-unit { display: grid; place-items: center; padding: 0 9px; font-size: 11.5px; color: var(--mut); }

.tn-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; padding: 3px; background: var(--surface); }
.tn-seg label { padding: 4px 11px; border-radius: 5px; font-size: 12.5px; cursor: pointer; color: var(--mut); }
.tn-seg label.on { background: var(--panel); color: var(--ink); font-weight: 600; box-shadow: var(--sh); }
.tn-seg input { position: absolute; opacity: 0; width: 0; }
.tn-text { border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; font: inherit;
  font-size: 13px; width: 100%; max-width: 340px; background: var(--panel); color: var(--ink); }

.tn-adv { border-top: 1px solid var(--line); }
.tn-adv summary { padding: 11px 22px; font-size: 12.5px; color: var(--mut); cursor: pointer; }
.tn-adv[open] summary { border-bottom: 1px solid var(--line); }

/* Sidebar */
.tn-save h2, .tn-verpanel h2, .tn-hist h2 { margin: 0 0 7px; font-size: 13.5px; }
.tn-save p { margin: 0 0 11px; font-size: 12px; line-height: 1.55; color: var(--mut); }
.btn.block { display: block; width: 100%; text-align: center; margin-bottom: 7px; }
.tn-back { display: block; text-align: center; font-size: 12px; color: var(--mut); margin-top: 3px; }
.tn-busy { display: none; font-size: 11.5px; color: var(--mut); margin: 4px 0 8px; text-align: center; }
.tn-busy.htmx-request { display: block; }
.tn-verpanel dl { margin: 0; font-size: 12.5px; }
.tn-verpanel dl div { display: flex; justify-content: space-between; gap: 12px; padding: 2px 0; }
.tn-verpanel dt { color: var(--mut); }
.tn-verpanel dd { margin: 0; font-weight: 600; }
.tn-verpanel .q { margin: 9px 0 0; padding-top: 9px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--mut); line-height: 1.55; }
.tn-verpanel .n { margin: 8px 0 0; font-size: 11px; color: var(--faint); line-height: 1.55; }
.tn-hist ol { margin: 0; padding: 0; list-style: none; }
.tn-hist li { padding: 8px 0; border-bottom: 1px solid var(--line); }
.tn-hist li:last-child { border-bottom: 0; }
.tn-hist .h { display: flex; gap: 7px; align-items: baseline; font-size: 12px; }
.tn-hist .h span { color: var(--faint); font-size: 11px; }
.tn-hist .ap { color: var(--primary); font-weight: 700; }
.tn-hist p { margin: 2px 0 0; font-size: 11.5px; color: var(--mut); line-height: 1.5; }

.tn-flash { border: 1px solid var(--line); background: var(--surface); border-radius: 8px;
  padding: 10px 14px; font-size: 12.5px; margin-bottom: 16px; }
.tn-flash.ok { border-color: var(--success); background: var(--success-subtle); }

/* Impact review modal */
[x-cloak] { display: none !important; }
.tn-modal { position: fixed; inset: 0; z-index: 80; display: flex; align-items: flex-start;
  justify-content: center; overflow-y: auto; padding: 40px 16px; }
.tn-scrim { position: fixed; inset: 0; background: rgba(20, 24, 28, .45); }
.tn-dialog { position: relative; width: 100%; max-width: 840px; background: var(--panel);
  border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--sh2, 0 10px 40px rgba(0,0,0,.2));
  overflow: hidden; }
.tn-mhd { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;
  padding: 16px 22px; border-bottom: 1px solid var(--line); }
.tn-mhd h2 { margin: 3px 0 0; font-size: 16px; }
.tn-mclose { border: 0; background: transparent; color: var(--mut); cursor: pointer; font-size: 12.5px; }
.tn-stale { margin: 0; padding: 12px 22px; background: var(--warning-subtle); color: var(--warning);
  font-size: 12.5px; line-height: 1.55; border-bottom: 1px solid var(--line); }
.tn-diffbar { display: flex; flex-wrap: wrap; gap: 7px; align-items: center;
  padding: 12px 22px; border-bottom: 1px solid var(--line); background: var(--surface); }
.tn-chip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--line);
  border-radius: 5px; padding: 2px 7px; font-size: 11.5px; background: var(--panel); }
.tn-chip .k { color: var(--mut); }
.tn-chip s { color: var(--faint); }
.tn-chip.sm { font-size: 11px; }
.tn-tallies { display: flex; gap: 28px; padding: 16px 22px; border-bottom: 1px solid var(--line); }
.tn-tally b { display: block; font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; }
.tn-tally span { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--mut); margin-top: 5px; }
.tn-tally.resolved b { color: var(--success); }
.tn-tally.new b { color: var(--sev-high); }
.tn-tally.changed b { color: var(--sev-medium); }
.tn-mnote { margin: 0; padding: 12px 22px; font-size: 12px; color: var(--mut); line-height: 1.55; }
.tn-collateral { margin: 0 22px 14px; padding: 12px 14px; border: 1px solid var(--warning);
  background: var(--warning-subtle); border-radius: 8px; font-size: 12px; line-height: 1.55; color: var(--ink); }
.tn-collateral ul { margin: 7px 0 0; padding-left: 16px; color: var(--mut); }
.tn-collateral .k { font-weight: 600; color: var(--ink); }
.tn-items { max-height: 46vh; overflow-y: auto; padding: 4px 22px 16px; }
.tn-items section { margin-top: 14px; }
.tn-items h3 { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 12.5px; }
.tn-items h3 em { font-style: normal; color: var(--faint); font-variant-numeric: tabular-nums; }
.tn-items h3 .dot { width: 8px; height: 8px; border-radius: 99px; background: var(--border-strong); }
.tn-items h3 .dot.resolved { background: var(--success); }
.tn-items h3 .dot.new { background: var(--sev-high); }
.tn-items h3 .dot.changed { background: var(--sev-medium); }
.tn-items ul { margin: 0; padding: 0; list-style: none; }
.tn-item { display: flex; gap: 11px; align-items: flex-start; padding: 9px 11px; margin-bottom: 6px;
  border: 1px solid var(--line); border-left-width: 3px; border-radius: 8px; background: var(--panel); }
.tn-item.resolved { border-left-color: var(--success); }
.tn-item.new { border-left-color: var(--sev-high); }
.tn-item.changed { border-left-color: var(--sev-medium); }
.tn-imain { flex: 1; min-width: 0; }
.tn-item .t { margin: 0; font-size: 13px; font-weight: 500; }
.tn-item.resolved .t { text-decoration: line-through; color: var(--mut); }
.tn-item .r { margin: 2px 0 0; font-size: 11.5px; color: var(--mut); }
.tn-ichanges { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.tn-item .amt { font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; flex: none; }
.tn-empty { color: var(--mut); font-size: 12.5px; padding: 14px 0; text-align: center; }
.tn-mft { display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 14px 22px; border-top: 1px solid var(--line); background: var(--surface); }
.tn-mfnote { margin: 0; font-size: 11.5px; color: var(--mut); }
.tn-mact { display: flex; gap: 8px; align-items: center; }
.tn-mact form { margin: 0; }

/* `.btn` is defined only inside `.fd-dock`, so the tuning page needs its own.
 * Scoped rather than promoted to a global: a global `.btn` would silently
 * restyle every existing button in the app, which is a much larger change than
 * this page is entitled to make. */
.tn-wrap .btn, .tn-modal .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
  color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 8px 13px; cursor: pointer; text-decoration: none;
  transition: background .12s, border-color .12s, color .12s;
}
.tn-wrap .btn:hover, .tn-modal .btn:hover { background: var(--muted); }
.tn-wrap .btn.primary, .tn-modal .btn.primary {
  background: var(--primary); border-color: var(--primary); color: var(--primary-foreground);
}
.tn-wrap .btn.primary:hover, .tn-modal .btn.primary:hover {
  background: var(--primary-hover); border-color: var(--primary-hover);
}
.tn-wrap .btn.quiet, .tn-modal .btn.quiet { border-color: transparent; color: var(--mut); }
.tn-wrap .btn.quiet:hover, .tn-modal .btn.quiet:hover { color: var(--ink); background: var(--muted); }
.tn-wrap .btn:focus-visible, .tn-modal .btn:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 2px;
}

/* ===========================================================================
 * FORM CONTROLS — the app-wide layer.
 *
 * Until this existed, `app.css` styled no `select`, `input` or `textarea` at
 * all: ten templates rendered raw browser chrome — a grey OS dropdown arrow, a
 * 21px-tall date field, a system font inside a 13px interface, a focus outline
 * that changed shape per control. Layout and type were designed; the controls
 * were whatever the browser shipped, and controls are most of what a working
 * screen actually IS. That mismatch is what read as unpolished.
 *
 * Sizes follow Meridian: a dense control is 32px, `--radius-md`, with
 * `--input`-weight border going to `--border-strong` on hover and `--primary`
 * plus a 2px ring on focus. Meridian's default is 40px; Conduit's interface is
 * denser (13px body against Meridian's 14px), so the dense step is the default
 * here and the roomier one is opt-in via `.ctl-lg`.
 * ======================================================================== */
:root {
  --ctl-h: 32px;
  --ctl-h-lg: 38px;
  --ctl-r: 8px;
  --ctl-px: 10px;
  --ctl-fs: 13px;
}

.wrap input[type="text"], .wrap input[type="search"], .wrap input[type="number"],
.wrap input[type="date"], .wrap input[type="email"], .wrap input[type="url"],
.wrap select, .wrap textarea,
.fd-panel input[type="text"], .fd-panel input[type="number"], .fd-panel input[type="date"],
.fd-panel select, .fd-panel textarea,
.fd-dock input[type="text"], .fd-dock input[type="date"], .fd-dock select,
.tn-modal input, .tn-modal select, .tn-modal textarea,
.site-header select {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  min-height: var(--ctl-h);
  padding: 0 var(--ctl-px);
  border: 1px solid var(--line);
  border-radius: var(--ctl-r);
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  font-size: var(--ctl-fs);
  line-height: 1.2;
  transition: border-color .12s var(--ease-standard, ease), box-shadow .12s var(--ease-standard, ease);
}
.wrap textarea, .fd-panel textarea, .tn-modal textarea {
  min-height: 72px; padding: 8px var(--ctl-px); line-height: 1.5; resize: vertical;
}
.wrap input::placeholder, .fd-panel input::placeholder, .tn-modal input::placeholder {
  color: var(--faint);
}
.wrap input:hover:not(:disabled), .wrap select:hover:not(:disabled),
.wrap textarea:hover:not(:disabled),
.fd-panel input:hover:not(:disabled), .fd-panel select:hover:not(:disabled),
.fd-dock select:hover:not(:disabled), .fd-dock input:hover:not(:disabled),
.tn-modal input:hover:not(:disabled), .tn-modal select:hover:not(:disabled),
.site-header select:hover:not(:disabled) {
  border-color: var(--line2);
}
.wrap input:focus-visible, .wrap select:focus-visible, .wrap textarea:focus-visible,
.fd-panel input:focus-visible, .fd-panel select:focus-visible, .fd-panel textarea:focus-visible,
.fd-dock input:focus-visible, .fd-dock select:focus-visible,
.tn-modal input:focus-visible, .tn-modal select:focus-visible, .tn-modal textarea:focus-visible,
.site-header select:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 35%, transparent);
}
.wrap input:disabled, .wrap select:disabled, .wrap textarea:disabled,
.fd-panel select:disabled, .tn-modal input:disabled {
  background: var(--muted); color: var(--faint); cursor: not-allowed;
}

/* The dropdown arrow. `appearance:none` removes the OS one, so it has to be
 * drawn back — inline SVG in a data URI, tinted by `--mut` at author time. Two
 * variants because the mark must stay legible on the dark header. */
.wrap select, .fd-panel select, .fd-dock select, .tn-modal select {
  padding-right: 28px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%237c7d7a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 10px 7px;
  cursor: pointer;
}
:root[data-theme="dark"] .wrap select,
:root[data-theme="dark"] .fd-panel select,
:root[data-theme="dark"] .tn-modal select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23a3a49f' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wrap select,
  :root:not([data-theme="light"]) .fd-panel select,
  :root:not([data-theme="light"]) .tn-modal select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23a3a49f' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  }
}

/* A date input keeps its native picker button; without this it renders at the
 * browser's own font size inside a 13px control and sits a pixel high. */
.wrap input[type="date"], .fd-panel input[type="date"], .fd-dock input[type="date"] {
  font-variant-numeric: tabular-nums;
}
input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: .5; cursor: pointer; padding: 0; margin-left: 2px;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* Numbers read as data, not prose. */
.wrap input[type="number"], .tn-modal input[type="number"] { font-variant-numeric: tabular-nums; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; }

/* One focus ring for everything focusable, so tabbing through a page does not
 * change shape control by control. */
.wrap a:focus-visible, .wrap button:focus-visible, .wrap summary:focus-visible,
.fd-panel a:focus-visible, .tn-modal a:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px;
}

/* ---------------------------------------------------------------------------
 * Header overflow.
 *
 * `.mainnav` is a nowrap flex row with `min-width: 0`, and `.hdr-actions` takes
 * `margin-left: auto`. Below about 1560px the nav is wider than the space left
 * for it, and the last items — Audit setup, Diagnostics, Ops — slid underneath
 * the theme toggle and the company switcher: present in the DOM, reachable by
 * keyboard, invisible to the eye and half-drawn at the seam. At 1512px, a
 * common laptop width, "Ops" rendered as a clipped "O".
 *
 * Scrolling the nav rather than hiding it keeps every destination reachable at
 * any width. The actions stop shrinking so the company switcher and account
 * menu never compress into ambiguity, and a mask fades the cut edge so a
 * partially visible item reads as "there is more" instead of as a rendering bug.
 * ------------------------------------------------------------------------- */
.mainnav {
  flex: 1 1 auto;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Room for the fade, so the last item is never sliced by its own mask. */
  padding-right: 4px;
  mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent 100%);
}
.mainnav::-webkit-scrollbar { display: none; }
/* No mask when nothing is clipped — otherwise the last item is permanently
 * faded on a wide screen, which looks like a disabled link. */
@media (min-width: 1600px) {
  .mainnav { mask-image: none; -webkit-mask-image: none; }
}
.hdr-actions { flex: 0 0 auto; }
.site-header .hdr-inner { gap: 10px; }

/* Between roughly 1180px and 1600px the nav fits only if it gives up a little
 * padding. Tightening it there means the scroll-and-fade above is reserved for
 * genuinely small windows, rather than being what a 1512px laptop always sees. */
@media (max-width: 1600px) {
  .mainnav-link { padding: 0 8px; font-size: 13px; }
  .site-header .hdr-inner { padding: 0 16px; }
}
@media (max-width: 1280px) {
  .mainnav-link { padding: 0 6px; font-size: 12.5px; }
}

/* ---------------------------------------------------------------------------
 * Drawer: pin the action dock to the bottom.
 *
 * `.fd` asks for `height: 100%`, but its parent `#finding-drawer-body` had no
 * height of its own — so the percentage resolved against `auto` and was
 * ignored, leaving `.fd` at content height. The dock then sat wherever the
 * content happened to end, with panel-coloured emptiness below it: on a short
 * result, "Mark reviewed" floated in the middle of the panel with a third of
 * the drawer blank underneath.
 *
 * Making the body a flex column that fills the panel gives `.fd` a real height
 * to be 100% of. The panel stops scrolling as a whole so the scroll lives in
 * the content region, which is what keeps the header and the dock fixed while
 * a long derivation scrolls between them.
 * ------------------------------------------------------------------------- */
.drawer.finding .drawer-panel { overflow: hidden; }
#finding-drawer-body {
  flex: 1;
  min-height: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
#finding-drawer-body > .fd { flex: 1; min-height: 0; }
/* The scroll region between the fixed header and the fixed dock. */
.fd-scroll { overflow-y: auto; overscroll-behavior: contain; }
.fd-dock { flex: none; }

/* ---------------------------------------------------------------------------
 * The page frame.
 *
 * `.wrap` was never defined here — every page declared its own inside its
 * `<style>` block, at eight slightly different widths (1000 / 1040 / 1120 /
 * 1140px) and paddings (20-22px top, 22-24px sides). Two consequences: the
 * content column shifts as you move between pages, and any page that forgot to
 * declare one got no frame at all — content flush to the viewport edge and
 * jammed under the header, which is exactly what happened to the tuning page.
 *
 * Declared here as the default. Every existing page's own `<style>` still wins
 * (it is parsed after this file), so nothing that already looks right changes;
 * what this fixes is the page that says nothing, and it gives the next one a
 * correct frame for free.
 * ------------------------------------------------------------------------- */
.wrap {
  max-width: var(--shell-max, 1140px);
  margin: 0 auto;
  padding: 22px 24px 64px;
}
/* The same failure, one level up. /admin, /ops, /diagnostics and the sign-in /
 * realm / authorisation error pages open their own <main> inside the layout's
 * `#main` instead of a `.wrap`, bring no stylesheet, and got no frame either:
 * /admin was wearing `class="ops"` on the strength of a comment, and `.ops` had
 * never been declared. Keyed on the structure rather than a class so the next
 * plain page cannot forget it. Narrower than `.wrap` because these are prose.
 * `tests/ci/test_pages_have_a_gutter.py` holds both rules in place. */
#main > main {
  max-width: 820px;
  margin: 0 auto;
  padding: 22px 24px 64px;
}
#main > main h1 { margin: 0 0 4px; font-size: 23px; letter-spacing: -.4px; }
.ops-note { color: var(--mut); font-size: 13.5px; max-width: 72ch; }

/* The job console (docs/plans/job-console.md). Tables of runs want more
 * than the 820px prose frame; `.ops-wide` widens the nested-main frame for
 * the pages that carry one. The severity tokens colour the states so the
 * console reads the same in both themes. */
#main > main.ops-wide { max-width: 1180px; }
.ops-engine-error {
  border: 1px solid var(--crit-line); background: var(--critbg); color: var(--ink);
  border-radius: 8px; padding: 10px 14px; font-size: 13.5px;
}
.ops-notice {
  border: 1px solid var(--line); background: var(--okbg); color: var(--ink);
  border-radius: 8px; padding: 10px 14px; font-size: 13.5px;
}
.ops-form-error {
  border: 1px solid var(--crit-line); background: var(--critbg); color: var(--ink);
  border-radius: 8px; padding: 10px 14px; font-size: 13.5px;
}
.ops-counters {
  list-style: none; margin: 10px 0 4px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px;
}
.ops-counters li a {
  display: block; min-width: 120px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: 10px; text-decoration: none; color: var(--mut);
  font-size: 12.5px; text-transform: uppercase; letter-spacing: .05em;
}
.ops-counters li a:hover { border-color: var(--ink); color: var(--ink); }
.ops-count { display: block; font-size: 24px; font-weight: 700; letter-spacing: -.5px; color: var(--ink); }
.ops-counters li.is-failed .ops-count { color: var(--crit); }
.ops-retention { margin-top: 2px; }
.ops-throughput-wrap { margin: 8px 0 0; }
.ops-throughput { display: block; width: 100%; max-width: 640px; height: 64px; }
.ops-tp-ok { fill: var(--ok); }
.ops-tp-fail { fill: var(--crit); }
.ops-tp-axis { stroke: var(--line); stroke-width: 1; }
.ops-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 12px 0 2px; border-bottom: 1px solid var(--line); }
.ops-tab {
  padding: 8px 12px; text-decoration: none; color: var(--mut); font-size: 13.5px;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.ops-tab:hover { color: var(--ink); }
.ops-tab.is-active { color: var(--ink); border-bottom-color: var(--ink); font-weight: 600; }
.ops-badge {
  display: inline-block; min-width: 18px; padding: 0 6px; margin-left: 2px;
  border-radius: 9px; background: var(--muted); color: var(--ink);
  font-size: 11.5px; font-weight: 700; text-align: center; line-height: 18px;
}
.ops-filters { display: flex; flex-wrap: wrap; align-items: end; gap: 12px; margin: 8px 0 4px; font-size: 13px; color: var(--mut); }
.ops-filters label { display: flex; flex-direction: column; gap: 4px; }
.ops-filters select, .ops-filters input[type="text"] {
  font: inherit; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px;
}
table.ops-runs { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 10px; }
table.ops-runs th {
  text-align: left; font-size: 10.5px; font-weight: 800; letter-spacing: .05em;
  color: var(--faint); text-transform: uppercase; padding: 8px 10px; border-bottom: 1px solid var(--line);
}
table.ops-runs td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.ops-runs tr:last-child td { border-bottom: 0; }
table.ops-runs .rt-num { text-align: right; font-variant-numeric: tabular-nums; }
.ops-error-cell code { white-space: pre-wrap; word-break: break-word; }
.ops-status { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: 2px 7px; border-radius: 6px; background: var(--muted); color: var(--mut); }
.ops-status.is-failed { background: var(--critbg); color: var(--crit); }
.ops-status.is-completed, .ops-status.is-succeeded { background: var(--okbg); color: var(--ok); }
.ops-status.is-running { background: var(--hibg); color: var(--hi); }
.ops-status.is-queued { background: var(--medbg); color: var(--med); }
.ops-action { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.ops-run-now input[type="datetime-local"] { font: inherit; font-size: 12.5px; border: 1px solid var(--line); border-radius: 6px; padding: 3px 6px; color: var(--ink); background: var(--paper); }
.ops-run-now input[aria-invalid="true"] { border-color: var(--crit); }
.ops-id { font-size: 15px; }
.ops-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px 18px; margin: 8px 0; }
.ops-facts dt { font-size: 10.5px; font-weight: 800; letter-spacing: .05em; color: var(--faint); text-transform: uppercase; }
.ops-facts dd { margin: 2px 0 0; font-size: 13.5px; }
.ops-run-head { display: flex; flex-wrap: wrap; align-items: start; justify-content: space-between; gap: 12px; }
.ops-run-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 6px 0; }
.ops-io { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }
.ops-pre { font-size: 12.5px; background: var(--muted); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; overflow: auto; max-height: 420px; white-space: pre-wrap; word-break: break-word; }
.ops-pre.ops-error { border-color: var(--crit-line); background: var(--critbg); }
.ops-timeline { list-style: none; margin: 8px 0; padding: 0; font-size: 13px; }
.ops-timeline li { padding: 4px 0; border-bottom: 1px dashed var(--line); }
.ops-timeline time { font-variant-numeric: tabular-nums; color: var(--mut); margin-right: 8px; }
.ops-event { font-weight: 600; margin-right: 6px; }
table.ops-logs tr.is-error td, table.ops-logs tr.is-warn td, table.ops-logs tr.is-warning td { color: var(--crit); }
.ops-empty { color: var(--mut); font-size: 13.5px; }
.crumb {
  font-size: 12.5px;
  color: var(--faint);
  margin-bottom: 4px;
}
.crumb a { color: var(--mut); text-decoration: none; }
.crumb a:hover { color: var(--ink); text-decoration: underline; }

/* ---------------------------------------------------------------------------
 * Shared surface primitives.
 *
 * Like `.wrap`, none of these existed globally: `.panel` was declared in seven
 * pages at four different radii, `.empty` in seven, `.badge` in three, and
 * `.lbl` in none at all — so the eyebrow labels on any page that used it
 * rendered as ordinary body text. A page that reached for a house class it had
 * not personally declared got nothing, and the result looked like a page that
 * had been styled and then half-unstyled.
 *
 * Defaults only. Every page's own `<style>` is parsed after this file and still
 * wins, so nothing that already looks right moves; this is the floor.
 * ------------------------------------------------------------------------- */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: var(--sh);
  overflow: hidden;
}
.panel + .panel { margin-top: 16px; }

.empty {
  padding: 34px 24px;
  text-align: center;
  color: var(--mut);
  font-size: 13px;
  line-height: 1.6;
}

/* The uppercase eyebrow above a title or a figure. */
.lbl {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .075em;
  text-transform: uppercase;
  color: var(--mut);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  background: var(--muted);
  color: var(--mut);
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}
.badge.core {
  border-color: color-mix(in oklab, var(--primary) 30%, var(--border));
  background: var(--primary-subtle);
  color: var(--primary);
  font-family: var(--font-sans);
  letter-spacing: 0;
}

/* `.panel` is deliberately padding-free — several pages put a flush table or a
 * row list inside one. A panel holding prose has to say so. */
.tn-save, .tn-verpanel, .tn-hist { padding: 16px 18px; }
.tn-save + .tn-verpanel, .tn-verpanel + .tn-hist { margin-top: 0; }
.tn-wrap .panel + .panel { margin-top: 14px; }
/* Three actions on one row; wrapping a label mid-phrase ("Keep current /
 * results") makes a decision harder to read at exactly the moment it is made. */
.tn-wrap .btn, .tn-modal .btn { white-space: nowrap; }
.tn-mact { flex-wrap: wrap; justify-content: flex-end; }
