:root {
  --bg: #f9fafb;
  --surface: #ffffff;
  --surface-2: #f2f4f7;
  --surface-inset: #f9fafb;
  --border: #e4e7ec;
  --border-strong: #d0d5dd;
  --text: #101828;
  --text-muted: #667085;
  --text-faint: #98a2b3;
  --accent: #06beb3;
  --accent-hover: #05a79d;
  --accent-ink: #067a72;
  --accent-weak: #e0f9f7;
  --accent-text: #06302c;
  --ok: #12b76a;      --ok-ink: #027a48;   --ok-weak: #ecfdf3;
  --warn: #dc6803;    --warn-ink: #b54708; --warn-weak: #fef0c7;
  --danger: #d92d20;  --danger-ink: #b42318; --danger-weak: #fef3f2;
  --info: #0ba5ec;    --info-ink: #026aa2; --info-weak: #f0f9ff;
  /* Flat by design: surfaces are separated by --border, not by elevation. The
     tokens are kept rather than deleted so this is a one-line change if drop
     shadows ever come back, and so nothing has to be hunted down across
     .card/.kpi/.seg/.auth-card. Shadows used as an affordance rather than for
     elevation — the :focus ring, the status dot's halo, the brand mark's inset —
     are declared inline and are deliberately unaffected. */
  --shadow: none;
  --shadow-lg: none;
  --radius: 11px;
  --radius-sm: 8px;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --display: "Montserrat", "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Tells the browser which way to paint the parts it owns: the popup a
     <select> opens, date pickers, scrollbars. Without it those stay light
     while the page is dark — the country dropdown rendered white-on-white,
     unreadable, and no amount of CSS on the <select> itself reaches the
     popup. */
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0c111d; --surface: #101828; --surface-2: #1a2231; --surface-inset: #0c111d;
    --border: #262d3c; --border-strong: #344054; --text: #f9fafb; --text-muted: #98a2b3; --text-faint: #667085;
    --accent: #31d1c5; --accent-hover: #5cdcd1; --accent-ink: #5cdcd1; --accent-weak: #0e2e2b; --accent-text: #04201d;
    --ok: #32d583; --ok-ink: #6ce9a6; --ok-weak: #10241d; --warn: #f79009; --warn-ink: #fdb022; --warn-weak: #2a2010;
    --danger: #f04438; --danger-ink: #fda29b; --danger-weak: #2c1414; --info: #36bffa; --info-ink: #7cd4fd; --info-weak: #10222e;
    color-scheme: dark;
    /* Deliberately no --shadow override: dark inherits the flat tokens. The
       values here used to be far heavier than the light ones (.35/.5 alpha). */
  }
}
:root[data-theme="light"] {
  --bg: #f9fafb; --surface: #ffffff; --surface-2: #f2f4f7; --surface-inset: #f9fafb;
  --border: #e4e7ec; --border-strong: #d0d5dd; --text: #101828; --text-muted: #667085; --text-faint: #98a2b3;
  --accent: #06beb3; --accent-hover: #05a79d; --accent-ink: #067a72; --accent-weak: #e0f9f7; --accent-text: #06302c;
  --ok: #12b76a; --ok-ink: #027a48; --ok-weak: #ecfdf3; --warn: #dc6803; --warn-ink: #b54708; --warn-weak: #fef0c7;
  --danger: #d92d20; --danger-ink: #b42318; --danger-weak: #fef3f2; --info: #0ba5ec; --info-ink: #026aa2; --info-weak: #f0f9ff;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --bg: #0c111d; --surface: #101828; --surface-2: #1a2231; --surface-inset: #0c111d;
  --border: #262d3c; --border-strong: #344054; --text: #f9fafb; --text-muted: #98a2b3; --text-faint: #667085;
  --accent: #31d1c5; --accent-hover: #5cdcd1; --accent-ink: #5cdcd1; --accent-weak: #0e2e2b; --accent-text: #04201d;
  --ok: #32d583; --ok-ink: #6ce9a6; --ok-weak: #10241d; --warn: #f79009; --warn-ink: #fdb022; --warn-weak: #2a2010;
  --danger: #f04438; --danger-ink: #fda29b; --danger-weak: #2c1414; --info: #36bffa; --info-ink: #7cd4fd; --info-weak: #10222e;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--sans); font-size: 14px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
h1, h2, h3 { font-family: var(--display); }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Skip link: off screen until focused, then the first thing a keyboard lands on. */
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: 0 0 9px 0; padding: 10px 16px; font-size: 13px; font-weight: 600; }
.skip-link:focus { left: 0; }


/* ---------- Shell ---------- */
.app { display: grid; grid-template-columns: 236px 1fr; min-height: 100vh; }
.sidebar { background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; }
.brand { display: flex; align-items: center; gap: 10px; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.brand-mark { width: 30px; height: 30px; border-radius: 9px; flex: none; background: linear-gradient(150deg, var(--accent), color-mix(in srgb, var(--accent) 62%, #101828)); display: grid; place-items: center; box-shadow: inset 0 0 0 1px rgba(255,255,255,.2); }
.brand-name { font-weight: 700; letter-spacing: -.02em; font-size: 16px; font-family: var(--display); }
.brand-name span { color: var(--accent-ink); }
.nav { padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; flex: 1; overflow-y: auto; }
.nav-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em; color: var(--text-faint); font-weight: 700; padding: 14px 10px 6px; }
.nav-item { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: var(--radius-sm); color: var(--text-muted); font-weight: 500; border: none; background: none; width: 100%; text-align: left; font-size: 13.5px; }
.nav-item svg { width: 17px; height: 17px; flex: none; opacity: .85; }
.nav-item:hover { background: var(--surface-2); color: var(--text); }
.nav-item.active { background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
.nav-item.active svg { opacity: 1; }
/* A flex box with an explicit height, not an inline box with padding. Inline,
   its height came from the inherited line-height (1.5 of 11px = 16.5px) and the
   digit sat on its baseline inside that, which left the number visibly high in
   the pill. line-height:1 plus centring puts the glyph in the middle of a shape
   whose size we actually control. min-width keeps a single digit round rather
   than an oval narrower than the two-digit case. */
.nav-badge { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 18px; padding: 0 6px; font-family: var(--mono); font-size: 11px; line-height: 1; background: var(--surface-2); color: var(--text-muted); border-radius: 20px; }
.nav-item.active .nav-badge { background: var(--accent); color: var(--accent-text); }
.project-switch { display: flex; align-items: center; gap: 9px; padding: 7px 11px; background: var(--surface-2); border-radius: var(--radius-sm); border: 1px solid var(--border); }
.project-switch .meta { min-width: 0; max-width: 190px; text-align: left; }
.project-switch .meta b { font-size: 13px; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.project-switch .meta small { font-size: 11px; color: var(--text-faint); font-family: var(--mono); }
.project-switch { cursor: pointer; list-style: none; }
/* Safari renders a disclosure triangle from a pseudo-element the standard
   list-style cannot reach; the chevron below is ours and would sit next to it. */
.project-switch::-webkit-details-marker { display: none; }
.project-switch:hover { border-color: var(--border-strong); }
.project-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.project-switch .chevron { width: 14px; height: 14px; flex: none; color: var(--text-faint); transition: transform .15s ease; }
.project-switch-menu[open] .project-switch .chevron { transform: rotate(180deg); }
/* Absolute, so opening it does not shove the topbar's own height around. */
.project-switch-menu { position: relative; }
.project-switch-list { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; min-width: 220px; display: flex; flex-direction: column; gap: 2px; padding: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); max-height: 50vh; overflow-y: auto; }
.project-switch-item { display: block; width: 100%; text-align: left; padding: 7px 11px; border-radius: var(--radius-sm); font-size: 12.5px; color: var(--text-muted); background: none; border: 1px solid transparent; }
.project-switch-item:hover { background: var(--surface-2); color: var(--text); }
.project-switch-item.current { color: var(--text); background: var(--surface-2); border-color: var(--border); font-weight: 600; }

/* ---------- Main ---------- */
.main { display: flex; flex-direction: column; min-width: 0; }
.topbar { position: sticky; top: 0; z-index: 20; background: color-mix(in srgb, var(--surface) 85%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 16px; padding: 12px 26px; }
.search { flex: 1; max-width: 440px; display: flex; align-items: center; gap: 9px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px; padding: 8px 12px; color: var(--text-faint); }
.search svg { width: 15px; height: 15px; }
.search input { border: none; background: none; color: var(--text); font-size: 13px; flex: 1; outline: none; }
/* The inner control drops its own outline, so the wrapper has to show focus —
   without this, tabbing into the search or any filter leaves no visible cursor
   position at all. */
.search:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.topbar-spacer { flex: 1; }
.icon-btn { width: 34px; height: 34px; border-radius: 9px; border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); display: grid; place-items: center; }
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn svg { width: 16px; height: 16px; }
.avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--accent); color: var(--accent-text); display: grid; place-items: center; font-weight: 700; font-size: 13px; }
.content { padding: 26px; max-width: 1320px; width: 100%; margin: 0 auto; }

/* ---------- Page header ---------- */
.page-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 22px; }
.page-head h1 { font-size: 22px; font-weight: 700; letter-spacing: -.025em; margin: 0 0 3px; }
.page-head p { margin: 0; color: var(--text-muted); font-size: 13.5px; }
.page-head .actions { margin-left: auto; display: flex; gap: 9px; }
/* The back link's own row, above the title. Tighter than a page-head because
   it belongs to the heading below it rather than standing on its own. */
.back-row { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }

/* ---------- Buttons ---------- */
.btn { display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px; border-radius: 9px; font-weight: 550; font-size: 13px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); }
.btn svg { width: 15px; height: 15px; }
.btn:hover { background: var(--surface-2); }
.btn-primary { background: var(--accent); color: var(--accent-text); border-color: var(--accent); font-weight: 650; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-ok { background: var(--ok); color: #fff; border-color: var(--ok); font-weight: 600; }
.btn-danger { background: var(--surface); color: var(--danger-ink); border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.btn-danger:hover { background: var(--danger-weak); }
.btn-ghost { border-color: transparent; background: transparent; color: var(--text-muted); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }
.btn-sm { padding: 6px 10px; font-size: 12.5px; }
/* In flight: htmx disables the form's buttons (hx-disabled-elt) and marks the
   form .htmx-request. Disabled alone reads as "broken"; the spinner is what
   says "working". */
.btn:disabled { opacity: .65; cursor: default; }
.htmx-request button[type="submit"]::after {
  content: ""; width: 12px; height: 12px; flex: none; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: btn-spin .6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
/* `display: inline-flex` above outranks the UA stylesheet's `[hidden]`, so
   without this a hidden button stays on screen — which is silent, because
   the attribute is set and everything looks correct in the DOM. */
.btn[hidden] { display: none; }
.btn-block { width: 100%; justify-content: center; }

/* ---------- KPI ---------- */
.kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 22px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; box-shadow: var(--shadow); }
.kpi .lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .07em; color: var(--text-faint); font-weight: 700; }
.kpi .val { font-size: 27px; font-weight: 650; letter-spacing: -.02em; margin-top: 8px; font-family: var(--mono); }
.kpi .sub { font-size: 12px; color: var(--text-muted); margin-top: 4px; }

/* ---------- Cards ---------- */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }
.card-head { display: flex; align-items: center; gap: 12px; padding: 15px 18px; border-bottom: 1px solid var(--border); }
.card-head h2 { font-size: 14.5px; font-weight: 650; margin: 0; letter-spacing: -.01em; }
.card-head .actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
/* ---------- Modal ---------- */
.modal { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); padding: 0; max-width: 440px; width: calc(100% - 32px); }
.modal::backdrop { background: rgba(12, 17, 29, .6); }
.modal form { padding: 20px; }
.modal-title { font-size: 15px; margin: 0 0 8px; }
.modal-text { font-size: 13.5px; color: var(--text-muted); line-height: 1.6; margin: 0 0 18px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

.card-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; align-items: start; }
@media (max-width: 1100px) { /* ---------- Modal ---------- */
.modal { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); padding: 0; max-width: 440px; width: calc(100% - 32px); }
.modal::backdrop { background: rgba(12, 17, 29, .6); }
.modal form { padding: 20px; }
.modal-title { font-size: 15px; margin: 0 0 8px; }
.modal-text { font-size: 13.5px; color: var(--text-muted); line-height: 1.6; margin: 0 0 18px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

.card-row { grid-template-columns: 1fr; } }
.card-body { padding: 18px; }
/* The action bar at the foot of a form card: a card-head turned upside down.
   Three forms had spelled that out inline, identically, which is three places
   to miss when the shape changes. */
.card-foot { display: flex; align-items: center; gap: 12px; padding: 15px 18px; border-top: 1px solid var(--border); justify-content: flex-end; }
.card-body.is-table { padding: 0; }
/* Anything that is not the table, inside a card that is. */
.card-note { padding: 16px 16px 0; }
.card-foot { padding: 14px 16px; border-top: 1px solid var(--border); }

/* A list of things inside a card reads as one list, not as a stack of boxes.
   Each verification used to carry its own border and radius inside the card
   that already had one, and a rejection reason added a third box inside that —
   three nested outlines for one sentence. Entries are separated by a single
   rule instead. */
.entry-list { display: flex; flex-direction: column; }
.entry { padding: 16px 0; }
.entry + .entry { border-top: 1px solid var(--border); }
.entry:first-child { padding-top: 2px; }
.entry:last-child { padding-bottom: 2px; }

/* A two-column read-only field list. Separators run under every row but the
   final one, where the rule separated nothing and floated above the card's own
   padding.
   Which cells are in that final row depends on the count: always the last, and
   the one before it only when that one starts the row — an ODD position two
   from the end. With an odd number of fields the last row holds one cell, and
   `:nth-last-child(2)` is then in the row above and keeps its rule. */
.kv { display: grid; grid-template-columns: repeat(2, 1fr); }
.kv-row { display: flex; flex-direction: column; gap: 3px; padding: 12px 4px; border-bottom: 1px solid var(--border); }
.kv-row:last-child, .kv-row:nth-last-child(2):nth-child(odd) { border-bottom: none; }
.kv-key { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); font-weight: 700; }
.kv-value { font-size: 13.5px; }

/* A diagnosis belonging to one entry, not an alert about the page: the colour
   and a left rule carry it without another box. */
.note-danger { border-left: 2px solid var(--danger); padding: 1px 0 1px 10px; color: var(--danger-ink); font-size: 13px; }

/* ---------- Dashboard ---------- */
/* Two columns while there is room for two readable ones, one below that. The
   breakpoint is where the right column would start wrapping its own rows
   rather than a device width — a laptop at 1000px reads the same as a tablet. */
.dash-grid { display: grid; grid-template-columns: 1fr; gap: 18px; align-items: start; }
@media (min-width: 1100px) {
  .dash-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
}
.dash-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.card-head-link { margin-left: auto; font-size: 12.5px; color: var(--text-muted); text-decoration: none; white-space: nowrap; }
.card-head-link:hover { color: var(--text); }
/* Ages line up down the column, so "9d" beside "4m" is a shape, not a read. */
.age-cell { width: 62px; font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.activity-subject { font-size: 12.5px; color: var(--text-muted); margin-top: 4px; }
.activity-actor { font-size: 12px; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.delivery-bad { color: var(--danger-ink); font-size: 13px; margin-bottom: 12px; }
.delivery-ok { color: var(--text-muted); font-size: 13px; }
.delivery-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.delivery-list li { display: flex; align-items: baseline; gap: 10px; font-size: 12.5px; flex-wrap: wrap; }
.delivery-url { max-width: 100%; overflow-wrap: anywhere; }
.delivery-count { color: var(--danger-ink); font-weight: 650; }

/* ---------- Filters ---------- */
.filters { display: flex; gap: 9px; flex-wrap: wrap; margin-bottom: 16px; align-items: center; }
.field { display: flex; align-items: center; gap: 7px; background: var(--surface); border: 1px solid var(--border); border-radius: 9px; padding: 7px 11px; font-size: 13px; color: var(--text-muted); }
.field select, .field input { border: none; background: none; color: var(--text); font-size: 13px; outline: none; font-family: inherit; }
/* The options inside a <select>, stated rather than inherited.
   `color-scheme: dark` on :root paints the popup the browser owns, and that is
   enough for a select carrying `.input`, which has a real background. It is not
   enough for the ones in a filter row: `background: none` above lets the pill
   behind them show through, and Chrome then draws the popup with a white
   background while the options keep this rule's near-white `color` — the
   country filter opened white on white. Both need the pair set explicitly. */
select option, select optgroup { background-color: var(--surface); color: var(--text); }
.field:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.field-sep { color: var(--text-faint); font-size: 12px; }
/* Labels a screen reader needs and the filter row has no space for. */
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px; padding: 2px; }
.seg button, .seg a { border: none; background: none; padding: 6px 12px; border-radius: 7px; font-size: 12.5px; color: var(--text-muted); font-weight: 500; }
.seg .on { background: var(--surface); color: var(--text); box-shadow: var(--shadow); font-weight: 600; }

/* ---------- Table ---------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
thead th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-faint); font-weight: 700; padding: 11px 16px; border-bottom: 1px solid var(--border); white-space: nowrap; }
/* `tbody th` too, not just td: the key/value tables (extracted data, a failed
   message's fields) put their labels in a row header, which was inheriting no
   padding at all — the labels sat flush against the card edge, out of line with
   the card's own heading, and the rows were cramped against their rules. */
tbody td, tbody th { padding: 13px 16px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td, tbody tr:last-child th { border-bottom: none; }
/* A row header is centred by default, which every one of those tables was
   overriding inline. */
tbody th { text-align: left; font-weight: 600; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--surface-inset); }
.applicant-cell { display: flex; align-items: center; gap: 11px; }
.mini-avatar { width: 34px; height: 34px; border-radius: 9px; background: var(--surface-2); display: grid; place-items: center; font-weight: 650; font-size: 12px; color: var(--text-muted); flex: none; border: 1px solid var(--border); }
.applicant-cell b { font-weight: 600; font-size: 13.5px; display: block; }
.applicant-cell small { color: var(--text-faint); font-family: var(--mono); font-size: 11.5px; }

/* ---------- Pills / chips ---------- */
.pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; }
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill.ok { color: var(--ok-ink); background: var(--ok-weak); }
.pill.warn { color: var(--warn-ink); background: var(--warn-weak); }
.pill.danger { color: var(--danger-ink); background: var(--danger-weak); }
.pill.info { color: var(--info-ink); background: var(--info-weak); }
.pill.muted { color: var(--text-muted); background: var(--surface-2); }
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; padding: 3px 9px; border-radius: 7px; background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); }
/* A value the reader has to copy character for character. Inside a label it
   cannot rely on <b> alone: the label is already 600 weight and muted, so bold
   text is nearly indistinguishable from the instruction around it — which is a
   problem when the instruction is "type exactly this". Sets its own colour and
   family rather than inheriting the label's. */
.literal { font-family: var(--mono); font-weight: 700; color: var(--text); background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; padding: 1px 6px; }

/* ---------- Team ---------- */
/* ---------- Settings ---------- */
.setting-row { display: flex; gap: 32px; flex-wrap: wrap; }
.setting-label { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); margin-bottom: 3px; }
.setting-value { font-size: 14px; font-weight: 600; }
.setting-value.is-figure { font-size: 22px; font-family: var(--mono); letter-spacing: -.01em; }
/* Pushed right in the card header, where .actions would sit. */
.setting-count { margin-left: auto; font-size: 12px; color: var(--text-faint); text-align: right; }
.card-head .pill { margin-left: auto; }

.cell-who { display: flex; align-items: center; gap: 10px; }
.cell-quiet { font-size: 12px; color: var(--text-faint); }
.cell-actions { text-align: right; white-space: nowrap; }
.cell-actions form { display: inline-block; }
.team-who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.team-who b { font-size: 13px; }
.team-who small { font-size: 11.5px; color: var(--text-faint); }
.avatar-sm { width: 28px; height: 28px; flex: none; border-radius: 50%; background: var(--accent-weak); color: var(--accent-ink); display: grid; place-items: center; font-size: 11px; font-weight: 700; }

.input-sm { padding: 6px 9px; font-size: 12.5px; width: auto; }
/* Reads as text until you interact with it, so a rename does not look like a
   form to fill in — but it is a real input, focusable and keyboard-reachable. */

/* Destructive, but not shouting: full danger styling on every row would make
   Remove the loudest thing on the page. */
.btn-quiet-danger { color: var(--text-muted); }
.btn-quiet-danger:hover { color: var(--danger-ink); background: var(--danger-weak); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }

.add-project { display: flex; gap: 8px; margin-top: 12px; }
.add-project .input { flex: 1; }
.add-member { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

.theme-choice { display: flex; gap: 4px; padding: 3px; background: var(--surface-2); border-radius: 9px; }
.theme-option { flex: 1; padding: 7px 10px; border: none; background: none; color: var(--text-muted); font-size: 12.5px; font-weight: 550; border-radius: 7px; }
.theme-option:hover { color: var(--text); }
.theme-option.selected { background: var(--surface); color: var(--text); }
.add-member .input { flex: 1; min-width: 150px; }

/* A credential that exists in exactly one place on exactly one page load, so
   it is styled to be noticed and read accurately rather than skimmed past. */
.password-issued { border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--border)); background: var(--warn-weak); border-radius: 9px; padding: 14px; margin-bottom: 14px; }
.password-issued-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 13px; color: var(--warn-ink); }
.password-issued-head .pill { margin-left: auto; }
.password-issued-value { display: block; font-size: 15px; letter-spacing: .02em; padding: 10px 12px; border-radius: 7px; background: var(--surface); border: 1px solid var(--border); color: var(--text); user-select: all; word-break: break-all; }
.password-issued p { font-size: 12.5px; color: var(--warn-ink); margin: 10px 0 0; line-height: 1.55; }


/* ---------- Score bar ---------- */
.score { display: flex; align-items: center; gap: 10px; min-width: 148px; }
.score-track { position: relative; flex: 1; height: 7px; border-radius: 20px; background: var(--surface-2); }
.score-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 20px; }
.score-thresh { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--text-faint); border-radius: 2px; }
.score-val { font-family: var(--mono); font-size: 12.5px; font-weight: 600; min-width: 34px; text-align: right; }

/* ---------- Forms ---------- */
.form-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
/* ---------- Developers ---------- */
.endpoint { margin-bottom: 16px; }
.endpoint:last-child { margin-bottom: 0; }
.endpoint-value { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.endpoint-value code { background: var(--surface-2); border: 1px solid var(--border); border-radius: 7px; padding: 7px 11px; font-size: 13px; user-select: all; }
.endpoint-link { color: var(--accent-ink); font-size: 13px; }
.endpoint-link:hover { text-decoration: underline; }
.endpoint-note { font-size: 12px; color: var(--text-faint); }

/* Numbered steps: the marker is our own, so it can sit beside the text as a
   column rather than inside the flow of the first line. */
.steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 18px; }
.step { display: grid; grid-template-columns: 26px 1fr; gap: 12px; align-items: start; }
.step-n { width: 26px; height: 26px; border-radius: 50%; background: var(--accent-weak); color: var(--accent-ink); display: grid; place-items: center; font-size: 12px; font-weight: 700; }
.step b { font-size: 13.5px; display: block; margin-bottom: 3px; }
.step p { margin: 0 0 9px; font-size: 13px; color: var(--text-muted); line-height: 1.65; }
.step p:last-child { margin-bottom: 0; }
.step code { font-size: 12.5px; }

.field-row { display: flex; gap: 10px; align-items: center; }
.field-row .input { flex: 1; }
.field-hint { display: block; margin-top: 5px; font-size: 12px; color: var(--text-faint); }

/* ---------- Verification level editor ---------- */
/* Countries and the selfie step are the same kind of thing — a required step
   with options — so they share one row shape. The selfie row used to push its
   checkbox to the far right with flex:1, landing it in a column of its own
   while every document checkbox sat 150px in. Same question, two alignments,
   which is what made it read as unrelated. */
.level-row { display: flex; align-items: center; gap: 14px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.level-row:last-of-type { border-bottom: none; }
.level-row-label { width: 150px; font-weight: 600; flex: none; }
.level-row-options { display: flex; gap: 18px; flex-wrap: wrap; }
.level-option { display: flex; align-items: center; gap: 7px; font-size: 13px; cursor: pointer; }

/* ---------- Webhook event picker ---------- */
/* A list of checkboxes rather than a <select>: an endpoint subscribes to
   several events, and a multi-select is the control users most reliably get
   wrong (ctrl-click to add, click to silently replace everything). */
.event-picker { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; margin: 0 0 16px; }
.event-picker legend { font-size: 12.5px; font-weight: 600; color: var(--text-muted); padding: 0 6px; }
.event-all { display: flex; gap: 10px; align-items: flex-start; padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--border); }
.event-list { display: flex; flex-direction: column; gap: 9px; }
/* Ticking "All events" makes the individual boxes meaningless, so they are
   dimmed and disabled rather than left looking like they still decide
   something. */
.event-list.is-covered { opacity: .45; }
.event-option { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; }
/* Both the wildcard row and the individual ones stack a name over its
   description. Only .event-option had the rule, so "All events" ran its label
   and its explanation together on one line. */
.event-option span, .event-all span { display: flex; flex-direction: column; gap: 2px; }
.event-option small, .event-all small { font-size: 12px; color: var(--text-faint); }
.event-option input, .event-all input { margin-top: 2px; flex-shrink: 0; }
.event-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.delivery-error { margin-top: 4px; font-size: 11.5px; color: var(--text-faint); max-width: 260px; }
.card-note-text { margin: 16px 0 0; font-size: 12.5px; color: var(--text-faint); line-height: 1.6; }
.form-field label { font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.input { width: 100%; padding: 10px 12px; border-radius: 9px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); font-size: 14px; font-family: inherit; }
.input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
/* Declared after .input on purpose: same specificity, so order is what decides
   whether the field reads as text or as a box. */
.input-inline { flex: 1; min-width: 130px; background: none; border-color: transparent; font-weight: 600; }
.input-inline:hover { border-color: var(--border-strong); }
.input-inline:focus { background: var(--surface); border-color: var(--accent); }


/* ---------- Alert ---------- */
.alert { display: flex; gap: 10px; padding: 11px 13px; border-radius: 9px; font-size: 13px; margin-bottom: 16px; }
.alert.error { background: var(--danger-weak); color: var(--danger-ink); border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent); }
.alert.info { background: var(--accent-weak); color: var(--accent-ink); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); }

.empty { text-align: center; color: var(--text-muted); padding: 40px 20px; }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 14px; color: var(--text-muted); font-size: 12.5px; }
.pager-links { display: flex; gap: 8px; }

/* ---------- Auth ---------- */
.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.auth-card { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 32px; }
.auth-brand { display: flex; align-items: center; gap: 11px; margin-bottom: 24px; }
.auth-brand .brand-name { font-size: 20px; }
.auth-card h1 { font-size: 20px; margin: 0 0 4px; letter-spacing: -.02em; }
.auth-card .sub { color: var(--text-muted); font-size: 13.5px; margin: 0 0 22px; }

@media (max-width: 720px) {
  .app { grid-template-columns: 1fr; }
  .sidebar { display: none; }
  .kpi-row { grid-template-columns: 1fr 1fr; }
}
