/* KAS design system.
 *
 * Mobile-first and dark-first. The reference points are Dark Sky and Oura:
 * near-black ground, soft floating surfaces, generous vertical rhythm, and
 * colour reserved for meaning rather than decoration. Risk tier is the only
 * thing allowed to be loud.
 *
 * Layout rule: one primary action per card. Everything secondary is one tap
 * away, not competing for the same row.
 */

:root {
  /* Ground and surfaces */
  --bg: #0b0c0f;
  --surface: #14161b;
  --surface-raised: #1b1e25;
  --line: rgba(255, 255, 255, 0.07);
  --line-strong: rgba(255, 255, 255, 0.13);

  /* Type */
  --text: #eceef2;
  --text-dim: #8a909d;
  --text-faint: #5c626e;

  /* Brand. Taken from the mark: a deep violet and the pale lilac inside it.
     These are the two fixed points; everything tinted derives from them. */
  --brand: #4A2E6B;
  --brand-soft: #D9CCEE;

  /* Meaning. The accent was a blue that had nothing to do with the mark, so
     every highlighted thing pulled against the logo sitting above it. It is
     now the brand violet, lightened for a dark ground where #4A2E6B is too
     close to the background to read as emphasis. */
  --accent: #B49BE8;
  --accent-quiet: color-mix(in srgb, var(--accent) 14%, transparent);
  /* Text on top of the accent. The accent is pale on a dark ground and deep
     on a light one, so a single hardcoded colour is unreadable in one of the
     two — which is exactly what happened when the accent changed. */
  --on-accent: #16101f;

  /* Left alone on purpose: red, amber and green are what a reader already
     knows danger, caution and safety look like. Bending them toward the brand
     would cost more in comprehension than it gains in tidiness. */
  --high: #e8615a;
  --medium: #d9a24a;
  --low: #4fa97b;

  /* Rhythm — 4px base */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s7: 32px; --s8: 48px;

  --r-card: 14px;
  --r-btn: 10px;
  --r-pill: 999px;

  /* Motion. Entrances ease out; nothing bounces. */
  --fast: 130ms cubic-bezier(0.3, 0, 0.2, 1);
  --base: 220ms cubic-bezier(0.2, 0, 0, 1);

  --safe-b: env(safe-area-inset-bottom, 0px);
}

/* Light, when the system asks for it. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #f7f8fa;
    --surface: #ffffff;
    --surface-raised: #ffffff;
    --line: rgba(0, 0, 0, 0.08);
    --line-strong: rgba(0, 0, 0, 0.14);
    --text: #14171d;
    --text-dim: #646b78;
    --text-faint: #939aa6;
    /* Darker than the dark-mode accent for the same reason, in reverse: the
       pale lilac disappears against white. */
    --accent: #5B3A8C;
    --brand-soft: #EDE6F7;
    --on-accent: #ffffff;
  }
}

/* Light, because the reader chose it — has to win over the media query above,
   which it does on both order and specificity. */
:root[data-theme="light"] {
    --bg: #f7f8fa;
    --surface: #ffffff;
    --surface-raised: #ffffff;
    --line: rgba(0, 0, 0, 0.08);
    --line-strong: rgba(0, 0, 0, 0.14);
    --text: #14171d;
    --text-dim: #646b78;
    --text-faint: #939aa6;
    /* Darker than the dark-mode accent for the same reason, in reverse: the
       pale lilac disappears against white. */
    --accent: #5B3A8C;
    --brand-soft: #EDE6F7;
    --on-accent: #ffffff;
}

/* Dark, because the reader chose it. Nothing is needed here beyond the base
   values at the top; this exists so the light media query cannot override a
   deliberate choice. */
:root[data-theme="dark"] {
  --bg: #0b0c0f;
  --surface: #14161b;
  --surface-raised: #1b1e25;
  --line: rgba(255, 255, 255, 0.07);
  --line-strong: rgba(255, 255, 255, 0.13);
  --text: #eceef2;
  --text-dim: #8a909d;
  --text-faint: #5c626e;
  --accent: #B49BE8;
  --brand-soft: #D9CCEE;
  --on-accent: #16101f;
}

@media (prefers-reduced-motion: reduce) {
  :root { --fast: 1ms; --base: 1ms; }
  * { animation: none !important; }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code { font: 0.92em/1 ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ───────────────────────── Header ───────────────────────── */

header {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s4) var(--s5);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  position: sticky; top: 0; z-index: 20;
  border-bottom: 1px solid var(--line);
}

.brand {
  font-weight: 700; letter-spacing: 0.14em; font-size: 14px;
  margin-right: auto;
}

/* Desktop nav lives in the header; on mobile it moves to a bottom bar. */
header nav { display: none; gap: var(--s5); margin-right: auto; }
header nav a { color: var(--text-dim); font-size: 14px; font-weight: 500; }
header nav a:hover { color: var(--text); text-decoration: none; }
header nav a.on { color: var(--text); }

header form.signout-header { display: none; }

/* ───────────────────── Poller status pill ───────────────────── */

.poller-control { display: flex; align-items: center; gap: var(--s2); }

.pill {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: 12.5px; font-weight: 500; color: var(--text-dim);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: var(--s1) var(--s3); min-height: 30px;
}
.pill:hover { text-decoration: none; color: var(--text); }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint); }
.pill.on { color: var(--low); border-color: color-mix(in srgb, var(--low) 40%, transparent); }
.pill.on .dot { background: var(--low); animation: breathe 2.6s ease-in-out infinite; }

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--low) 55%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--low) 0%, transparent); }
}

/* ───────────────────────── Banner ───────────────────────── */

.banner {
  padding: var(--s3) var(--s5); font-size: 13.5px; color: var(--text-dim);
  border-bottom: 1px solid var(--line);
}
.banner strong { color: var(--text); font-weight: 600; }
.banner.shadow { background: color-mix(in srgb, var(--low) 9%, transparent); }
.banner.active { background: color-mix(in srgb, var(--high) 10%, transparent); }

/* ───────────────────────── Layout ───────────────────────── */

main {
  max-width: 720px; margin: 0 auto;
  padding: var(--s6) var(--s5) calc(var(--s8) + 64px + var(--safe-b));
}

h1 {
  font-size: 23px; line-height: 1.2; letter-spacing: -0.02em;
  font-weight: 650; margin: 0 0 var(--s4);
}
h2 { font-size: 17px; font-weight: 600; margin: var(--s7) 0 var(--s3); letter-spacing: -0.01em; }
h3 { font-size: 13px; font-weight: 600; color: var(--text-dim); margin: var(--s5) 0 var(--s2); }

.count { color: var(--text-faint); font-weight: 400; font-size: 20px; margin-left: var(--s2); }
.note { color: var(--text-dim); font-size: 13.5px; line-height: 1.5; }
/* Full-height only when the whole page is empty; inside a section it just
   needs breathing room, not a void. */
.empty {
  color: var(--text-dim); font-size: 14.5px; line-height: 1.6;
  padding: var(--s6) 0;
}
.queue + .empty, main > .empty {
  text-align: center; padding: var(--s8) var(--s5);
}
.saved { color: var(--low); font-size: 14px; }
.error { color: var(--high); font-size: 14px; }

footer {
  max-width: 720px; margin: 0 auto;
  padding: var(--s6) var(--s5) calc(var(--s6) + 64px + var(--safe-b));
  color: var(--text-faint); font-size: 12.5px; line-height: 1.55;
  border-top: 1px solid var(--line);
}

/* ───────────────────────── Queue ───────────────────────── */

.queue { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s3); }

.queue > li {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--s5);
  position: relative; overflow: hidden;
  animation: rise var(--base) both;
}
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.queue > li:nth-child(2) { animation-delay: 30ms; }
.queue > li:nth-child(3) { animation-delay: 60ms; }
.queue > li:nth-child(n+4) { animation-delay: 90ms; }

/* Tier reads as a colour bar down the leading edge — the only loud colour. */
.queue > li::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--text-faint);
}
.queue > li.tier-high::before { background: var(--high); }
.queue > li.tier-medium::before { background: var(--medium); }
.queue > li.tier-low::before { background: var(--low); }
.queue > li.reviewed { opacity: 0.5; }

.row-head { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.subject-link {
  font-size: 16.5px; font-weight: 600; color: var(--text);
  letter-spacing: -0.01em; line-height: 1.35; flex: 1; min-width: 0;
}
.subject-link:hover { text-decoration: none; color: var(--accent); }
.loading { color: var(--text-faint); font-weight: 400; }

.sender {
  color: var(--text-dim); font-size: 13px; margin: var(--s2) 0 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.tier-badge {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; padding: 3px var(--s2); border-radius: var(--r-pill);
  background: var(--line); color: var(--text-dim); white-space: nowrap;
}
.tier-badge.tier-high { background: color-mix(in srgb, var(--high) 18%, transparent); color: var(--high); }
.tier-badge.tier-medium { background: color-mix(in srgb, var(--medium) 18%, transparent); color: var(--medium); }
.tier-badge.tier-low { background: color-mix(in srgb, var(--low) 16%, transparent); color: var(--low); }

.done {
  font-size: 11px; color: var(--text-faint);
  border: 1px solid var(--line); border-radius: var(--r-pill); padding: 2px var(--s2);
}

.reasons { margin: var(--s4) 0 0; padding: 0; list-style: none; display: grid; gap: var(--s2); }
.reasons li {
  color: var(--text-dim); font-size: 14px; line-height: 1.5;
  padding-left: var(--s4); position: relative;
}
.reasons li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 4px; height: 4px; border-radius: 50%; background: var(--text-faint);
}

.tags { display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s3); }
.tag {
  font-size: 11.5px; color: var(--text-faint);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 2px var(--s2);
}

/* ───────────────────────── Actions ───────────────────────── */

.actions {
  display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
  margin-top: var(--s5);
}
.actions.big { margin: var(--s6) 0; }

button {
  font: inherit; font-size: 14px; font-weight: 550;
  min-height: 44px;                     /* touch target */
  padding: 0 var(--s4);
  border-radius: var(--r-btn);
  border: 1px solid var(--line-strong);
  background: var(--surface-raised); color: var(--text);
  cursor: pointer;
  transition: transform var(--fast), background var(--fast), border-color var(--fast);
}
button:hover { border-color: var(--text-faint); }
button:active { transform: scale(0.97); }

button.primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--on-accent); font-weight: 650;
}
button.primary:hover { filter: brightness(1.07); }

button.danger { color: var(--high); border-color: color-mix(in srgb, var(--high) 35%, var(--line)); }
button.danger:hover { background: var(--high); border-color: var(--high); color: #fff; }

button.small { min-height: 32px; font-size: 13px; padding: 0 var(--s3); }
button.link {
  border: none; background: none; color: var(--text-dim);
  min-height: 32px; padding: 0; font-weight: 500;
}
button.link:hover { color: var(--text); }

.sep { flex-basis: 100%; height: 0; }
.view { font-size: 13.5px; margin-left: auto; order: 4; color: var(--text-dim); }
form.inline { display: inline-flex; gap: var(--s2); }

/* ───────────────────── Message detail ───────────────────── */

.back { margin-bottom: var(--s4); font-size: 14px; }
.meta {
  display: flex; gap: var(--s2) var(--s4); flex-wrap: wrap;
  color: var(--text-dim); font-size: 13px; margin-bottom: var(--s5);
  align-items: center;
}
.why {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s2) var(--s5) var(--s5);
}
.why h2 { margin-top: var(--s5); }
.why ul { margin: 0; padding-left: var(--s5); }
.why li { color: var(--text-dim); font-size: 14.5px; line-height: 1.55; margin-bottom: var(--s2); }

.email-body {
  white-space: pre-wrap; word-break: break-word;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s5);
  font: 13px/1.65 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text-dim);
  max-height: 55vh; overflow: auto;
  -webkit-overflow-scrolling: touch;
}
.links {
  font: 12px/1.7 ui-monospace, Menlo, monospace;
  word-break: break-all; color: var(--text-dim); padding-left: var(--s5);
}
.prior { color: var(--text-faint); font-size: 13px; }

details.stages { margin-top: var(--s6); }
details.stages summary {
  cursor: pointer; color: var(--text-dim); font-size: 13.5px;
  min-height: 44px; display: flex; align-items: center;
}

/* ───────────────────────── Tables ───────────────────────── */

table { width: 100%; border-collapse: collapse; font-size: 14px; margin: var(--s2) 0; }
th, td { text-align: left; padding: var(--s3) var(--s2); border-bottom: 1px solid var(--line); }
th { color: var(--text-faint); font-weight: 500; font-size: 12px;
     text-transform: uppercase; letter-spacing: 0.06em; }
td { color: var(--text-dim); }
td:last-child { text-align: right; color: var(--text); font-variant-numeric: tabular-nums; }

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.audit td { font-size: 12.5px; }
table.audit td:last-child { text-align: left; color: var(--text-dim); }

/* ───────────────────────── Cards / stats ───────────────────────── */

.cards {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--s3); margin-bottom: var(--s5);
}
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s5);
  color: var(--text-dim); font-size: 12.5px; line-height: 1.4;
}
.card .n {
  display: block; font-size: 30px; font-weight: 650; color: var(--text);
  letter-spacing: -0.03em; margin-bottom: var(--s1);
  font-variant-numeric: tabular-nums;
}

/* ───────────────────────── Forms ───────────────────────── */

section { margin-bottom: var(--s7); }
label { display: block; margin-bottom: var(--s4); font-size: 14px; }
label.radio, label.check {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s3); margin: 0 calc(-1 * var(--s3)) var(--s1);
  border-radius: var(--r-btn); cursor: pointer;
  transition: background var(--fast);
}
label.radio:hover, label.check:hover { background: var(--surface); }
label.radio input, label.check input { margin-top: 3px; width: 18px; height: 18px; accent-color: var(--accent); }

.grid { display: grid; grid-template-columns: 1fr; gap: var(--s4); }

input[type=number], input[type=password], input[type=text],
input[type=email], select, textarea {
  font: inherit; font-size: 16px;      /* 16px stops iOS zooming on focus */
  width: 100%; min-height: 44px; padding: var(--s3) var(--s4);
  border-radius: var(--r-btn); border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--text);
  transition: border-color var(--fast);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
}
textarea { font: 13.5px/1.6 ui-monospace, Menlo, monospace; resize: vertical; min-height: 200px; }

.unlock {
  margin-top: var(--s4); padding: var(--s4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.blocked { font: 13px/1.9 ui-monospace, Menlo, monospace; color: var(--text-dim); padding-left: var(--s5); }

/* ───────────────────────── Status page ───────────────────────── */

.statusbox {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s2) var(--s5) var(--s6);
}
.statusbox.on { border-color: color-mix(in srgb, var(--low) 30%, transparent); }
.statusbox h2 { display: flex; align-items: center; gap: var(--s3); font-size: 19px; }
.statusbox .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--text-faint); flex: none; }
.statusbox.on .dot { background: var(--low); animation: breathe 2.6s ease-in-out infinite; }
.statusbox p { color: var(--text-dim); font-size: 14px; }

/* ───────────────────────── Suggestions ───────────────────────── */

.suggestions { list-style: none; padding: 0; display: grid; gap: var(--s3); }
.suggestions li {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s4) var(--s5);
  display: grid; gap: var(--s3);
}
.suggestions .why {
  display: block; color: var(--text-faint); font-size: 12.5px;
  background: none; border: none; padding: 0; margin-top: var(--s1);
}

/* ───────────────────────── Login ───────────────────────── */

/* A fixed fraction of the viewport pushed this down by 14% of the *full*
   screen even with a keyboard open covering half of it — iOS does not shrink
   vh units for the keyboard — so the field being typed into ended up beneath
   it. Clamped, and it gives up the space entirely on a short screen. */
.login {
  max-width: 340px;
  margin: clamp(var(--s5), 8vh, 72px) auto 0;
  text-align: center;
}
@media (max-height: 620px) { .login { margin-top: var(--s4); } }

/* Focusing a field scrolls it into view; without this the browser is free to
   stop with it flush against the keyboard. */
input, textarea, select { scroll-margin-block: var(--s8) 40vh; }
.login h1 { letter-spacing: 0.16em; font-size: 26px; margin-bottom: var(--s7); }
.login label { text-align: left; font-size: 13px; color: var(--text-dim); margin-bottom: var(--s2); }
.login button { width: 100%; margin-top: var(--s4); }

pre {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-btn); padding: var(--s4); overflow-x: auto;
  font: 13px/1.6 ui-monospace, Menlo, monospace; color: var(--text-dim);
}

/* ───────────────────── Bottom nav (mobile) ───────────────────── */

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; justify-content: space-around; align-items: stretch;
  padding-bottom: var(--safe-b);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(160%) blur(16px);
  border-top: 1px solid var(--line);
}
.tabbar a {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px;
  padding: var(--s2) 0 var(--s3); min-height: 56px;
  color: var(--text-faint); font-size: 10.5px; font-weight: 550;
  letter-spacing: 0.02em; text-decoration: none;
  transition: color var(--fast);
}
.tabbar a svg { width: 21px; height: 21px; stroke-width: 1.7; }
.tabbar a.on { color: var(--accent); }
.tabbar a:active { color: var(--text); }
.tabbar .badge {
  position: absolute; transform: translate(14px, -10px);
  min-width: 16px; height: 16px; padding: 0 4px;
  background: var(--high); color: #fff;
  border-radius: var(--r-pill); font-size: 10px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}

/* ───────────────────────── Desktop ─────────────────────────
   Gated on a fine pointer, not width alone. A Galaxy Fold unfolds to roughly
   700-900 CSS px, so a width-only rule flipped it into desktop mode — moving
   navigation from thumb reach at the bottom to the top of a screen that is
   still being held in two hands. Width tells you how much room there is;
   pointer tells you what the user is doing with it. */

@media (min-width: 720px) and (pointer: fine), (min-width: 1024px) {
  header nav { display: flex; }
  .brand { margin-right: var(--s6); }
  header form.signout-header { display: inline-flex; }
  .tabbar { display: none; }
  main { padding-bottom: var(--s8); }
  footer { padding-bottom: var(--s7); }
  .cards { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
  h1 { font-size: 32px; }
}

/* ─────────────────── Foldables and tablets ───────────────────
   Unfolded, a Fold is a nearly square canvas around 700-900px wide, held in
   both hands. It wants the extra width used and the bottom bar kept. Capped
   below 1024px so a landscape tablet still gets the desktop treatment rather
   than a tab bar stretched across the whole screen. */

@media (min-width: 680px) and (max-width: 1023px) and (pointer: coarse) {
  header nav { display: none; }
  .tabbar { display: flex; }

  main { max-width: 860px; padding-left: var(--s6); padding-right: var(--s6); }
  h1 { font-size: 30px; }

  /* Two columns where the content is a set of independent items. Forms are
     left alone — a fieldset split across a column break is worse than a
     narrow one. */
  .cards { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
  .grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
  .usagegrid { grid-template-columns: repeat(4, 1fr); }

  /* The bar spans the full width, but its targets should not: a 900px-wide
     row of five icons puts them nowhere near a thumb. */
  .tabbar { justify-content: center; gap: var(--s8); }
  .tabbar a { flex: 0 0 auto; min-width: 72px; }
}

/* The cover screen: ~360px and very tall. Nothing here is a new layout, only
   less air, so more than one card is visible at a time. */
@media (max-width: 400px) {
  main { padding-left: var(--s3); padding-right: var(--s3); }
  h1 { font-size: 24px; }
  section { margin-bottom: var(--s5); }
  .settings-nav { gap: 2px; }
  .settings-nav a { padding: 3px var(--s2); font-size: 11px; }
}

/* Unfolding mid-session changes the viewport under a laid-out page. Sizing in
   relative units and letting wide content scroll inside its own box means the
   reflow is a reflow, not a horizontal scrollbar on the body. */
.legend, .oprow, .usagegrid, .grid { max-width: 100%; }
.queue, .blocked { overflow-wrap: anywhere; }

/* ─────────────── "More" disclosure on queue cards ─────────────── */

.more { order: 3; margin-left: auto; }
.more summary {
  list-style: none; cursor: pointer;
  min-height: 44px; display: flex; align-items: center;
  color: var(--text-dim); font-size: 13.5px; font-weight: 500;
  padding: 0 var(--s2);
}
.more summary::-webkit-details-marker { display: none; }
.more summary:hover { color: var(--text); }
.more[open] summary { color: var(--text); }

.more-actions {
  display: flex; gap: var(--s2); flex-wrap: wrap;
  padding-top: var(--s3); width: 100%;
  animation: rise var(--fast) both;
}
.more[open] { flex-basis: 100%; }

/* ───────────────────────── Charts ─────────────────────────
 *
 * Server-rendered inline SVG: no charting library, no inline styles, so the
 * strict CSP stands. Dynamic widths are SVG presentation attributes, which
 * are not subject to style-src.
 */

.chart {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s5);
}
.chart svg { width: 100%; height: 90px; display: block; }
.chart .bar-total { fill: var(--line-strong); }
.chart .bar-held { fill: var(--accent); }
.chart .axis { stroke: var(--line); stroke-width: 0.5; }

.chart-legend {
  display: flex; gap: var(--s4); align-items: center;
  margin-top: var(--s3); font-size: 12px; color: var(--text-dim);
}
.chart-legend .right { margin-left: auto; color: var(--text-faint); }
.swatch {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: var(--s1); vertical-align: -1px;
}
.swatch.total { background: var(--line-strong); }
.swatch.held { background: var(--accent); }

/* Was KAS right? */
.verdict {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: var(--s5);
}
.verdict-bar { width: 100%; height: 8px; display: block; margin-bottom: var(--s5); }
.verdict-bar .track { fill: var(--line); }
.verdict-bar .correct { fill: var(--low); }
.verdict-nums { display: grid; gap: var(--s4); }
.verdict-nums > div { color: var(--text-dim); font-size: 13.5px; }
.verdict-nums .n {
  display: inline-block; min-width: 2ch; margin-right: var(--s3);
  font-size: 26px; font-weight: 650; color: var(--text);
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
  vertical-align: -3px;
}
.verdict-nums .n.warn { color: var(--high); }

/* Cost breakdown */
.costrow { margin-bottom: var(--s4); }
.costrow-head {
  display: flex; align-items: baseline; gap: var(--s3);
  font-size: 13.5px; margin-bottom: var(--s2);
}
.costrow .stage { color: var(--text); font-weight: 550; }
.costrow .calls { color: var(--text-faint); font-size: 12px; }
.costrow .amount {
  margin-left: auto; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.costbar { width: 100%; height: 4px; display: block; }
.costbar .fill { fill: var(--accent); }

/* ─────────────────── Grouped queue ─────────────────── */

.day-group { margin-bottom: var(--s5); }
.day-group > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--s3);
  min-height: 44px; padding: 0 var(--s1);
  font-size: 13px; font-weight: 600; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.day-group > summary::-webkit-details-marker { display: none; }
.day-group > summary::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}
.day-group > summary .n {
  color: var(--text-faint); font-weight: 500;
  text-transform: none; letter-spacing: 0;
}
.day-group > summary:hover { color: var(--text); }
.day-group[open] > summary { color: var(--text); }

/* ---------------------------------------------------------------------------
   Settings
   The page carries the decisions with real consequences — what KAS is allowed
   to move, who pays for the AI, when scanning stops. Each section states the
   tradeoff rather than only the control, so a choice is never made blind.
   --------------------------------------------------------------------------- */

.settings-nav {
  display: flex; flex-wrap: wrap; gap: var(--s1);
  margin: 0 0 var(--s6);
}
.settings-nav a {
  font-size: 12px; letter-spacing: 0.02em;
  color: var(--text-dim); text-decoration: none;
  padding: var(--s1) var(--s3);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  transition: color var(--fast), border-color var(--fast);
}
.settings-nav a:hover, .settings-nav a:focus-visible {
  color: var(--text); border-color: var(--line-strong);
}

.section-intro {
  margin: calc(var(--s2) * -1) 0 var(--s4);
  color: var(--text-dim); font-size: 14px; line-height: 1.5;
}

/* What each routing action actually does, next to the control that sets it. */
.legend {
  margin: var(--s3) 0 var(--s4); padding: var(--s3) var(--s4);
  background: var(--surface-raised); border-radius: var(--r-btn);
  font-size: 13px; line-height: 1.6;
  display: grid; grid-template-columns: auto 1fr; gap: var(--s1) var(--s3);
}
.legend dt { color: var(--text); font-weight: 600; font-family: ui-monospace, monospace; }
.legend dd { margin: 0; color: var(--text-dim); }

/* Usage meters ------------------------------------------------------------ */

.meterrow { margin: 0 0 var(--s4); }
.meterhead {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: var(--s2); font-size: 13px; color: var(--text-dim);
}
.meterhead strong { color: var(--text); font-variant-numeric: tabular-nums; }
.meter {
  height: 8px; border-radius: var(--r-pill);
  background: var(--surface-raised); overflow: hidden;
}
.meter i {
  display: block; height: 100%; border-radius: var(--r-pill);
  background: var(--low); transition: width var(--base);
}
.meter i.near { background: var(--medium); }
.meter i.over { background: var(--high); }

.usagegrid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3);
  margin-bottom: var(--s4);
}
.usagestat {
  background: var(--surface-raised); border-radius: var(--r-btn);
  padding: var(--s4); text-align: center;
}
.usagestat .n {
  display: block; font-size: 26px; font-weight: 650;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.usagestat .k {
  display: block; margin-top: var(--s1);
  font-size: 12px; color: var(--text-dim);
}

.warn {
  margin: var(--s3) 0; padding: var(--s3) var(--s4);
  border-radius: var(--r-btn); font-size: 13px; line-height: 1.55;
  background: color-mix(in srgb, var(--high) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--high) 35%, transparent);
}

/* Advanced ---------------------------------------------------------------- */

.advanced {
  border: 1px solid var(--line); border-radius: var(--r-card);
  margin: var(--s6) 0; background: var(--surface);
}
.advanced > summary {
  cursor: pointer; list-style: none;
  padding: var(--s4) var(--s5);
  display: flex; justify-content: space-between; align-items: center;
  font-weight: 600;
}
.advanced > summary::-webkit-details-marker { display: none; }
.advanced > summary .hint { font-weight: 400; font-size: 12px; color: var(--text-faint); }
.advanced > summary::after {
  content: "›"; margin-left: var(--s3); color: var(--text-faint);
  transition: transform var(--fast);
}
.advanced[open] > summary::after { transform: rotate(90deg); }
.advanced[open] > summary { border-bottom: 1px solid var(--line); }
.advanced > section { padding: 0 var(--s5) var(--s5); }
.advanced h3 { font-size: 15px; margin: var(--s5) 0 var(--s2); }

/* The honest-tradeoff block: visually distinct from a hint, because it is the
   part a user deciding whether to trust this with their mail actually needs. */
.truth {
  padding: var(--s4); border-radius: var(--r-btn);
  background: var(--surface-raised);
  border-left: 2px solid var(--accent);
}

.keyrow { margin-top: var(--s4); }
.keystate {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 13px; color: var(--text-dim); margin-bottom: var(--s2);
}
.keystate .ok { color: var(--low); font-family: ui-monospace, monospace; }
.keystate .muted { color: var(--text-faint); }
.keyrow input[type="password"] { width: 100%; font-family: ui-monospace, monospace; }
.keyrow .actions { margin-top: var(--s3); }

.modelgrid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

.savebar { width: 100%; margin-top: var(--s5); }

@media (max-width: 420px) {
  .usagegrid { grid-template-columns: 1fr; }
}

/* Operator console --------------------------------------------------------
   Deliberately plain. It shows counts and money, not mail, and it should not
   look like a place where mail could be read. */

.opgrid { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.usagestat .n.danger { color: var(--high); }

.opaccount {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface); margin-bottom: var(--s3);
}
.opaccount > summary {
  cursor: pointer; list-style: none; padding: var(--s4) var(--s5);
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--s3);
}
.opaccount > summary::-webkit-details-marker { display: none; }
.opaccount[open] > summary { border-bottom: 1px solid var(--line); }
.opemail {
  font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.opmeta { display: flex; align-items: center; gap: var(--s2); flex-shrink: 0; }
.opcost { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Scoped: an unqualified .pill here was overriding the header status pill
   further up the file, shrinking it to 11px. These are the small inline tags
   used inside cards, not the status control. */
.opmeta .pill, .guardhead .pill, .pcardhead .pill {
  font-size: 11px; padding: 2px var(--s2); border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); color: var(--text-dim);
}
.pill.own { color: var(--low); border-color: color-mix(in srgb, var(--low) 45%, transparent); }
.pill.kas { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.pill.paused { color: var(--high); border-color: color-mix(in srgb, var(--high) 45%, transparent); }

.oprow {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s1) var(--s4);
  padding: var(--s4) var(--s5) 0; font-size: 13px; margin: 0;
}
.oprow dt { color: var(--text-dim); }
.oprow dd { margin: 0; font-variant-numeric: tabular-nums; }

.oplimits { padding: var(--s4) var(--s5) var(--s5); }

/* Trusted Guardian --------------------------------------------------------
   Every screen here is read by someone deciding whether to trust another
   person with their mail, so the copy carries the weight and the styling
   stays quiet. */

.codebox {
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-radius: var(--r-card); padding: var(--s5); margin-bottom: var(--s5);
}
.codebox .code {
  font-size: 40px; font-weight: 650; letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums; text-align: center;
  margin: var(--s3) 0; font-family: ui-monospace, monospace;
}

.guardian {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface); padding: var(--s5); margin-bottom: var(--s4);
}
.guardian.pending {
  border-color: color-mix(in srgb, var(--medium) 50%, transparent);
  background: color-mix(in srgb, var(--medium) 7%, transparent);
}
.guardhead {
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--s3); margin-bottom: var(--s3);
}
.guardhead .who {
  display: block; font-size: 12px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis;
}
.guardfoot {
  margin-top: var(--s4); padding-top: var(--s4);
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: var(--s3);
  align-items: center; justify-content: space-between;
}
.irreversible { color: var(--high); font-style: normal; }

.reconsent {
  border-radius: var(--r-btn); padding: var(--s4); margin-bottom: var(--s4);
  background: color-mix(in srgb, var(--medium) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--medium) 35%, transparent);
}

/* The code is the secret; the address is not. Styled to make that difference
   legible at a glance, because the whole protocol rests on it. */
.codesay { margin: 0 0 var(--s4); text-align: center; font-size: 14px; }
.codelink {
  border-top: 1px dashed color-mix(in srgb, var(--accent) 35%, transparent);
  padding-top: var(--s4); margin-top: var(--s4);
}
.codelinklede { font-size: 13px; color: var(--text-dim); margin: 0 0 var(--s2); }
.joinurl {
  font-family: ui-monospace, monospace; font-size: 15px; font-weight: 600;
  margin: 0 0 var(--s2); color: var(--accent);
  /* `anywhere` rather than `break-all`: browsers then prefer the slashes, so a
     narrow phone splits the address between path segments instead of through
     the middle of a word. */
  overflow-wrap: anywhere; word-break: normal;
}

.guardwait { text-align: center; padding: var(--s6) var(--s4); }
/* Instructions the guardian reads aloud, so they need to be scannable while
   talking rather than pretty. */
.readout {
  text-align: left; border: 1px solid var(--line); border-radius: var(--r-card);
  padding: var(--s4); margin: var(--s5) 0; background: var(--surface);
}
.readoutlede {
  font-size: 13px; color: var(--text-dim); margin: 0 0 var(--s3);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.readsteps { padding-left: var(--s5); margin: 0; font-size: 15px; }
.readsteps li { padding: var(--s2) 0; line-height: 1.5; }

.guardended {
  border-radius: var(--r-card); padding: var(--s5); margin-bottom: var(--s5);
  border: 1px solid var(--line); background: var(--surface);
}
.guardended h2 { margin-top: 0; }

/* The guardian's way in, on the owner's sign-in page. Set apart so it cannot
   be mistaken for a third way for the owner to sign in. */
.guardianentry {
  margin-top: var(--s6); padding-top: var(--s5);
  border-top: 1px solid var(--line); text-align: center;
}
.guardianentry p { margin: 0 0 var(--s2); }

/* The guardian's own notification controls, on their own screen — Settings
   belongs to whoever owns a mailbox, and a guardian may not own one. */
.gnotify {
  margin-top: var(--s6); padding: var(--s5);
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface);
}
.gnotify h2 { margin-top: 0; font-size: 16px; }
.gnotify .actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s4) 0; }

.guardadd { margin-top: var(--s5); font-size: 14px; }

/* Folded away: it is the guardian's own exit, not something to offer them
   every time they open the app. */
.standdown { margin-top: var(--s3); }
.standdown > summary {
  cursor: pointer; font-size: 13px; color: var(--text-dim);
  padding: var(--s2) 0;
}
.standdown[open] > summary { margin-bottom: var(--s3); }

.optional { color: var(--text-faint); font-weight: 400; }

.signout-footer {
  margin-top: var(--s7); padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

.linkbutton {
  display: inline-block; padding: var(--s3) var(--s4);
  border: 1px solid var(--line-strong); border-radius: var(--r-btn);
  text-decoration: none; color: var(--text); font-weight: 600; font-size: 14px;
}
.linkbutton:hover { border-color: var(--accent); color: var(--accent); }

/* Sign-in and onboarding -------------------------------------------------- */

.tagline {
  color: var(--text-dim); font-size: 15px; line-height: 1.5;
  margin-bottom: var(--s6);
}
.googlebtn {
  display: block; text-align: center; text-decoration: none;
  padding: var(--s4); border-radius: var(--r-btn);
  background: var(--text); color: var(--bg);
  font-weight: 650; font-size: 15px;
}
.googlebtn:hover { opacity: 0.9; }
.or {
  text-align: center; color: var(--text-faint); font-size: 12px;
  margin: var(--s5) 0; text-transform: uppercase; letter-spacing: 0.08em;
}

/* Said before the user meets it, not after — being surprised by a security
   warning is the wrong first impression for a product about not trusting
   things. */
.expect {
  margin-top: var(--s5); padding: var(--s4);
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface-raised);
  font-size: 13px; line-height: 1.6; color: var(--text-dim);
}
.expect h2 { font-size: 13px; color: var(--text); margin: 0 0 var(--s2); }
.expect p { margin: 0 0 var(--s3); }
.expect p:last-child { margin-bottom: 0; }

.welcome .steps { list-style: none; padding: 0; counter-reset: step; }
.welcome .steps > li {
  counter-increment: step; position: relative;
  padding: var(--s5) 0 var(--s5) var(--s7);
  border-bottom: 1px solid var(--line);
}
.welcome .steps > li:last-child { border-bottom: 0; }
.welcome .steps > li::before {
  content: counter(step); position: absolute; left: 0; top: var(--s5);
  width: 22px; height: 22px; border-radius: var(--r-pill);
  background: var(--surface-raised); color: var(--text-dim);
  font-size: 12px; font-weight: 650;
  display: flex; align-items: center; justify-content: center;
}
.welcome .steps h2 { font-size: 15px; margin: 0 0 var(--s2); }
.welcome .steps p { font-size: 14px; line-height: 1.6; margin: 0 0 var(--s2); }
.welcome .actions { margin-top: var(--s6); display: flex; flex-wrap: wrap; gap: var(--s3); }
.linkbutton.primary-link {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}

/* ─────────────────── Settings groups ───────────────────
   Each group is a collapsed row whose right-hand side states its current
   value. The page previously showed every control at once, so finding out
   what KAS was set to do meant reading all of it; this way the summary column
   answers that in one pass, and opening a row is a deliberate act. */

.sgroup {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface); margin-bottom: var(--s3);
  overflow: hidden;
}
.sgroup > summary {
  cursor: pointer; list-style: none;
  padding: var(--s4) var(--s5);
  display: flex; align-items: center; gap: var(--s4);
  /* Comfortably past the 44px minimum: these are read and tapped on a phone
     by people who are not necessarily quick with a touchscreen. */
  min-height: 56px;
}
.sgroup > summary::-webkit-details-marker { display: none; }
.sgroup > summary:hover { background: var(--surface-raised); }

.sname { font-weight: 600; flex: 0 0 auto; }
.sval {
  margin-left: auto; text-align: right;
  color: var(--text-dim); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sgroup > summary::after {
  content: "›"; flex: 0 0 auto;
  color: var(--text-faint); font-size: 18px; line-height: 1;
  transition: transform var(--fast);
}
.sgroup[open] > summary::after { transform: rotate(90deg); }
.sgroup[open] > summary { border-bottom: 1px solid var(--line); }

.sbody { padding: var(--s5); }
.sbody > .section-intro { margin-top: 0; }
.sbody h3 {
  font-size: 14px; margin: var(--s6) 0 var(--s2);
  padding-top: var(--s5); border-top: 1px solid var(--line);
}
.sbody h3:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }

/* A group that needs the user's attention says so while still closed —
   a paused scan is the one state you should not have to open a row to find. */
.sgroup.attention { border-color: color-mix(in srgb, var(--high) 45%, transparent); }
.sgroup.attention .sval { color: var(--high); }

/* Same row, but it navigates instead of expanding. */
.slink {
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s4) var(--s5); min-height: 56px;
  text-decoration: none; color: var(--text);
}
.slink::after {
  content: "›"; margin-left: 0; color: var(--text-faint); font-size: 18px;
}
.slink:hover { background: var(--surface-raised); }

.savebar { width: 100%; margin: var(--s5) 0 var(--s6); }

@media (max-width: 400px) {
  /* Long values wrap under the label rather than being squeezed to an
     ellipsis on a cover screen. */
  .sgroup > summary { flex-wrap: wrap; row-gap: 2px; padding: var(--s3) var(--s4); }
  .sval { flex-basis: 100%; text-align: left; margin-left: 0; }
  .sgroup > summary::after { position: absolute; right: var(--s4); }
  .sgroup > summary { position: relative; }
  .sbody { padding: var(--s4); }
}

/* ─────────────────── Profile ───────────────────
   The account, who helps with it, and what it costs. Reached from the avatar
   at the top right — the one control that stays in the same place whether the
   app is on a phone, unfolded, or on a desktop. */

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.avatar {
  flex: 0 0 auto; margin-left: var(--s3);
  width: 34px; height: 34px; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-raised); color: var(--text);
  border: 1px solid var(--line-strong);
  font-weight: 650; font-size: 14px; text-decoration: none;
  transition: border-color var(--fast), color var(--fast);
}
.avatar:hover { border-color: var(--accent); color: var(--accent); }
.avatar.on { border-color: var(--accent); color: var(--accent); }

.phead {
  display: flex; align-items: center; gap: var(--s4);
  margin-bottom: var(--s6);
}
.pavatar {
  flex: 0 0 auto; width: 52px; height: 52px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-raised); border: 1px solid var(--line-strong);
  font-size: 22px; font-weight: 650;
}
.phead h1 { margin: 0; font-size: 24px; }
.pemail {
  margin: 2px 0 0; color: var(--text-dim); font-size: 13px;
  overflow-wrap: anywhere;
}

.pcard {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface); padding: var(--s5); margin-bottom: var(--s4);
}
.pcard.attention { border-color: color-mix(in srgb, var(--medium) 45%, transparent); }
.pcardhead {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); margin-bottom: var(--s2);
}
.pcardhead h2 { margin: 0; font-size: 16px; }
.pcard .linkbutton { margin-top: var(--s3); }
.pcard form { margin-top: var(--s4); }

.plist { list-style: none; padding: 0; margin: 0 0 var(--s3); }
.plist li {
  display: flex; justify-content: space-between; gap: var(--s3);
  padding: var(--s3) 0; border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.plist li:last-child { border-bottom: 0; }
.plist .muted { color: var(--text-dim); font-size: 13px; }

/* ─────────────────── Activity ───────────────────
   A log is only useful if the person it is for can read it. The raw action
   name stays available in the title attribute for debugging. */

.activity { list-style: none; padding: 0; margin: 0; }
.activity > li {
  display: flex; gap: var(--s4);
  padding: var(--s3) 0 var(--s3) var(--s3);
  border-left: 2px solid var(--line);
}
.acttime {
  flex: 0 0 62px; font-size: 12px; color: var(--text-faint);
  font-variant-numeric: tabular-nums; padding-top: 1px;
}
.actbody { flex: 1 1 auto; min-width: 0; }
.actlabel { margin: 0; font-size: 14px; line-height: 1.4; }
.actdetail {
  margin: 2px 0 0; font-size: 13px; color: var(--text-dim);
  overflow-wrap: anywhere;
}
.actlink {
  display: inline-block; margin-top: var(--s2);
  font-size: 12px; color: var(--accent); text-decoration: none;
}

/* Who did it, at a glance — the distinction between "KAS did this" and "you
   did this" is the one someone deciding whether to trust it cares about. */
.act-you { border-left-color: color-mix(in srgb, var(--accent) 55%, transparent); }
.act-kas { border-left-color: var(--line-strong); }
.act-other { border-left-color: color-mix(in srgb, var(--low) 55%, transparent); }
.act-warn { border-left-color: var(--high); }
.act-warn .actlabel { color: var(--high); }

@media (max-width: 400px) {
  .acttime { flex-basis: 54px; font-size: 11px; }
}

/* Destructive operator actions are visually separated and collapsed, because
   the rows above them look alike and one of them cannot be undone. */
.oprow-actions { padding: 0 var(--s5) var(--s4); }
.dangerzone {
  margin: 0 var(--s5) var(--s5);
  border: 1px solid color-mix(in srgb, var(--high) 35%, transparent);
  border-radius: var(--r-btn); padding: var(--s3) var(--s4);
}
.dangerzone > summary { cursor: pointer; color: var(--high); font-size: 13px; }
.dangerzone form { margin-top: var(--s3); }
.dangerzone code { font-size: 12px; }



/* A switcher entry that rebinds the session is a button, not a link, so it
   has to be un-styled back into looking like the links beside it. */
.swmenu form { margin: 0; }
.switchbtn {
  display: block; width: 100%; text-align: left;
  padding: var(--s3) var(--s4); border: 0; border-radius: var(--r-btn);
  background: none; color: var(--text); font: inherit; cursor: pointer;
}
.switchbtn:hover { background: var(--surface-raised); }
.plist form.inline { margin: 0; }
.plist button { font-size: 12px; padding: 2px var(--s3); }


/* ─────────────── Mailbox switcher ───────────────
   Which mailbox you are looking at is status, not navigation, so it wears the
   same pill as the watching indicator and sits between the brand and it.
   Centred in the space between, rather than absolutely: the header's two ends
   are different widths, and pinning it to the true centre made it collide
   with the nav on desktop. */

/* `flex: 0 0 auto` on purpose. With auto margins on both the brand and the nav,
   a shrinkable switcher gets squeezed to the width of its own chevron while the
   label keeps its full size and spills across the navigation — mailbox names
   printed on top of "Quarantine". Sizing to content and truncating inside the
   summary keeps it legible at every width. */
.switcher { position: relative; margin: 0 auto; min-width: 0; flex: 0 0 auto; }
.switcher > summary {
  cursor: pointer; list-style: none;
  max-width: min(46vw, 260px); overflow: hidden;
}
.switcher > summary::-webkit-details-marker { display: none; }
.switcher > summary::after {
  content: "▾"; color: var(--text-faint); font-size: 10px; flex: 0 0 auto;
}
.switcher[open] > summary::after { content: "▴"; }
.switcher > summary .swlabel {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.switcher[open] > summary { color: var(--text); border-color: var(--line-strong); }

/* The menu floats rather than pushing the header taller, so opening it does
   not shift the page under the reader. */
.swmenu {
  position: absolute; top: calc(100% + var(--s2)); left: 50%;
  transform: translateX(-50%);
  min-width: max(220px, 100%); z-index: 30;
  background: var(--surface-raised);
  border: 1px solid var(--line-strong); border-radius: var(--r-card);
  padding: var(--s2); box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
}
.swmenu a, .switchbtn {
  display: block; width: 100%; text-align: left;
  padding: var(--s3) var(--s4); border-radius: var(--r-btn);
  text-decoration: none; color: var(--text);
  border: 0; background: none; font: inherit; cursor: pointer;
}
.swmenu a:hover, .switchbtn:hover { background: var(--surface); }
.swmenu a.on { background: var(--surface); }
.swmenu form { margin: 0; }
.swlabel { display: block; font-weight: 600; font-size: 13px; }
.swsub { display: block; font-size: 12px; color: var(--text-dim); margin-top: 1px; }
.muted { color: var(--text-dim); }

/* The slim header guardian pages get: no owner navigation, but they still
   have to say whose mail is on screen and offer the way back. */
header.slim { justify-content: flex-start; }
header.slim .switcher { margin-left: var(--s4); margin-right: 0; }

@media (max-width: 400px) {
  .switcher > summary { max-width: 40vw; }
  .brand { letter-spacing: 0.08em; }
}

/* ─────────── Status pill: label collapses to a dot ───────────
   The label plus Start/Stop plus the avatar plus the mailbox switcher does not
   fit a narrow phone, and the pill was overlapping its neighbours. Below the
   breakpoint the colour carries the meaning on its own and the title attribute
   keeps it available to a screen reader. */

.pill.paused .dot { background: var(--text-faint); }
.pill.stopped { color: var(--high); border-color: color-mix(in srgb, var(--high) 40%, transparent); }
.pill.stopped .dot { background: var(--high); }
.pilltext { white-space: nowrap; }

@media (max-width: 520px) {
  .pilltext { display: none; }
  .pill { padding: var(--s2); min-width: 30px; justify-content: center; }
  /* The bare dot is the whole control at this width, so give it presence. */
  .pill .dot { width: 9px; height: 9px; }
  header { gap: var(--s2); padding: var(--s3) var(--s4); }
  .poller-control { gap: var(--s1); }
  .poller-control button.small { padding: var(--s1) var(--s2); font-size: 12px; }
}

/* ─────────── Collapsible message cards ─────────── */

.queue > li > details.msg > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: var(--s3);
  min-height: 48px;
}
.queue > li > details.msg > summary::-webkit-details-marker { display: none; }
.queue > li > details.msg > summary::after {
  content: "›"; margin-left: auto; flex: 0 0 auto;
  color: var(--text-faint); font-size: 17px;
  transition: transform var(--fast);
}
.queue > li > details.msg[open] > summary::after { transform: rotate(90deg); }
.queue > li > details.msg > summary .subject-link {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; font-weight: 600;
}
.msgbody { padding-top: var(--s3); }
.msgbody .sender { margin-bottom: var(--s2); }

.minilink {
  display: inline-block; font-size: 12px; color: var(--accent);
  text-decoration: none; margin-top: var(--s3);
}
.minilink:hover { text-decoration: underline; }

.sectionhead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
}
.sectionhead h2 { margin-bottom: var(--s2); }
.stagewhat {
  margin: 2px 0 var(--s2); font-size: 12.5px; color: var(--text-dim);
  line-height: 1.45;
}

/* Per-mailbox usage breakdown. A total says what you're spending; only this
   says which mailbox is spending it. */
.usagelist li { flex-wrap: wrap; row-gap: 2px; }
.usagelist .muted { font-variant-numeric: tabular-nums; }
.danger { color: var(--high); }

/* ─────────────── Brand mark ─────────────── */

.brand {
  display: inline-flex; align-items: center; gap: var(--s2);
  text-decoration: none; color: var(--text);
  flex: 0 0 auto;
}
.brand:hover { text-decoration: none; color: var(--text); }
.brandmark { width: 22px; height: 22px; flex: 0 0 auto; display: block; }

.loginmark { display: flex; justify-content: center; margin-bottom: var(--s3); }
.loginmark .brandmark { width: 56px; height: 56px; }

@media (max-width: 520px) {
  /* The wordmark is the first thing to go: the mark alone identifies the app,
     and the row has a switcher, a status dot and an avatar to fit. */
  .brand span { display: none; }
  .brandmark { width: 24px; height: 24px; }
}

/* Row icons, Android-settings style: a glyph column that makes the list
   scannable by shape before you read a word of it. */
.rowicon {
  width: 20px; height: 20px; flex: 0 0 auto;
  color: var(--text-dim);
}
.sgroup > summary:hover .rowicon,
.sgroup[open] > summary .rowicon { color: var(--accent); }
.slink .rowicon { color: var(--text-dim); }

/* Larger mark — it was reading as an afterthought next to the wordmark. */
.brandmark { width: 30px; height: 30px; }
.loginmark .brandmark { width: 72px; height: 72px; }
@media (max-width: 520px) { .brandmark { width: 28px; height: 28px; } }

/* ─────────── Second-opinion slider ───────────
   A number between 0 and 1 told the reader nothing about what it would do or
   what it would cost. The position carries the meaning now, and the warning
   only appears where the spending actually starts. */

.slider { margin-top: var(--s3); }
.slider label { display: block; margin-bottom: var(--s3); font-weight: 500; }
.slider input[type="range"] {
  width: 100%; margin: 0; accent-color: var(--accent);
  height: 28px;   /* a comfortable drag target on a phone */
}
.slider.costly input[type="range"] { accent-color: var(--medium); }

.sliderends {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--text-faint); margin-top: -2px;
}
.sliderlabel {
  margin: var(--s3) 0 0; font-size: 16px; font-weight: 650;
}
.slider.costly .sliderlabel { color: var(--medium); }
.sliderdetail {
  margin: 2px 0 0; font-size: 13px; color: var(--text-dim); line-height: 1.5;
}

/* Shown only at the settings that actually spend money. */
.slidercost { display: none; }
.slider.costly .slidercost {
  display: block; margin: var(--s3) 0 0;
  padding: var(--s3) var(--s4); border-radius: var(--r-btn);
  font-size: 13px; line-height: 1.55;
  background: color-mix(in srgb, var(--medium) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--medium) 35%, transparent);
}

/* ─────────── Toggle ───────────
   A real switch for a setting people turn on and off deliberately. The native
   checkbox stays in the DOM and keeps its keyboard behaviour and focus ring;
   only its appearance is replaced. */

.toggle {
  display: flex; align-items: flex-start; gap: var(--s4);
  cursor: pointer; padding: var(--s2) 0;
}
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle .track {
  flex: 0 0 auto; margin-top: 2px;
  width: 44px; height: 26px; border-radius: var(--r-pill);
  background: var(--surface-raised); border: 1px solid var(--line-strong);
  transition: background var(--fast), border-color var(--fast);
  display: flex; align-items: center;
}
.toggle .knob {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--text-faint); margin-left: 3px;
  transition: transform var(--fast), background var(--fast);
}
.toggle input:checked + .track {
  background: color-mix(in srgb, var(--low) 30%, transparent);
  border-color: color-mix(in srgb, var(--low) 55%, transparent);
}
.toggle input:checked + .track .knob {
  transform: translateX(18px); background: var(--low);
}
.toggle input:focus-visible + .track {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.toggletext { display: flex; flex-direction: column; gap: 2px; }
.toggletext strong { font-size: 15px; }
.toggletext span { font-size: 13px; color: var(--text-dim); line-height: 1.5; }

/* ═══════════════ Unified surfaces ═══════════════
   Six card styles had accumulated — settings groups, operator rows, guardian
   panels, day groups, the invite box — each with its own border, radius and
   background, written at different times. Same elevation, same shape now, so
   the eye reads them as one system and a new panel has an obvious default. */

.sgroup,
.opaccount,
.guardian,
.advanced,
.dangerzone,
.codebox {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
}

/* Rows that open. One disclosure behaviour everywhere: pointer, no marker,
   a chevron that turns, and a divider once open. */
.sgroup > summary,
.opaccount > summary,
.day-group > summary,
.advanced > summary {
  cursor: pointer;
  list-style: none;
}
.sgroup > summary::-webkit-details-marker,
.opaccount > summary::-webkit-details-marker,
.day-group > summary::-webkit-details-marker,
.advanced > summary::-webkit-details-marker { display: none; }

.sgroup > summary:hover,
.opaccount > summary:hover { background: var(--surface-raised); }

/* Keyboard users get the same affordance as everyone else. */
.sgroup > summary:focus-visible,
.opaccount > summary:focus-visible,
.day-group > summary:focus-visible,
.msg > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--r-btn);
}

/* Anything asking for attention borrows the brand tint rather than inventing
   its own highlight. */
.codebox {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-quiet);
}
.codebox .code { color: var(--accent); }

/* The mark's pale lilac, used as a wash behind the one block on each page
   that explains rather than controls. */
.truth {
  background: var(--accent-quiet);
  border-left-color: var(--accent);
}

/* Tier colour bars on queue cards, matched to the badges beside them. */
.queue > li.tier-high { border-left-color: var(--high); }
.queue > li.tier-medium { border-left-color: var(--medium); }
.queue > li.tier-low { border-left-color: var(--low); }

/* Section headings carry a small mark of their own, so a long page reads as
   a sequence of parts rather than one column of text. */
.secicon {
  width: 17px; height: 17px; flex: 0 0 auto;
  color: var(--accent); vertical-align: -3px; margin-right: var(--s2);
}

/* Selection and focus pick up the brand rather than the browser default. */
::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }
a { color: var(--accent); }
button.primary, .googlebtn { }
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Section headings: the glyph sits on the baseline with the text, at the
   accent, so a long page reads as a sequence of parts. */
h2 > .rowicon {
  width: 17px; height: 17px; color: var(--accent);
  vertical-align: -2px; margin-right: var(--s2);
}

/* ═══════════════ Guardian mode ═══════════════
   The pages look like your own app and the buttons do the same things. What
   must never blur is whose mail it is, so the marker names the person and
   stays on every screen rather than tinting the chrome and hoping. */

.gbar {
  display: flex; align-items: flex-start; gap: var(--s3);
  padding: var(--s4) var(--s5); margin-bottom: var(--s5);
  border-radius: var(--r-card);
  background: var(--accent-quiet);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
}
.gmark { flex: 0 0 auto; color: var(--accent); display: flex; }
.gmark .rowicon { width: 22px; height: 22px; }
.gtext { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gtext strong { font-size: 15px; }
.gtext span { font-size: 13px; color: var(--text-dim); line-height: 1.5; }
.gbar form { margin-left: auto; flex: 0 0 auto; }

/* Guardian tabs sit where the owner's do, so muscle memory carries over. */
.gtabs { display: flex; }
@media (min-width: 720px) and (pointer: fine), (min-width: 1024px) {
  .gtabs { display: flex; }   /* keep them: there is no header nav here */
}

/* The owner's persistent strip. Quieter than the guardian's marker — it is a
   standing fact, not a mode you are inside. */
.banner.guardianbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3);
  background: var(--accent-quiet);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--text);
}
.banner.guardianbar a {
  flex: 0 0 auto; font-weight: 600; font-size: 13px;
  text-decoration: none; color: var(--accent);
}
.banner.guardianbar a:hover { text-decoration: underline; }

@media (max-width: 420px) {
  .gbar { flex-wrap: wrap; }
  .gbar form { margin-left: 0; width: 100%; }
  .banner.guardianbar { font-size: 13px; }
}

/* Privacy page: prose, so it gets a readable measure and real paragraph
   rhythm rather than the dense settings treatment. */
.plainlist { padding-left: var(--s5); margin: var(--s3) 0 0; }
.plainlist li { margin-bottom: var(--s3); line-height: 1.6; font-size: 14px; }
.privacylink { margin-top: var(--s5); text-align: center; }
.pcard h2 { font-size: 17px; margin: 0 0 var(--s3); }
.pcard p { line-height: 1.65; }

/* ═══════════════ Setup ═══════════════
   One decision per screen, centred, with everything else off the page. The
   opposite of the settings page on purpose: nothing to scan, nothing to
   compare, one thing to answer. */

.setup {
  max-width: 460px; margin: 0 auto; padding: var(--s6) 0 var(--s8);
  text-align: center;
}
.setup h1 { font-size: 26px; margin: 0 0 var(--s3); }
.setuplede {
  color: var(--text-dim); font-size: 15px; line-height: 1.6;
  margin: 0 auto var(--s6); max-width: 40ch;
}

/* Progress. Filled dots rather than a count: "3 of 5" invites people to
   measure how much is left instead of reading what is on screen. */
.setupdots {
  display: flex; justify-content: center; gap: var(--s2);
  margin-bottom: var(--s7);
}
.setupdots span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--line-strong); transition: background var(--base);
}
.setupdots span.on { background: var(--accent); }

.setupmark { margin-bottom: var(--s5); }
.setupmark .brandmark { width: 72px; height: 72px; }
.setupicon {
  width: 60px; height: 60px; margin: 0 auto var(--s5);
  border-radius: var(--r-pill);
  background: var(--accent-quiet);
  display: flex; align-items: center; justify-content: center;
}
.setupicon .rowicon { width: 26px; height: 26px; color: var(--accent); }
.setupicon.done { background: color-mix(in srgb, var(--low) 16%, transparent); }
.setupicon.done .rowicon { color: var(--low); }

/* Points of reassurance, left-aligned because they are read, not scanned. */
.setuplist { list-style: none; padding: 0; margin: 0 0 var(--s6); text-align: left; }
.setuplist li {
  display: flex; gap: var(--s4); align-items: flex-start;
  padding: var(--s3) 0;
}
.setuplist .rowicon { width: 20px; height: 20px; color: var(--accent); margin-top: 2px; }
.setuplist strong { display: block; font-size: 15px; }
.setuplist span { display: block; font-size: 13px; color: var(--text-dim); line-height: 1.55; }

.setup .toggle { text-align: left; margin-bottom: var(--s4); }
.setup label { text-align: left; display: block; }
.setup textarea { width: 100%; }
.setupaction {
  margin: var(--s5) 0; padding: var(--s4);
  border-radius: var(--r-card); background: var(--surface);
  border: 1px solid var(--line);
}
.setupsummary { text-align: left; }

/* The primary action is full width and unmissable; the escape is quiet but
   present, because a wizard you cannot leave teaches people to click through
   without reading. */
.setupnext { width: 100%; margin-top: var(--s5); min-height: 50px; font-size: 15px; }
.setupskip {
  width: 100%; margin-top: var(--s3);
  border: 0; background: none; color: var(--text-dim);
}
.setupskip:hover { color: var(--text); border-color: transparent; }

.setupfoot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: var(--s7); padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: 13px;
}
.setupfoot a { color: var(--text-dim); text-decoration: none; }
.setupfoot a:hover { color: var(--text); }
.setupfoot form { margin: 0; }

/* What one message cost to check. Quiet by default — it sits beside every
   checked message, and a column of highlighted numbers would read as a bill
   rather than a footnote. */
.actcost {
  display: inline-block; margin-left: var(--s2);
  font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 0 var(--s2);
  vertical-align: 1px;
}

/* ═══════════════ Mode picker ═══════════════
   Two states, picked like buttons. The previous version was a pair of radios
   plus a separate checkbox further down the page, so "which mode am I in" and
   "is it actually doing anything" were two answers in two places — and people
   read the first one and stopped. */

.modepick { display: grid; gap: var(--s3); margin-bottom: var(--s5); }
.modeopt {
  display: flex; align-items: flex-start; gap: var(--s4);
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface); cursor: pointer;
  transition: border-color var(--fast), background var(--fast);
}
.modeopt:hover { border-color: var(--line-strong); }
.modeopt input { position: absolute; opacity: 0; width: 0; height: 0; }

/* Selected state comes off :has() where supported, and off the server-rendered
   class everywhere else, so the choice is visible before any JavaScript and
   still tracks a click without a reload. */
.modeopt.chosen,
.modeopt:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-quiet);
}
.modeopt:has(input:checked):not(:has(input:disabled)) .modeicon { color: var(--accent); }
.modeopt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.modeicon { flex: 0 0 auto; color: var(--text-dim); margin-top: 2px; }
.modeicon .rowicon { width: 22px; height: 22px; }
.modebody { display: flex; flex-direction: column; gap: 3px; }
.modebody strong { font-size: 15px; }
.modebody > span { font-size: 13px; color: var(--text-dim); line-height: 1.55; }
.modetag {
  align-self: flex-start; margin-top: var(--s1);
  font-size: 11px; color: var(--text-faint);
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  padding: 1px var(--s2);
}

/* Not available yet, rather than broken. */
.modeopt.unavailable { opacity: 0.55; cursor: not-allowed; }
.modeopt.unavailable:hover { border-color: var(--line); }


}

/* ─────────── Appearance picker ───────────
   Three buttons rather than a dropdown: there are exactly three answers and
   the current one should be visible without opening anything. */

.themepick {
  display: flex; gap: var(--s1); padding: var(--s1);
  background: var(--surface-raised); border-radius: var(--r-btn);
  border: 1px solid var(--line);
}
.themeopt {
  flex: 1 1 0; min-height: 40px; font-size: 13px;
  border: 1px solid transparent; background: none; color: var(--text-dim);
  border-radius: calc(var(--r-btn) - 2px);
}
.themeopt:hover { color: var(--text); border-color: transparent; }
.themeopt.on {
  background: var(--surface); color: var(--text);
  border-color: var(--line-strong); font-weight: 600;
}

/* ─────────── Mode switch in the banner ─────────── */

.modeswitch {
  min-height: 30px; padding: var(--s1) var(--s3);
  font-size: 12px; font-weight: 550;
  border-radius: var(--r-pill);
  background: none; border: 1px solid currentColor; color: inherit;
  opacity: 0.85;
}
.modeswitch:hover { opacity: 1; border-color: currentColor; }

@media (max-width: 440px) {
  .banner.shadow, .banner.active { font-size: 13px; }
  .modeswitch { width: 100%; margin-top: var(--s2); }
}

/* What KAS has learned. Listed plainly and individually forgettable —
   learned behaviour nobody can see is indistinguishable from a bug, and
   learned behaviour nobody can undo is worse than no learning at all. */
.learnedlist li { align-items: flex-start; }
.learnedlist strong { display: block; font-size: 14px; }
.learnedlist .muted { display: block; font-size: 12px; margin-top: 1px; }

/* The deletion deadline, next to the button that acts on it. Blocking a
   sender is only useful while their message is still in front of you. */
.willdelete {
  margin: var(--s2) 0 var(--s3); font-size: 12.5px; line-height: 1.5;
  color: var(--text-dim);
  padding-left: var(--s3);
  border-left: 2px solid color-mix(in srgb, var(--medium) 50%, transparent);
}

/* ─────────── Brand tile ───────────
   The mark sat at the same weight as the status dot next to it, so the two
   read as a pair of indicators rather than as the app's identity and one
   piece of state. In a tile at icon size it is unmistakably the former. */

.brandtile {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: 0 0 auto;
  background: #000;
  border-radius: 11px;            /* the squircle proportion of an app icon */
  border: 1px solid var(--line-strong);
}
.brandtile .brandmark { width: 30px; height: 30px; }
.brand { gap: var(--s3); }

@media (max-width: 520px) {
  .brandtile { width: 34px; height: 34px; border-radius: 10px; }
  .brandtile .brandmark { width: 27px; height: 27px; }
}

/* ═══════════════ Queue redesign ═══════════════
   A queue is read in two passes: "is any of this urgent?" from across the
   room, then "what is this one?" up close. The old cards served the second
   and not the first — every row looked identical until you read it. Risk now
   carries colour and position, and the subject leads. */

.qhead {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--s4); margin-bottom: var(--s6);
}
.qhead h1 { margin: 0 0 var(--s1); }
.qsub { margin: 0; font-size: 13px; color: var(--text-dim); }
.qhigh { color: var(--high); font-weight: 600; }

/* Day heading as a quiet rule rather than another card edge. */
.qday { margin-bottom: var(--s6); }
.qdayhead {
  display: flex; align-items: center; gap: var(--s3);
  margin-bottom: var(--s3);
}
.qdayhead h2 {
  margin: 0; font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint);
}
.qdayhead::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--line);
}
.qdaycount {
  font-size: 11px; color: var(--text-faint);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 0 var(--s2); order: 3;
}

.queue { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s2); }

.qcard {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--surface);
  border-left: 3px solid var(--line-strong);
  overflow: hidden;
  transition: border-color var(--fast), background var(--fast);
}
.qcard:hover { background: var(--surface-raised); }
.qcard.tier-high { border-left-color: var(--high); }
.qcard.tier-medium { border-left-color: var(--medium); }
.qcard.tier-low { border-left-color: var(--low); }
.qcard.reviewed { opacity: 0.62; }

.qcard > details > summary {
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s4) var(--s5);
  cursor: pointer; list-style: none; min-height: 62px;
}
.qcard > details > summary::-webkit-details-marker { display: none; }
.qcard > details[open] > summary { border-bottom: 1px solid var(--line); }
.qcard > details > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Risk chip: colour plus a word, so it is not carried by colour alone. */
.qrisk {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--s1);
  font-size: 11px; font-weight: 650; letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: var(--s1) var(--s2); border-radius: var(--r-btn);
  border: 1px solid currentColor; color: var(--text-faint);
  min-width: 74px; justify-content: center;
}
.qrisk .rowicon { width: 13px; height: 13px; }
.qrisk.tier-high { color: var(--high); background: color-mix(in srgb, var(--high) 12%, transparent); }
.qrisk.tier-medium { color: var(--medium); background: color-mix(in srgb, var(--medium) 12%, transparent); }
.qrisk.tier-low { color: var(--low); background: color-mix(in srgb, var(--low) 12%, transparent); }

/* Subject leads, sender supports. It was the other way round, which meant
   every card opened with an address instead of what the message says it is. */
.qmain { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.qsubject {
  font-weight: 600; font-size: 14.5px; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qfrom {
  font-size: 12.5px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qmeta {
  flex: 0 0 auto; display: flex; align-items: center; gap: var(--s2);
  font-size: 11px; color: var(--text-faint);
}
.qdone {
  color: var(--low); border: 1px solid color-mix(in srgb, var(--low) 40%, transparent);
  border-radius: var(--r-pill); padding: 0 var(--s2);
}
.qwhen { font-variant-numeric: tabular-nums; }

/* The reasons are the most valuable thing on the page, so they get a frame
   rather than being a bare list under the fold. */
.qwhy {
  background: var(--surface-raised); border-radius: var(--r-btn);
  padding: var(--s3) var(--s4); margin-bottom: var(--s3);
}
.qwhylabel {
  display: block; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-faint); margin-bottom: var(--s2);
}
.qwhy .reasons { margin: 0; padding-left: var(--s4); }
.qwhy .reasons li { font-size: 13.5px; line-height: 1.55; margin-bottom: var(--s1); }

/* An empty queue is the product working, not a page that failed to load. */
.qempty { text-align: center; padding: var(--s8) var(--s4); }
.qemptymark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border-radius: var(--r-pill);
  background: var(--accent-quiet);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  margin-bottom: var(--s4);
}
.qemptymark .rowicon { width: 27px; height: 27px; color: var(--accent); }
.qemptytitle { font-size: 16px; font-weight: 600; margin: 0 0 var(--s2); }

@media (max-width: 480px) {
  .qcard > details > summary { padding: var(--s3) var(--s4); gap: var(--s3); }
  /* The word goes; the colour and the card's left edge still carry it. */
  .qrisk { min-width: 0; padding: var(--s1); }
  .qrisk span { display: none; }
  .qrisk .rowicon { width: 15px; height: 15px; }
  .qmeta .qwhen { display: none; }
}

/* Setup: the numbered explanation of the pipeline, and the optional
   model-picking folded inside it. */
.setupsteps {
  counter-reset: s; list-style: none; padding: 0;
  margin: 0 0 var(--s6); text-align: left;
}
.setupsteps li {
  counter-increment: s; position: relative;
  padding: var(--s3) 0 var(--s3) var(--s7);
  border-bottom: 1px solid var(--line);
}
.setupsteps li:last-child { border-bottom: 0; }
.setupsteps li::before {
  content: counter(s); position: absolute; left: 0; top: var(--s3);
  width: 22px; height: 22px; border-radius: var(--r-pill);
  background: var(--accent-quiet); color: var(--accent);
  font-size: 11px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.setupsteps strong { display: block; font-size: 15px; }
.setupsteps span { display: block; font-size: 13px; color: var(--text-dim); line-height: 1.5; }

.setupadvanced { text-align: left; margin: var(--s5) 0 0; }
.setup .modepick { text-align: left; }
.setup .grid { text-align: left; }

/* The password fallback. Present, findable, and not competing with the button
   almost everyone will use. */
.pwsignin {
  margin-top: var(--s6); text-align: left;
  border-top: 1px solid var(--line); padding-top: var(--s4);
}
.pwsignin > summary {
  cursor: pointer; list-style: none; text-align: center;
  font-size: 13px; color: var(--text-dim); padding: var(--s2);
}
.pwsignin > summary::-webkit-details-marker { display: none; }
.pwsignin > summary:hover { color: var(--text); }
.pwsignin form { margin-top: var(--s3); }

/* One row per mailbox you help with: who it is, and how you want to hear
   about it. */
.helprow {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); padding: var(--s3) 0;
  border-bottom: 1px solid var(--line);
}
.helprow:last-of-type { border-bottom: 0; }
.helprow > span { display: flex; flex-direction: column; min-width: 0; font-size: 14px; }
.helprow .muted { font-size: 12px; }
.helprow select { flex: 0 0 auto; max-width: 46%; }
