/* ==========================================================================
   nami -- screen stylesheet (T-28a)

   The UI is Thai (D-98), responsive across PC, tablet and phone (NFR-05,
   D-02), and keyboard-driven: NFR-01 wants a two-line receipt issued in
   under 60 seconds, so a visible focus ring, a readable refusal and a
   clearly marked primary action matter more here than decoration.

   SCOPE. This file styles the screens from `templates/base.html` outwards.
   It styles **no** print output: the A4 page is `static/print/a4.css`,
   attached from disk by `documents/render.py` because WeasyPrint resolves it
   there, and `templates/print/base.html` is a standalone document that does
   not extend `base.html`. The two files never meet, which is asserted in
   `nami/tests/test_static_assets.py`.

   FONT. IBM Plex Sans Thai is vendored for the UI under static/fonts/ (D-153).
   Print uses its separate pinned files and stylesheet.

   D-06 took a whole class of field out of scope and it does not come back
   through a stylesheet. The prototype under `prototype/` predates D-06 and
   still shows the UI it removed; nothing here came from it, and
   `nami/tests/test_static_assets.py` scans this file -- comments included --
   for the vocabulary, which is why the sentence above does not use it.
   ========================================================================== */

@font-face {
  font-family: "IBM Plex Sans Thai UI";
  src: url("../fonts/IBMPlexSansThai-Regular.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans Thai UI";
  src: url("../fonts/IBMPlexSansThai-SemiBold.woff2") format("woff2");
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
}

:root {
  /* The vendored Thai UI face keeps text shaping consistent across devices;
     platform Thai faces remain as fallbacks. `Segoe UI` on its own
     leaves Thai to whatever the browser falls back to, which is how tone
     marks end up rendered from a different face than the letters they sit
     on. `Leelawadee UI` is the face Windows itself uses for Thai UI;
     `Thonburi` is macOS's (and the one Q-39 measured as shaping and
     extracting Thai correctly); `Noto Sans Thai` covers Android, ChromeOS
     and Linux; `Tahoma` is last because it is on every Windows install since
     XP -- a floor, not a preference, since its tone-mark positioning is
     tighter than Leelawadee's. */
  --font-ui: "IBM Plex Sans Thai UI", -apple-system, BlinkMacSystemFont, "Segoe UI", "Leelawadee UI",
             "Noto Sans Thai", "IBM Plex Sans Thai", Thonburi, Tahoma,
             "Helvetica Neue", Arial, sans-serif;

  --gray-900: #14181d;
  --gray-700: #353b43;
  --gray-600: #4a545f;
  --gray-500: #6b7580;
  --gray-450: #7f8a97;
  --gray-300: #c3ccd5;
  --gray-200: #e9eef2;
  --gray-100: #f3f6f8;
  --gray-50: #f8fafb;
  --ink: #14181d;
  --ink-soft: #4a545f;
  --line: #c3ccd5;
  /* Darkened from #8d99a6 by the lead, 2026-11-05. The old value was
     2.90:1 on --bg, under the 3:1 floor this file's own tests import
     from WCAG 2.1 1.4.11 -- and it is the border of every input, select,
     textarea and button, i.e. the canonical component-boundary case.
     Having adopted a published threshold, missing it on the one pair it
     most clearly governs should be a decision, not an omission.
     #7f8a97 is 3.51:1 on --bg and 3.23:1 on --bg-soft. --line stays as
     it is: at 1.63:1 it draws zone, fieldset and row separators, which
     1.4.11 exempts as decorative. */
  --line-strong: #7f8a97;
  --bg: #ffffff;
  --bg-soft: #f3f6f8;
  --bg-sunken: #e9eef2;

  --accent: #0a5c6b;
  --accent-ink: #ffffff;
  --accent-soft: color-mix(in srgb, var(--accent) 10%, white);
  --accent-hover: color-mix(in srgb, var(--accent) 88%, black);

  --danger: #a4161a;
  --danger-bg: #fdf0f0;
  --warn: #7a5200;
  --warn-bg: #fff5e0;
  --ok: #1b5e20;
  --ok-bg: #ecf7ee;

  --focus: #0a5c6b;

  --radius: 6px;
  --radius-card: 10px;
  --shadow-bar: 0 -2px 12px rgb(20 24 29 / 12%);
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --gutter: 16px;
  --field-gap: 16px;
  --fs-title: 24px;
  --fs-h2: 19px;
  --fs-body: 16px;
  --fs-label: 15px;
  --fs-small: 14px;
  --fs-total: 26px;
  --fs-docno: 18px;
  --gap: 0.75rem;
  --tap: 2.75rem;        /* 44px+ touch target, phone and tablet (NFR-05) */
  --shell: 64rem;
}

/* --------------------------------------------------------------------------
   Reset, only as far as it is needed
   -------------------------------------------------------------------------- */

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

html {
  /* The approved UI scale has one 16px root at every viewport width. */
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-ui);
  /* Thai stacks marks vertically; 1.65 is headroom, not taste. */
  line-height: 1.6;
  color: var(--ink);
  background: var(--gray-50);
}

.app-main {
  width: min(calc(100% - 2 * var(--gutter)), var(--shell));
  margin: 0 auto;
  padding: var(--sp-5) 0 var(--sp-6);
}
.app-main:has(#doc-screen) { width: min(calc(100% - 2 * var(--gutter)), 90rem); }
.app-header { background: var(--bg-soft); border-bottom: 1px solid var(--line); }
.app-header-inner {
  width: min(calc(100% - 2 * var(--gutter)), var(--shell));
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--sp-4);
}
.app-name { font-size: 18px; font-weight: 600; white-space: nowrap; }
.app-header .zone { margin: 0; padding: 0; border: 0; }
.login-card, .landing-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--sp-5);
}
.login-card { max-width: 22rem; margin: min(14vh, 8rem) auto 0; }
.login-card form { margin-bottom: 0; }
.login-card p { margin-bottom: var(--field-gap); }
.login-card .btn-primary { width: 100%; }
.login-card .err { margin-bottom: var(--sp-4); }
.landing-card { max-width: 52rem; margin-inline: auto; }
.landing-card h1 { margin: 0; }
.landing-card .role-caption { font-size: var(--fs-small); color: var(--ink-soft); margin-bottom: var(--sp-5); }
.landing-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
.landing-action { display: flex; align-items: center; gap: var(--sp-3); min-height: 76px; padding: var(--sp-4); border: 1px solid var(--line-strong); border-radius: var(--radius-card); background: var(--bg); color: var(--ink); font-weight: 600; text-decoration: none; }
.landing-action:hover, .landing-action:focus-visible { border-color: var(--accent); background: var(--accent-soft); }
.landing-action img { flex: none; width: 24px; height: 24px; }
.landing-action-primary { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }
.landing-action-primary img { filter: brightness(0) invert(1); }
.landing-action-primary:hover, .landing-action-primary:focus-visible { background: var(--accent-hover); color: var(--accent-ink); }
.landing-card form { margin: var(--sp-5) 0 0; }
@media (max-width: 35rem) { .landing-actions { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Visibility utilities -- load-bearing, see the comment
   -------------------------------------------------------------------------- */

/* `[hidden]` comes from the UA stylesheet, and **any** author rule setting
   `display` on a matching element beats it, whatever the specificity. A bare
   `button { display: inline-flex }` would therefore reveal the hidden default
   submit button that `templates/documents/_screen.html` puts first in the
   form -- a second "บันทึกฉบับร่าง" at the top of the Create Document screen,
   outside §4's layout. So this is declared first and it is declared loudly. */
[hidden] { display: none !important; }

/* `templates/documents/_screen.html` writes `class="zone-h sr"` on Zone E's
   heading: a heading for assistive technology that §4 does not draw. Until
   this file existed there was no stylesheet to define `.sr`, so "สรุปยอด"
   rendered visibly. Clip rather than `display: none`, which would take it out
   of the accessibility tree as well.

   **Every declaration is `!important`, and that is not laziness.** The one
   element in the project carrying this class carries `.zone-h` too, and
   `.zone-h` is declared ~380 lines further down at *equal* specificity --
   so without `!important` it wins `margin`, `padding-bottom`,
   `border-bottom` and `font-size` here, and whether "สรุปยอด" stays hidden
   comes down to which of two rules a later edit happens to move. A
   visually-hidden utility that depends on source order is one refactor away
   from being visible, so it is pinned declaration by declaration instead. */
.sr {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  border: 0 !important;
  overflow: hidden !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
}

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */

h1, h2, h3, legend {
  margin: 0 0 0.5rem;
  line-height: 1.4;
  font-weight: 600;
  /* Never `text-transform: uppercase`: Thai has no case, and it only mangles
     the Latin and the digits mixed into Thai labels. */
}

h1 { font-size: 1.45rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 0.75rem; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

/* Thai has no inter-word spaces, so a long unbroken string -- an address, a
   note -- has no break opportunity a space-based algorithm can find. */
p, td, li, .baht, .hint { overflow-wrap: anywhere; }

.hint, .helptext, small {
  display: block;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   Forms -- the whole product is a form
   -------------------------------------------------------------------------- */

form { margin: 0 0 1rem; }

label {
  display: block;
  margin-bottom: 0.15rem;
  font-weight: 600;
  font-size: 0.95rem;
}

/* A radio or checkbox label is one line with its control, not above it. */
label:has(> input[type="radio"]),
label:has(> input[type="checkbox"]) {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-right: 1rem;
  font-weight: 400;
}

input, select, textarea {
  font: inherit;
  color: var(--ink);
  /* Full width of its column on a phone, but a column is not a screen: a
     1088px-wide box for a 13-digit tax ID is harder to read, not easier, and
     it hides how long the expected value is. `.row` and a table cell both
     override this, which is where the wide screens put their fields. */
  width: 100%;
  max-width: 28rem;
  min-height: var(--tap);
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg);
}

.row input, .row select, .row textarea,
td input, td select, td textarea { max-width: none; }

input[type="radio"], input[type="checkbox"] {
  width: 1.15rem;
  height: 1.15rem;
  max-width: none;
  min-height: 0;
  padding: 0;
  accent-color: var(--accent);
  flex: none;
}

textarea { min-height: 5rem; max-width: 42rem; resize: vertical; }

input:disabled, select:disabled, textarea:disabled {
  background: var(--bg-sunken);
  color: var(--ink-soft);
}

input[readonly] { background: var(--bg-soft); }

/* Figures the staff check against a paper pad have to line up in a column. */
input[inputmode="numeric"], input[inputmode="decimal"], input[type="number"],
.num, .v, .amount, td.num {
  font-variant-numeric: tabular-nums;
}
.num, .v, .amount, td.num, th.num { text-align: right; }

fieldset {
  margin: 0 0 var(--gap);
  padding: 0.6rem 0.8rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
legend { padding: 0 0.3rem; font-size: 0.95rem; }

/* `.seg` is Zone A's payment-method control. It contains real radios and a
   button, and wraps on a phone rather than scrolling sideways. */
fieldset.seg { border-color: var(--line-strong); }
fieldset.seg > label,
.seg .options { display: inline-flex; flex-wrap: wrap; gap: 0.5rem 1rem; }

/* A field group. `templates/documents/_screen.html` marks these `.row`. */
.row {
  display: grid;
  gap: var(--gap);
  align-items: end;
  margin-bottom: var(--gap);
}

/* --------------------------------------------------------------------------
   Buttons -- and which one is the default action
   -------------------------------------------------------------------------- */

button, .button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0.4rem 1.1rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
}

button:hover:not(:disabled), .btn:hover:not(:disabled) { background: var(--bg-soft); }
button:active:not(:disabled) { transform: translateY(1px); }

/* The document's บันทึกและพิมพ์ keeps its id; `.btn-primary` marks the one
   primary action on other screens, including the type confirmation.

   What CSS cannot do, said plainly so nobody assumes otherwise: there is no
   selector for "the submit button this form will activate when Enter is
   pressed". That button is decided by tree order, which is markup, and
   getting it wrong is what reverted a document type and spent a number
   (T-06 round 1). A stylesheet can make the intended action obvious; it
   cannot make it the default. */
#btn-print, .btn-primary, button[type="submit"].primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
#btn-print:hover:not(:disabled),
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-text { border: 0; background: transparent; color: var(--accent); padding-inline: 0; }
.btn-text:hover:not(:disabled) { background: var(--accent-soft); text-decoration: underline; }

/* §3.7: บันทึกและพิมพ์ stays disabled until the document is valid. A disabled
   button that still looks pressable is a user waiting for nothing. */
button:disabled, .btn-primary:disabled, #btn-print:disabled {
  cursor: not-allowed;
}
.btn-primary:disabled, #btn-print:disabled { opacity: .4; background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}
/* Reading order puts the primary action last in `.actions`; put it visually
   first on a wide screen so the eye lands on it. */
@media (min-width: 48rem) {
  /* Keep cancel above the sticky totals on desktop. */
  #doc-column { display: flex; flex-direction: column; }
  #discard-form { order: 1; margin-bottom: 180px; }
  #zone-e { order: 2; }
  .actions { flex-direction: row-reverse; justify-content: flex-end; }
}

/* --------------------------------------------------------------------------
   Navigation -- the nav T-31 put in `templates/base.html` (T-36)
   -------------------------------------------------------------------------- */

/* T-31 shipped five plain links in a `.zone`, and `.zone` above is margin,
   padding, border and radius -- no `display`, no `gap`. So the five Thai
   labels rendered as inline text one collapsed space apart, each link's own
   box 20px tall at the old 17px root and 18px at the phone's 16px (Chrome), under
   the 44px floor every other control here meets (NFR-05).
   This is the layout rule T-31 reported missing rather than inventing.

   Styled as `nav.zone`, and **no class is added**: the nav's class set is
   pinned to exactly `zone` by `nami/tests/test_navigation.py`, deliberately,
   so that a nav wanting layout gets a rule in this file where a reviewer
   sees it.

   `.actions` is the obvious reach and is refused. It is
   `flex-direction: row-reverse` above 48rem, so these five links would run
   right to left on every tablet and PC -- against their DOM order and their
   tab order, which is WCAG 1.3.2 and 2.4.3 rather than a matter of taste.
   Nothing here reverses or reorders the nav, and
   `test_rules_naming_the_nav_or_zone_cannot_reorder_it` holds the rules that
   name the nav or `.zone` to that. A selector scan cannot see a rule on `a`
   or `*`, so those are a reviewer's to catch.

   No media query of its own: the phone is where the fingertip is, so the
   row and the tap target are the unconditional case and the wide screens
   inherit them. `flex-wrap` is what the narrow end needs -- the links wrap
   onto a second line instead of forcing a sideways scroll -- and `gap`
   applies between rows as well as between links, so two wrapped lines of
   targets do not share an edge either. */
nav.zone {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
}

/* A tap target, not a word of running text.

   `min-height` is the same `--tap` the inputs and buttons take: 44px is a
   property of a fingertip, not of a form control, so there is one number
   here and not two. `min-width` holds the other axis, because nothing in
   the test suite can measure the width of a Thai label, so a short one should
   not depend on its glyphs.

   `display: inline-flex` does two things, neither of them the height today.
   While `nav.zone` is flex the link is a flex item and is blockified, so
   `min-height` applies with or without it (Chrome: 44px either way). It lets
   `align-items: center` put the label in the middle of the box, and it keeps
   the floor if the nav ever stops being flex, because `min-height` has no
   effect on a non-replaced inline box. `padding` gives the hit area room
   around the glyphs.

   The active link receives a solid accent marker and hover restores an
   underline; the links remain in their source order. */
nav.zone a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0 12px;
  border-radius: var(--radius);
}
.app-header img { width: 16px; height: 16px; flex: none; margin-inline-end: 6px; }
.app-header a { color: var(--ink); text-decoration: none; }
.app-header a[aria-current="page"] { border-bottom: 3px solid var(--accent); background: var(--accent-soft); }
.app-header a:hover, .app-header a:focus-visible { text-decoration: underline; }

/* --------------------------------------------------------------------------
   Focus -- NFR-01 is a keyboard path, so this is a feature, not a polish
   -------------------------------------------------------------------------- */

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Browsers without :focus-visible still get a ring. Nothing in this file
   ever removes an outline. */
:focus { outline: 3px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline-color: color-mix(in srgb, var(--focus) 45%, transparent); }

input:focus, select:focus, textarea:focus { border-color: var(--focus); }

/* --------------------------------------------------------------------------
   Refusals -- a 422 with no message on the page is the defect this styles
   -------------------------------------------------------------------------- */

/* Django's own markup, emitted by every form in the project
   (`{{ form.errors }}`, `{{ form.as_p }}`), so it is the one error selector
   that is already on screen everywhere. */
.errorlist {
  margin: 0.25rem 0 0.5rem;
  padding: 0.4rem 0.7rem 0.4rem 1.6rem;
  list-style: none;
  color: var(--danger);
  background: var(--danger-bg);
  border-inline-start: 4px solid var(--danger);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 0.92rem;
}
.errorlist li { position: relative; }
.errorlist li::before { content: "⚠"; position: absolute; inset-inline-start: -1.1rem; }

/* A page-level refusal (`form.non_field_errors`) reads as a block, not as a
   note beside one field. */
.errorlist.nonfield {
  margin-bottom: 1rem;
  padding: 0.7rem 0.9rem 0.7rem 1.9rem;
  font-size: 1rem;
  font-weight: 600;
}

/* `.err` is the field-level message in `templates/documents/_screen.html`,
   tied to its input by `aria-describedby="err-<field>"`. */
.err, [role="alert"] {
  display: block;
  margin-top: 0.2rem;
  color: var(--danger);
  font-size: 0.92rem;
  font-weight: 600;
}

/* The field itself has to look refused, not just carry a message somewhere
   below it. Border *and* background: a border alone is invisible to anyone
   who cannot pick that red out from that grey. */
[aria-invalid="true"] {
  border: 2px solid var(--danger);
  background: var(--danger-bg);
}
[aria-invalid="true"]:focus,
[aria-invalid="true"]:focus-visible {
  outline-color: var(--danger);
  border-color: var(--danger);
}

/* §3.7 / Zone E: the error count. The one thing on the screen that says a
   refusal happened at all, so it is the loudest thing in this file. */
#error-count, .error-count {
  margin: 0.5rem 0;
  padding: 0.7rem 0.9rem;
  color: var(--danger);
  background: var(--danger-bg);
  border: 2px solid var(--danger);
  border-radius: var(--radius);
  font-weight: 700;
}

/* §4's backdate banner: amber, a state rather than an error. */
.warn, #backdate-banner {
  margin: 0.5rem 0;
  padding: 0.6rem 0.9rem;
  color: var(--warn);
  background: var(--warn-bg);
  border-inline-start: 4px solid var(--warn);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-weight: 600;
}

[role="status"], #saved-note {
  margin: 0.5rem 0;
  padding: 0.5rem 0.9rem;
  background: var(--bg-soft);
  border-inline-start: 4px solid var(--line-strong);
  border-radius: 0 var(--radius) var(--radius) 0;
}
#saved-note { color: var(--ok); border-inline-start-color: var(--ok); }

/* --------------------------------------------------------------------------
   Tables -- the products list, and Zone C's lines
   -------------------------------------------------------------------------- */

table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1rem;
}
th, td {
  padding: 0.45rem 0.55rem;
  border-bottom: 1px solid var(--line);
  text-align: start;
  vertical-align: top;
}
thead th {
  background: var(--bg-soft);
  border-bottom: 2px solid var(--line-strong);
  white-space: nowrap;
  font-size: 0.92rem;
}
tbody tr:hover { background: var(--bg-soft); }

.product-toolbar { display: flex; flex-wrap: wrap; align-items: end; gap: var(--sp-3); }
.product-search { flex: 1 1 18rem; }
.product-search input { min-height: 48px; }
.product-toolbar > .btn-primary { margin-inline-start: auto; }
.product-table { background: var(--bg); }
.product-table th { color: var(--gray-700); background: var(--bg-sunken); font-size: var(--fs-label); }
.product-table td { height: 48px; vertical-align: middle; }
.product-table td a { display: block; min-height: var(--tap); padding: 10px 0; }
.product-table .num { white-space: nowrap; }
.product-code-mobile { display: none; }
.status-chip { display: inline-block; padding: 2px 8px; border-radius: var(--radius); background: var(--bg-sunken); color: var(--ink-soft); font-size: var(--fs-small); white-space: nowrap; }
.status-chip.is-active { background: var(--ok-bg); color: var(--ok); }
.product-form { max-width: 32rem; padding: var(--sp-5); background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card); }
.product-form .field { margin-bottom: var(--field-gap); }
.product-form .field label { margin-bottom: var(--sp-1); }
.product-active { display: inline-flex; align-items: center; min-height: var(--tap); gap: var(--sp-2); }
.product-actions { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); }
@media (max-width: 30rem) {
  .product-toolbar > .btn-primary { margin-inline-start: 0; }
  .product-table th:first-child, .product-table td:first-child,
  .product-table th:nth-child(3), .product-table td:nth-child(3) { display: none; }
  .product-code-mobile { display: block; color: var(--ink-soft); font-weight: 400; font-size: var(--fs-small); }
  .product-table th, .product-table td { padding-inline: 4px; }
}

table.lines { table-layout: fixed; }
table.lines form { margin: 0; }
table.lines thead th { white-space: normal; line-height: 1.25; }
table.lines th:nth-child(1) { width: 20%; }
table.lines th:nth-child(2) { width: 20%; }
table.lines th:nth-child(3) { width: 12%; }
table.lines th:nth-child(4) { width: 16%; }
table.lines th:nth-child(5) { width: 16%; }
table.lines th:nth-child(6) { width: 16%; }
table.lines-exclusive th:nth-child(1) { width: 15%; }
table.lines-exclusive th:nth-child(2) { width: 18%; }
table.lines-exclusive th:nth-child(3) { width: 8%; }
table.lines-exclusive th:nth-child(4) { width: 13%; }
table.lines-exclusive th:nth-child(5) { width: 12%; }
table.lines-exclusive th:nth-child(6) { width: 10%; }
table.lines-exclusive th:nth-child(7) { width: 10%; }
table.lines-exclusive th:nth-child(8) { width: 14%; }
table.lines td { vertical-align: top; min-width: 0; }
table.lines input, table.lines select { min-width: 0; width: 100%; }
table.lines .amount { white-space: nowrap; font-variant-numeric: tabular-nums; }
.line-calculated { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.line-calculated output { display: block; min-height: var(--tap); padding: var(--sp-2) var(--sp-1); color: var(--ink-soft); }
/* Save and remove share one cell; a generic last-cell button width split them. */
.line-actions { display: flex; flex-wrap: nowrap; align-items: center; justify-content: center; gap: var(--sp-1); }
.line-actions-cell { padding-inline: var(--sp-1); }
.line-actions form { display: contents; }
table.lines .line-row .line-actions button { flex: none; width: var(--tap); min-width: var(--tap); height: var(--tap); min-height: var(--tap); padding: 0; }
.line-actions button img { width: 18px; height: 18px; }
.line-save { border-color: var(--accent); color: var(--accent); }
.line-save img { filter: invert(30%) sepia(46%) saturate(1356%) hue-rotate(145deg) brightness(90%) contrast(94%); }
.line-add-actions td { padding-top: var(--sp-2); text-align: right; }
.line-add-button::before { content: '+'; font-size: 1.35rem; line-height: 1; }
.line-more summary { min-height: var(--tap); display: flex; align-items: center; cursor: pointer; }
.line-more-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); padding: var(--sp-2) 0; }
.line-more-fields > div { min-width: 0; }
.line-more-fields input { width: 100%; }
/* T-59: `position` makes this the containing block of the `.sr` labels
   inside, so they overflow here and not across the page at 390px. */
.table-scroll { max-width: 100%; overflow-x: auto; position: relative; }

/* A table is the wrong element on a phone, but it is the right one for the
   data, so the narrow case scrolls rather than reflows into nonsense. */
@media (min-width: 48rem) {
  .table-scroll { overflow: visible; }
}
@media (max-width: 47.99rem) {
  .table-scroll table.lines, table.lines tbody { display: block; width: 100%; }
  table.lines thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  table.lines tr.line-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); padding: var(--sp-3); border: 1px solid var(--line); border-bottom: 0; border-radius: var(--radius-card) var(--radius-card) 0 0; background: var(--bg); }
  table.lines tr.line-detail { display: block; padding: 0 var(--sp-3) var(--sp-2); margin-bottom: var(--sp-3); border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--radius-card) var(--radius-card); background: var(--bg); }
  table.lines tr.line-detail td { display: block; padding: 0; border: 0; }
  table.lines tr.line-row td { display: block; padding: 0; border: 0; min-width: 0; }
  table.lines tr.line-row td:nth-child(1), table.lines tr.line-row td:nth-child(2) { grid-column: 1 / -1; }
  table.lines tr.line-row .amount { align-self: center; text-align: right; font-size: var(--fs-docno); font-weight: 600; }
  table.lines tr.line-row .line-actions-cell { grid-column: 1 / -1; }
  table.lines tr.line-row .line-actions { flex-direction: row; }
  table.lines tr.line-row .line-actions button { width: auto; min-width: var(--tap); height: var(--tap); min-height: var(--tap); padding-inline: var(--sp-3); }
  .line-actions .line-save::after { content: 'บันทึก'; }
  .line-actions .line-delete::after { content: 'ลบ'; }
  table.lines tr.line-row .line-actions-cell:empty { display: none; }
  table.lines tr.line-row .line-calculated { padding: var(--sp-1) var(--sp-2); background: var(--bg-soft); border-radius: var(--radius); }
  table.lines tr.line-row .line-calculated::before { display: block; color: var(--ink-soft); font-size: var(--fs-small); }
  table.lines tr.line-row .line-calculated:nth-child(5)::before { content: 'ก่อน VAT/ชิ้น'; }
  table.lines tr.line-row .line-calculated:nth-child(6)::before { content: 'VAT/รายการ'; }
  table.lines tr.line-row .line-calculated output { min-height: 0; padding: 0; }
  table.lines tr.line-add-actions { display: block; margin: 0 0 var(--sp-3); text-align: right; }
  table.lines tr.line-add-actions td { display: block; }
  .line-more-fields { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Customer search results (M2, and Zone B)
   -------------------------------------------------------------------------- */

[role="listbox"], #customer-results, #results {
  margin: 0 0 1rem;
}
[role="listbox"] ul, #customer-results ul {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
[role="option"], #customer-results li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  padding: 0.35rem 0.6rem;
  border-bottom: 1px solid var(--line);
}
[role="option"]:last-child, #customer-results li:last-child { border-bottom: 0; }
[role="option"][aria-selected="true"] {
  background: var(--bg-soft);
  box-shadow: inset 3px 0 0 var(--accent);
}
[role="option"] button {
  flex: 1 1 auto;
  min-height: 2.25rem;
  text-align: start;
  border-color: transparent;
  background: transparent;
}
[role="option"] button:hover { background: var(--bg-sunken); }
[role="option"] span { font-weight: 400; color: var(--ink-soft); }

.picked, #picked-customer {
  padding: 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-soft);
}

.customer-search-screen #customer-search { max-width: 36rem; }
.customer-search-screen #q { max-width: 36rem; min-height: 48px; }
.customer-search-screen #customer-search .hint { margin-top: var(--sp-1); }
.customer-create { margin-bottom: var(--sp-5); }
.customer-search-screen #results ul { background: var(--bg); }
.customer-search-screen #results [role="option"] { flex-wrap: nowrap; min-height: 56px; padding: 0 var(--sp-2); }
.customer-search-screen #results [role="option"][aria-selected="true"] { background: var(--accent-soft); }
.customer-search-screen #results [role="option"] button { min-width: 0; min-height: var(--tap); display: flex; flex-direction: column; align-items: flex-start; justify-content: center; padding-inline: var(--sp-2); }
.customer-search-screen #results [role="option"] button span { font-size: var(--fs-small); }
.customer-search-screen #results [role="option"] .btn-small { flex: none; width: var(--tap); min-height: var(--tap); padding: 0; font-size: var(--fs-small); }
.empty-state { padding: var(--sp-4); background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card); }
#picked-customer { background: var(--bg-soft); border-radius: var(--radius-card); }
.picked-details { margin: 0 0 var(--sp-4); }
.picked-details > div { display: grid; grid-template-columns: 10rem minmax(0, 1fr); gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--line); }
.picked-details dt { color: var(--ink-soft); }
.picked-details dd { margin: 0; overflow-wrap: anywhere; }
.customer-form { max-width: 38rem; padding: var(--sp-5); background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card); }
.customer-field { margin-bottom: var(--field-gap); }
.customer-field > label, .customer-field > legend { margin-bottom: var(--sp-1); }
.customer-branch-group { border: 0; padding: 0; }
.customer-branch-group > label:has(> input[type="radio"]) { min-height: var(--tap); }
.customer-branch-group > label[for="cust_branch_no"] { display: block; margin-top: var(--sp-3); }
.customer-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; margin-top: var(--sp-5); }
.customer-state-action { margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--line); }
.customer-confirm { max-width: 36rem; padding: var(--sp-4); background: var(--danger-bg); border: 1px solid var(--danger); border-radius: var(--radius-card); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: white; }
.btn-danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 88%, black); }
@media (max-width: 47.99rem) {
  .picked-details > div { grid-template-columns: minmax(0, 1fr); gap: 0; }
}

/* --------------------------------------------------------------------------
   Create Document screen (specs/create-document.md §4)
   -------------------------------------------------------------------------- */

#choose-document { max-width: 40rem; margin-inline: auto; }
#choose-document .chooser-steps { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-4); padding: 0; list-style: none; counter-reset: step; }
#choose-document .chooser-steps li { display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-3); border-radius: var(--radius); background: var(--bg-sunken); color: var(--ink-soft); font-size: var(--fs-small); font-weight: 600; counter-increment: step; }
#choose-document .chooser-steps li::before { content: counter(step); display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 5px; background: var(--accent-soft); color: var(--accent); }
#choose-type-form .seg { display: flex; flex-wrap: wrap; gap: 0.5rem; }
#choose-type-form .seg > label { min-height: var(--tap); padding: 0 0.75rem; border: 1px solid var(--line-strong); border-radius: var(--radius); }
#choose-type-form .seg > label:has(input:checked) { background: var(--bg-soft); outline: 2px solid var(--accent); }
#choose-type-form > div { margin-bottom: 1rem; }
#choose-type-form > button { width: 100%; }
#invalid-document-type a { display: inline-flex; align-items: center; min-height: var(--tap); }

#doc-column > section, .zone {
  margin: 0 0 1rem;
  padding: 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
#doc-column > section, #choose-type-form { padding: var(--sp-5); border-radius: var(--radius-card); background: var(--bg); }
.form-step { display: inline-grid; place-items: center; flex: none; width: 25px; height: 25px; margin-right: var(--sp-2); border-radius: 7px; background: var(--accent-soft); color: var(--accent); font-size: var(--fs-small); font-weight: 700; }
.required-mark { color: var(--danger); font-weight: 700; }
.type-change-flow { margin: 0 0 var(--sp-4); color: var(--ink-soft); font-size: var(--fs-small); }
#doc-column #customer-fields input:not([type="radio"]), #doc-column #customer-fields textarea,
#doc-column #zone-d input, #doc-column #zone-a input[type="date"], #doc-column #zone-a select { width: 100%; max-width: none; }
#customer-fields > div { min-width: 0; }
#customer-fields .print-required-missing { border: 2px solid var(--danger); background: var(--danger-bg); }
#customer-fields .inline-required { display: block; color: var(--danger); font-size: var(--fs-small); font-weight: 600; margin-top: var(--sp-1); }
#customer-fields .client-cleared { display: none; }
.line-delete { width: var(--tap); height: var(--tap); min-width: var(--tap); padding: 0; border: 1px solid var(--danger); color: var(--danger); background: var(--bg); }
.line-delete img { width: 18px; height: 18px; filter: invert(20%) sepia(83%) saturate(2314%) hue-rotate(338deg) brightness(78%) contrast(91%); }
@media (max-width: 30rem) { #doc-column > section, #choose-type-form { padding: var(--sp-4); } }
.doc-title-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: start; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.doc-title-row h1 { font-size: var(--fs-title); margin: 0; }
.doc-subtitle { color: var(--ink-soft); margin: 0; }
.zone-a-details summary { min-height: var(--tap); display: flex; align-items: center; cursor: pointer; font-weight: 600; }
.zone-a-details[open] summary { margin-bottom: var(--sp-3); }
.vat-setup { margin-top: var(--sp-4); padding: var(--sp-4); border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg-soft); }
.vat-setup h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-body); }
.vat-setup .hint { margin: var(--sp-2) 0 0; }
.vat-presence { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-3); padding: 0; border: 0; }
.vat-presence legend { margin-bottom: var(--sp-2); font-weight: 600; }
.vat-presence label { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--tap); padding: var(--sp-2) var(--sp-3); border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); }
.vat-presence:not(.vat-fixed) { display: none; }
.vat-js .vat-presence:not(.vat-fixed) { display: flex; }
.vat-js .vat-presence label:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.vat-presence.vat-fixed { opacity: .8; }
#vat-method-wrap label { display: block; margin-bottom: var(--sp-2); font-weight: 600; }
#vat-method-wrap select { width: min(100%, 28rem); }
.price-rounding-note { max-width: 58rem; margin: var(--sp-3) 0 0; }
.vat-fixed-note { margin: 0; font-weight: 700; color: var(--accent); }
.vat-fixed-note .hint { margin-inline-start: var(--sp-2); font-weight: 400; }
.vat-save-button { margin-top: var(--sp-3); }
#zone-a .seg > label { min-height: var(--tap); }
#zone-a .seg > button { margin-top: var(--sp-2); }
#zone-a .row > div:has(#doc_type) { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-2); }
#zone-a .row > div:has(#doc_type) label { grid-column: 1 / -1; }
#zone-a .row > div:has(#doc_type) select { min-width: 0; }
#zone-b #customer-search { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-2); align-items: end; }
#zone-b #customer-search > label, #zone-b #customer-results { grid-column: 1 / -1; }
#zone-b #customer-search > button { min-height: var(--tap); }
#customer-fields { margin-top: var(--sp-4); }
#customer-gate-remedy { margin: 0 0 var(--sp-3); }
#cust-hq label { display: inline-flex; align-items: center; min-height: var(--tap); }
.vehicle-group + .vehicle-group { margin-top: var(--sp-5); }
.vehicle-group h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-body); }
.vehicle-fields { display: grid; gap: var(--sp-4); }
.vehicle-fields > div { min-width: 0; }
.result-card { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card); padding: var(--sp-6); }
.result-card .totals { margin: var(--sp-5) 0; max-width: 22rem; }
.result-card .totals > div:has(#total-value) { padding-top: var(--sp-2); border-top: 1px solid var(--line-strong); }
.result-card #total-value { font-size: var(--fs-total); font-weight: 700; }
.result-type { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-size: var(--fs-h2); font-weight: 600; }
.state-chip { display: inline-flex; align-items: center; min-height: var(--tap); margin: 0; padding: var(--sp-2) var(--sp-3); border-radius: var(--radius); font-size: var(--fs-h2); font-weight: 600; }
.state-chip-ok { background: var(--ok-bg); color: var(--ok); }
.state-chip-muted { background: var(--bg-soft); color: var(--ink-soft); }
#issued-actions { flex-direction: row; justify-content: flex-start; margin-top: var(--sp-5); }
#issued-actions > form { margin: 0; }
#issued-actions > form > button, #issued-actions > .btn { min-height: var(--tap); }
#void-confirm { margin-top: var(--sp-6); border-color: var(--line); }
#void-confirm h2 { font-size: 17px; color: var(--ink-soft); }
#void-confirm button { margin-top: var(--sp-3); }
.void-reason { margin: var(--sp-5) 0; padding: var(--sp-3) var(--sp-4); border-left: 3px solid var(--line-strong); background: var(--bg-soft); }
.state { max-width: 44rem; margin: var(--sp-6) auto; padding: var(--sp-6); text-align: center; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-card); }
.state h1 { margin: 0 0 var(--sp-3); font-size: var(--fs-h2); font-weight: 600; }
.state p { color: var(--ink-soft); }
.state p:last-child { margin: var(--sp-5) 0 0; }
.state-danger { border-color: var(--danger); background: var(--danger-bg); }
.state-danger h1 { color: var(--danger); }
.report-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.report-toolbar label { margin: 0; }
.report-toolbar input[type="date"] { flex: 1 1 9rem; width: auto; max-width: 14rem; min-width: 0; }
.report-toolbar button { flex: none; }
#report-table .num { white-space: nowrap; }
#report-table { min-width: 40rem; }
#discarded-qualifier { margin: var(--sp-2) 0 0; }
@media (max-width: 47.99rem) {
  #report-table th:first-child { position: sticky; left: 0; z-index: 1; background: var(--bg); }
}
@media (max-width: 29.99rem) {
  .result-card { padding: var(--sp-5); }
  .state { padding: var(--sp-5); }
  #issued-actions { flex-direction: column; align-items: stretch; }
  #issued-actions > form > button, #issued-actions > .btn { width: 100%; }
}
@media (min-width: 48rem) {
  #zone-a .row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #zone-a .seg { grid-column: 1 / -1; }
  #customer-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); }
  #customer-fields > div:has(#customer_name), #customer-fields > div:has(#address), #cust-hq { grid-column: 1 / -1; }
  #customer-gate-remedy { grid-column: 1 / -1; }
  .vehicle-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vehicle-fields .vehicle-wide { grid-column: 1 / -1; }
}

.zone-h {
  margin: 0 0 0.6rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--line);
  font-size: 1.05rem;
}

/* §4: the document number is read-only and sits top right of Zone A. */
.docno {
  justify-self: end;
  text-align: end;
}
.docno .zone-h {
  border: 0;
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
}
.docno-value {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-soft);
  font-size: var(--fs-docno);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* The number was just re-claimed (a type or date change). D-12 never reuses
   one, so the staff want to see that it moved. */
.docno-value.flash {
  background: var(--warn-bg);
  border-color: var(--warn);
  color: var(--warn);
}

/* T-68: the total and actions follow the fields. A sticky card covered the
   customer form on a phone; the approved prototype uses normal flow. */
#zone-e {
  position: static;
  background: var(--bg);
  border-color: var(--line-strong);
}

.totals {
  display: grid;
  gap: 0.15rem 1rem;
  margin-bottom: 0.6rem;
}
.totals > div { display: flex; justify-content: space-between; gap: 1rem; }
.totals .k { color: var(--ink-soft); }
.totals .v {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
#total-value { font-size: var(--fs-total); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.grand-total { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); border-top: 1px solid var(--line-strong); }
/* The baht text is the line a customer reads to check the figure, so it gets
   the width of the box and no truncation. */
.baht {
  grid-column: 1 / -1;
  padding-top: 0.3rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

#non-financial-note { color: var(--ink-soft); }

#type-confirm, #immutable, #no-branch, #no-customer-found {
  padding: 0.8rem;
  border: 2px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-soft);
}
#type-confirm { padding: var(--sp-4); border: 1px solid var(--warn); border-radius: var(--radius-card); background: var(--warn-bg); }
#type-confirm-q { font-size: var(--fs-h2); font-weight: 600; }
#type-confirm-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
#immutable, #no-branch { border-color: var(--danger); background: var(--danger-bg); }

/* --------------------------------------------------------------------------
   Responsive (NFR-05, D-02): phone first, then tablet, then the PC split
   -------------------------------------------------------------------------- */

/* Tablet and up: field rows go side by side instead of stacking. */
@media (min-width: 48rem) {
  .row { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
  .totals { grid-template-columns: minmax(0, 1fr); max-width: 24rem; margin-inline-start: auto; }
  #zone-e { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: end; gap: var(--sp-4); }
  #zone-e-figures { width: 100%; min-width: 0; }
  #zone-e .totals { max-width: none; margin: 0; }
  #zone-e-bar { min-width: 0; display: grid; gap: var(--sp-3); }
  #zone-e-bar .actions { flex-direction: row; justify-content: flex-end; }
  #zone-e-bar .grand-total { position: static; width: 100%; padding-top: var(--sp-2); }
  #zone-e #error-count { position: static; width: 100%; margin: var(--sp-2) 0 0; }
}
@media (max-width: 47.99rem) {
  #zone-e { display: block; }
  #zone-e-figures { padding: 0; }
  #zone-e-bar { position: static; display: grid; gap: var(--sp-3); margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--line); }
  #zone-e-bar .grand-total { padding-top: 0; }
  #zone-e-bar .grand-total .v { font-size: 22px; }
  #zone-e-bar .actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
  #zone-e-bar .actions > button, #zone-e-bar #issue-action { flex: 1 1 9rem; }
  #zone-e-bar #btn-print { width: 100%; }
}

/* §6: a scaled A4 sheet; the iframe uses the same layout HTML and CSS as print. */
#doc-preview { background: var(--bg-soft); }
#doc-preview h2 { margin: 0 0 .4rem; }
.preview-heading { display: flex; align-items: start; justify-content: space-between; gap: var(--sp-2); }
.preview-heading h2 { margin: 0; }
#preview-expand { font-size: var(--fs-small); padding-inline: var(--sp-2); }
.preview-paper { overflow: auto; width: 100%; background: #ddd; padding: .5rem; box-sizing: border-box; }
#preview-frame { display: block; width: 210mm; height: 297mm; border: 0; background: white; zoom: .62; }
#preview-overflow { font-weight: 700; }
#preview-toggle { display: none; }

/* PC: persistent form and preview columns. */
@media (min-width: 72rem) {
  #doc-screen {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: var(--sp-5);
    align-items: start;
  }
  /* T-59: exactly two grid items -- #doc-column, then #doc-preview -- so
     nothing is auto-placed under the preview. No grid-row: with no explicit
     rows, `1 / -1` covered row 1 only. */
  #doc-preview {
    position: sticky;
    top: var(--sp-4);
    max-height: calc(100vh - 2rem);
    overflow: auto;
  }
  #preview-frame { zoom: .39; }
  body.preview-expanded-body { overflow: hidden; }
  #doc-preview.preview-expanded { position: fixed; inset: var(--sp-4); z-index: 20; max-height: none; overflow: auto; padding: var(--sp-4); background: var(--bg); box-shadow: 0 0 0 100vmax rgb(12 24 29 / 68%), 0 12px 36px rgb(12 24 29 / 25%); }
  #doc-preview.preview-expanded .preview-paper { max-width: 52rem; margin-inline: auto; }
  #doc-preview.preview-expanded #preview-frame { zoom: 1; }
}

@media (min-width: 72rem) and (max-width: 79.99rem) {
  #doc-screen { grid-template-columns: minmax(0, 1fr) 18rem; }
  #preview-frame { zoom: .33; }
}

@media (max-width: 71.99rem) {
  #preview-toggle { display: block; position: static; margin: 0 0 var(--sp-4); }
  #doc-preview { display: none; }
  #doc-preview.preview-open { display: block; }
  #preview-expand { display: none; }
  /* Everything but the toggle: it is the way back (ui-refresh 8.4.7). */
  #doc-screen.preview-only #doc-column > :not(#preview-toggle) { display: none; }
  #doc-screen.preview-only #preview-toggle { position: static; width: 100%; margin: 0 0 var(--sp-4); }
}

@media (max-width: 47.99rem) {
  #preview-frame { zoom: .42; }
}
@media (max-width: 23.99rem) {
  #preview-frame { zoom: .34; }
}

/* The shop's phones are the narrow end; nothing may need a sideways scroll. */
@media (max-width: 30rem) {
  .app-header-inner { position: relative; display: block; }
  .app-name { position: absolute; right: 0; bottom: 0; letter-spacing: -.65px; line-height: var(--tap); }
  .app-header img { display: none; }
  .login-card { margin-top: 0; }
  .actions > button { flex: 1 1 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  button:active:not(:disabled) { transform: none; }
}
