/* PageLab — account pages (login / manage). Shares the palette with style.css but is its own
   sheet: these are utility screens, not marketing, so they get a calmer, denser treatment. */

/* ⚠️ Use the SEMANTIC tokens (--text-muted, --text-body, --surface-card), never the BRAND ones
   (--ink-muted, --forest-900, --parchment), for anything that sits on a themed ground. Brand
   tokens do not flip: --ink-muted #6E7566 is a light-ground grey, and it was being used for the
   .notice/.legal-body/.legal-nav headings, which land on the DARK page ground on every legal
   page -- 4.02:1, under AA. --text-muted is 8.07:1 on the cream card and 9.08:1 on the dark
   ground. The exception is .auth-card, which re-points the semantic tokens to light values
   because it is a fixed light island; see the comment there. */

@import url("/site/style.css");

body.account { background: var(--surface); color: var(--text); }

/* Centred card layout for sign-in */
.auth-shell {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 40px var(--pad);
  background:
    radial-gradient(90% 60% at 50% 0%, rgba(232,185,100,.14), transparent 60%),
    linear-gradient(180deg, var(--midnight-900) 0%, var(--forest-900) 100%);
}
.auth-card {
  /* 🐛 A LIGHT TOKEN ISLAND, ON PURPOSE. This card is deliberately cream in BOTH themes -- it
     sits on .auth-shell's dark gradient, and everything inside it (--ink-muted subtitles,
     --forest-700 links, the --forest-900 mark) was picked against cream.
     But `body.account { color: var(--text) }` at :6 is THEME-dependent, and it leaked the page
     theme's ink INTO this fixed-light card. With no data-theme stamped, --text was the DARK
     value #F4EFE4, and the live signup page rendered its <h1> at 1.08:1 and its <label>s at
     1.45:1 -- invisible. 16 of 28 text nodes on the card were under 3:1.
     Re-pointing the SEMANTIC tokens here makes the card self-contained: text, inputs, hairlines
     and focus rings all resolve against the card instead of the page, in either theme and with
     no data-theme at all. Values are copied from :root[data-theme="light"] in style.css --
     keep them in step if that block changes.
     ⚠️ Do NOT "fix" this by making the card follow the theme. Its contents are not theme-aware. */
  --surface:         #F4EFE4;
  --surface-card:    #FBF8F0;
  --surface-inset:   #EAE3D3;
  --text:            #1B211A;
  --text-rgb:        27,33,26;
  --text-body:       #2A3128;
  --text-body-dim:   #454C42;
  --text-soft:       #2F3A2C;
  --text-muted:      #2A5536;
  --text-dim:        #5B6656;
  --hairline-rgb:    20,42,27;
  --field-bg:        #FFFFFF;
  --field-fg:        #1B211A;
  --danger:          #A83A24;
  --danger-bright:   #8E2E1B;
  /* The ACCENT has to be re-pointed too, and it is the one that gets forgotten. `body.account a`
     at :358 sets `color: var(--accent)`, and custom properties INHERIT -- so with no value here
     every link inside the card resolved --accent from :root, i.e. the dark-theme amber #E8B964,
     which is 1.71:1 on cream. That is exactly why "Terms of Service", "Privacy Policy" and
     "Sign in" stayed invisible after the rest of the card was already fixed.
     Forest rather than the reader's live accent preset: this card is a fixed light ground, and
     only a fixed ink is guaranteed legible on it across all 8 presets. Costs a little theme
     fidelity on this one card and buys 8.07:1. */
  --accent:          #2A5536;
  --accent-bright:   #1F3F28;
  --focus-ring:      #8A6220;
  color: var(--text-body);

  width: 100%; max-width: 430px;
  background: var(--surface-card);
  border-radius: 16px;
  padding: 34px 32px 30px;
  box-shadow: 0 24px 60px -30px rgba(0,0,0,.7);
}
.auth-card .mark { color: var(--forest-900); justify-content: center; margin-bottom: 6px; }
.auth-card h1 {
  font-family: var(--serif); font-size: 27px; font-weight: 600;
  margin: 12px 0 4px; text-align: center; letter-spacing: -.01em;
}
.auth-card .sub {
  text-align: center; color: var(--text-muted); font-size: 14.5px; margin: 0 0 24px;
}

label { display: block; font-size: 13.5px; font-weight: 650; margin: 0 0 6px; color: var(--text-body-dim); }
input[type=email], input[type=password], input[type=text], textarea, select {
  width: 100%; padding: 11px 13px;
  border: 1px solid rgba(var(--hairline-rgb),.34); border-radius: 9px;
  background: var(--field-bg); color: var(--field-fg);
  font: inherit; font-size: 15.5px;
}
input:focus, textarea:focus, select:focus {
  outline: 2px solid var(--focus-ring); outline-offset: 1px; border-color: transparent;
}
.field { margin-bottom: 16px; }
.field .hint { font-size: 12.5px; color: var(--text-dim); margin: 6px 0 0; }
/* Bare .hint (outside a .field) had NO rule at all and inherited 17px body text. */
.hint { font-size: 12.5px; color: var(--text-dim); }

.btn-block { width: 100%; justify-content: center; }
.btn-solid {
  background: var(--forest-700); color: var(--parchment);
  border: 1px solid transparent;
}
.btn-solid:hover { background: var(--forest-800); }
.btn-solid[disabled] { opacity: .6; cursor: not-allowed; }
.btn-quiet {
  background: transparent; color: var(--text-body-dim); border: 1px solid rgba(var(--hairline-rgb),.34);
}
.btn-quiet:hover { border-color: var(--accent); color: var(--accent); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: var(--danger-bright); }

.divider {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0; color: var(--text-muted); font-size: 12.5px;
}
.divider::before, .divider::after {
  content: ""; flex: 1; height: 1px; background: rgba(var(--hairline-rgb),.28);
}

.alert {
  border-radius: 9px; padding: 11px 14px; font-size: 14.5px;
  margin-bottom: 16px; display: none;
}
.alert.show { display: block; }
.alert-error { background: var(--alert-err-bg); color: var(--alert-err-fg); border: 1px solid var(--alert-err-border); }
.alert-ok { background: var(--alert-ok-bg); color: var(--alert-ok-fg); border: 1px solid var(--alert-ok-border); }

/* Used by signup, forgot and delete-account and defined NOWHERE — it inherited 17px body text,
   so every "we'll email you a code" subtitle rendered at the same weight as the heading's
   surroundings instead of reading as secondary. */
.auth-sub { margin: 0 0 20px; font-size: 14.5px; line-height: 1.5; color: var(--text-muted); }

.auth-foot { text-align: center; margin: 18px 0 0; font-size: 14px; color: var(--text-muted); }
.auth-foot a { color: var(--forest-700); }

/* A standing explanatory block, as opposed to .alert — which is a transient response to
   something the reader just did and starts `display: none`. Used on /delete-account, where the
   consequences have to be on screen BEFORE the button is pressed, not after. */
.notice {
  background: rgba(var(--hairline-rgb),.06);
  border: 1px solid rgba(var(--hairline-rgb),.20);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 20px;
  font-size: 14.5px;
  line-height: 1.5;
}
.notice h2 {
  margin: 0 0 8px; font-size: 13px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted);
}
.notice p { margin: 0; }
.notice ul { margin: 0; padding-left: 20px; }
.notice li { margin-bottom: 6px; }
.notice li:last-child { margin-bottom: 0; }
.notice .hint { margin: 10px 0 0; }
.notice a { color: var(--forest-700); }

/* Signup consent (§M C4). The box and its label are one hit target, and the label wraps to
   several lines on a phone — so baseline-align rather than centre, or the box floats mid-text. */
.consent { margin-bottom: 20px; }
.consent-label {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 14px; line-height: 1.5; color: var(--text-body); cursor: pointer;
}
.consent-label input[type="checkbox"] {
  flex: none; width: 17px; height: 17px; margin: 2px 0 0;
  accent-color: var(--forest-700); cursor: pointer;
}
.consent-label a { color: var(--forest-700); }
/* The /login variant: a disclosure under the Google button, which GIS gives no pre-click hook to
   gate. Centred under the button it belongs to, and quiet — it is a statement, not a control. */
.consent-inline { margin: 12px 0 0; text-align: center; line-height: 1.5; }
.consent-inline a { color: var(--forest-700); }

/* ── Legal pages (§M C3) ────────────────────────────────────────────────── */
/* Long-form reading, not a form: a single measured column rather than the auth card. */
.legal-shell { padding: 40px var(--pad) 64px; background: var(--surface); }
/* 46rem = 736px, about 90 characters — against the comment two lines above claiming 65, and
   against the --measure token the block ignored entirely. 38rem is ~65ch at this font size. */
.legal-wrap { max-width: 38rem; margin: 0 auto; }

/* Per-page contents, generated in legalPages.js build() from the h2s themselves.

   🐛 IT WAS A FULL SCREEN OF LINKS. As a single bulleted column at body size, the contents box
   on terms.html measured 732px against a 720px viewport — 102%, so a reader arriving at the
   agreement saw one entire screen of navigation and none of the terms. privacy.html (11 entries)
   was not much better. Terms has 16 h2s and that is not a drafting problem to fix by writing
   fewer sections; it is a layout that assumed a short list.

   Two columns, no bullets, and a size below body copy: 732px -> 327px, a 55% cut, measured on
   the live page. `auto-fill` with a 15rem floor is what makes it responsive without a media
   query — on a phone the track count drops to one on its own, which is right, because a narrow
   column is where a two-up TOC would start wrapping every entry.

   ⚠️ 15rem IS A LEGIBILITY FLOOR, NOT A GUESS. Tried at 11rem it packs three columns and shaves
   another 36px, but 12 of terms’ 16 entries then wrap to two lines and the box turns ragged.
   An inline `·`-separated flow is smaller still (262px) and was rejected for the same reason it
   looks tidy in isolation: a table of contents is scanned down a column, and 16 clause names run
   together read as a paragraph. Going denser trades the thing the box is FOR. */
.legal-toc {
  margin: 0 0 22px; padding: 12px 14px;
  background: rgba(var(--hairline-rgb),.06);
  border: 1px solid rgba(var(--hairline-rgb),.18); border-radius: 10px;
}
.legal-toc h2 { margin: 0 0 6px; font-size: 11.5px; letter-spacing: .05em; text-transform: uppercase;
  font-weight: 700; color: var(--text-muted); }
/* No `padding-left`/marker: the bullets bought nothing and cost an indent per column. */
.legal-toc ul {
  margin: 0; padding-left: 0; list-style: none;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 2px 18px;
}
.legal-toc li { font-size: 13.5px; line-height: 1.45; }
.legal-toc a { color: var(--accent); }
/* So a jumped-to clause is not welded to the top edge of the viewport. */
.legal-body h2 { scroll-margin-top: 18px; }

/* 🐛 cookies.html:9 is a real 3-column table and NO stylesheet on this site contained a single
   table/th/td selector — it rendered at UA defaults: 2px border-spacing, 1px cell padding, no
   rules, and no way to escape its own width on a phone. */
.legal-body table {
  display: block; overflow-x: auto; width: 100%;
  border-collapse: collapse; margin: 18px 0; font-size: 14.5px;
}
.legal-body th, .legal-body td {
  text-align: left; padding: 9px 12px; vertical-align: top;
  border-bottom: 1px solid rgba(var(--hairline-rgb),.18);
}
.legal-body th { font-weight: 650; color: var(--text); white-space: nowrap; }

/* 🐛 NO PRINT STYLES ANYWHERE — `@media print` matched 0 times across all three sheets. Browsers
   suppress backgrounds when printing but keep foreground colour, so saving any policy as a PDF
   put --text-body #E4E0D2 on white at 1.32:1: a legal document that prints blank. Someone
   archiving the terms they agreed to is the exact person who needs this to work. */
@media print {
  :root { --accent: #000; }
  body.account, .legal-shell { background: #fff !important; color: #000 !important; }
  .legal-body, .legal-lede, .legal-body h2, .legal-meta, .legal-toc h2 { color: #000 !important; }
  .legal-wrap { max-width: none; }
  .legal-body a { color: #000 !important; text-decoration: underline; }
  /* A printed page cannot be clicked, so the destination has to be on the paper. */
  .legal-body a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .85em; word-break: break-all; }
  .legal-body a[href^="/"]::after { content: " (pagelab.app" attr(href) ")"; font-size: .85em; }
  .legal-toc, .legal-nav, .legal-wrap > .mark, .account-head { display: none !important; }
  .legal-body h2 { break-after: avoid; }
  .legal-body table { display: table; overflow: visible; }
}
.legal-wrap > .mark { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 28px; }
.legal-wrap h1 { margin: 0 0 4px; }
.legal-meta { margin: 0 0 22px; font-size: 13.5px; color: var(--text-dim); }

.legal-draft {
  border: 1px solid var(--alert-err-border);
  background: var(--alert-err-bg); color: var(--alert-err-fg);
  border-radius: 10px; padding: 13px 16px; margin-bottom: 26px;
  font-size: 14.5px; line-height: 1.5;
}

/* ~65 characters is the readable measure; these pages are the only long-form prose on the site. */
.legal-body { font-size: 16px; line-height: 1.65; color: var(--text-body); }
.legal-lede { font-size: 17px; color: var(--text); margin: 0 0 24px; }
.legal-body h2 {
  margin: 30px 0 10px; font-size: 15px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted);
}
/* The one block on a legal page that is a physical fact rather than prose. Set apart from the
   running text so it can be found without reading the page, and selected without picking the words
   out of a sentence — which is what someone addressing an envelope is actually doing here. */
.legal-body .legal-address {
  margin: 0 0 16px; padding: 13px 16px; line-height: 1.7;
  border-left: 3px solid var(--forest-700);
  background: rgba(var(--hairline-rgb), .07);
  border-radius: 0 6px 6px 0;
}
.legal-body ul { margin: 0; padding-left: 22px; }
.legal-body li { margin-bottom: 9px; }
.legal-body p { margin: 0 0 14px; }
.legal-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em; background: rgba(var(--hairline-rgb),.10);
  padding: 1px 5px; border-radius: 4px;
}
.legal-body a { color: var(--forest-700); }

.legal-index { list-style: none; margin: 0; padding: 0; }
.legal-index li {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 13px 0; border-bottom: 1px solid rgba(var(--hairline-rgb),.14);
}
.legal-index li:last-child { border-bottom: 0; }
.legal-index a { font-weight: 600; }
.legal-sum { flex: 1 1 16rem; font-size: 14px; color: var(--text-dim); }
.legal-tag {
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--alert-err-fg); background: var(--alert-err-bg);
  border-radius: 999px; padding: 2px 9px;
}

.legal-nav { margin-top: 40px; padding-top: 22px; border-top: 1px solid rgba(var(--hairline-rgb),.18); }
.legal-nav h2 {
  margin: 0 0 10px; font-size: 13px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted);
}
.legal-nav a { display: inline-block; margin: 0 16px 8px 0; font-size: 14.5px; color: var(--forest-700); }

/* ── Account management ─────────────────────────────────────────────────── */
.account-head {
  background: var(--forest-900); color: var(--parchment);
  padding-block: 26px;
}
.account-head .wrap { display: flex; align-items: center; gap: 16px; }
.account-head .who { margin-left: auto; display: flex; align-items: center; gap: 14px; font-size: 14px; }
.account-head .who span { color: var(--forest-100); }
.account-head .who button {
  background: transparent; border: 1px solid rgba(244,239,228,.3); color: var(--parchment);
  padding: 7px 15px; border-radius: 999px; font: inherit; font-size: 13.5px; cursor: pointer;
}
.account-head .who button:hover { border-color: var(--accent); color: var(--accent); }

.panel {
  background: var(--surface-card); border: 1px solid rgba(var(--hairline-rgb),.22);
  border-radius: 14px; padding: 26px 26px 22px; margin-bottom: 20px;
}
.panel h2 {
  font-family: var(--serif); font-size: 21px; margin: 0 0 4px; font-weight: 600;
}
.panel .panel-sub { color: var(--text-dim); font-size: 14.5px; margin: 0 0 20px; }
.panel.danger { border-color: var(--panel-danger-border); background: var(--panel-danger-bg); }
.panel.danger h2 { color: var(--panel-danger-fg); }

.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.grid-2 { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

.pill-state {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 650; padding: 5px 12px; border-radius: 999px;
  background: var(--alert-ok-bg); color: var(--alert-ok-fg); border: 1px solid var(--alert-ok-border);
}
.pill-state.warn { background: rgba(var(--accent-rgb),.16); color: var(--accent); border-color: rgba(var(--accent-rgb),.45); }

.skeleton { color: var(--text-dim); font-size: 15px; padding: 40px 0; text-align: center; }

/* Blocked readers — the only place a block can be undone (a blocked profile 404s). */
.block-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.block-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 11px 4px; border-bottom: 1px solid rgba(var(--hairline-rgb),.2);
}
.block-row:last-child { border-bottom: 0; }
.block-name { font-size: 15px; }
.btn-sm { padding: 6px 14px; font-size: 13px; }

/* ── Settings controls ──────────────────────────────────────────────────────
   Added for the notification / appearance / library / receipts panels. Every control
   here is a REAL form element (checkbox or radio) restyled with appearance:none, not a
   div with a click handler — so keyboard focus, space/arrow keys, form semantics and
   screen-reader state come for free instead of being reimplemented badly. */

/* Toggle switch — a checkbox wearing a different coat. */
.switch {
  appearance: none; -webkit-appearance: none;
  position: relative; flex: none;
  width: 42px; height: 24px; margin: 0;
  border-radius: 999px; border: 1px solid rgba(var(--hairline-rgb),.4);
  background: var(--surface-inset);
  cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.switch::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--text-dim);
  transition: transform .15s ease, background .15s ease;
}
.switch:checked { background: var(--accent-fill); border-color: transparent; }
.switch:checked::after { transform: translateX(18px); background: var(--on-accent); }
.switch:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.switch:disabled { opacity: .45; cursor: not-allowed; }

/* A labelled switch row. */
.switch-row {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 0; border-bottom: 1px solid rgba(var(--hairline-rgb),.16);
}
.switch-row:last-child { border-bottom: 0; }
.switch-row .switch-text { flex: 1; min-width: 0; }
.switch-row .switch-title { font-size: 15px; font-weight: 600; display: block; }
.switch-row .switch-sub { font-size: 12.5px; color: var(--text-dim); display: block; margin-top: 2px; }

/* Notification matrix: one row per category, two columns of switches. */
.notif-head {
  display: grid; grid-template-columns: 1fr 74px 74px; gap: 10px; align-items: end;
  padding-bottom: 8px; border-bottom: 1px solid rgba(var(--hairline-rgb),.26);
}
.notif-head span { font-size: 11.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-dim); text-align: center; }
.notif-head span:first-child { text-align: left; }
.notif-row {
  display: grid; grid-template-columns: 1fr 74px 74px; gap: 10px; align-items: center;
  padding: 11px 0; border-bottom: 1px solid rgba(var(--hairline-rgb),.16);
}
.notif-row:last-of-type { border-bottom: 0; }
.notif-row .notif-name { font-size: 15px; }
.notif-cell { display: flex; justify-content: center; }
/* Direct messages have no inbox row on the server, so its cell is deliberately empty
   rather than showing a switch that would write a key nothing reads. */
.notif-cell.na::before { content: "—"; color: var(--text-dim); font-size: 14px; }
@media (max-width: 540px) {
  .notif-head, .notif-row { grid-template-columns: 1fr 56px 56px; gap: 6px; }
}

/* Segmented control (Light / Dark / System) — radios, not buttons. */
.segmented { display: inline-flex; border: 1px solid rgba(var(--hairline-rgb),.34);
  border-radius: 999px; overflow: hidden; background: var(--surface-inset); }
.segmented label {
  margin: 0; padding: 9px 18px; font-size: 14px; font-weight: 600; cursor: pointer;
  color: var(--text-body-dim); transition: background .15s ease, color .15s ease;
}
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented input:checked + label { background: var(--accent-fill); color: var(--on-accent); }
/* 🐛 `outline-offset: -2px` drew the ring INSIDE the label, and a CHECKED label's background is
   --accent-fill -- so the focus ring landed on the accent, in the accent's own colour. Measured
   across the 8 presets it was 1.22:1 (atelier) to 2.69:1 (oxblood); every one under the 3:1 floor.
   A two-tone inset ring instead: it does not depend on the fill, because only ONE of the two
   tones has to clear 3:1 and for every preset at least one does (atelier 10.57:1 via --surface,
   oxblood 6.55:1 via --text). */
.segmented input:focus-visible + label {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--surface), inset 0 0 0 4px var(--text);
}

/* Accent preset swatches. */
.swatches { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 4px; }
.swatch-opt input { position: absolute; opacity: 0; pointer-events: none; }
.swatch-opt label {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  cursor: pointer; margin: 0; font-size: 12px; color: var(--text-dim); font-weight: 600;
}
.swatch-dot {
  width: 34px; height: 34px; border-radius: 50%;
  border: 2px solid transparent; box-shadow: 0 0 0 1px rgba(var(--hairline-rgb),.35) inset;
  transition: transform .12s ease;
}
.swatch-opt input:checked + label .swatch-dot {
  border-color: var(--text); transform: scale(1.08);
}
.swatch-opt input:focus-visible + label .swatch-dot { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.swatch-opt input:checked + label { color: var(--text); }

/* Per-section status line. #alert lives at the top of a now-long page, so a save down
   here would otherwise confirm somewhere the reader cannot see. */
.section-status { font-size: 13px; margin: 12px 0 0; min-height: 1.2em; color: var(--text-dim); }
.section-status.ok { color: var(--alert-ok-fg); }
.section-status.err { color: var(--danger); }
.section-status.busy { opacity: .7; }

/* Import / export */
.file-drop {
  border: 1px dashed rgba(var(--hairline-rgb),.45); border-radius: 12px;
  padding: 20px; text-align: center; background: var(--surface-inset);
}
.file-drop.dragover { border-color: var(--accent); background: rgba(var(--accent-rgb),.08); }
.file-drop input[type=file] { display: block; margin: 10px auto 0; font-size: 13.5px; max-width: 100%; }
.import-summary { margin: 14px 0 0; font-size: 14px; line-height: 1.7; }
.import-summary b { font-variant-numeric: tabular-nums; }
.unmatched-list {
  margin: 10px 0 0; padding: 10px 12px; max-height: 190px; overflow-y: auto;
  background: var(--surface-inset); border-radius: 9px;
  font-size: 13px; color: var(--text-body-dim); list-style: none;
}
.unmatched-list li { padding: 3px 0; }
.progress-track {
  height: 6px; border-radius: 999px; background: var(--surface-inset);
  overflow: hidden; margin-top: 12px;
}
.progress-fill { height: 100%; width: 0; background: var(--accent-fill); transition: width .2s ease; }

/* ── Account page: theme-responsive overrides ───────────────────────────────
   These are scoped to body.account ON PURPOSE. The same classes are used by /login,
   /signup and /forgot, which are pre-auth: there is no signed-in reader whose accent we
   could honour there, so those pages keep the fixed forest-green identity and only the
   signed-in account page follows the chosen theme. */

/* The global rule is `a { color: var(--forest-700) }` — a dark green that lands at roughly
   2:1 on the dark ground, i.e. an invisible link. */
body.account a { color: var(--accent); }
body.account a:hover { color: var(--accent-bright); }

/* Primary buttons pick up the accent, so choosing "Teal" is visible on this page and not
   only inside /app. */
body.account .btn-solid { background: var(--accent-fill); color: var(--on-accent); }
body.account .btn-solid:hover { background: var(--accent-bright); color: var(--on-accent); }

/* The green header band is brand chrome and stays put in both themes; its own text colours
   are already fixed against that green. */
body.account hr { border-color: rgba(var(--hairline-rgb),.2); }

/* ── Small screens ──────────────────────────────────────────────────────────
   The auth card was 384px wide on a 375px phone: 320px of Google button plus 32px of padding
   each side. A grid item with `place-items: center` cannot shrink below its min-content, so it
   overflowed to the right, which read as "not centred" and gave the page a sideways scroll.
   The button is responsive now; this trims the padding so the card fits with room to spare. */
@media (max-width: 480px) {
  .auth-shell { padding: 24px 14px; }
  .auth-card { padding: 26px 18px 24px; border-radius: 14px; }
  .auth-card h1 { font-size: 23px; }

  .account-head { padding-block: 18px; }
  .account-head .wrap { flex-wrap: wrap; gap: 10px; }
  .account-head .who { margin-left: 0; width: 100%; justify-content: space-between; }
  .panel { padding: 18px 16px 16px; border-radius: 12px; }
  .panel h2 { font-size: 19px; }
  .grid-2 { grid-template-columns: 1fr; }

  /* Stacked label + control: a 108px label column leaves ~200px for the input on a phone. */
  .studio-field { flex-direction: column; align-items: stretch; gap: 6px; }
  .studio-field > span { flex: none; }
  .segmented { width: 100%; }
  .segmented label { flex: 1; text-align: center; padding: 9px 8px; }
}

/* Inputs must be >=16px or iOS Safari zooms the page on focus and never zooms back out —
   which strands the user on a horizontally-scrolled viewport. */
@media (max-width: 900px) {
  input[type=email], input[type=password], input[type=text], input[type=number],
  input[type=search], textarea, select { font-size: 16px; }
}

/* Touch targets. `pointer: coarse` rather than a width query — a small laptop still has a mouse,
   and a large tablet still has fingers, so the input device is the thing that actually matters. */
@media (pointer: coarse) {
  .switch { width: 52px; height: 30px; }
  .switch::after { width: 24px; height: 24px; }
  .switch:checked::after { transform: translateX(22px); }
  /* Give the whole row a comfortable height so the miss-tap lands on padding, not a neighbour. */
  .switch-row, .notif-row { min-height: 48px; }
  .notif-cell { min-height: 44px; align-items: center; }
  .studio-layer-name, .studio-layer-eye { padding-block: 12px; }
  .btn-sm { padding: 9px 15px; }
  .account-head .who button { padding: 10px 16px; }
}
