/* Clear Ledger — minimal auth/access surface styling.
   Palette from docs/DESIGN.md. System font stacks stand in for the brand
   typefaces (Bricolage Grotesque / IBM Plex) so this page never fetches a
   third-party font; swap in self-hosted fonts when the UI phase lands. */
:root {
  --ink: #0B2D45;
  --canvas: #F6F4EE;
  --card: #FFFFFF;
  --brass: #D6A550;
  --moss: #287A59;
  --clear: #16A39A;
  /* Every use of the teal in this stylesheet is an INDICATOR — the global
     :focus-visible outline, .dropzone:focus-within, the selected/current
     state borders and the hover affordances. WCAG SC 1.4.11 requires 3:1
     against the adjacent colour for exactly that, and #16A39A measures
     2.83:1 on --canvas, 2.88:1 on the picker's #eef8f6 selected fill and
     2.99:1 inside the dropzone — i.e. the focus ring FAILED AA on the page
     background. #12908A is the same hue darkened until it clears 3:1 on
     every surface it is drawn against (3.55 canvas / 3.90 card / 3.65 on
     --ink for the focused skip link). --clear itself is retained as the
     canonical docs/BRAND.md palette value. Measured, not guessed:
     brain/ops/contrast.py, gated by tests/test_contrast_wcag.py
     (18 Aug 2026). */
  --clear-deep: #12908A;
  --amber: #A96F1D;
  /* Darker amber for small text on a filled pill: white on #A96F1D is
     ~4.2:1, below AA for sub-large text; #8A5512 clears 6:1 (product-
     owner readability feedback, 2 Aug 2026). */
  --amber-deep: #8A5512;
  --clay: #A43B31;
  --slate: #526673;
  --font-ui: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  /* Spacing scale — used for consistent rhythm across cards/sections. */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --border: #d8dfe2;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-ui);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.5rem 1rem 2rem;
}
.skip-link {
  position: fixed;
  left: 1rem;
  top: -4rem;
  z-index: 10;
  padding: 0.65rem 0.85rem;
  border-radius: 6px;
  background: var(--ink);
  color: white;
}
.skip-link:focus { top: 1rem; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.brand-bar {
  width: 100%;
  max-width: 880px;
  margin-bottom: 0.9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -0.01em;
}
.brand img { display: block; }
.brand span { display: grid; line-height: 1.05; }
.brand strong { font-size: 1.05rem; }
.brand small {
  margin-top: 0.22rem;
  color: var(--slate);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.active-company {
  max-width: 48%;
  overflow: hidden;
  color: var(--slate);
  font-size: 0.82rem;
  font-weight: 600;
  text-align: right;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card {
  background: var(--card);
  border: 1px solid rgba(11, 45, 69, 0.08);
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(11, 45, 69, 0.08);
  padding: 2rem;
  width: 100%;
  max-width: 520px;
}
/* Screens with more to scan (dashboard, reports index, etc.) get more
   breathing room on desktop instead of the narrow single-column auth card
   width — still capped well short of full-bleed so line lengths stay
   readable. */
.card-wide { max-width: 880px; }
h1 {
  font-size: 1.25rem;
  margin: 0 0 1.25rem;
  color: var(--ink);
}
label {
  display: block;
  font-size: 0.9rem;
  margin: 0.9rem 0 0.3rem;
}
input[type=text], input[type=email], input[type=password],
input[type=number], input[type=date], input[type=search], select {
  width: 100%;
  padding: 0.55rem 0.6rem;
  border: 1px solid #d8d3c4;
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: var(--font-ui);
  background: var(--card);
  color: var(--ink);
}
.hint {
  color: var(--slate);
  font-size: 0.875rem;
  margin: 0.3rem 0 0;
  line-height: 1.4;
}
.fixed-defaults { margin-top: 1rem; }
fieldset {
  border: 1px solid #d8d3c4;
  border-radius: 8px;
  padding: 0.9rem 0.9rem 0.75rem;
  margin: 0.9rem 0;
}
fieldset legend {
  padding: 0 0.5rem;
  margin-left: -0.35rem;
  background: var(--card);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink);
}
fieldset label { margin-top: 0.3rem; }
/* Button hierarchy: a bare <button>/.btn/.btn-primary is the filled,
   visually dominant action on a screen; .btn-secondary is an outlined
   alternative that reads as available but not the default choice;
   .btn-tertiary is a low-emphasis text action (skip/defer/"not now") that
   recedes further still. Applied consistently so "the next useful action
   is obvious" (docs/BRAND.md interaction signature). */
button, .btn, .btn-primary {
  margin-top: 1.3rem;
  width: 100%;
  padding: 0.65rem 0.9rem;
  background: var(--ink);
  color: var(--canvas);
  border: 1px solid var(--ink);
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  /* Anchor-styled buttons (<a class="btn...">) otherwise keep the UA's
     default link underline, which reads as a strikethrough-like artifact
     when the label wraps on mobile (visual audit, 14 Aug 2026). */
  text-decoration: none;
  display: inline-block;
}
button:hover, .btn:hover, .btn-primary:hover { background: #15506F; border-color: #15506F; color: #FFFFFF; }
.btn-secondary {
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--border);
  font-weight: 600;
}
.btn-secondary:hover { background: var(--canvas); border-color: var(--clear-deep); }
.btn-tertiary {
  width: auto;
  background: transparent;
  color: var(--slate);
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 0.5rem 0.4rem;
  font-weight: 500;
  text-decoration: underline;
  box-shadow: none;
}
.btn-tertiary:hover { background: transparent; color: var(--ink); }
.error {
  background: #fbeae7;
  color: var(--clay);
  border: 1px solid var(--clay);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}
.notice {
  background: #fbf3e3;
  color: var(--ink);
  border: 1px solid var(--amber);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}
.success {
  background: #e8f5ee;
  color: var(--moss);
  border: 1px solid var(--moss);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}
.sensitive {
  font-family: var(--font-mono);
  word-break: break-all;
  background: var(--canvas);
  border: 1px dashed var(--clay);
  padding: 0.6rem;
  border-radius: 6px;
  font-size: 0.82rem;
}
.mono { font-family: var(--font-mono); }
.mfa-qr {
  display: flex;
  justify-content: center;
  margin: 1rem 0;
}
.mfa-qr img {
  width: min(240px, 100%);
  height: auto;
  padding: 0.5rem;
  background: #fff;
  border: 1px solid #d8d3c4;
  border-radius: 10px;
}
.mfa-manual { margin: 0.75rem 0 1rem; }
.mfa-manual summary { color: var(--navy); font-weight: 600; cursor: pointer; }
.mfa-recovery { margin-top: 1rem; }
.recovery-code-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.35rem 1rem;
  padding: 0.75rem 0 0;
  margin: 0;
  list-style: none;
}
.recovery-code-list code { font-size: 0.78rem; overflow-wrap: anywhere; }
.mfa-restart { margin-top: 0.75rem; }
.muted { color: var(--slate); font-size: 0.875rem; }
/* Setup-flow intro copy: full-contrast body text, never .muted — guidance
   a first-time non-accountant must actually read (product-owner
   feedback, 2 Aug 2026: the COA intro "gets lost"). */
.setup-lead { color: var(--ink); font-size: 1rem; line-height: 1.55; max-width: 46rem; }
/* Dashboard intelligence panels (2 Aug 2026). */
.money-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0.6rem; }
.money-tile {
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 0.7rem 0.85rem; border: 1px solid #d8d3c4; border-radius: 10px;
  background: var(--card); text-decoration: none;
}
.money-tile:hover { border-color: var(--clear-deep); }
.money-label { color: var(--slate); font-size: 0.75rem; }
.money-value { color: var(--ink); font-weight: 700; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.coming-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.45rem; }
.coming-list a {
  display: flex; flex-wrap: wrap; gap: 0.15rem 0.8rem; align-items: flex-start;
  padding: 0.55rem 0.8rem; border: 1px solid #d8d3c4; border-radius: 10px;
  background: var(--card); text-decoration: none; color: var(--ink);
}
.coming-list a:hover { border-color: var(--clear-deep); }
.coming-due { flex: 0 0 6.5rem; color: var(--clay); font-weight: 700; font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.coming-body { flex: 1 1 12rem; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.coming-body strong { display: block; }
.coming-detail { display: block; color: var(--slate); font-size: 0.78rem; }

/* Ten-Minute Month stages. */
.month-stages { list-style: none; padding: 0; margin: 1rem 0; display: flex; flex-direction: column; gap: 0.6rem; }
.month-stage { display: flex; gap: 0.8rem; align-items: flex-start; padding: 0.8rem 0.9rem; border: 1px solid #d8d3c4; border-radius: 10px; background: var(--card); }
.month-stage.current { border-color: var(--clear-deep); box-shadow: 0 3px 12px rgba(22,163,154,0.12); }
.month-stage.done { opacity: 0.7; }
.month-stage-mark { flex: 0 0 1.7rem; height: 1.7rem; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--ink); color: white; font-weight: 700; font-size: 0.85rem; }
.month-stage.done .month-stage-mark { background: var(--moss); }
.month-stage-detail { display: block; color: var(--slate); font-size: 0.82rem; margin: 0.15rem 0 0.4rem; }
/* P15-15: a stage that does not apply, or that this role cannot open, is
   dimmed but NEVER given the done treatment — same reason it is not
   hidden. `untracked` is a step whose completion Clear Ledger cannot
   observe; it carries no tick and no completion colour. */
.month-stage.na { opacity: 0.75; border-style: dashed; }
.month-stage.na .month-stage-mark { background: var(--slate); }
.month-stage.untracked .month-stage-mark { background: var(--clear-deep); }
.month-stage-state { display: inline-block; margin-left: 0.5rem; padding: 0.05rem 0.45rem; border-radius: 999px; border: 1px solid #d8d3c4; color: var(--slate); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; vertical-align: middle; }
.month-stage-caveat { display: block; color: var(--slate); font-size: 0.78rem; font-style: italic; margin: 0 0 0.4rem; }

/* Busy submit buttons (busy.js): inline spinner + no double-submit. */
button.is-busy, input[type="submit"].is-busy {
  position: relative;
  opacity: 0.75;
  cursor: progress;
}
button.is-busy::after {
  content: "";
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.55em;
  vertical-align: -0.1em;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: white;
  border-radius: 50%;
  animation: cl-spin 0.7s linear infinite;
}
@keyframes cl-spin { to { transform: rotate(360deg); } }

/* Drag-and-drop upload zones (progressive enhancement, dropzone.js). The
   real input sits inside, visually quiet but still focusable/clickable —
   keyboard and no-JS flows are untouched. */
.dropzone {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 1.1rem 1rem;
  border: 2px dashed #b9c3ca;
  border-radius: 10px;
  background: #fbfaf7;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone.dragover { border-color: var(--clear-deep); background: #eef8f7; }
.dropzone.has-file { border-style: solid; border-color: var(--moss); }
.dropzone:focus-within { outline: 2px solid var(--clear-deep); outline-offset: 2px; }
.dropzone-prompt { color: var(--slate); font-size: 0.85rem; }
.dropzone-file { color: var(--moss); font-weight: 600; font-size: 0.85rem; word-break: break-all; }
.dropzone .dropzone-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.template-picker { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin-bottom: 0.75rem; }
.template-picker label { flex-basis: 100%; }
.template-picker select { padding: 0.35rem 0.5rem; font-size: 0.95rem; }
.template-picker button { margin-top: 0; }
.pill-template { background: var(--moss); color: white; margin-left: 0.35rem; }
/* `.company-list` lived here until 17 Aug 2026. It was the pre-BM-2
   company chooser: a list reset plus a card-ish button treatment. The
   /portfolio rebuild (BM-2, 2 Aug 2026) replaced it with
   `.company-portfolio` / `.portfolio-card` immediately below, which carry
   the same list reset and a fuller button treatment, and companies.html /
   portfolio.html have rendered those ever since. Deleted rather than
   rewired: unlike `.attention-card`, nothing needed this component — its
   successor is right there and already in use. */
.site-footer { text-align: center; color: var(--slate); font-size: 0.8rem; margin-top: 2rem; margin-bottom: 0; }
.portfolio-search { margin: 1rem 0; }
.portfolio-search input[type=search] { max-width: 320px; display: inline-block; }
.portfolio-search button { width: auto; margin: 0.5rem 0.5rem 0 0; }
.portfolio-search a { display: inline-block; margin-top: 0.5rem; }
.company-portfolio { list-style: none; padding: 0; margin: 1rem 0 0; }
.portfolio-card { margin-bottom: 0.8rem; }
.portfolio-card button {
  margin: 0;
  padding: 1rem;
  background: var(--card);
  color: var(--ink);
  border: 1px solid #d8dfe2;
  border-radius: 10px;
  text-align: left;
}
.portfolio-card button:hover {
  background: #f7fbfb;
  color: var(--ink);
  border-color: var(--clear-deep);
}
.portfolio-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.portfolio-heading strong { font-size: 0.95rem; }
.portfolio-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.65rem;
  margin-top: 0.8rem;
  color: var(--slate);
  font-size: 0.8rem;
}
.portfolio-meta small {
  display: block;
  margin-bottom: 0.15rem;
  color: var(--slate);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.portfolio-next {
  display: block;
  margin-top: 0.8rem;
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: 700;
}
/* /portfolio cards carry more than one action (search result meta +
   status badges + a single "open" button), unlike the plain-button
   /companies cards above — the box styling moves from the button onto a
   wrapper so the button itself can stay a normal small action. */
.portfolio-card-body {
  padding: 1rem;
  background: var(--card);
  border: 1px solid #d8dfe2;
  border-radius: 10px;
}
.portfolio-card-body .portfolio-meta + .portfolio-meta { margin-top: 0.4rem; }
.portfolio-card-body form { margin: 0.8rem 0 0; }
.portfolio-card-body .primary-action { width: auto; padding: 0.5rem 1rem; }
.access-list { list-style: none; padding: 0; margin: 0; }
.access-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid #e8e4d9;
  font-size: 0.85rem;
}
.access-list small { display: block; color: var(--slate); margin-top: 0.15rem; }
.pending-actions { display: flex; align-items: center; gap: 0.4rem; }
.pending-actions form { margin: 0; }
.link-button {
  width: auto;
  margin: 0;
  min-height: 32px;
  padding: 0.3rem 0.5rem;
  border: 0;
  background: transparent;
  color: var(--clay);
  text-decoration: underline;
  font-size: 0.82rem;
}
.link-button:hover { background: transparent; color: var(--ink); }
.role-guide {
  margin: 0.6rem 0 0;
  padding-left: 1.1rem;
  color: var(--slate);
  font-size: 0.875rem;
  line-height: 1.45;
}
.role-guide li { margin-bottom: 0.3rem; }
.vat-conditional {
  margin: 1rem 0 0;
  padding: 0.8rem;
  border: 1px solid #e8e4d9;
  border-radius: 6px;
  background: #fcfbf7;
}
.vat-conditional[hidden], [data-vat-group-fields][hidden] { display: none; }
.check-row {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  line-height: 1.4;
  cursor: pointer;
}
.check-row input { margin-top: 0.15rem; flex: 0 0 auto; }
.notice a { color: inherit; font-weight: 600; }
h2 { font-size: 1rem; margin: 1.5rem 0 0.5rem; }
.pill {
  display: inline-block;
  font-size: 0.75rem;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--slate);
  color: white;
  margin-left: 0.4rem;
}
.pill-warning { background: var(--clay); }
/* docs/BRAND.md: Blocked #A43B31 (--clay) = "cannot proceed safely". A
   skipped chart-upgrade row is exactly that — Clear Ledger refuses to
   touch an account a person has not decided about. coa_upgrade.html named
   this class from the day it was written; only the rule was missing, so a
   skipped row rendered in the neutral --slate pill. Same variant shape as
   the existing `.attention-card.blocked`.
   NOT changed here: `.pill-warning` above also renders --clay, so the two
   look alike today. Per BRAND that one arguably wants --amber ("needs
   attention but is not broken"), but its five callers say "Disabled",
   "Superseded", "Overdue", "Never reviewed" — re-colouring them is a
   judgement about those screens, not this defect. Recorded, not done. */
.pill-blocked { background: var(--clay); }
.access-list-item { flex-wrap: wrap; }
.inline-role-form {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
}
.inline-role-form select {
  width: auto;
  min-height: 32px;
  padding: 0.2rem 0.4rem;
  font-size: 0.82rem;
}
.hidden { display: none; }
.logout-form { margin-top: 1rem; }
.logout-form-small { margin-top: 0.5rem; }
.switch-company {
  display: block;
  text-align: center;
  text-decoration: none;
}
.switch-company-wrapper { margin-top: 1rem; }
.setup-nav {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
}
.setup-nav a {
  padding: 0.55rem 0;
  color: var(--ink);
  font-weight: 600;
}
.primary-action {
  display: block;
  text-align: center;
  text-decoration: none;
}
.action-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.7rem;
  margin-top: 1.25rem;
  /* Defensive reset: this is a <nav> of cards, never a plain link list —
     no marker column, no inherited left rule from list/quote styling. */
  list-style: none;
  padding: 0;
  border-left: none;
}
.action-card {
  display: block;
  min-height: 92px;
  padding: 0.85rem;
  border: 1px solid #d8dfe2;
  border-radius: 10px;
  background: var(--card);
  box-shadow: 0 1px 3px rgba(11, 45, 69, 0.05);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.action-card strong, .action-card span { display: block; }
.action-card strong { font-size: 0.86rem; }
.action-card span {
  margin-top: 0.35rem;
  color: var(--slate);
  font-size: 0.75rem;
  line-height: 1.35;
}
.action-card:hover, .action-card:focus-visible {
  border-color: var(--clear-deep);
  box-shadow: 0 5px 16px rgba(11, 45, 69, 0.08);
  transform: translateY(-1px);
}
/* Must out-specify `.action-card span` (which sets slate + block), or the
   badge renders slate-on-amber and stretches the full card width
   (product-owner screenshot, 2 Aug 2026). */
.action-card .count-badge {
  margin-top: 0.5rem;
  display: inline-flex;
  align-self: flex-start;
  width: fit-content;
  color: white;
  font-size: 0.78rem;
}
button:focus-visible, .btn:focus-visible, a:focus-visible,
input:focus-visible, select:focus-visible,
summary:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--clear-deep);
  outline-offset: 3px;
}

/* Dashboard-style grouped sections (docs/DESIGN.md "each page has one
   visually dominant next action" + grouping into scannable clusters). */
.dashboard-section { margin-top: var(--sp-6); }
.dashboard-section:first-of-type { margin-top: var(--sp-4); }
.section-heading {
  margin: 0 0 var(--sp-2);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--slate);
}
.attention-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--sp-3);
}
.attention-card {
  display: block;
  padding: var(--sp-4);
  border-radius: 10px;
  border: 1px solid var(--amber);
  background: #fbf3e3;
  color: var(--ink);
  text-decoration: none;
  transition: box-shadow 120ms ease, transform 120ms ease;
}
.attention-card:hover, .attention-card:focus-visible {
  box-shadow: 0 5px 16px rgba(11, 45, 69, 0.08);
  transform: translateY(-1px);
}
.attention-card strong { display: block; font-size: 0.9rem; }
.attention-card span { display: block; margin-top: 0.3rem; color: var(--slate); font-size: 0.8rem; line-height: 1.4; }
.attention-card.blocked { border-color: var(--clay); background: #fbeae7; }
.attention-note {
  margin: 0 0 var(--sp-3);
}
.attention-note:last-child { margin-bottom: 0; }
.count-badge {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.8;
  padding: 0.05rem 0.55rem;
  border-radius: 999px;
  background: var(--ink);
  color: white;
}
/* Tables scroll within their own container on narrow screens instead of
   breaking the page layout (P10-01). Every template that renders a <table>
   wraps it in this container — see tests/test_p10_ux_polish.py, which sweeps
   the template directory so a newly added table cannot silently regress it.
   `min-width: 0` matters inside grid/flex parents: without it the container
   would refuse to shrink and the page body would scroll instead. */
.table-scroll {
  width: 100%;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: thin;
}
/* A scrollable region that only a mouse can scroll strands keyboard users on
   a wide trial balance or VAT 201. Every wrapper therefore carries
   role="region" + tabindex="0" + an aria-label taken from the table's own
   caption (so these are named stops, not 76 anonymous ones). The focus ring
   is the shared `[tabindex]:focus-visible` rule above — this only stops the
   ring being clipped by the container's own overflow. */
.table-scroll:focus-visible { outline-offset: -3px; }
@media (min-width: 720px) {
  .card-wide .action-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* P10-01: the missing 420-600px band. Everything below 600px got the
   Exceptions touch-target and picker rules, but the *page frame* only
   adapted at 420px — so a 480px phone kept desktop card padding and a
   two-up action grid, which is what pushed report tables off screen.
   Written as max-width: 600px (not a 421-600 range) so the 420px block
   below stays a further tightening rather than a replacement. */
@media (max-width: 600px) {
  .card { padding: 1.5rem 1.15rem; }
  .action-grid { grid-template-columns: 1fr; }
  .money-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); }
  /* Data tables get a touch more room by giving back the horizontal
     padding they don't need; the amount columns stay mono, right-aligned
     and unbreakable — the container scrolls, the figure never wraps. */
  .journal-lines-table, .report-table, .data-table { font-size: 0.82rem; }
  .journal-lines-table th, .journal-lines-table td,
  .report-table th, .report-table td,
  .data-table th, .data-table td { padding: 0.4rem 0.35rem; }
  .report-window-form { gap: 0.5rem; }
  .report-window-form label, .report-window-form input, .report-window-form select { width: 100%; }
  .setup-nav { flex-direction: column; gap: 0.5rem; }
}
@media (max-width: 420px) {
  body { padding: 1rem 0.75rem; }
  .card { padding: 1.35rem; }
  .recovery-code-list { grid-template-columns: 1fr; }
  .action-grid { grid-template-columns: 1fr; }
  .portfolio-meta { grid-template-columns: 1fr; }
  .attention-grid { grid-template-columns: 1fr; }
  .active-company { max-width: 100%; white-space: normal; overflow-wrap: anywhere; text-align: left; }
  .brand-bar { flex-wrap: wrap; }
}

/* Journal (P2-07/P2-08 manual-journal web slice) */
.journal-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.75rem 0;
}
.journal-filters .pill {
  background: var(--card);
  color: var(--ink);
  border: 1px solid #d8d3c4;
  text-decoration: none;
  margin-left: 0;
}
.journal-filters .pill-active { background: var(--ink); color: var(--canvas); border-color: var(--ink); }
.journal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  text-decoration: none;
  color: inherit;
}
/* `.report-table` and `.data-table` are the same object as
   `.journal-lines-table` — a ledger-style data table — and previously had no
   styling at all, so money columns rendered left-aligned in the body font.
   One rule set, one look (docs/DESIGN.md "money right-aligned in mono"). */
.journal-lines-table, .report-table, .data-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.75rem 0;
  font-size: 0.85rem;
}
.report-table th, .report-table td,
.data-table th, .data-table td {
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid #e8e4d9;
  vertical-align: top;
}
/* An amount is a single unit of meaning: never break "1,234.56" across two
   lines. The wrapper above scrolls instead. */
.journal-lines-table td.amount, .journal-lines-table th.amount,
.report-table td.amount, .report-table th.amount,
.data-table td.amount, .data-table th.amount {
  text-align: right;
  font-family: var(--font-mono);
  white-space: nowrap;
}
.report-table tfoot td, .data-table tfoot td {
  font-weight: 700;
  border-top: 2px solid var(--ink);
  border-bottom: none;
}
.journal-lines-table th, .journal-lines-table td {
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid #e8e4d9;
  /* Top-align so a long wrapped explanation column (e.g. the VAT-threshold
     "Why" cells on mobile) doesn't leave neighbouring short cells floating
     mid-row (visual audit, 14 Aug 2026). */
  vertical-align: top;
}
.journal-lines-table tfoot td { font-weight: 700; border-top: 2px solid var(--ink); border-bottom: none; }
.journal-line-row select, .journal-line-row input { margin-bottom: 0.4rem; }
.journal-line-row { border-bottom: 1px solid #e8e4d9; padding-bottom: 0.75rem; margin-bottom: 0.75rem; }
.journal-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.journal-actions form { margin: 0; flex: 1 1 auto; }
.journal-actions button, .journal-actions .btn { margin-top: 0; }
.journal-meta { color: var(--slate); font-size: 0.85rem; margin: 0.2rem 0 1rem; }
.journal-meta div { margin-bottom: 0.15rem; }

/* Phase 6: Exceptions Inbox */
.exceptions-txn {
  background: var(--canvas);
  border: 1px solid #e8e4d9;
  border-radius: 8px;
  padding: 0.85rem 1rem;
  margin: 0.75rem 0;
}
.exceptions-txn p { margin: 0.2rem 0; }
.exceptions-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.exceptions-actions form { margin: 0; }
.exceptions-actions button, .exceptions-actions .btn { margin-top: 0; }
.exceptions-change-form { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.exceptions-lead { font-size: 1rem; margin: 0.9rem 0 0.4rem; }
.why-detail { margin: 0.5rem 0 0.75rem; }
.why-detail summary {
  cursor: pointer;
  color: var(--slate);
  font-size: 0.82rem;
  font-weight: 600;
}
.why-detail p { margin: 0.4rem 0 0; }

/* Phase 9: reporting & sign-off */
.report-window-form { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: flex-end; margin: 0.75rem 0 1rem; }
.report-window-form label { display: block; font-size: 0.8rem; color: var(--slate); }
.report-notes { margin-top: 1.5rem; border-top: 1px solid #e8e4d9; padding-top: 1rem; }
.report-notes-list { list-style: none; margin: 0; padding: 0; }
.report-notes-list li { border-bottom: 1px solid #e8e4d9; padding: 0.5rem 0; }
.report-note-form { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.75rem; max-width: 40rem; }
.report-note-form textarea { font-family: inherit; }

/* Phase 3 web upload flow: banking + statements */
.quarantine-detail {
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink);
  background: var(--canvas);
  border: 1px solid #e8e4d9;
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  margin: 0;
}

/* COA/classification v2 — grouped picker + export-evidence confirmations */
.picker-search { display: block; margin: 0 0 .3rem; max-width: 28rem; }
.export-evidence { margin-top: .5rem; }
.export-evidence label { display: block; }
.upgrade-list li { flex-wrap: wrap; gap: .35rem; }
.upgrade-list li span:first-child { overflow-wrap: anywhere; min-width: 0; }
.picker-search-status { margin: .15rem 0 .35rem; }

/* Taxonomy v3 — picker legend, follow-up evidence blocks, touch sizing */
.picker-legend { margin: 0 0 .4rem; }
.picker-legend summary { cursor: pointer; color: var(--slate); font-size: 0.82rem; font-weight: 600; }
.picker-legend ul { margin: .35rem 0 0; padding-left: 1.1rem; }
.picker-legend li { margin: .2rem 0; font-size: 0.85rem; }
.picker-followup { margin: .5rem 0; flex-basis: 100%; }
.picker-followup label { display: block; }
.picker-followup select { max-width: 100%; }
.picker-followup .hint { margin: .15rem 0 0; }
@media (max-width: 600px) {
  /* Touch targets (spec §6.11): comfortable minimum hit size on the
     answer/review/correction forms; search + follow-up controls wrap
     inside the viewport — never a horizontal scroll. */
  .exceptions-actions select, .exceptions-actions button,
  .exceptions-change-form select, .exceptions-change-form button,
  .exceptions-review-form select, .exceptions-review-form button,
  .auto-record-run button {
    min-height: 44px;
  }
  .picker-search { max-width: 100%; min-height: 44px; }
  .exceptions-change-form select, .exceptions-review-form select,
  .exceptions-actions select { max-width: 100%; }
}

/* Wave-3b — review-screen suggestion line + explicit use-suggestion tick,
   and the advisory corporate-tax block (all additive). */
.review-suggestion { margin: .35rem 0 .15rem; color: var(--slate); }
.review-use-suggestion { display: block; margin: 0 0 .5rem; }
.ct-advisory { margin: 1rem 0; padding: .75rem .9rem; border: 1px solid var(--border, #d8dee6); border-radius: 8px; }
.ct-advisory .section-heading { margin-top: 0; }
.ct-advisory-amounts { max-width: 24rem; }
.ct-advisory-amounts th { text-align: left; font-weight: 600; }
.ct-advisory-questions ul { margin: .25rem 0 0; padding-left: 1.1rem; }
.ct-advisory-source { overflow-wrap: anywhere; }
.ct-advisory-disclaimer { font-weight: 600; }
.ct-advisory-fallback { color: var(--slate); }

/* Wave-3c — progressive group -> category -> treatment picker. The native
   grouped select stays in the document as the submitted source of truth and
   is only visually hidden after JavaScript has built the step controls. */
.category-picker { width: 100%; min-width: 0; }
.picker-native-enhanced {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.picker-steps {
  width: 100%;
  min-width: 0;
  margin: .45rem 0 .65rem;
}
.picker-step-heading {
  margin: .7rem 0 .25rem;
  color: var(--ink);
  font-size: .95rem;
}
.picker-step-help { margin-bottom: .45rem; }
.picker-current-selection {
  margin: .35rem 0 .55rem;
  padding: .45rem .55rem;
  border-left: 3px solid var(--clear-deep);
  background: #eef8f6;
  overflow-wrap: anywhere;
}
.picker-button-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: .45rem;
  width: 100%;
  min-width: 0;
}
.picker-choice-button,
.picker-trail-button {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  margin: 0;
  padding: .65rem .75rem;
  border: 1px solid #d8d3c4;
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  line-height: 1.35;
  text-align: left;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: normal;
  cursor: pointer;
}
.picker-choice-button:hover { border-color: var(--clear-deep); background: #f5faf9; }
.picker-choice-button[aria-pressed="true"] {
  border-color: var(--clear-deep);
  box-shadow: 0 0 0 2px rgba(16, 126, 117, .18);
  background: #eef8f6;
}
.picker-suggestion-list {
  margin-bottom: .75rem;
  padding-bottom: .75rem;
  border-bottom: 1px solid #e8e4d9;
}
.picker-suggestion-button { border-style: dashed; }
.picker-suggested-treatment { border-color: var(--brass); }
.picker-trail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem;
  width: 100%;
  min-width: 0;
  margin-bottom: .4rem;
}
.picker-trail-button {
  width: auto;
  min-height: 36px;
  padding: .35rem .55rem;
  color: var(--slate);
  font-size: .82rem;
}
.picker-search-status.error { width: 100%; padding: .45rem .55rem; }

@media (max-width: 600px) {
  .category-picker,
  .picker-steps,
  .picker-button-list,
  .picker-choice-button { max-width: 100%; }
  .picker-button-list { grid-template-columns: minmax(0, 1fr); }
  .picker-choice-button { min-height: 48px; }
  .picker-legend summary { min-height: 44px; display: flex; align-items: center; }
}

/* Suggested AR/AP matches (/bills, /invoices) — a proposal with its
   reason and a one-click accept, never an applied match. */
.suggestion {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: baseline;
  margin: .35rem 0;
}
.suggestion form { margin: 0; }

/* P10-03 long-operation indicator (_longop.html). The "before" forecast
   reuses the existing <details> disclosure look; the "during" state is an
   INDETERMINATE <progress> — deliberately valueless, because none of
   these operations can count how far through itself it is, and a bar
   filling on a timer would be a fabricated figure. */
.longop-forecast {
  margin: 0 0 var(--sp-3);
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fbfaf7;
}
.longop-forecast summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
}
.longop-steps {
  margin: 0.4rem 0 0.6rem 1.1rem;
  padding: 0;
  color: var(--slate);
  font-size: 0.86rem;
}
.longop-steps li { margin: 0.15rem 0; }
.longop-running {
  margin: 0.6rem 0;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--clear-deep);
  border-radius: 10px;
  background: #eef8f7;
}
.longop-running[hidden] { display: none; }
.longop-progress { width: 100%; height: 0.6rem; }

/* P10-05 term-level help (_help.html): the same quiet disclosure the
   picker legend uses, so a definition never competes with the action. */
.term-help { margin: 0.35rem 0 0.6rem; }
.term-help summary {
  cursor: pointer;
  color: var(--slate);
  font-size: 0.82rem;
  font-weight: 600;
}
.term-help .hint { margin: 0.25rem 0 0; }
.glossary-index ul {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--sp-4);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
}
.glossary-entry { margin: 0 0 var(--sp-5); }
.glossary-short { font-weight: 600; }

/* P10-04 notices: the frame slot and the /notifications list. */
.brand-notices {
  color: var(--ink);
  text-decoration: none;
  font-size: 0.86rem;
  font-weight: 600;
  white-space: nowrap;
}
.brand-notices:hover { text-decoration: underline; }
.notice-list { list-style: none; padding: 0; margin: 0 0 var(--sp-4); }
.notice-item {
  padding: 0.7rem 0.9rem;
  margin: 0 0 0.6rem;
  border: 1px solid var(--border);
  border-left: 4px solid var(--brass);
  border-radius: 10px;
  background: var(--card);
}
.notice-item form { margin: 0.3rem 0 0; }

@media (max-width: 600px) {
  .term-help summary { min-height: 44px; display: flex; align-items: center; }
  .longop-forecast summary { min-height: 44px; display: flex; align-items: center; }
  .brand-notices { min-height: 44px; display: inline-flex; align-items: center; }
}
