/* Additions on top of site.css (copied from datafactory). Product-specific pieces only. No inline styles anywhere:
   the content security policy forbids them. */
.admin-nav { margin-bottom: 14px; } .admin-nav a { font-weight: 600; text-decoration: none; color: var(--ink); display: inline-flex; align-items: center; min-height: var(--tap); }
.admin-nav a[aria-current=page] { color: var(--accent); border-bottom: 2px solid var(--accent); }
.plan-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; align-items: stretch; }
@media (min-width: 700px) { .plan-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .plan-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.plan { margin-bottom: 0; display: flex; flex-direction: column; }
.plan > p:last-child { margin-top: auto; }
.plan-featured { border-color: var(--accent); }
.plan-price { font-size: 2rem; font-weight: 700; margin: 0; }
.step-no { font-size: 1.6rem; font-weight: 700; color: var(--accent); margin: 0 0 4px; }
.check-msg { border-left: 4px solid var(--accent); padding: 10px 14px; margin: 12px 0; background: color-mix(in srgb, var(--accent) 8%, transparent); }
.check-msg p { margin: 0 0 8px; }
.auth-aside-text { padding: 32px; display: none; }
@media (min-width: 960px) { .auth-aside-text { display: flex; flex-direction: column; justify-content: center; gap: 12px; } }
.auth-aside-text .auth-caption { position: static; padding: 0; background: none; }
.auth-aside-text .auth-caption strong { display: block; font-size: 1.3rem; margin-bottom: 6px; }
ol.steps { padding-left: 1.2rem; }
ol.steps li { margin-bottom: 6px; }

/* firm app */
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.counter-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (min-width: 800px) { .counter-row { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.counter { display: block; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: inherit; text-decoration: none; font-size: .9rem; }
.counter:hover { border-color: var(--accent); }
.counter-n { display: block; font-size: 1.8rem; font-weight: 700; line-height: 1.1; }
.counter-warn .counter-n { color: #b3261e; }
.pill-warn { background: color-mix(in srgb, #d9651c 18%, transparent); }
.tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.tabs a { display: inline-flex; align-items: center; min-height: var(--tap); padding: 6px 14px; border: 1px solid var(--line); border-radius: 999px; text-decoration: none; color: inherit; font-size: .9rem; }
.tabs a[aria-current="page"] { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.table-wrap { overflow-x: auto; margin-bottom: 18px; }
.table-wrap table { width: 100%; border-collapse: collapse; }
.table-wrap th, .table-wrap td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.rows li { padding: 8px 0; border-bottom: 1px solid var(--line); }
.rows li:last-child { border-bottom: none; }
/* a row link is one run of text (name, then title): inline-block so it wraps as a sentence, never as two columns */
.rows li > a { display: inline-block; min-height: 0; padding-block: 9px; }
.row-form { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line); }
.row-form > span:first-child { flex: 1 1 220px; min-width: 0; }
.row-form > * { max-width: 100%; }
.inline-form { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 4px 6px 4px 0; max-width: 100%; }
.inline-details { display: inline-block; vertical-align: top; }
.inline-details > summary { list-style: none; cursor: pointer; }
.inline-details[open] { display: block; margin-top: 8px; }
.item { scroll-margin-top: 80px; }
.item-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; align-items: baseline; }
.item-head h2, .item-head h3 { margin: 0; }
.h3 { font-size: 1.15rem; }
.item-actions { margin-top: 10px; }
.file-row > span { min-width: 0; }
.file-row { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; padding: 8px 0; border-top: 1px dashed var(--line); }
.choice { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 8px; cursor: pointer; }
.choice:has(input:checked) { border-color: var(--accent); }
.choice input { margin-top: 4px; }
.check-line { display: block; margin: 8px 0; }
.preview-box { border: 1px dashed var(--line); border-radius: var(--radius); padding: 12px 14px; margin: 12px 0; }
.preview-box p { margin: 0 0 4px; }
.copy-field { width: 100%; font-family: ui-monospace, monospace; font-size: .85rem; }
.btn-danger { background: #b3261e; border-color: #b3261e; color: #fff; }

.nav .inline-form { margin: 0; }
.nav .inline-form .btn { color: var(--accent); background: transparent; border-color: var(--accent); }
.client-body section { padding-block: 14px; }
.client-body h1 { font-size: clamp(1.5rem, 6vw, 2rem); }
.client-body { overflow-wrap: anywhere; }
/* the quiet disclosures on the client page are still things a thumb has to hit */
.client-body details.na > summary, .client-body details.small > summary { padding-block: 11px; cursor: pointer; }

/* client upload page: phone first, the firm's colour through --accent (served by /r/<token>/brand.css) */
.client-header { border-bottom: 1px solid var(--line); padding: 14px 0; background: var(--surface); }
.client-firm { margin: 0; font-weight: 700; font-size: 1.1rem; }
.client-footer { padding: 24px 0 40px; border-top: 1px solid var(--line); margin-top: 24px; }
.lang-form label { white-space: nowrap; }
.lang-form { display: flex; gap: 8px; align-items: center; justify-content: flex-end; font-size: .9rem; margin-bottom: 8px; }
progress.progress { width: 100%; height: 10px; accent-color: var(--accent); }
.upload-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }
.upload-form .btn { min-height: 48px; display: inline-flex; align-items: center; }
.upload-form p { flex-basis: 100%; margin: 0; }
.item-needs_fix { border-color: #d9651c; }
.item-accepted, .item-na, .item-received_offline { opacity: .75; }
details.na { margin-top: 10px; font-size: .95rem; }
/* A document joined from several pages (app/intake). The one new shape on this page: a sheet with two more behind it, so
   "several pages, one document" is seen before it is read. Everything inside stays the plain file row it always was. */
.file-row.doc-stack { position: relative; margin: 14px 8px 16px 0; padding: 12px 14px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); box-shadow: 4px 4px 0 -1px var(--surface), 4px 4px 0 0 var(--line), 8px 8px 0 -1px var(--surface), 8px 8px 0 0 var(--line); }
.doc-title { font-weight: 700; flex-basis: 100%; }
.doc-note { flex-basis: 100%; margin: 0; color: var(--ink-2); font-size: .95rem; max-width: 60ch; }
.doc-pages { flex-basis: 100%; font-size: .95rem; }
.doc-pages summary { cursor: pointer; padding: 11px 0; color: var(--accent); font-weight: 600; }
.page-list { margin: 0; padding-left: 1.6em; }
.page-list li { padding: 8px 0 4px; border-top: 1px dashed var(--line); }
.page-list li::marker { font-weight: 700; color: var(--ink-2); }
.page-name { display: block; overflow-wrap: anywhere; }
/* one line of controls a page, also on a phone: the two order buttons, then the two rarer actions as plain links */
.page-actions { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; margin-top: 2px; }
.page-actions .btn { min-height: var(--tap); min-width: var(--tap); padding: 6px 12px; }
.page-actions .btn-link { font-weight: 500; font-size: .92rem; }
/* the firm's side of the same thing: the originals behind a joined PDF */
.originals { flex-basis: 100%; font-size: .9rem; margin: 2px 0 0; }
.originals summary { cursor: pointer; color: var(--ink-2); }
.originals ol { margin: 6px 0 0; padding-left: 1.6em; }
.counter meter, td meter { display: block; width: 100%; max-width: 160px; height: 8px; margin-top: 6px; }
/* country model (docs/COUNTRY-MODEL.md): builder groups, the deadlines card, the landing country block */
.group-title { font-size: .95rem; margin: 14px 0 6px; color: var(--muted, #555); text-transform: uppercase; letter-spacing: .03em; }
.country-block { border: 1px solid var(--line); border-radius: 12px; padding: 16px; margin: 16px 0; }
.country-block h3 { margin: 12px 0 4px; font-size: 1rem; }
.country-block .country-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }
.country-block .country-form select { min-height: var(--tap, 44px); }
.country-block ul.deadlines { list-style: none; padding: 0; margin: 0; }
.country-block ul.deadlines li { padding: 4px 0; }
.country-block .integrations { display: flex; flex-wrap: wrap; gap: 6px; padding: 0; margin: 0; list-style: none; }
.country-block .integrations li { border: 1px solid var(--line); border-radius: 999px; padding: 2px 10px; font-size: .9rem; }

/* credit meter (app/web/templates/app/_credit_meter.html): the month's deep checks, on the dashboard and on Billing.
   One bar, one line of numbers, and the buy button only where it is useful. Every value comes from app/saas/pricing.py. */
.credit-meter { border-top: 1px solid var(--line); margin-top: 14px; padding-top: 12px; }
.credit-head { display: flex; flex-wrap: wrap; gap: 8px; justify-content: space-between; align-items: baseline; margin: 0 0 6px; }
.credit-count { font-variant-numeric: tabular-nums; }
progress.credit-bar { display: block; width: 100%; height: 8px; border: 0; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--line) 70%, transparent); accent-color: var(--accent); color: var(--accent); }
progress.credit-bar::-webkit-progress-bar { background: color-mix(in srgb, var(--line) 70%, transparent); border-radius: 999px; }
progress.credit-bar::-webkit-progress-value { background: var(--accent); border-radius: 999px; }
progress.credit-bar::-moz-progress-bar { background: var(--accent); border-radius: 999px; }
.credit-meter-warn progress.credit-bar { accent-color: #d9651c; }
.credit-meter-warn progress.credit-bar::-webkit-progress-value { background: #d9651c; }
.credit-meter-warn progress.credit-bar::-moz-progress-bar { background: #d9651c; }
.credit-meter-out progress.credit-bar { accent-color: #b3261e; }
.credit-meter-out progress.credit-bar::-webkit-progress-value { background: #b3261e; }
.credit-meter-out progress.credit-bar::-moz-progress-bar { background: #b3261e; }
.credit-meter p { margin: 6px 0 0; }

/* Settings -> WhatsApp, connected state (app/web/templates/app/settings.html) */
dl.kv { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0 0 1em; }
dl.kv dt { color: var(--muted, #5b6472); }
dl.kv dd { margin: 0; overflow-wrap: anywhere; }
.actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 1em; }
#wa-connect-status.error { color: #b3261e; }
/* Settings: WhatsApp first, then the firm's own settings under one heading */
.section-title { margin: 2.2em 0 .6em; padding-top: 1.2em; border-top: 1px solid var(--line); font-size: 1.15rem; }

/* =====================================================================================================================   The firm's path (design review 28 Sep 2026): Settings -> WhatsApp, checklists, new request, the request page, clients.
   One idea runs through every page: a bookkeeper's ledger. Each line of a checklist starts with a mark in a tick column
   (ticked, queried, waiting); the verdict colours are the only colours; the follow-up is a timeline read top to bottom
   ("the chase line"). Pages wrap their body in .app, which sets a working type scale (the marketing h1/h2 are display
   sizes and too loud for a tool). Everything uses the site tokens, so light and dark both follow.
   ========================================================================================================================== */
.app { --attn: var(--warn); --done: var(--ok); --stop: var(--bad); --rail: var(--line); --gap: clamp(16px, 2.4vw, 28px); }
.app h1 { font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.35rem); line-height: 1.1; letter-spacing: -.022em; margin-bottom: .3em; }
.app h2 { font-size: 1.3rem; letter-spacing: -.012em; margin-bottom: .45em; }
.app h3, .app .h3 { font-size: 1.04rem; letter-spacing: -.005em; margin-bottom: .3em; }
.app .page-head { padding-block: clamp(22px, 3.6vw, 40px) 8px; }
.app section { padding-block: 0 clamp(28px, 4vw, 44px); }
.app .card { padding: clamp(16px, 2.2vw, 24px); }
.app .lead { font-size: 1.08rem; }
.app .num, .app time { font-variant-numeric: tabular-nums; }
.app .crumbs { margin-bottom: 0; }
.app .crumbs a { min-height: 32px; }
.app-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap); align-items: start; }
@media (min-width: 1000px) { .app-split { grid-template-columns: minmax(0, 1fr) 360px; } }
.app .hint { max-width: 70ch; }

/* a sentence that says where things stand */
.state-line { font-size: 1.12rem; line-height: 1.45; margin: 0 0 12px; max-width: 64ch; }
.state-line strong { font-weight: 650; }
.meta-row { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 0 0 14px; padding: 0; list-style: none; color: var(--ink-2); font-size: .95rem; }
.meta-row b { font-weight: 600; color: var(--ink); }

/* status stamp next to a title: outlined in a verdict colour, never filled */
.stamp { display: inline-flex; align-items: center; gap: 6px; font-size: .82rem; font-weight: 650; line-height: 1; padding: 6px 10px; letter-spacing: 0;
  border: 1.5px solid currentColor; border-radius: 6px; vertical-align: middle; color: var(--ink-2); white-space: nowrap; }
.stamp-open { color: var(--accent); } .stamp-complete { color: var(--done); } .stamp-draft { color: var(--ink-2); border-style: dashed; }
.stamp-cancelled { color: var(--stop); }
h1 .stamp { position: relative; top: -.25em; margin-left: 8px; }

/* the tick column: a mark per line. The glyph is decoration (aria-hidden); the words next to it carry the state. */
.mark { flex: none; display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; font-size: 14px; font-weight: 800;
  line-height: 1; border: 2px solid var(--line); color: transparent; background: var(--surface); }
.mark::before { content: ""; }
.mark-done { background: var(--done); border-color: var(--done); color: var(--surface); }
.mark-done::before, .mark-ready::before { content: "\2713"; }
.mark-ready { border-color: var(--done); color: var(--done); }
.mark-attn, .mark-fix { border-color: var(--attn); color: var(--attn); }
.mark-attn::before, .mark-fix::before { content: "!"; }
.mark-attn { background: color-mix(in srgb, var(--attn) 14%, var(--surface)); }
.mark-wait { border-style: dashed; border-color: color-mix(in srgb, var(--ink-2) 70%, transparent); }
.mark-na { color: var(--ink-2); }
.mark-na::before { content: "\2013"; }
.mark-bad { border-color: var(--stop); color: var(--stop); }
.mark-bad::before { content: "\00d7"; }
.mark-now { border-color: var(--accent); background: var(--accent); }
.tone-done, .tone-ready { color: var(--done); } .tone-attn, .tone-fix { color: var(--attn); } .tone-bad { color: var(--stop); }
.tone-wait, .tone-na { color: var(--ink-2); }
.state-word { font-size: .9rem; font-weight: 600; }

/* the ledger bar: one segment per checklist line, in order. No widths to compute, so no inline styles. */
.ledger-bar { display: flex; gap: 3px; margin: 0 0 8px; max-width: 640px; }
.ledger-bar span { flex: 1 1 0; height: 10px; border-radius: 2px; background: color-mix(in srgb, var(--ink-2) 20%, transparent); }
.ledger-bar .seg-done { background: var(--done); }
.ledger-bar .seg-na { background: color-mix(in srgb, var(--done) 45%, var(--surface)); }
.ledger-bar .seg-ready { background: color-mix(in srgb, var(--done) 55%, var(--surface)); }
.ledger-bar .seg-attn, .ledger-bar .seg-fix { background: var(--attn); }
.ledger-key { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: .88rem; color: var(--ink-2); margin: 0 0 16px; padding: 0; list-style: none; }
.ledger-key li { display: inline-flex; align-items: center; gap: 6px; }
.ledger-key i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; background: color-mix(in srgb, var(--ink-2) 20%, transparent); }
.ledger-key .k-done { background: var(--done); } .ledger-key .k-attn { background: var(--attn); }

/* the ledger: checklist lines under a heading that says who acts next */
.ledger { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: var(--gap); }
.ledger-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px;
  padding: 14px clamp(14px, 2vw, 20px) 12px; border-bottom: 1px solid var(--line); }
.ledger-head h2 { font-size: 1.08rem; margin: 0; }
.ledger-head p { margin: 0; font-size: .9rem; color: var(--ink-2); }
.ledger-you { border-color: color-mix(in srgb, var(--attn) 55%, var(--line)); }
.ledger-you .ledger-head { background: color-mix(in srgb, var(--attn) 8%, var(--surface)); border-radius: var(--radius) var(--radius) 0 0; }
.line { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 4px 14px; padding: 14px clamp(14px, 2vw, 20px); border-top: 1px solid var(--line); scroll-margin-top: 90px; }
.ledger-head + .line { border-top: 0; }
.line > .mark { margin-top: 1px; }
.line-body { min-width: 0; }
.line-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0; font-size: 1.02rem; font-weight: 650; }
.line-title .pos { font-weight: 500; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.line-title .opt { font-weight: 400; font-size: .88rem; color: var(--ink-2); }
.line p { margin: 4px 0 0; }
.line .instr { color: var(--ink-2); font-size: .93rem; max-width: 72ch; }
.line .note { margin-top: 8px; padding: 8px 12px; border-left: 3px solid var(--attn); background: color-mix(in srgb, var(--attn) 7%, var(--surface)); border-radius: 0 6px 6px 0; font-size: .93rem; }
.line .note-bad { border-left-color: var(--stop); background: color-mix(in srgb, var(--stop) 7%, var(--surface)); }
.files { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.file { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); }
.file a.file-name { font-weight: 600; overflow-wrap: anywhere; min-height: 32px; display: inline-flex; align-items: center; }
.file .file-meta { font-size: .86rem; color: var(--ink-2); }
.file .file-check { flex-basis: 100%; font-size: .88rem; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; margin: 0; }
.file .file-check .pill { font-size: .82rem; }
.file form { margin-left: auto; }
.file-rejected { opacity: .72; }
.file-rejected .file-name { text-decoration: line-through; }
.line-actions { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin-top: 12px; }
.line-actions .inline-form { margin: 0; }
.line-actions details[open] { flex-basis: 100%; }
.line-actions details > summary { list-style: none; display: inline-flex; }
.line-actions details > summary::-webkit-details-marker { display: none; }
.line-actions details form { margin-top: 10px; max-width: 560px; }
.line-actions textarea { margin: 6px 0 8px; }
.line-actions .check-line { margin: 0; }
.more { margin-top: 6px; }
.more > summary { cursor: pointer; font-size: .9rem; color: var(--ink-2); min-height: 32px; display: inline-flex; align-items: center; }
.ledger-done .line { padding-block: 10px; }

/* buttons with the weight of a link: the quiet actions next to the one primary button */
.btn-link { background: none; border: 0; padding: 0 2px; min-height: var(--tap); color: var(--accent); font: inherit; font-weight: 600; cursor: pointer;
  text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent); text-underline-offset: 3px; }
.btn-link:hover { color: var(--accent-deep); text-decoration-color: currentColor; }
.btn-link.danger { color: var(--stop); }
.btn-link.quiet { color: var(--ink-2); font-weight: 500; font-size: .88rem; min-height: 32px; }
.btn-link.quiet:hover { color: var(--stop); }
.btn-link:disabled { color: var(--ink-2); cursor: not-allowed; }
.app .btn:disabled { opacity: .55; cursor: not-allowed; }

/* guidance next to the thing it is about: what is wrong, what to do, and the button that does it */
.guide { padding: 12px 14px; border: 1px solid var(--line); border-left: 4px solid var(--accent); border-radius: 8px; background: var(--surface); margin: 12px 0; }
.guide p { margin: 0 0 6px; max-width: 70ch; } .guide p:last-child { margin-bottom: 0; }
.guide .guide-act { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; margin-top: 10px; }
.guide .inline-form { margin: 0; }
.guide-warn { border-left-color: var(--attn); background: color-mix(in srgb, var(--attn) 6%, var(--surface)); }
.guide-bad { border-left-color: var(--stop); background: color-mix(in srgb, var(--stop) 6%, var(--surface)); }
.guide-ok { border-left-color: var(--done); background: color-mix(in srgb, var(--done) 6%, var(--surface)); }
.guide strong { font-weight: 650; }

/* the chase line: what was sent (newest first) and what will be (dashed rail, hollow marks) */
.chase { list-style: none; margin: 0; padding: 0; }
.chase > li { position: relative; padding: 0 0 16px 34px; }
.chase > li::before { content: ""; position: absolute; left: 11px; top: 26px; bottom: 2px; width: 2px; background: var(--rail); }
.chase > li:last-child { padding-bottom: 4px; }
.chase > li:last-child::before { display: none; }
.chase > li > .mark { position: absolute; left: 0; top: 0; }
.chase-future > li::before { background: repeating-linear-gradient(to bottom, var(--rail) 0 4px, transparent 4px 8px); }
.chase .ev-title { display: flex; flex-wrap: wrap; gap: 0 10px; align-items: baseline; margin: 0; font-weight: 650; line-height: 1.5; }
.chase .ev-title time, .chase .ev-title .when { font-weight: 400; color: var(--ink-2); font-size: .9rem; }
.chase .ev-rows { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 6px; }
.ev-row { font-size: .9rem; line-height: 1.45; }
.ev-row .ch { font-weight: 600; }
.ev-row .to { color: var(--ink-2); overflow-wrap: anywhere; }
.ev-row .ev-st { display: block; }
.ev-row .why { display: block; margin-top: 4px; padding: 8px 10px; border-radius: 6px; background: color-mix(in srgb, var(--stop) 8%, var(--surface)); color: var(--ink); }
.ev-row .why + .why { margin-top: 2px; }
.chase-next > .mark { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 20%, transparent); }
.chase-sep { font-size: .85rem; color: var(--ink-2); margin: 4px 0 10px; }
.aside-block { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; margin-bottom: 16px; }
.aside-block > h2 { font-size: 1.08rem; margin-bottom: 10px; }
.aside-block > :last-child { margin-bottom: 0; }
.aside-block .actions { margin: 12px 0 0; }
.aside-block .actions .inline-form { margin: 0; }
.reply { margin: 0 0 10px; padding: 10px 12px; border-radius: 10px 10px 10px 2px; background: var(--surface-2); font-size: .93rem; }
.reply time { display: block; font-size: .8rem; color: var(--ink-2); }

/* numbered steps (a real sequence: connect, templates, test / WhatsApp, client, checklist, request) */
.steps-v { list-style: none; margin: 0; padding: 0; counter-reset: st; }
.steps-v > li { counter-increment: st; position: relative; padding: 0 0 22px 48px; }
.steps-v > li::after { content: ""; position: absolute; left: 15px; top: 36px; bottom: 4px; width: 2px; background: var(--line); }
.steps-v > li:last-child { padding-bottom: 0; }
.steps-v > li:last-child::after { display: none; }
.steps-v > li::before { content: counter(st); position: absolute; left: 0; top: 0; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  font-weight: 700; font-size: .95rem; border: 2px solid var(--line); color: var(--ink-2); background: var(--surface); }
.steps-v > li.is-done::before { content: "\2713"; background: var(--done); border-color: var(--done); color: var(--surface); }
.steps-v > li.is-current::before { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.steps-v > li.is-warn::before { content: "!"; background: var(--surface); border-color: var(--attn); color: var(--attn); }
.steps-v > li.is-done::after { background: var(--done); }
.steps-v h3 { margin: 4px 0; font-size: 1.08rem; }
.steps-v > li.is-todo h3 { color: var(--ink-2); }
.steps-v p { margin: 0 0 8px; max-width: 66ch; }
.steps-v .step-sum { color: var(--ink-2); font-size: .94rem; }
.steps-v .opt { font-weight: 400; font-size: .88rem; color: var(--ink-2); }
.step-act { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; margin-top: 10px; }
.step-act .inline-form { margin: 0; }

/* the connected number, as a plate: the thing a firm checks first */
.plate { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px 28px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); margin: 8px 0 4px; }
@media (min-width: 640px) { .plate { grid-template-columns: auto 1fr; align-items: center; } }
.plate-num { font-size: 1.45rem; font-weight: 700; letter-spacing: -.01em; font-variant-numeric: tabular-nums; margin: 0; line-height: 1.2; }
.plate-name { margin: 0; color: var(--ink-2); }
.plate dl { margin: 0; display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 2px 14px; font-size: .9rem; }
.plate dt { color: var(--ink-2); } .plate dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }

/* Meta's four templates as a compact list: what it is for, its name, its status */
.tpl-list { list-style: none; margin: 10px 0; padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.tpl-list > li { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; gap: 2px 12px; align-items: start; padding: 10px 12px; border-top: 1px solid var(--line); }
.tpl-list > li:first-child { border-top: 0; }
.tpl-list .tpl-what { margin: 0; font-weight: 600; }
.tpl-list code { font-size: .8rem; color: var(--ink-2); overflow-wrap: anywhere; }
.tpl-list details { grid-column: 2 / -1; font-size: .88rem; }
.tpl-list details summary { cursor: pointer; color: var(--ink-2); min-height: 32px; display: inline-flex; align-items: center; }
.tpl-list details p { margin: 4px 0 0; white-space: pre-line; }
.tpl-list .state-word { white-space: nowrap; padding-top: 2px; }
.tpl-controls { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: end; }
.tpl-controls .field { margin: 0; }
.tpl-controls select { width: auto; min-width: 180px; }

.quiet-foot { border-top: 1px solid var(--line); margin-top: 18px; padding-top: 4px; }
.quiet-foot > details > summary { cursor: pointer; color: var(--ink-2); min-height: var(--tap); display: flex; align-items: center; font-weight: 500; }
.quiet-foot > details[open] > summary { color: var(--ink); font-weight: 600; }

/* the request builder: numbered sections of one form */
.build { counter-reset: bs; }
.build-sec { margin: 0 0 var(--gap); }
.build-sec fieldset.panel { margin: 0; min-width: 0; }
.build-sec > h2 { counter-increment: bs; display: flex; align-items: center; gap: 12px; font-size: 1.2rem; margin-bottom: 12px; }
.build-sec > h2::before { content: counter(bs); flex: none; width: 30px; height: 30px; display: grid; place-items: center; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink); font-size: .95rem; }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: clamp(14px, 2vw, 20px); }
.panel > :last-child { margin-bottom: 0; }
.pick-group { margin: 0 0 16px; }
.pick-group > h3 { font-size: .95rem; color: var(--ink-2); font-weight: 600; margin: 0 0 8px; }
.pick { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
@media (min-width: 760px) { .pick-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.app .choice { margin: 0; background: var(--surface); padding: 12px 14px; align-items: flex-start; }
.app .choice:hover { border-color: var(--ink-2); }
.app .choice:has(input:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: color-mix(in srgb, var(--accent) 6%, var(--surface)); }
.app .choice:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
.app .choice input { width: 18px; height: 18px; flex: none; accent-color: var(--accent); }
.app .choice strong { display: block; }
.choice-meta { font-size: .86rem; color: var(--ink-2); display: block; }
.build-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; padding: 16px 0 0; border-top: 1px solid var(--line); }
.build-foot p { margin: 0; color: var(--ink-2); font-size: .93rem; }
.follow-plan { list-style: none; margin: 8px 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.follow-plan li { border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; font-size: .9rem; background: var(--bg); }
.follow-plan li b { font-weight: 650; }

/* lists of things (clients, checklists): one row each, the name first, facts after, actions at the end */
.rowlist { list-style: none; margin: 0 0 var(--gap); padding: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.rowlist > li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; padding: 12px clamp(14px, 2vw, 20px); border-top: 1px solid var(--line); }
.rowlist > li:first-child { border-top: 0; }
.rowlist .row-main { flex: 1 1 240px; min-width: 0; }
.rowlist .row-main > a, .rowlist .row-main > strong { font-weight: 650; font-size: 1.02rem; }
.rowlist .row-main > a { min-height: 32px; display: inline-flex; align-items: center; }
.rowlist .row-sub { display: block; font-size: .9rem; color: var(--ink-2); overflow-wrap: anywhere; }
.rowlist .row-facts { flex: 1 1 200px; display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: .9rem; color: var(--ink-2); }
.rowlist .row-act { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }
.rowlist .row-act .inline-form { margin: 0; }
.rowlist .copy-field { margin-top: 6px; }
.chan { display: inline-flex; align-items: center; gap: 6px; font-size: .9rem; }
.chan-warn { color: var(--attn); font-weight: 600; }
.toolbar { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; justify-content: space-between; margin: 0 0 14px; }
.toolbar .inline-form input { width: 220px; max-width: 100%; }
@media (max-width: 560px) { .toolbar .inline-form, .toolbar .inline-form input, .toolbar .inline-form select { width: 100%; } }

/* empty states: what this page is for and the one next step */
.empty { background: var(--surface); border: 1px dashed color-mix(in srgb, var(--ink-2) 45%, var(--line)); border-radius: var(--radius); padding: clamp(18px, 3vw, 28px); margin-bottom: var(--gap); }
.empty h2 { font-size: 1.2rem; }
.empty p { max-width: 62ch; }
.empty .cta-row { margin-top: 14px; align-items: center; }

/* contacts on a client page */
.contact { padding: 14px 0; border-top: 1px solid var(--line); }
.contact:first-of-type { border-top: 0; padding-top: 0; }
.contact-head { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; }
.contact-head strong { font-size: 1.02rem; }
.contact-lines { margin: 2px 0 0; font-size: .92rem; color: var(--ink-2); overflow-wrap: anywhere; }
.contact-chan { margin: 6px 0 0; }
.contact details.edit > summary, details.add-contact > summary { cursor: pointer; color: var(--accent); font-weight: 600; min-height: var(--tap); display: inline-flex; align-items: center; }
.contact details.edit .form, details.add-contact .form { margin-top: 8px; }
.radio-row { display: grid; gap: 6px; max-width: 560px; }
.radio-row .choice strong { display: inline; margin-right: 8px; }
.radio-row .choice .choice-meta { display: inline; }
.radio-row .choice { font-size: .95rem; }
fieldset.field { border: 0; padding: 0; margin: 0 0 14px; min-width: 0; }
fieldset.field > legend { font-weight: 600; margin-bottom: 6px; padding: 0; }
.checks-row { display: flex; flex-wrap: wrap; gap: 0 20px; margin: 0 0 12px; }
.checks-row label { display: inline-flex; gap: 8px; align-items: center; min-height: var(--tap); }
.checks-row input { width: 20px; height: 20px; }

/* checklist editor: one numbered item per panel, move/remove small and to the side, save always in reach */
.tpl-item { margin-bottom: 14px; }
/* suggested text (static/suggest.js): light, clearly not typed; Tab takes it */
.app input::placeholder, .app textarea::placeholder { color: color-mix(in srgb, var(--ink-2) 72%, var(--bg)); opacity: 1; font-style: normal; }
.suggest-hint { font-size: .875rem; margin-top: 4px; }
.app input[type=date] { width: 100%; min-height: var(--tap); padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--ink); font: inherit; }
.setup-wrap { max-width: 760px; }
#send { margin-bottom: var(--gap); }
.reach-list { list-style: none; margin: 0 0 14px; padding: 0 0 12px; border-bottom: 1px solid var(--line); font-size: .9rem; }
.reach-list li { margin: 0 0 4px; }
.reach-list .chan { font-size: .88rem; }
.step-act input[type=tel] { max-width: 280px; }
@media (max-width: 560px) {
  .plate dl { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .plate dd { margin-bottom: 6px; }
  .tpl-list > li { grid-template-columns: 24px minmax(0, 1fr); }
  .tpl-list .state-word { grid-column: 2; padding-top: 0; }
  .step-act input[type=tel] { max-width: none; }
}
.app .section-h { margin: var(--gap) 0 12px; }
.app .form > .panel, .app form > .panel { margin-bottom: 14px; }
.tpl-item-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; margin-bottom: 8px; }
.tpl-item-head .pos { font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.tpl-item-head .btn-row { display: flex; gap: 6px; flex-wrap: wrap; }
.tpl-item .grid-3 { align-items: end; }
.save-bar { border-top: 1px solid var(--line); padding: 14px 0 0; display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }

@media (prefers-reduced-motion: no-preference) {
  .guide-flash { animation: guide-in .35s ease-out both; }
  @keyframes guide-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
}
.panel, .ledger, .rowlist, .aside-block, .guide, .empty { overflow-wrap: anywhere; }
/* a link that is the only thing in a table cell (the request in the requests list): a full-height target, same row height */
.table-wrap td > a:only-child { display: inline-block; padding-block: 9px; margin-block: -9px; }
.table-wrap .pill { white-space: nowrap; }
.plan-grid { margin-bottom: 18px; }
form.form + .card { margin-top: 18px; }
/* the requests list on a phone: each request is a block (client, request, then progress, due date and status on one line)
   instead of a table whose last two columns sit off-screen. The column heads stay for screen readers. */
@media (max-width: 640px) {
  table.stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  table.stack, table.stack tbody { display: block; }
  table.stack tr { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
  table.stack tr:last-child { border-bottom: 0; }
  table.stack td { display: block; padding: 0; border: 0; min-width: 0; }
  table.stack td:nth-child(1) { flex-basis: 100%; font-size: .9rem; color: var(--ink-2); }
  table.stack td:nth-child(2) { flex-basis: 100%; font-size: 1.02rem; font-weight: 650; overflow-wrap: anywhere; }
  table.stack td[data-label]::before { content: attr(data-label) " "; color: var(--ink-2); }
  table.stack td > a:only-child { padding-block: 10px; margin-block: 0; }
}
/* phones and tablets: the quiet controls of the firm app grow to a thumb-sized target (44px); desktop keeps the denser rows */
@media (max-width: 1024px) {
  .rowlist .row-main > a, .file a.file-name, .btn-link.quiet, .more > summary, .tpl-list details summary, .app .crumbs a, label.event-box { min-height: var(--tap); }
  .delivery-log summary { padding-block: 10px; }
  .check-line { padding-block: 9px; margin-block: 0; }
  .check-line input[type=checkbox] { width: 20px; height: 20px; vertical-align: -4px; margin: 0 6px 0 0; }
}
@media (max-width: 560px) {
  .app .step-act .btn, .app .guide-act .btn { flex: 1 1 auto; }
  .file form { margin-left: 0; }
  h1 .stamp { top: -.12em; margin-left: 4px; }
}
/* Integrations page (app/web/templates/app/integrations.html): Drive, Dropbox, Slack, webhooks, coming soon.
   Built from the app's own cards, pills, kv lists and tables; only what the page adds lives here. */
.pill-ok { background: color-mix(in srgb, var(--ok) 18%, transparent); }
.integration-head { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.integration-head h3 { margin: 0; }
.integration h4 { margin: 1em 0 .4em; font-size: 1rem; }
.delivery-list { list-style: none; padding: 0; margin: 0 0 1em; }
.delivery-list li { padding: 6px 0; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.delivery-list li:last-child { border-bottom: none; }
.endpoint { border-top: 1px solid var(--line); padding-top: 14px; margin-top: 14px; }
.endpoint-url { overflow-wrap: anywhere; font-size: .92rem; }
.event-boxes { border: 0; padding: 0; margin: 0 0 12px; display: flex; flex-wrap: wrap; gap: 6px 18px; }
.event-boxes legend { font-weight: 600; padding: 0; margin-bottom: 6px; }
.event-box { display: inline-flex; gap: 8px; align-items: center; min-height: 32px; }
.event-box input { width: 20px; height: 20px; flex: none; }
.endpoint-new { border-top: 1px solid var(--line); padding-top: 14px; margin-top: 14px; }
.delivery-log summary { cursor: pointer; margin: 6px 0 10px; }
.secret-once { border-color: var(--ok); }
.secret-once .secret { display: block; padding: 10px 12px; border: 1px dashed var(--line); border-radius: 8px; overflow-wrap: anywhere; user-select: all; }
/* Intuit's "Connect to QuickBooks" button is an image they supply (550 x 96, shown at half size so it is sharp on every
   screen); it is shown as is, only its focus ring is ours */
.qb-connect { display: inline-block; max-width: 100%; line-height: 0; border-radius: 6px; }
.qb-connect img { display: block; width: auto; height: 48px; max-width: 100%; object-fit: contain; object-position: left center; }   /* Intuit's own mark at its own proportions, whichever file (lg 550 x 96, med 160 x 55): never stretched */
.qb-connect:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
/* Xero's "Connect to Xero" and "Disconnect from Xero" buttons are images Xero supplies (43px tall); shown as they are,
   only the focus ring is ours */
.xero-btn { display: inline-block; max-width: 100%; line-height: 0; padding: 0; border: 0; background: none; border-radius: 4px; cursor: pointer; vertical-align: middle; }
.xero-btn img { display: block; max-width: 100%; height: auto; }
.xero-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
/* connection slots: a note on the card (disconnected by Pingtail, waiting for a connection, about to go idle). A rule
   down the left edge in the accent, so it reads as a note about this card and not as an error. */
.slot-note { border-left: 3px solid var(--accent); padding: 2px 0 2px 14px; margin: 0 0 1em; }
.slot-note p { margin: 0 0 .4em; }
.slot-note .inline-form { margin-top: 6px; }
.slot-meter { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; padding: 0; list-style: none; }
.slot-meter li { width: 28px; height: 28px; border: 1px solid var(--line); border-radius: 6px; }
.slot-meter li.used { background: var(--accent); border-color: var(--accent); }
.slot-meter li.held { background: color-mix(in srgb, var(--accent) 30%, transparent); }
.xero-contacts { list-style: none; padding: 0; margin: 0 0 16px; }
.xero-contacts li { padding: 8px 0; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.xero-contacts label { display: flex; gap: 10px; align-items: baseline; }
.integration-soon { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 18px; }
@media (min-width: 700px) { .integration-soon { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* site.css styles text inputs by type and has no rule for type=url, which only this page uses */
.integration input[type=url] { width: 100%; min-height: var(--tap); padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font: inherit; font-size: 1rem; }

/* --- owner console: the funnel report (/admin/funnel) ------------------------------------------------------------------
   One row per stage: what it is, how many, a bar that is a share of the section's first stage, and what was lost since the
   stage before. One series, one hue (the accent); every number is printed beside its bar, so colour never carries it alone.
   An optional step (a firm can pass it by) is drawn hollow, a difference of texture rather than of colour. */
.funnel-filters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; align-items: end; margin: 18px 0 10px; }
.funnel-filters .field { margin: 0; min-width: 0; }
.funnel-filters label { font-size: .88rem; }
.funnel-filters select, .funnel-filters input { width: 100%; min-height: var(--tap); }
.funnel-filter-actions { display: flex; gap: 14px; align-items: center; grid-column: 1 / -1; }
@media (min-width: 760px) { .funnel-filters { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1180px) { .funnel-filters { grid-template-columns: repeat(8, minmax(0, 1fr)) auto; }
  .funnel-filter-actions { grid-column: auto; } }
.funnel-note { max-width: 78ch; margin-top: -4px; }
.funnel { list-style: none; margin: 0 0 30px; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.funnel-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 14px; padding: 14px 16px; border-bottom: 1px solid var(--line); align-items: center; }
.funnel-row:last-child { border-bottom: 0; }
.funnel-what strong { display: block; font-weight: 650; }
.funnel-what .pill { font-size: .78rem; }
.funnel-what .small { display: block; max-width: 60ch; }
.funnel-n { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; line-height: 1.1; }
.funnel-bar { grid-column: 1 / -1; appearance: none; -webkit-appearance: none; display: block; width: 100%; height: 10px; border: 0;
  background: var(--surface-2); border-radius: 0 4px 4px 0; overflow: hidden; color: var(--accent); }
.funnel-bar::-webkit-progress-bar { background: var(--surface-2); border-radius: 0 4px 4px 0; }
.funnel-bar::-webkit-progress-value { background: var(--accent); border-radius: 0 4px 4px 0; }
.funnel-bar::-moz-progress-bar { background: var(--accent); border-radius: 0 4px 4px 0; }
.funnel-optional .funnel-bar::-webkit-progress-value { background: transparent; box-shadow: inset 0 0 0 2px var(--accent); }
.funnel-optional .funnel-bar::-moz-progress-bar { background: transparent; box-shadow: inset 0 0 0 2px var(--accent); }
.funnel-step { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 2px 18px; font-variant-numeric: tabular-nums; }
@media (min-width: 900px) {
  .funnel-row { grid-template-columns: minmax(0, 5fr) 5.5rem minmax(0, 4fr) minmax(0, 3.4fr); gap: 0 20px; }
  .funnel-bar, .funnel-step { grid-column: auto; }
  .funnel-step { flex-direction: column; gap: 0; }
}
.funnel-campaigns .num, table.data th.num, table.data td.num { text-align: right; }
.funnel-leak { margin-bottom: 10px; }
.funnel-leak summary { display: flex; justify-content: space-between; gap: 12px; align-items: center; cursor: pointer; font-weight: 650; min-height: var(--tap); }
.funnel-leak[open] summary { margin-bottom: 10px; }

/* Forward by email (app/web/templates/app/_forward_card.html, forward_clients.html, forward_confirm.html).
   The one thing this card adds is the tally: four plain counts in a row, because "sent" is all Pingtail can know and
   "not sent" and "bounced" must be as easy to see. Everything else is the page's own cards, pills, kv lists and forms. */
.fwd-name { margin: 0; font-size: 1.05rem; }
.fwd-tally { list-style: none; margin: 0 0 14px; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.fwd-tally li { padding: 8px 10px; font-size: .88rem; color: var(--ink-2); border-left: 1px solid var(--line); min-width: 0; }
.fwd-tally li:first-child { border-left: 0; }
.fwd-tally strong { display: block; font-size: 1.35rem; line-height: 1.2; color: var(--ink); font-variant-numeric: tabular-nums; }
.fwd-tally .fwd-flag { background: color-mix(in srgb, #d9651c 12%, transparent); }
.fwd-tally .fwd-flag strong { color: var(--warn); }
@media (max-width: 420px) { .fwd-tally { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fwd-tally li:nth-child(3) { border-left: 0; } .fwd-tally li:nth-child(n+3) { border-top: 1px solid var(--line); } }
/* "Where do you keep the books?": the firm's question first, each answer a row that jumps to its card */
.books { margin: 0 0 8px; }
.books h2 { font-size: 1.45rem; margin-bottom: .3em; }
.books ul { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.books li { border-bottom: 1px solid var(--line); }
.books a { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px 20px; padding: 14px 4px; min-height: var(--tap); color: var(--ink); text-decoration: none; }
.books a strong { color: var(--accent); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.books a strong .pill { text-decoration: none; display: inline-block; font-weight: 400; }
.books a span { color: var(--ink-2); }
.books a:hover strong { color: var(--accent-deep); }
@media (min-width: 700px) { .books a { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); align-items: baseline; } }
.fwd-example { border-left: 3px solid var(--ok); padding: 2px 0 2px 14px; }
.fwd-works ul { margin: 0 0 1em; padding-left: 1.2em; }
.fwd-works li { margin-bottom: .4em; }
.fwd-presets { display: flex; flex-wrap: wrap; gap: 6px 6px; align-items: center; margin: 0 0 6px; }
.fwd-presets a.pill { min-height: 36px; }
.fwd-presets a.fwd-picked { background: var(--accent); color: var(--accent-ink); }
.fwd-after-boxes { margin: -6px 0 14px; }
.fwd-size input { max-width: 9em; }
.fwd-h { font-size: 1.1rem; margin: 0 0 .6em; }
.fwd-confirm { border-color: var(--warn); }
.fwd-clients { list-style: none; margin: 0 0 14px; padding: 0; }
.fwd-client { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px 14px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line); }
.fwd-client:last-child { border-bottom: 0; }
.fwd-client-name { font-weight: 600; overflow-wrap: anywhere; }
.fwd-client input[type=email] { width: 100%; }
.fwd-client-why { grid-column: 1 / -1; margin: 0; }
@media (min-width: 760px) {
  .fwd-client { grid-template-columns: minmax(0, 1fr) max-content minmax(0, 1.1fr) 6.5em; }
  .fwd-client-name { grid-column: 1; } .fwd-client-now { grid-column: 2; white-space: nowrap; }
  .fwd-client input[type=email] { grid-column: 3; } .fwd-client-remove { grid-column: 4; }
}
/* the request page: where an accepted file was emailed, or why it was not */
.file .fwd-line { color: var(--ink-2); }
.file .fwd-line .fwd-to { font-weight: 600; color: var(--ink); }
.file .fwd-not_sent, .file .fwd-bounced { color: var(--warn); }

/* The one-minute guide (app/web/guide.py; templates/_minute.html): five ruled rows. The step number sits in the same circle
   as the setup path, then one sentence, then the one link that does it (beside the sentence from 700px, under it on a phone). */
.minute-steps { list-style: none; margin: 0 0 14px; padding: 0; counter-reset: minute; border-top: 1px solid var(--line); }
.minute-steps > li { counter-increment: minute; position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 28px;
  padding: 14px 4px 14px 48px; border-bottom: 1px solid var(--line); }
.minute-steps > li::before { content: counter(minute); position: absolute; left: 4px; top: 16px; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; font-weight: 700; font-size: .95rem; font-variant-numeric: tabular-nums;
  border: 2px solid var(--line); color: var(--ink-2); background: var(--surface); }
.minute-say { margin: 0; padding-block: 6px; max-width: 58ch; font-size: 1.06rem; line-height: 1.45; }
.minute-go { justify-self: start; display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 500; }
.minute-go.btn { margin-block: 4px 2px; }
.minute-ask { color: var(--ink-2); font-weight: 400; font-size: .92rem; }
@media (min-width: 700px) {
  .minute-steps > li { grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
  .minute-go { justify-self: end; white-space: nowrap; }
  .minute-go.btn { margin-block: 2px 0; }
}
/* who the steps are for: the person's own version is picked for them, the others are one tap away */
.minute-who { margin: 0 0 22px; }
.minute-who > p { margin: 0 0 8px; color: var(--ink-2); }
.minute-who ul { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.minute-who li a { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 16px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink); text-decoration: none; font-weight: 500; }
.minute-who li a:hover { border-color: var(--accent); color: var(--accent-deep); }
.minute-who li a[aria-current] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.minute-who > p:last-child { margin-bottom: 0; }
/* the dashboard's one-time copy (app/_minute_once.html): the setup panel's frame with the accent down its left edge, the
   person's five steps open, then the two buttons that close it for good and the one line that says where it lives after */
.minute-once { border-left: 4px solid var(--accent); }
.minute-once > h2 { margin-top: 0; }
.minute-once .minute-steps { margin-bottom: 0; }
.minute-close { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding-top: 14px; }
.minute-close .minute-leave { margin-left: auto; }
/* one step at a time: a revealed step takes focus and shows it with the accent down its left edge; a short fade when it
   appears, none if the person asked for less motion */
.minute-walk > li { outline: none; }
.minute-walk > li[hidden], .minute-close [hidden] { display: none; }   /* the rows are a grid and the buttons inline-flex: say it again */
.minute-walk > li:focus, .minute-walk > li:target { box-shadow: inset 3px 0 0 var(--accent); }
.minute-walk > li.is-new { animation: minute-in .25s ease-out; }
@keyframes minute-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .minute-walk > li.is-new { animation: none; } }
/* the folded copy at the top of the client's page (behind its own setting) */
.minute-fold { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); margin: 0 0 14px; }
.minute-fold > summary { cursor: pointer; padding: 10px 16px; min-height: var(--tap); font-weight: 650; }
.minute-fold > summary span { font-weight: 400; color: var(--ink-2); margin-left: 6px; }
.minute-fold[open] > summary { border-bottom: 1px solid var(--line); }
.minute-fold .minute-steps { border-top: 0; margin: 0; padding-inline: 12px; }
.minute-fold > p { margin: 0; padding: 12px 16px; }
.minute-fold .minute-steps > li:last-child { border-bottom: 0; }
.minute-fold .minute-steps:has(+ p) > li:last-child { border-bottom: 1px solid var(--line); }
.minute-client .minute-say { font-size: 1rem; }
.minute-tour h2 { font-size: 1.45rem; margin-bottom: .7em; }
.minute-tour .cta-row { margin-top: 26px; }
@media print { .minute-who ul, .minute-who > p:last-child { display: none; } }
/* --- Queries (app/txn): the firm's review and the client's answer page ------------------------------------------------
   The one bold element is the transaction slip: the amount set large in tabular figures, a state rule down its left
   edge (waiting, answered, sent back, posted), the answer choices as big tap targets under it. Everything else stays quiet. */
.tone-warn { color: var(--warn); }
.q-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; }
@media (min-width: 960px) { .q-grid { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; } }
.q-steps { margin: 0; padding-left: 1.2em; } .q-steps li { margin-bottom: 6px; }
.q-check { display: flex; gap: 10px; align-items: center; min-height: var(--tap); font-weight: 400; }
.q-check input { width: 20px; height: 20px; flex: none; }
.q-scroll { max-height: 260px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; padding: 4px 12px; }
.q-fieldset { border: 0; padding: 0; margin: 0 0 14px; } .q-fieldset legend { font-weight: 600; margin-bottom: 4px; padding: 0; }
.q-choice-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 12px; padding: 12px 0; border-top: 1px solid var(--line); }
.q-choice-row .field { margin-bottom: 8px; }
@media (min-width: 720px) { .q-choice-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) auto; align-items: end; } .q-choice-note { grid-column: 1 / -1; } }
.q-choice-act { display: flex; gap: 12px; align-items: center; }
.q-meter .credit-bar { width: 100%; }
.q-meter-off { border-left: 4px solid var(--warn); padding-left: 12px; }

/* firm: one list */
.q-tally { display: flex; flex-wrap: wrap; gap: 10px 28px; margin: 14px 0 0; }
.q-tally div { display: flex; flex-direction: column-reverse; }
.q-tally dt { font-size: .85rem; color: var(--ink-2); } .q-tally dd { margin: 0; font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.q-actions { padding-block: 8px; }
.q-next { margin: 0 0 10px; font-weight: 600; } .q-next:empty { display: none; }
.q-bar { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: center; justify-content: space-between; }
.q-bar-act { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; } .q-bar-act .inline-form { margin: 0; }
.q-send { display: grid; gap: 0 14px; grid-template-columns: minmax(0, 1fr); margin-top: 10px; }
@media (min-width: 720px) { .q-send { grid-template-columns: 200px minmax(0, 1fr) auto; align-items: end; } .q-send .btn { margin-bottom: 14px; } }
.q-rows-sec { padding-top: 8px; }
.q-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px 22px; background: var(--surface); border: 1px solid var(--line);
  border-left: 5px solid var(--line); border-radius: 10px; padding: 14px 16px; margin-bottom: 10px; }
@media (min-width: 900px) { .q-row { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.2fr) minmax(0, 1.3fr); } }
.q-row p { margin: 0 0 4px; }
.q-state-answered, .q-state-failed { border-left-color: var(--warn); } .q-state-approved { border-left-color: var(--accent); }
.q-state-posted { border-left-color: var(--ok); } .q-state-returned { border-left-color: var(--warn); border-left-style: dashed; }
.q-state-excluded, .q-state-resolved { opacity: .62; }
.q-amount { font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.01em; line-height: 1.15; }
.q-dir { font-size: .78rem; font-weight: 600; color: var(--ink-2); margin-left: 8px; letter-spacing: 0; }
.q-payee { font-weight: 650; }
.q-label { font-size: .82rem; color: var(--ink-2); font-weight: 600; }
.q-quote { margin: 4px 0; padding: 4px 0 4px 12px; border-left: 3px solid var(--accent-soft); font-style: normal; }
.q-before { text-decoration: line-through; color: var(--ink-2); }
/* Xero path B: a note is in Xero, the account is changed there by the firm (the re-code list) */
.q-state-noted { border-left-color: var(--accent); border-left-style: dashed; }
.q-recode { margin: 0; padding: 0; }
.q-recode-why { max-width: 62ch; margin: 0; }
.q-move { font-size: 1.12rem; line-height: 1.35; margin-bottom: 6px; }
.q-move-to { color: var(--ink-2); font-size: .92rem; margin: 0 4px; }
.q-xero { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.q-xero .xero-btn { display: inline-block; line-height: 0; }
.q-xero .xero-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.q-decide-form select { width: 100%; margin-bottom: 8px; }
.q-decide-act { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.q-return { margin-top: 8px; } .q-return textarea { width: 100%; }
.q-undo-all { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }
.q-trail { list-style: none; margin: 0 0 12px; padding: 0; font-size: .92rem; }
.q-trail li { padding: 6px 0; border-bottom: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 4px 10px; }
.q-trail time { font-variant-numeric: tabular-nums; color: var(--ink-2); }

/* client: the answer page (phone first; the dock holds progress and Send) */
.q-head { padding-block: 28px 4px; }
.q-head h1 { font-size: clamp(1.7rem, 1.2rem + 2.2vw, 2.4rem); }
.q-sort { display: flex; gap: 6px; margin-top: 8px; }
.q-sort a { padding: 8px 14px; min-height: var(--tap); display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 999px;
  text-decoration: none; color: var(--ink); font-size: .92rem; }
.q-sort a[aria-current] { background: var(--ink); border-color: var(--ink); color: var(--surface); }
.q-list { padding-block: 10px 24px; }
.q-group { margin-bottom: 26px; padding: 0; }
.q-group-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; border-bottom: 2px solid var(--ink);
  padding-bottom: 6px; margin-bottom: 10px; }
.q-group-head h2 { margin: 0; } .q-group-head p { margin: 0; }
.q-bulk { background: var(--accent-soft); border-radius: 10px; padding: 4px 14px; margin-bottom: 12px; }
.q-bulk > summary { min-height: var(--tap); display: flex; align-items: center; font-weight: 650; cursor: pointer; color: var(--accent-deep); }
.q-bulk[open] { padding-bottom: 14px; }
.q-item { position: relative; background: var(--surface); border: 1px solid var(--line); border-left: 5px solid var(--accent); border-radius: 10px;
  padding: 14px 14px 12px; margin-bottom: 12px; }
.q-item.q-done, .q-item.q-saved { border-left-color: var(--ok); }
.q-item.q-returned { border-left-color: var(--warn); }
.q-item.q-focus { box-shadow: 0 0 0 3px var(--focus); }
.q-item-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.q-item-head p { margin: 0; } .q-date { color: var(--ink-2); font-size: .92rem; white-space: nowrap; }
.q-desc { margin: 2px 0 8px; color: var(--ink-2); font-size: .95rem; overflow-wrap: anywhere; }
.q-firm-asks { border-left: 3px solid var(--warn); padding-left: 10px; }
.q-answered { margin: 6px 0 0; }
.q-choices { border: 0; padding: 0; margin: 0 0 8px; display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
.q-choices legend { font-weight: 600; font-size: .92rem; margin-bottom: 6px; padding: 0; width: 100%; }
.q-more > summary { min-height: var(--tap); display: inline-flex; align-items: center; color: var(--accent); cursor: pointer; font-size: .95rem; }
.q-note-label { display: block; font-weight: 600; font-size: .9rem; margin: 4px 0; }
.q-form textarea { width: 100%; }
.q-item-act { display: flex; gap: 12px; align-items: center; margin-top: 6px; }
.q-item-act .btn { flex: none; }
/* where an answer's words are (static/queries.js): one quiet word, no spinner. "Saved on this phone" is not an error: it
   stays in the muted ink like "Saved"; only a refusal turns red (.tone-bad). */
.q-status { color: var(--ink-2); }
.q-status.tone-bad { color: var(--bad); }
.q-wait, .q-send-note { margin: 4px 0 0; color: var(--ink-2); }
.q-wait[hidden], .q-send-note[hidden], .q-home-line[hidden] { display: none; }
.q-send-note { padding-bottom: 8px; }
.q-home-line { margin-block: 18px 8px; text-align: center; }
.q-receipt { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.q-file { position: relative; display: inline-flex; align-items: center; min-height: var(--tap); color: var(--accent); font-weight: 600; font-size: .95rem; cursor: pointer; }
.q-file input { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }
.q-file:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 6px; }
.q-pages { display: flex; flex-wrap: wrap; gap: 6px; }
.q-pages a { min-width: var(--tap); min-height: var(--tap); display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 8px; }
.q-pages a[aria-current] { background: var(--ink); color: var(--surface); }
/* sticky, not fixed: it rides the bottom of the screen while the questions scroll, then comes to rest in the page flow
   after the last question, so it never covers the last card, a receipt control or the footer (owner, 8 Oct 2026) */
.q-dock { position: sticky; bottom: 0; background: var(--surface); border-top: 1px solid var(--line); box-shadow: 0 -6px 18px rgba(15, 27, 45, .08); z-index: 5;
  padding-bottom: env(safe-area-inset-bottom, 0px); }
.q-dock-in { display: flex; gap: 14px; align-items: center; justify-content: space-between; padding-block: 10px; }
.q-dock form { margin: 0; flex: none; }
.q-progress { flex: 1 1 auto; min-width: 0; } .q-progress progress { width: 100%; height: 10px; } .q-progress p { margin: 2px 0 0; }
.q-resend { display: flex; flex-direction: column; align-items: flex-start; gap: 0; margin: 8px 0 12px; }
.q-receipt-send[hidden] { display: none; }

/* receipts (app/txn/receipts.py): one drop zone, then every receipt with what was read and one status line. The left edge
   says where it stands, as the question cards do: blue while it is read, green once it is filed, amber while the firm
   decides, grey when nothing matched. */
.rcp { margin: 8px 0 28px; }
.rcp > h2 { margin-bottom: 2px; }
.rcp-drop { margin: 12px 0 14px; }
.rcp-zone { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 120px;
  padding: 18px 16px; border: 2px dashed var(--accent); border-radius: 12px; background: var(--accent-soft); text-align: center; cursor: pointer; }
.rcp-zone-main { font-weight: 650; font-size: 1.05rem; color: var(--accent-deep); }
.rcp-zone-sub { color: var(--ink-2); }
.rcp-zone input { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; height: 100%; }
.rcp-zone:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; }
.rcp-busy[hidden] { display: none; }
.rcp-list { list-style: none; margin: 0; padding: 0; }
.rcp-row { background: var(--surface); border: 1px solid var(--line); border-left: 5px solid var(--accent); border-radius: 10px; padding: 10px 14px; margin-bottom: 8px; }
.rcp-row p { margin: 0; }
.rcp-name { font-weight: 600; overflow-wrap: anywhere; }
.rcp-read { color: var(--ink-2); }
.rcp-amount { white-space: nowrap; margin-left: 8px; font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; }
.rcp-status { margin-top: 2px; }
.rcp-attached { border-left-color: var(--ok); }
.rcp-to_confirm { border-left-color: var(--warn); }
.rcp-unmatched, .rcp-not_read { border-left-color: var(--line); }
/* the firm's Review block */
.rr-group { margin: 6px 0 22px; }
.rr-group > h3 { margin: 10px 0 6px; }
.rr-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4px 20px; }
.rr-row .rr-side p { margin: 0; }
.rr-label { font-size: .82rem; color: var(--ink-2); font-weight: 600; }
.rr-why { color: var(--ink-2); }
.rr-pick { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.rr-pick select { max-width: 100%; min-width: 0; flex: 1 1 240px; }
@media (max-width: 640px) { .rr-row { grid-template-columns: minmax(0, 1fr); } }
/* rubbish guard on the client page (GUARD_ON_CLIENT_PAGE): one quiet note, one drawn picture, four lines */
.guard-why { margin: 4px 0 0; }
.guard-note { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 14px 16px; margin: 16px 0; }
.guard-note h2 { margin: 0 0 6px; }
.guard-note p { margin: 0 0 10px; }
.guard-guide { display: flex; gap: 14px; align-items: flex-start; }
.guard-guide img { flex: 0 0 auto; width: 96px; height: auto; }
.guard-guide ul { margin: 0; padding-left: 18px; }
.guard-guide li { margin: 0 0 6px; }
/* the firm's quiet line about a client's unreadable files (client page, Review) */
.quality-line { margin: 8px 0 12px; }
.quality-files li { padding: 6px 0; border-bottom: 1px solid var(--line); }

/* the signed-in firm's footer (app/_app_footer.html, shown when app_page is set): one quiet row, links left, language and theme right */
.app-footer { padding-block: 8px; }
.app-footer-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px; }
.app-footer-links { display: flex; flex-wrap: wrap; gap: 0 20px; font-size: .92rem; }
.app-footer-links a { color: var(--ink-2); display: inline-flex; align-items: center; min-height: 44px; }
.app-footer-links a:hover { color: var(--ink); }
.app-footer-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.app-footer-tools .inline-form { display: flex; align-items: center; gap: 8px; }

/* Review as a table (layout review 10 Oct 2026, issue 4): one row per file, grouped by client, the decision on the row.
   A grid of rows rather than <table> so each row stacks on a phone and the reject note can open under its buttons. */
.review-accept-all { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 4px; }
.review-table { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
/* fixed column widths, so every row lines up under the one header row */
.review-row { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1fr) minmax(0, 1.6fr) 372px;
              gap: 6px 18px; align-items: center; padding: 12px 16px; border-top: 1px solid var(--line); scroll-margin-top: 80px; }
.review-row > div { min-width: 0; }
.review-row p { margin: 0; }
.review-cols { border-top: 0; padding-block: 8px; font-size: .85rem; font-weight: 600; color: var(--ink-2); background: var(--surface-2); }
.review-client { font-size: 1rem; margin: 0; padding: 14px 16px 6px; border-top: 1px solid var(--line); letter-spacing: 0; }
.review-cols + .review-client { border-top: 0; }
.review-client + .review-row { border-top: 0; }
.review-title { font-size: 1rem; margin: 0; letter-spacing: 0; line-height: 1.35; }
.review-file { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.review-table, .review-table * { overflow-wrap: normal; word-break: normal; }   /* never break inside a word */
/* a file name is one line at every width: an ellipsis, the whole name in its title */
.review-fline { display: flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; }
.review-fname, .review-title a, .review-note { display: block; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.review-fline .pill { flex: none; }
.review-check { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.review-check .small, .review-check .review-sub { display: block; width: 100%; }
.review-actions { margin-top: 0; display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; align-items: center; }
.review-actions .inline-form { margin: 0; }
.review-actions .inline-details[open] { width: 100%; margin-top: 0; }
/* desktop: one line per row. The second lines go (they are in each cell's title and on the request page); the check is
   its pill and the start of its reason, cut with an ellipsis */
@media (min-width: 1024px) {
  .review-sub { display: none !important; }
  .review-check { flex-wrap: nowrap; min-width: 0; overflow: hidden; container-type: inline-size; }
  .review-check .pill { flex: none; white-space: nowrap; }
  .review-check .small { flex: 1 1 auto; width: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .review-actions .btn { white-space: nowrap; }
}
/* a reason with no room beside its pill would show as one stray letter: then it is only in the cell's title */
@container (max-width: 380px) { .review-check > .small { display: none; } }
@media (max-width: 1023px) {
  .review-row { grid-template-columns: 1fr; gap: 6px; align-items: start; }
  .review-cols { display: none; }
  .review-actions { justify-content: flex-start; padding-top: 4px; }
}

/* Queries for a client: "Answers the client can pick" as one table with one Save, full width under the two top columns
   (layout review 10 Oct 2026, issue 6). On a phone each row stacks: the answer, its account, then Offer. */
.q-wide .card + .card { margin-top: 18px; }
.q-answers { width: 100%; border-collapse: collapse; margin: 6px 0 14px; }
.q-answers th { text-transform: none; letter-spacing: 0; text-align: left; font-size: .85rem; font-weight: 600; color: var(--ink-2); padding: 6px 10px 6px 0; border-bottom: 1px solid var(--line); }
.q-answers td { padding: 8px 10px 8px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.q-answers td input:not([type]), .q-answers td input[type="text"], .q-answers td select { width: 100%; min-width: 0; }
.q-answers th:first-child, .q-answers td:first-child { width: 42%; }
.q-answers .q-answers-offer { width: 1%; white-space: nowrap; padding-right: 0; }
.q-answers .q-answers-offer-word { display: none; }
.q-answers .q-choice-note { margin: 4px 0 0; }
.q-wide .q-scroll { max-height: none; columns: 3 220px; column-gap: 24px; }
.q-wide .q-scroll .q-check { break-inside: avoid; }
@media (max-width: 640px) {
  .q-answers thead { display: none; }
  .q-answers tr { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; padding: 10px 0; border-bottom: 1px solid var(--line); }
  .q-answers td { display: block; width: auto !important; padding: 0; border: 0; }
  .q-answers .q-answers-offer-word { display: inline; }
}

/* Integrations, one row per tool (layout review 10 Oct 2026, issue 8): the full content width; Slack, webhooks and forward
   by email are a <details> whose summary is the row (name, state, and the way in on the right), folded until opened */
.integrations .card.integration { margin-bottom: 12px; }
.integration-off { padding-block: 12px; }
.integration-off .integration-head { margin-bottom: 0; }
.integration-off > p { margin: 0; }
details.tool > summary { list-style: none; cursor: pointer; margin-bottom: 0; min-height: var(--tap); }
details.tool > summary::-webkit-details-marker { display: none; }
details.tool[open] > summary { margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.tool-state { display: inline-flex; align-items: center; gap: 14px; margin-left: auto; }
.tool-open { color: var(--accent); font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.tool-open::after { content: ""; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
                    transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }
details.tool[open] .tool-open::after { transform: translateY(2px) rotate(-135deg); }
details.tool > summary:hover .tool-open { color: var(--accent-deep); }
@media (prefers-reduced-motion: reduce) { .tool-open::after { transition: none; } }
.books .books-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px 20px; padding: 14px 4px; margin: 0; }
.books .books-row span { color: var(--ink-2); }
.books .books-row strong .pill { font-weight: 400; }
@media (min-width: 700px) { .books .books-row { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); align-items: baseline; } }

/* Queries home (layout review 10 Oct 2026, issue 9): the clients as a table in the main column, the side one short card */
.q-clients td { vertical-align: middle; }
.q-clients th { text-transform: none; letter-spacing: 0; font-size: .85rem; }
.q-clients .q-clients-act { text-align: right; white-space: nowrap; }
details.quiet-foot > summary { cursor: pointer; color: var(--ink-2); min-height: var(--tap); display: flex; align-items: center; font-weight: 500; }
details.quiet-foot[open] > summary { color: var(--ink); font-weight: 600; }
.q-side-more .quiet-foot { margin-top: 10px; }
.q-trail-more { margin: -6px 0 12px; }
.q-trail-more > summary { cursor: pointer; color: var(--accent); font-weight: 500; min-height: var(--tap); display: flex; align-items: center; }
.q-trail-more[open] > summary { color: var(--ink); }

/* Tap targets (layout review 10 Oct 2026, issue 15): the quiet links and disclosures are at least 44 px tall at every
   width, by padding, not bigger text: Remove item on a draft, Do not ask on a query list, the client's "I do not have
   this" and the document-language line (CLIENT_PAGE_V2). */
.btn-link.quiet { min-height: var(--tap); }
details.na > summary, details.doc-lang > summary { min-height: var(--tap); padding-block: 10px; cursor: pointer; box-sizing: border-box; }
details.doc-lang { margin: 0 0 6px; font-size: .92rem; color: var(--ink-2); }
details.doc-lang[open] > summary { color: var(--ink); }
details.doc-lang select { display: block; margin-top: 4px; }

/* Layout fixes, 10 Oct 2026 (the verifier's leftovers) ------------------------------------------------------------------- */
/* Dashboard, Open requests: one line per request, the title cut with an ellipsis, the counts and due date to the right.
   CSS only (the dashboard is a frozen reviewer template); the card is found by the self-test form only it carries. */
@media (min-width: 900px) {
  .card:has(> form[action="/app/selftest"]) .rows li { display: flex; align-items: center; gap: 12px; }
  .card:has(> form[action="/app/selftest"]) .rows li > a { flex: 1 1 auto; min-width: 0; display: block; overflow: hidden;
                                                          text-overflow: ellipsis; white-space: nowrap; }
  .card:has(> form[action="/app/selftest"]) .rows li > .small { flex: none; margin-left: auto; white-space: nowrap; }
}
.card:has(> form[action="/app/selftest"]) .rows li > .small { white-space: nowrap; }

/* Dashboard, Open requests, a row with a promise: the promise folds on its own full-width line under the title, so it never
   takes width from the request title (the primary text). Wide screens only; narrow screens already stack. */
@media (min-width: 900px) {
  .card:has(> form[action="/app/selftest"]) .rows li { flex-wrap: wrap; }
  .card:has(> form[action="/app/selftest"]) .rows li > .promise { flex: 0 0 100%; margin: 6px 0 2px; }
  .card:has(> form[action="/app/selftest"]) .rows li > a { flex: 1 1 0; min-width: 12em; }   /* basis 0: the counts stay on the title's line */
}
/* 44 px tap targets at phone width (merge walk, 10 Oct 2026): the staff upload on the request page, the "Text to create at
   Meta" folds and the colour picker in settings. */
@media (max-width: 700px) {
  .app input[type=file], .app input[type=color] { min-height: var(--tap); }
  .app input[type=file]::file-selector-button { min-height: 32px; margin-right: 10px; }
  .app .field details > summary { padding-block: 11px; }
}

/* Queries home, Query lists: the client's name on one line, the list title takes the rest and ends in an ellipsis */
.q-lists td, .q-lists th { white-space: nowrap; }
table.q-lists td.q-lists-title > a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 700px) {
  .q-lists { table-layout: fixed; width: 100%; }
  .q-lists .q-lists-client { width: 10rem; }
  .q-lists .q-lists-status { width: 7rem; }
  .q-lists .q-lists-answered { width: 7.5rem; }
  .q-lists td.q-lists-client { overflow: hidden; text-overflow: ellipsis; }
}
/* Q_EASE: "Promised for Mon 20 Oct" under the count, for a client who picked a day on their questions page */
.q-lists .q-promised { display: block; white-space: normal; color: var(--ink-2); line-height: 1.3; }

/* The client's upload page: Stop reminders and Report this request as 44 px tap targets. CSS only (frozen template). */
.client-body a[href^="/r/"][href$="/unsubscribe"], .client-body a[href^="/r/"][href$="/report"] {
  display: inline-flex; align-items: center; min-height: var(--tap); }
/* promise detection (app/core/promises.py, app/web/templates/app/_promise.html): a client's "will send Friday", one folded
   line next to the contacts; open it for their words, what happens next and Resume reminders */
.promise { margin: 0 0 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.promise > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px;
  min-height: var(--tap); padding: 8px 36px 8px 12px; position: relative; }
.promise > summary::-webkit-details-marker { display: none; }
.promise > summary .fold-chev { position: absolute; right: 14px; top: 50%; margin-top: -5px; }   /* the one chevron: components.css */
.promise > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 10px; }
.promise-head { font-weight: 600; }
.promise-who { font-size: .85rem; color: var(--ink-2); }
.promise-firm { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }
.promise-firm .promise-head { color: var(--warn); }
.promise-body { padding: 0 12px 12px; }
.promise-quote { margin: 0 0 8px; padding: 8px 12px; border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0;
  background: var(--surface-2); font-size: .92rem; overflow-wrap: anywhere; }
.promise-what { margin: 0 0 8px; font-size: .85rem; color: var(--ink-2); }
.promise-act { margin: 0; }
.rows li .promise { margin: 8px 0 2px; }

.app-footer-tools .btn, .app-footer-tools select { min-height: 44px; }

/* A client's Queries page in steps (QUERIES_PAGE_V2, docs/QUERIES-PAGE.md): one 760 px column (DESIGN-LANGUAGE 2.3), the
   state line under the title, the four steps (components.css .reveal), then More. */
.qp-wrap { max-width: 760px; }
.qp-title { max-width: 22ch; margin-bottom: 6px; }
.qp-state { color: var(--ink-2); max-width: 62ch; margin: 0; font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.qp-body { padding-block: 16px 64px; }
.qp-body > .wrap > .form-error { margin-bottom: 20px; }
.qp-steps { margin-top: 12px; }
.qp-body { padding-top: 24px; }
.qp-step { min-width: 0; }
.qp-step-title { font-size: 1.25rem; line-height: 1.25; margin: 4px 0 6px; }
.qp-step .route-why { margin-bottom: 8px; }
.qp-step .form-error { margin: 8px 0 12px; }
.qp-step .qb-connect, .qp-step .xero-btn { display: inline-flex; align-items: center; min-height: 44px; line-height: 0; }
.qp-route { margin: 8px 0 4px; }
.qp-dates > summary { cursor: pointer; color: var(--accent); font-weight: 600; min-height: 44px; display: inline-flex; align-items: center; }
.qp-dates[open] { margin-bottom: 4px; }
.qp-pull .step-act { margin-top: 4px; }
.qp-more { margin-top: 36px; display: grid; gap: 12px; }
.qp-more-fold > .ask-src { margin-top: 12px; }
.qp-more-fold > summary { list-style: none; display: flex; align-items: center; gap: 4px 12px; min-height: 48px; cursor: pointer; padding: 4px 0;
  border-top: 1px solid var(--line); }
.qp-more-fold > summary::-webkit-details-marker { display: none; }
.qp-more-word { font-weight: 700; }
.qp-more-line { color: var(--ink-2); min-width: 0; flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qp-more-fold > summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 6px; }
.qp-more-head { font-size: 1.05rem; margin: 0; padding-top: 14px; border-top: 1px solid var(--line); color: var(--ink-2); font-weight: 600; }
.qp-more > .ask-src { margin: 0; }
.qp-more .card.ask-src { padding: 0; }   /* the row is its summary (56 px); .app .card's padding would double it */
.qp-row-lead { margin-top: 14px; }
.qp-reread { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
@media (max-width: 599px) {
  .qp-step-title { font-size: 1.12rem; }
  .qp-more-line { display: none; }
}
/* Step 1's second card while Queries on Xero is not switched on: shown, not choosable (owner, 13 Oct 2026) */
.route-card.is-soon { cursor: default; border-style: dashed; background: transparent; }
.route-card.is-soon:hover { border-color: var(--line); }
.route-card.is-soon .route-mark { grid-row: 1 / span 3; width: 22px; }
.route-card.is-soon .route-name { color: var(--ink-2); }
.route-card.is-soon .route-cost a { display: inline-flex; align-items: center; min-height: 44px; }

/* --- owner console: Insights (/admin/insights, slice I5): firm per row, numbers right-aligned in tabular figures, a firm over the 90 % rule shaded --- */
.ins-t th, .ins-t td { padding: 10px 14px; vertical-align: top; }
.ins-t td.r, .ins-t th.r { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ins-t tbody th { text-align: left; font-weight: 600; white-space: nowrap; text-transform: none; letter-spacing: 0; }
.ins-win a.is-current { font-weight: 700; text-decoration: none; }
.ins-t tbody a, .ins-win a { display: inline-flex; align-items: center; min-height: var(--tap); }
.ins-t tr.is-over th, .ins-t tr.is-over td { background: var(--surface-2); }
.ins-sec h2 { margin: 28px 0 4px; font-size: 1.15rem; }
.ins-sec > .wrap > p.muted { margin: 0 0 12px; max-width: 80ch; }

/* ---- a folded row reads as one pressable control (owner, 19 Oct 2026: "More ... was not even looking like it can be expanded") ----
   The one fold component (.fold-chev in components.css, inside the summary beside the title) on every <details> of the client
   Queries page: pointer on the whole row, hover and focus states, 44 px. No page-local chevron (G62). */
.qp-more-fold > summary, .qp-more .ask-src-sum, .qp-more .ask-never-sum, .qp-dates > summary, details.quiet-foot > summary, .conn-disc > summary,
.qp-more .rule-phone > summary, .qp-more .quiet-more > summary, .qp-more .rule-edit > summary { cursor: pointer; min-height: var(--tap); transition: background .15s ease; }
.qp-more-fold > summary:hover, .qp-more .ask-src-sum:hover, .qp-more .ask-never-sum:hover, .qp-dates > summary:hover, details.quiet-foot > summary:hover { background: var(--surface-2); }
.qp-more-fold > summary:focus-visible, .qp-more .ask-src-sum:focus-visible, .qp-dates > summary:focus-visible, details.quiet-foot > summary:focus-visible,
.conn-disc > summary:focus-visible, .qp-more .quiet-more > summary:focus-visible, .qp-more .rule-edit > summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: var(--radius, 8px); }
.qp-more-fold > summary { padding-left: 8px; padding-right: 8px; border-radius: var(--radius, 8px); }
.qp-more-fold > summary .fold-chev { order: 1; }
.qp-more-fold > summary .qp-more-line { order: 2; }
.qp-more .ask-src-sum { grid-template-columns: auto 12px minmax(0, 1fr); }
.qp-more .ask-src-sum > .fold-chev { grid-column: 2; grid-row: 1; }
.qp-more .ask-src-sum > .ask-src-line { grid-column: 3; grid-row: 1; }
/* a link-like summary, a ghost-button summary: title, then the chevron right beside it */
.qp-dates > summary, details.quiet-foot > summary, .conn-disc > summary, .qp-more .quiet-more > summary, .qp-more .rule-edit > summary { list-style: none; display: inline-flex; align-items: center; gap: 10px; }
details.quiet-foot > summary { color: var(--ink-2); font-weight: 500; padding: 0 8px; border-radius: var(--radius, 8px); }
details.quiet-foot[open] > summary { color: var(--ink); font-weight: 600; }
.qp-dates > summary .fold-chev { color: var(--accent); }
@media (max-width: 599px) {
  .qp-more .ask-src-sum { grid-template-columns: minmax(0, 1fr) 12px; }
  .qp-more .ask-src-sum > .fold-chev { grid-column: 2; grid-row: 1 / span 2; }
  .qp-more .ask-src-sum > .ask-src-line { grid-column: 1; grid-row: 2; }
}

/* ---- the connection status block, the same for Xero and QuickBooks (owner, 19 Oct 2026): one line, Disconnect on the same row,
   the one-ledger line, then (only when permissions are missing) the notice and the order: 1 Disconnect, 2 the ledger's own button ---- */
.conn-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.conn-status .conn-line { margin: 0; color: var(--ink); font-weight: 600; }
.conn-none { margin: 0 0 4px; font-weight: 600; color: var(--ink); }
.conn-disc[open] { flex-basis: 100%; }
.conn-disc > .form { margin-top: 8px; }
.conn-missing { margin-top: 12px; max-width: 70ch; }
.conn-missing > p { margin: 0; }
.conn-order { list-style: none; counter-reset: conn; display: grid; gap: 12px; margin: 12px 0 0; padding: 0; }
.conn-order > li { counter-increment: conn; display: flex; align-items: center; gap: 12px; }
.conn-order > li::before { content: counter(conn); flex: none; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%;
  border: 1.5px solid var(--line); color: var(--ink-2); font-weight: 700; font-size: .88rem; }
.conn-order .form { margin: 0; }
.disconnect-here { margin-top: 12px; }

/* ---- the find box above the accounts list (reuses .ws-search from the Lines page; hidden until accounts-find.js runs) ---- */
.qp-find { flex: none; width: 100%; max-width: 360px; margin: 4px 0 8px; }
.qp-find[hidden], .qp-find-none[hidden], .q-check[hidden] { display: none; }
.qp-reads { margin: 0 0 4px; }
.q-scroll:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* ---- the page is the connection and the settings (owner, 19 Oct 2026): no wizard, no step circles ---- */
.qp-page { margin-top: 12px; gap: var(--s-4); }
.qp-conn, .qp-next { min-width: 0; }
.qp-next .route-why { margin: 0 0 8px; max-width: 70ch; }
.qp-more { margin-top: 24px; }
