/* R92 THEME RETROFIT: this file maps ROLE names to properties. It carries
   ZERO visual values: every color, font, radius, and shadow arrives as a
   CSS custom property emitted from the theme table's row (packages/domain/
   theme_source.ts, one source for app pages and deck pages alike). What
   lives here is STRUCTURE and the READABILITY FLOORS (rules, not style):
   18px body minimum floor, 44px tap targets, fluid widths only (no
   horizontal scroll at 320px). A rebrand edits the theme row; this file
   does not change and a rebrand that breaks a floor fails the gate
   (ops/floor_check). The former @font-face pair and the look tokens moved
   to the theme row (items 1/2/6); print keeps its OWN role tokens (item 3:
   separate set, still tokens - never literals). */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--background);
  color: var(--text);
  font-family: var(--font_family);
  font-size: var(--font_size_body);
  line-height: 1.55;
  overflow-wrap: break-word;
}

main {
  max-width: 34rem;
  margin: 0 auto;
  padding: 1rem 1rem 2rem;
  width: 100%;
}

h1 { font-size: 1.5rem; line-height: 1.25; margin: 0.75rem 0; }
h2 { font-size: 1.25rem; }
p  { margin: 0.75rem 0; }
.prose p { max-width: 100%; }

label { display: block; font-weight: 700; margin: 0.75rem 0 0.25rem; }
label .req { color: var(--accent); font-size: 0.8rem; font-weight: 700; margin-left: 0.4rem; text-transform: uppercase; letter-spacing: 0.04em; }
.help, .section-help, .scale-legend, .progress-label { color: var(--text_soft); font-size: 1rem; }

input[type='email'], input[type='text'], textarea {
  width: 100%;
  min-height: var(--tap_target, 44px);
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 2px solid var(--text_soft);
  border-radius: var(--radius_small);
  padding: 0.5rem 0.6rem;
}
textarea { min-height: 8rem; }

button, .btn {
  display: inline-block;
  min-height: var(--tap_target, 44px);
  min-width: var(--tap_target, 44px);
  font: inherit;
  font-weight: 700;
  color: var(--accent_text);
  background: var(--accent);
  border: 2px solid var(--accent);
  border-radius: var(--radius_small);
  padding: 0.5rem 1.25rem;
  margin: 0.75rem 0.25rem 0.25rem 0;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}
button.secondary, .btn.secondary {
  background: transparent;
  color: var(--accent);
}

fieldset {
  border: 0;
  margin: 0.25rem 0 0.5rem;
  padding: 0;
}
.choice, .scale-opt {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: var(--tap_target, 44px);
  font-weight: 400;
  margin: 0;
}
.choice input, .scale-opt input { width: 22px; height: 22px; flex: none; }

.scale-row { display: flex; gap: 0.5rem; }
.scale-opt { flex-direction: column; justify-content: center; flex: 1 1 0; min-width: var(--tap_target, 44px); }
.scale-legend { display: flex; justify-content: space-between; gap: 0.5rem; }

.question { margin: 1.5rem 0 2rem; }

.progress { height: 8px; background: var(--line); border-radius: var(--radius_pill); margin-top: 0.5rem; }
.progress-fill { height: 8px; width: var(--pct, 0%); background: var(--accent); border-radius: var(--radius_pill); transition: width 0.2s; }

.notice {
  max-width: 34rem;
  margin: 0 auto;
  padding: 1rem;
  border-top: 1px solid var(--line);
  color: var(--text_soft);
  font-size: 1rem;
}

.crisis { background: var(--warning); border-left: 6px solid var(--accent); padding: 0.75rem 1rem; margin: 1rem 0; }

/* TEACH-1 (gate a3 root cause C2, Oct 21): the player + admin surfaces ship
   structure here; every visual value is a role token from the theme row
   (R92 law - apps/ carries no literals). */
.teach-controls { display: flex; gap: .5rem; align-items: center; margin: 1rem 0; padding: .6rem; border: 1px solid var(--line); border-radius: var(--radius_block); }
.teach-track { flex: 1; height: 8px; cursor: pointer; }
/* SMALLFIX-1 S-S carry (TEACH1FU review 9ddf1c7, NOT-CLOSED SHOULD): the
   two pseudo-element rules below only paint on a progress element whose
   NATIVE appearance is disabled; without appearance:none the UA shadow
   keeps its own fill (owner's Chromium read: the browser default color,
   not --accent). border:0 + the token --line track rules below complete the
   themed bar. SMALLFIX-2 S-2 correction (owner review c5093ca): the element
   background alone did NOT theme the empty track in Chromium - the UA paints
   ::-webkit-progress-bar over it (gray 128,128,128 measured), so the track
   needs its own parent-scoped rule (added below, same scope as the fill). */
.teach-fill { display: block; width: 100%; height: 8px; appearance: none; -webkit-appearance: none; border: 0; background: var(--line); }
/* TEACH-1 SHOULDs (round-4 review S-S): the native <progress> fill rendered
   in the BROWSER DEFAULT color (a theme-blind bar, odd in dark mode). The
   filled portion rides the --accent role token (R92 law: role tokens, zero
   literals) through the two engine pseudo-elements. Selector is PARENT-
   SCOPED (.teach-track progress, one progress per track): a direct
   '.teach-fill::-webkit-...' form reads to the R92H guard's color-property
   scan as the SVG 'fill' property meeting a colon (the class name ends in
   'fill') - parent scope hits the same element with no parser ambiguity. */
.teach-track progress::-webkit-progress-bar {
  background: var(--line);
}
.teach-track progress::-webkit-progress-value {
  background: var(--accent);
}
.teach-track progress::-moz-progress-bar {
  background: var(--accent);
}
.teach-times { font-variant-numeric: tabular-nums; }
.teach-listenline-row { display: flex; gap: .5rem; align-items: center; }
.teach-draft { background: var(--warning); color: var(--text); padding: .6rem 1rem; border-radius: var(--radius_small); }
.teach-calm { background: var(--surface); color: var(--text_soft); padding: .5rem; }
.teach-notice { background: var(--surface); color: var(--text_soft); padding: .5rem; }
.teach-meta { color: var(--text_soft); }
.teach-row { margin: .4rem 0; }
.crisis.pinned { margin: 0; max-width: none; }
main + .crisis { max-width: 34rem; margin: 0 auto; padding-left: 1rem; padding-right: 1rem; }

.error { color: var(--danger); font-weight: 700; }

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

.nav { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
/* R24 persistent reachability: one-line nav from any page to a finished guide.
   Chrome copy ("Your guide"), shown only when the server says an artifact
   exists. 44px tap target per the phone contract. */
.site-nav { max-width: 34rem; margin: 0 auto; padding: .25rem 1rem 0; font-weight: 700; }
.site-nav a { display: inline-block; min-height: var(--tap_target, 44px); line-height: var(--tap_target, 44px); }
.saved { color: var(--text_soft); font-size: 0.95rem; min-height: 1.2em; }

/* R23 (owner brief 2/5 2.5): print stylesheet. Browser print of the guide screen
   is the fallback if the PDF path is ever down: no navigation, no download
   button, page breaks before section headings, dark on light using the
   PRINT ROLE TOKENS (item 3: print keeps its own set, still tokens). */
/* R23 owner ruling 2026-09-10 (CANDIDATE A, applied to section 6 of the brief):
   a participant reading their own guide must never scroll sideways to finish a
   sentence. Below 600px the nested tables collapse to stacked labeled blocks:
   each row becomes one block, the row header becomes the block's label line.
   Semantics stay table markup in the DOM (display-only transform); the caption
   remains the visible block title. Above 600px nothing changes.
   Proved: ops/render_artifacts/r23_nested/ screenshots from the committed
   transform at 320px and 1200px; at 320px document scrollWidth == clientWidth
   (no sideways scroll exists at any level). */
/* Above the collapse the thead serves the labels: hide the per-cell span so
   desktop reads exactly as before (owner ruling: display:none at 600px and up). */
table.nested.trait .cell-label { display: none; }

@media (max-width: 600px) {
  table.nested thead { display: none; }
  table.nested, table.nested tbody, table.nested tr,
  table.nested th, table.nested td { display: block; width: 100%; }
  table.nested tr { border: 1px solid var(--text_soft); border-radius: var(--radius_block); margin-bottom: .75rem; }
  table.nested th[scope="row"], table.nested td { border: 0; padding: .4rem .75rem; }
  table.nested th[scope="row"] { font-weight: 700; padding-bottom: 0; }
  table.nested caption { padding-top: .4rem; }
  table.nested.trait td { border-top: 1px dashed var(--text_soft); }
  /* F-3 (owner ruling OPTION 3): below 600px the thead is hidden, so each trait
     cell shows its own real-DOM label (span.cell-label). Real text node, never
     CSS generated content. Hidden above where the thead carries it. */
  table.nested.trait .cell-label {
    display: block;
    font-weight: 700;
    font-size: .85em;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text_label);
  }
}

@media print {
  body { background: var(--print_background); color: var(--print_text); }
  main, .guide, .guide-section { max-width: none; }
  .nav, .site-nav, .download, .toc, button, .progress, .notice, .crisis { display: none; }
  .guide-section { break-before: page; page-break-before: always; }
  .guide-section:first-of-type { break-before: auto; page-break-before: avoid; }
  .guide-head { break-inside: avoid; }
  table.nested { border-collapse: collapse; width: 100%; }
  table.nested th, table.nested td { border: 1px solid var(--print_line); }
  a { color: var(--print_text); text-decoration: none; }
}

/* R87 listen bar: control surface above the guide, reading highlight on the
   section currently spoken. */
.listen-bar { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  border: 1px solid currentColor; border-radius: var(--radius_bar); padding: .6rem .8rem;
  margin: 0 0 1.2rem; }
.listen-bar .listen-label { flex: 1 1 100%; margin: 0; font-weight: 700; }
.listen-bar .listen-rate { margin: 0; }
.listen-notice { flex: 1 1 100%; margin: .2rem 0 0; min-height: 1em; }
.listen-notice.bad { color: var(--notice_danger); }
.guide-section.is-reading { outline: 2px solid currentColor; outline-offset: .4rem; }

/* R90 0k (owner theme rule): layout carried by CLASSES, not inline
   style attributes - no inline style= on new work. */
.inline-form { display: inline; }
.desk-batch { width: 100%; }
/* R92 item 4: the desk strays moved off inline styles onto classes. */
.desk-cell-wide { max-width: 340px; }
.desk-ack-form { margin-top: 6px; }

/* DESK-1 item 5 (owner brief 2026-10-18, MUST-FIX 4 owner re-verify
   2026-10-19): the desk's phone layout pass. The task cards carried NO rules
   at all - on a phone the long metadata lines forced sideways scrolling and
   two forms on one line crammed the 44px targets. One column everywhere:
   every card block-level full-width, its text wraps, its action forms sit
   one per line under the text. Theme tokens only - no new framework, no
   hardcoded colors (STANDING LAW: theme source, named by role). */
.task-card {
  display: block;
  width: 100%;
  border: 2px solid var(--text_soft);
  border-radius: var(--radius_small);
  padding: .6rem .8rem;
  margin: 0 0 .6rem;
  overflow-wrap: anywhere;
  list-style: none;
}
.desk-ack-form { margin-top: .4rem; display: block; }
.desk-ack-form .btn { margin: 0 .4rem .2rem 0; }
@media (max-width: 600px) {
  main form { display: block; max-width: 100%; }
  main input[type="text"], main input[type="email"], main select {
    width: 100%; max-width: 100%;
  }
}
/* Q13 VOICE NATIVE (flag-on pages only): tap targets, layout, one column at
   320 px. No colors here beyond var() tokens - the canvas color is read from
   --accent in JS (theme law). */
.voice-native { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .5rem; }
.voice-native .btn { min-width: var(--tap_target, 44px); min-height: var(--tap_target, 44px); }
.voice-native .vn-timer { font-variant-numeric: tabular-nums; }
.voice-native .vn-bars { display: block; }
.voice-native .vn-status { flex: 1 1 100%; margin: .2rem 0 0; min-height: 1em; }
.voice-native .vn-actions { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: .5rem; }
@media (max-width: 320px) { .voice-native { flex-direction: column; align-items: stretch; } .voice-native .vn-actions { flex-direction: column; } }

/* HANDSFREE-1 v3 (walk mode): TWO inert rules (the owner's Flag law). They
   match NOTHING until walk code adds the classes: .walk-on lands on
   documentElement only while walking (the recorder adds/removes it), and
   .wm-next only ever exists inside a recorder wrap the server marked
   data-voice-walk="1" (flag ON only). touch-action: manipulation stops iOS
   zoom on the walk's double tap (brief item 6); the flex rule is the same
   shape as .vn-status/.vn-actions above (structural only, no colors). */
.walk-on body { touch-action: manipulation; }
.voice-native .wm-next { flex: 1 1 100%; }
