/* ============================================================================
   MBS Companion — pocdoc design language v0.3

   Tokens and the four laws come from pocdoc-tokens.css and the style guide.
   This file is the component layer: it restyles the app's existing class
   vocabulary to those laws rather than renaming anything, so the views did not
   have to be rewritten to adopt the system.

   What the laws changed here, and why each was a real defect:

   1. COLOUR IS RESERVED FOR ABNORMALITY. The teal accent is gone entirely —
      links are underlined ink, buttons are ink or outline. The co-claim
      verdicts mattered most: "no restriction found" was rendered in reassuring
      green while its own copy said "an absence of evidence, not a clearance".
      Under law 1 that state is neutral ink, which is what the words meant.

   2. WHITE SPACE IS THE NORMAL RANGE. Spacing is only ever grouping.

   3. THE NUMBER IS THE LARGEST THING. For this tool the number the user came
      for is the item number, so it is set at --size-value on the detail view
      and dominates the row in a list. The fee is never the largest thing.

   4. NOTHING FLOATS. Every shadow is gone, radius is 2px, and the three
      provenance tiers are expressed as rule WEIGHT rather than three colours —
      solid 3px for the legislated text, solid hairline for departmental
      guidance, dashed for our own commentary. That survives a photocopy, and
      it stops provenance competing with the signal palette for meaning.
   ========================================================================== */

@import url('pocdoc-tokens.css');
@import url('fonts.css');

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-text);
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: var(--lh-tight); }
h1 { font-size: var(--size-display); }
h2 { font-size: 1.125rem; }
h3 { font-size: var(--size-body); }
p { margin: 0 0 var(--s-2); }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0 0 var(--s-2); padding-left: 1.25em; }
li { margin: 2px 0; }

/* Law 1: links are underlined ink. A coloured link would spend the signal
   budget on navigation. */
a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
code, kbd, .mono { font-family: var(--font-num); font-variant-numeric: tabular-nums lining-nums; }

:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--radius); }
:focus:not(:focus-visible) { outline: none; }
::selection { background: var(--paper-sunk); color: var(--ink); }

.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
      overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- app frame ---------- */

.app { min-height: 100dvh; display: flex; flex-direction: column; }

.hdr {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 56px; padding: var(--s-2) var(--s-3);
  background: var(--paper);
  border-bottom: var(--hair-strong);
}

.brand { display: flex; align-items: center; gap: var(--s-2); flex-shrink: 0;
         font-weight: 700; text-decoration: none; }
.brand-mark {
  width: 26px; height: 26px; border-radius: var(--radius); flex-shrink: 0;
  border: var(--hair-strong); display: grid; place-items: center;
  font-family: var(--font-num); font-size: 11px; font-weight: 700; color: var(--ink);
}
.brand-txt { font-size: var(--size-body); }
@media (max-width: 680px) { .brand-txt { display: none; } }

/* Search. Inset, not raised — law 4. */
.searchwrap { position: relative; flex: 1; max-width: 620px; }
.search {
  width: 100%; height: var(--tap); padding: 0 76px 0 34px;
  background: var(--paper-sunk); border: var(--hair-strong);
  border-radius: var(--radius); color: var(--ink); font-size: var(--size-body);
}
.search::placeholder { color: var(--ink-faint); }
.search::-webkit-search-cancel-button, .search::-webkit-search-decoration {
  -webkit-appearance: none; appearance: none; display: none;
}
.search:focus { outline: none; box-shadow: var(--focus); }
.search-ico { position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
              color: var(--ink-muted); pointer-events: none; display: grid; }
.search-hint { position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
               display: flex; gap: 4px; pointer-events: none; }
.search:focus ~ .search-hint { opacity: 0; }
.search-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
                width: 32px; height: 32px; border-radius: var(--radius); display: none;
                place-items: center; color: var(--ink-muted); }
.search-clear:hover { background: var(--paper-sunk); color: var(--ink); }
.searchwrap.has-q .search-clear { display: grid; }
.searchwrap.has-q .search-hint { display: none; }

kbd {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px;
  font-family: var(--font-num); font-size: 11px; font-weight: 700;
  border: var(--hair-strong); border-radius: var(--radius); color: var(--ink-muted);
}

.hdr-right { display: flex; align-items: center; gap: var(--s-1);
             margin-left: auto; flex-shrink: 0; }

/* ---------- verification stamp ----------
   "On every tool, always visible, never in a footer." Amber once the schedule
   is twelve months old — the interface enforces the maintenance policy rather
   than trusting anyone to remember it. */
.sched, .stamp {
  display: inline-flex; align-items: center; gap: var(--s-1);
  min-height: 28px; padding: 0 var(--s-2);
  border: var(--hair-strong); border-left-width: 3px; border-radius: var(--radius);
  font-size: var(--size-label); font-weight: 700; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--ink-muted); white-space: nowrap;
  background: none; font-family: var(--font-text);
}
.sched .mono, .stamp .mono { font-size: var(--size-label); color: var(--ink); }
.sched-dot { display: none; }
.sched.is-stale, .stamp.is-stale {
  color: var(--signal-caution); border-color: var(--signal-caution);
  background: var(--signal-caution-bg);
}
@media (max-width: 860px) { .sched-label, .stamp-label { display: none; } }

.iconbtn {
  width: var(--tap); height: var(--tap); border-radius: var(--radius);
  display: grid; place-items: center; color: var(--ink-muted);
}
.iconbtn:hover { background: var(--paper-sunk); color: var(--ink); }
.iconbtn[aria-pressed="true"] { background: var(--paper-sunk); color: var(--ink);
                                border: var(--hair-strong); }

.body { flex: 1; display: flex; width: 100%; max-width: 1280px; margin: 0 auto; }

/* ---------- rail ---------- */

.rail {
  width: 216px; flex-shrink: 0; padding: var(--s-4) var(--s-2) var(--s-5);
  border-right: var(--hair); position: sticky; top: 56px;
  height: calc(100dvh - 56px); overflow-y: auto;
}
.rail-sec { margin-bottom: var(--s-4); }
.rail-h { font-size: var(--size-label); font-weight: 700; letter-spacing: var(--track-label);
          text-transform: uppercase; color: var(--ink-faint);
          padding: 0 var(--s-2); margin-bottom: var(--s-2); }
.navlink {
  display: flex; align-items: center; gap: var(--s-2); width: 100%;
  padding: var(--s-2); min-height: var(--tap);
  border-radius: var(--radius); color: var(--ink-muted);
  font-size: var(--size-dense); text-align: left; text-decoration: none;
}
.navlink:hover { background: var(--paper-sunk); color: var(--ink); }
.navlink[aria-current="page"] {
  background: var(--paper-sunk); color: var(--ink); font-weight: 700;
  box-shadow: inset 3px 0 0 var(--ink);
}
.navlink svg { flex-shrink: 0; }
.navlink .count {
  margin-left: auto; min-width: 22px; height: 20px; padding: 0 6px;
  border: var(--hair-strong); border-radius: var(--radius);
  font-family: var(--font-num); font-size: var(--size-label); font-weight: 700;
  display: grid; place-items: center; font-variant-numeric: tabular-nums;
}
.navlink .count.hot { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.main { flex: 1; min-width: 0; padding: var(--s-4) var(--s-4) var(--s-6);
        max-width: 1000px; margin-inline: auto; }
@media (max-width: 1024px) {
  .rail { display: none; }
  .main { padding: var(--s-3) var(--s-3) 96px; }
}

/* ---------- mobile tabs ---------- */

.tabs {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 70;
  background: var(--paper); border-top: var(--hair-strong);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabs-in { display: flex; }
.tab {
  flex: 1; min-height: 56px; padding: var(--s-2) 2px;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  color: var(--ink-muted); font-size: var(--size-label); font-weight: 700;
  position: relative; text-decoration: none;
}
.tab[aria-current="page"] { color: var(--ink); box-shadow: inset 0 3px 0 var(--ink); }
.tab .badge {
  position: absolute; top: 4px; right: calc(50% - 20px);
  min-width: 18px; height: 18px; padding: 0 4px;
  background: var(--ink); color: var(--paper); border-radius: var(--radius);
  font-family: var(--font-num); font-size: 11px; font-weight: 700;
  display: grid; place-items: center;
}
@media (max-width: 1024px) { .tabs { display: block; } }

/* ---------- surfaces ----------
   Law 4: a bounded region is a hairline and an optional inset fill. Never a
   shadow, never a float. */

.card { background: none; border: var(--hair); border-radius: var(--radius); }
.card-pad { padding: var(--s-3); }
.sec { margin-bottom: var(--s-5); }
.sec-hdr { display: flex; align-items: baseline; gap: var(--s-2);
           margin-bottom: var(--s-3); flex-wrap: wrap;
           padding-bottom: var(--s-2); border-bottom: var(--hair); }
.sec-sub { font-size: var(--size-dense); color: var(--ink-muted); }
.sec-act { margin-left: auto; font-size: var(--size-dense); font-weight: 700; }

/* ---------- buttons: ink or outline, never coloured ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: var(--tap); padding: 0 var(--s-3);
  background: none; border: var(--hair-strong); border-radius: var(--radius);
  font-size: var(--size-dense); font-weight: 700; color: var(--ink);
  text-decoration: none;
}
.btn:hover { background: var(--paper-sunk); }
.btn-primary { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn-primary:hover { background: var(--ink); opacity: .88; }
.btn-ghost { border-color: transparent; color: var(--ink-muted); }
.btn-ghost:hover { background: var(--paper-sunk); color: var(--ink); }
.btn-sm { min-height: 32px; padding: 0 var(--s-2); font-size: var(--size-label); }
.btn[disabled] { opacity: .4; pointer-events: none; }

/* ---------- chips ----------
   Neutral by default. A chip only takes signal colour when it marks something
   the user must check — never for ordinary metadata. */

.chip {
  display: inline-flex; align-items: center; gap: var(--s-1);
  min-height: 24px; padding: 0 var(--s-2);
  border: var(--hair-strong); border-radius: var(--radius);
  font-size: var(--size-label); font-weight: 700; letter-spacing: .02em;
  color: var(--ink-muted); white-space: nowrap; background: none;
}
.chip svg { flex-shrink: 0; }
.chip-time, .chip-tele, .chip-ok { color: var(--ink-muted); }
.chip-freq { color: var(--ink); border-color: var(--rule-strong); }
.chip-derived, .chip-trap {
  color: var(--signal-caution); border-color: var(--signal-caution);
  border-left-width: 3px; background: var(--signal-caution-bg);
}
.chips { display: flex; flex-wrap: wrap; gap: var(--s-1); }

/* ---------- item row ----------
   Law 3: the item number is what the user came for, so it leads and it is the
   largest thing in the row. The fee is set at label size in muted ink. */

.rows { display: flex; flex-direction: column; }
.row {
  display: grid; grid-template-columns: auto 1fr auto; align-items: start; gap: var(--s-3);
  padding: var(--s-3) var(--s-2); background: none;
  border: 0; border-bottom: var(--hair); border-radius: 0;
  cursor: pointer; text-align: left; width: 100%; min-height: var(--tap);
}
.row:hover { background: var(--paper-sunk); }
.row:focus-within { background: var(--paper-sunk); }
.row.is-sel { background: var(--paper-sunk); box-shadow: inset 3px 0 0 var(--ink); }
/* Tap the number to copy it; tap the name to open it. One rule, everywhere.
   The number is a real target, sized for a gloved thumb, and it reads as
   pressable because it is inset and ruled. */
.row-n {
  font-family: var(--font-num); font-size: 1.375rem; font-weight: 700;
  letter-spacing: -.01em; color: var(--ink);
  min-width: 5ch; min-height: var(--tap); padding: 0 var(--s-2);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--paper-sunk); border: var(--hair); border-radius: var(--radius);
  font-variant-numeric: tabular-nums lining-nums; cursor: copy;
}
.row-n:hover { border-color: var(--rule-strong); background: var(--paper); }
.row-open {
  display: block; width: 100%; min-width: 0; text-align: left;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.row-open .row-label, .row-open .row-desc { display: block; }
.row-mid { min-width: 0; }
.row-label { font-weight: 700; font-size: var(--size-dense); margin-bottom: 2px;
             overflow-wrap: anywhere; }
.row-desc {
  font-size: var(--size-dense); color: var(--ink-muted); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.row-meta { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-top: var(--s-2); }
.row-right { display: flex; flex-direction: column; align-items: flex-end; gap: var(--s-1); flex-shrink: 0; }
.row-fee { font-family: var(--font-num); font-size: var(--size-dense); font-weight: 400;
           color: var(--ink-muted); font-variant-numeric: tabular-nums lining-nums; }
.row-fee.is-none { color: var(--ink-faint); font-family: var(--font-text); font-size: var(--size-label); }
.row-feelabel { font-size: var(--size-label); color: var(--ink-faint);
                letter-spacing: var(--track-label); text-transform: uppercase; }
.row-actions { display: flex; gap: var(--s-1); }

/* Highlight without colour: an inset fill and an underline. */
mark { background: var(--paper-sunk); color: inherit;
       text-decoration: underline; text-underline-offset: 2px; }

/* ---------- item detail page ----------
   Law 3, literally: the item number is the largest thing on the screen. It is
   what the user came for and what they are about to type into their software,
   so it outranks the title, the fee and everything else. */

.item-head { padding-bottom: var(--s-3); margin-bottom: var(--s-4);
             border-bottom: var(--hair-strong); }
.item-n {
  font-family: var(--font-num); font-size: var(--size-value); font-weight: 700;
  line-height: var(--lh-tight); letter-spacing: -.02em; color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-1) var(--s-2); margin-left: calc(var(--s-2) * -1);
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  cursor: copy;
}
.item-n:hover { background: var(--paper-sunk); border-color: var(--rule); }
.item-n::after {
  content: 'copy'; font-family: var(--font-text); font-size: var(--size-label);
  font-weight: 700; letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--ink-faint);
}
.item-title { font-size: var(--size-display); margin-top: var(--s-1); max-width: var(--measure); }

/* The one permitted confirmation, asked in place rather than over the page. */
.confirm-inline { margin: var(--s-2) 0; }

/* ---------- provenance: three rule weights, not three colours ---------- */

.prov { padding: var(--s-2) 0 var(--s-2) var(--s-3); margin: var(--s-3) 0;
        border-left: 1px solid var(--rule-strong); }
.prov-hdr { display: flex; align-items: center; gap: var(--s-1); margin-bottom: var(--s-1); }
.prov-tag { font-size: var(--size-label); font-weight: 700;
            letter-spacing: var(--track-label); text-transform: uppercase;
            color: var(--ink-muted); }
/* The legislated text carries the heaviest rule. */
.prov-law { border-left: 3px solid var(--ink); background: var(--paper-sunk); padding-right: var(--s-3); }
/* Departmental guidance: a plain hairline. */
.prov-guidance { border-left: 1px solid var(--rule-strong); }
/* Ours: dashed, because it is the only tier that is not a source. */
.prov-ours { border-left: 1px dashed var(--rule-strong); }

.descriptor { font-family: var(--font-text); font-size: var(--size-body);
              line-height: var(--lh-body); color: var(--ink); max-width: var(--measure); }
.reviewed { font-size: var(--size-label); color: var(--ink-faint); margin-top: var(--s-1); }
.reviewed.is-stale { color: var(--signal-caution); font-weight: 700; }
.quote { font-style: italic; font-size: var(--size-dense); color: var(--ink-muted);
         border-left: 1px solid var(--rule); padding-left: var(--s-2); margin-top: var(--s-2); }

/* ---------- verdicts ----------
   "No restriction found" is NOT a positive result and is no longer drawn as
   one. Neutral ink, rule only. Colour appears only for a real restriction. */

.verdict { display: flex; align-items: flex-start; gap: var(--s-2);
           padding: var(--s-3); margin: var(--s-2) 0;
           border: var(--hair); border-left-width: 3px; border-radius: var(--radius); }
.verdict-ok       { border-left-color: var(--rule-strong); }
.verdict-none     { border-left-color: var(--rule); background: var(--paper-sunk); }
.verdict-caution  { border-color: var(--signal-caution); background: var(--signal-caution-bg); }
.verdict-conflict { border-color: var(--signal-critical); background: var(--signal-critical-bg); }
.verdict-ico { flex-shrink: 0; margin-top: 1px; color: var(--ink-muted); }
.verdict-caution .verdict-ico  { color: var(--signal-caution); }
.verdict-conflict .verdict-ico { color: var(--signal-critical); }
.verdict-body { min-width: 0; }
.verdict-title { font-weight: 700; font-size: var(--size-dense); margin-bottom: 2px; }
.verdict-why { font-size: var(--size-dense); color: var(--ink-muted); line-height: 1.4; }
.verdict-caution .verdict-title  { color: var(--signal-caution); }
.verdict-conflict .verdict-title { color: var(--signal-critical); }

/* ---------- empty / unverified ---------- */

.empty { text-align: center; padding: var(--s-5) var(--s-3); color: var(--ink-muted); }
.empty-ico { color: var(--ink-faint); margin-bottom: var(--s-2); }
.empty h3 { margin-bottom: var(--s-1); color: var(--ink); }
.empty p { font-size: var(--size-dense); max-width: 46ch; margin: 0 auto var(--s-1); }

.unverified {
  display: inline-flex; align-items: center; gap: var(--s-1); padding: 2px var(--s-2);
  border: 1px dashed var(--signal-caution); border-left-width: 3px;
  border-radius: var(--radius); background: var(--signal-caution-bg);
  font-size: var(--size-label); font-weight: 700; color: var(--signal-caution);
}

/* ---------- paste block ----------
   Plain ASCII only. Smart quotes, em dashes and bullets corrupt on paste into
   practice software, which is where every one of these numbers is going. */

.paste {
  background: var(--paper-raised); border: var(--hair-strong); border-radius: var(--radius);
  padding: var(--s-3); font-family: var(--font-num); font-size: var(--size-dense);
  line-height: 1.5; white-space: pre-wrap; word-break: break-word; color: var(--ink);
}
.paste-hdr { display: flex; align-items: baseline; gap: var(--s-2);
             margin-bottom: var(--s-2); font-size: var(--size-label);
             letter-spacing: var(--track-label); text-transform: uppercase;
             color: var(--ink-muted); font-weight: 700; }
.paste-len { margin-left: auto; font-family: var(--font-num); }

/* ---------- restored state ----------
   Law 8. Ambiguity about whose data is on screen is the most dangerous state
   this interface can be in, so it is stated rather than implied. */

.restored {
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  padding: var(--s-2) var(--s-3); margin-bottom: var(--s-3);
  border: var(--hair-strong); border-left-width: 3px; border-radius: var(--radius);
  background: var(--paper-sunk); font-size: var(--size-dense); color: var(--ink-muted);
}
.restored strong { color: var(--ink); }
.restored .btn { margin-left: auto; }

/* ---------- tables ---------- */

.tbl-wrap, .mtx-wrap { overflow-x: auto; border: var(--hair); border-radius: var(--radius); }
.tbl, .mtx { border-collapse: collapse; width: 100%; font-size: var(--size-dense); }
.tbl th, .tbl td, .mtx th, .mtx td {
  padding: var(--s-2); text-align: left; border-bottom: var(--hair);
}
.tbl th, .mtx thead th {
  background: var(--paper-sunk); font-size: var(--size-label); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink-muted);
  border-bottom: var(--hair-strong);
}
.tbl tr:last-child td, .mtx tr:last-child td { border-bottom: 0; }
.tbl td.num, .mtx td.num { font-family: var(--font-num);
                           font-variant-numeric: tabular-nums lining-nums; text-align: right; }
.mtx { min-width: 560px; }
.mtx td, .mtx th { text-align: center; }
.mtx tbody th { text-align: left; font-weight: 400; color: var(--ink-muted);
                background: var(--paper); position: sticky; left: 0;
                border-right: var(--hair); }
.mtx-cell {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 56px; min-height: var(--tap); padding: 0 var(--s-2);
  border: var(--hair-strong); border-radius: var(--radius);
  font-family: var(--font-num); font-weight: 700; font-size: var(--size-body);
  color: var(--ink); background: none;
}
.mtx-cell:hover { background: var(--paper-sunk); }
.mtx-na { color: var(--ink-faint); font-size: var(--size-label); }

.notehtml table { border-collapse: collapse; width: 100%; font-size: var(--size-dense); margin: var(--s-2) 0; }
.notehtml th, .notehtml td { border: var(--hair); padding: var(--s-2); text-align: left; }
.notehtml th { background: var(--paper-sunk); font-weight: 700; }
.notewrap { overflow-x: auto; }

/* A last resort when the clipboard is denied: the number, pre-selected. */
.copy-fallback {
  display: block; width: 8ch; margin-bottom: var(--s-3);
  font-size: var(--size-value); font-weight: 700; text-align: center;
  background: var(--paper-sunk); border: 2px solid var(--signal-caution);
  border-radius: var(--radius); color: var(--ink);
}

/* ---------- toast ----------
   Not an alert. Law 7 forbids modals; this is a transient confirmation of an
   action the user just took, and it never asks for anything. */

.toasts { position: fixed; z-index: 90; left: 50%; transform: translateX(-50%);
          bottom: var(--s-4); display: flex; flex-direction: column; gap: var(--s-2);
          align-items: center; pointer-events: none; }
.toast { display: flex; align-items: center; gap: var(--s-2);
         padding: var(--s-2) var(--s-3); border-radius: var(--radius);
         background: var(--ink); color: var(--paper);
         font-size: var(--size-dense); font-weight: 700; }
@media (max-width: 1024px) { .toasts { bottom: calc(72px + env(safe-area-inset-bottom)); } }

/* ---------- utility ---------- */

.stack { display: flex; flex-direction: column; }
.gap-4 { gap: 4px; } .gap-6 { gap: 6px; } .gap-8 { gap: 8px; }
.gap-12 { gap: 12px; } .gap-16 { gap: 16px; }
.rowflex { display: flex; align-items: center; }
.spread { justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }
.small { font-size: var(--size-dense); }
.xs { font-size: var(--size-label); }
.b { font-weight: 700; }
.tnum { font-variant-numeric: tabular-nums lining-nums; }
.trunc { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hr { height: 0; border: 0; border-top: var(--hair); margin: var(--s-4) 0; }
.grid-auto { display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.nowrap { white-space: nowrap; }

/* ---------- mobile reachability contract ----------
   Law 10. The thumb arc covers the bottom two-thirds; the top corners require
   a grip shift, which is when phones get dropped. So on a phone the header
   carries the search and the stamp only, and every control moves down. */

@media (max-width: 560px) {
  .hdr { flex-wrap: wrap; row-gap: var(--s-2); padding: var(--s-2) var(--s-3); }
  .brand { order: 1; }
  .hdr-right { order: 2; }
  .searchwrap { order: 3; flex-basis: 100%; max-width: none; }
  .brand-txt { display: inline; }

  /* Law 10: no controls in the top right. It is the least reachable point on a
     phone and reaching it needs a grip shift, which is when phones get dropped
     in clinical areas. The stamp stays — it is read, never tapped — and the
     theme and settings controls move to the tab bar in the thumb zone. */
  .hdr-right .iconbtn { display: none; }
  .tabs .tab-more { display: flex; }
  .sec-hdr { align-items: flex-start; }
  .sec-act { margin-left: 0; flex-basis: 100%; }
  /* Single column, no horizontal scroll, without exception. The number leads
     its own line so a long label can never crowd or clip it. */
  .row { grid-template-columns: 1fr; gap: var(--s-1); }
  .row-n { text-align: left; min-width: 0; }
  .row-right { flex-direction: row; align-items: center;
               justify-content: flex-start; gap: var(--s-3); }
  .row-desc { -webkit-line-clamp: 3; }
  /* 56px primary targets: nitrile gloves and wet hands degrade touch accuracy.
     The 44px floor still applies to everything secondary. */
  .btn { min-height: 56px; }
  .btn-sm { min-height: var(--tap); }
  .row-n { min-height: 56px; font-size: 1.5rem; }
  .mtx-cell { min-height: 56px; }
  .tab { min-height: 56px; }
  .iconbtn { width: var(--tap); height: var(--tap); }
}

/* ---------- print ----------
   Some wards cannot copy to the EMR at all. */

@media print {
  .hdr, .rail, .tabs, .toasts, .no-print { display: none !important; }
  .main { max-width: none; padding: 0; }
  .row { break-inside: avoid; }
  .prov-law { border-left: 3px solid #000; }
}

/* --- AI commentary: the correction route out of a block ------------------
   The tag already says the text is unreviewed. This is the other half: a way
   for the reader who knows better to send it back, which is the only mechanism
   by which any line here stops being unreviewed. It is a text button, not a
   filled one — it must read as available, never as the thing to do next. */
.prov-ai .ai-list { margin: 0 0 var(--s-2); padding-left: 1.2em; }
.ai-actions { margin-top: var(--s-2); }
.linkbtn {
  font: inherit;
  font-size: var(--size-label);
  color: var(--ink-muted);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  padding: 0 0 1px;
  cursor: pointer;
  min-height: auto;
}
.linkbtn:hover { color: var(--ink); border-bottom-color: var(--ink); }
.linkbtn:focus-visible { outline: var(--focus); outline-offset: 3px; }

/* --- desktop quick-copy strip -------------------------------------------
   The mirror of .tabs: that bar is phone-only, this one is desktop-only, and
   the breakpoint is the same 1024px so the two can never both be present.
   Fixed chrome ruled off from the page, not a floating card — law 4 forbids
   the second, and the tab bar already established the first. */
.palette { display: none; }

@media (min-width: 1025px) {
  .palette[hidden] { display: none; }
  .palette {
    display: block; position: fixed; bottom: 0; left: 0; right: 0; z-index: 70;
    background: var(--paper); border-top: var(--hair-strong);
  }
  .pal-in {
    display: flex; align-items: center; gap: var(--s-3);
    max-width: 1280px; margin: 0 auto;
    padding: var(--s-2) var(--s-4);
  }
  .pal-cap, .pal-hint {
    font-size: var(--size-label); color: var(--ink-faint);
    letter-spacing: var(--track-label); text-transform: uppercase; white-space: nowrap;
  }
  .pal-hint { margin-left: auto; }
  .pal-list { display: flex; gap: var(--s-2); overflow-x: auto; flex: 1; }
  .pal-btn {
    display: flex; align-items: baseline; gap: var(--s-2);
    background: none; border: var(--hair); border-radius: var(--radius);
    padding: var(--s-1) var(--s-3); cursor: pointer; white-space: nowrap;
    color: var(--ink); font: inherit; min-height: 34px;
  }
  .pal-btn:hover { background: var(--paper-sunk); border-color: var(--rule-strong); }
  .pal-btn:focus-visible { outline: var(--focus); outline-offset: 2px; }
  .pal-n { font-family: var(--font-num); font-weight: 700; font-size: var(--size-body); }
  .pal-l { font-size: var(--size-label); color: var(--ink-muted); }

  /* The strip is fixed, so the page has to stop above it. The height is
     published by palette.js from a real measurement; the 0px fallback is what
     applies when the strip is empty and therefore absent. */
  body { padding-bottom: var(--pal-h, 0px); }
}

/* --- a newer schedule is ready -------------------------------------------
   Ruled into the top of the view, not floated over it. It is information, not
   an alarm: a new schedule is expected monthly, so this must not use a signal
   colour it would then wear permanently. */
.update-bar {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  border: var(--hair-strong); border-radius: var(--radius);
  background: var(--paper-sunk);
  padding: var(--s-2) var(--s-3); margin-bottom: var(--s-4);
  font-size: var(--size-dense);
}

/* The commentary lede. The disclosure marker is the only affordance; the lede
   itself must read as the sentence it is, not as a link. */
.ai-more > summary { cursor: pointer; }
.ai-more > summary::marker { color: var(--ink-faint); }
.ai-more > summary:focus-visible { outline: var(--focus); outline-offset: 2px; }
.ai-more > p, .ai-more > ul { margin-top: var(--s-2); }

/* The manual-copy fallback. Monospaced because it is a form to be read back,
   and full width because wrapping a report makes it harder to check. */
.ai-report {
  display: block; width: 100%; margin-top: var(--s-2);
  font-family: var(--font-num); font-size: var(--size-label);
  color: var(--ink); background: var(--paper-sunk);
  border: var(--hair); border-radius: var(--radius);
  padding: var(--s-2); resize: vertical;
}

/* --- link surfaces vs links in prose --------------------------------------
   `a` is underlined globally, which is right for a link inside a sentence and
   wrong for a link that IS a card. Every pathway card was rendering its whole
   title and description underlined, which reads as broken rather than as a
   target: the card's own border and hover already say it is clickable. */
a.card, a.flow-card, a.row, a.tile { text-decoration: none; }
a.card:hover .flow-title, a.flow-card:hover .flow-title {
  text-decoration: underline; text-underline-offset: 2px;
}

/* The open target fills its column, so the row has no dead vertical band when
   the fee and chips on the right make the row taller than the label. */
.row-open { align-self: stretch; }

/* --- a bare number that copies, with a quiet way into the descriptor -------
   Shared by the skin grid, the attendance grid and the desktop palette, so a
   GP meets one object with one behaviour in all three. The corner control stays
   quiet until the cell is hovered or something inside it has focus, so a grid
   still reads as a grid of numbers rather than a grid of buttons — but it is
   never hidden from the keyboard, because revealing it only on hover would hide
   it from anyone tabbing. */
.numcell { position: relative; display: block; }
.numcell.is-missing { opacity: .55; }
.numcell > .numcell-copy { width: 100%; }

/* Always visible, not hover-revealed.

   It was gated on :hover, on the reasoning that a grid should read as a grid of
   numbers rather than a grid of buttons. That was wrong in the way that matters:
   someone looking at the attendance grid concluded the feature had not been
   built, because on a still page there is nothing to see. A control that is
   only discoverable by chance is not quiet, it is missing.

   So it sits there at the faintest ink in the palette and darkens on hover. In
   a 132x44 cell a 20px mark in the corner is still well clear of the number. */
.numcell-open {
  position: absolute; top: 2px; right: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: var(--radius);
  color: var(--ink-faint); text-decoration: none;
}
.numcell:hover .numcell-open { color: var(--ink-muted); }
.numcell-open:hover { color: var(--ink); background: var(--paper-sunk); }
.numcell-open:focus-visible { outline: var(--focus); outline-offset: 1px; color: var(--ink); }

/* The control is an overlay, so any cell whose content runs the full width has
   to leave room for it. Two do: the palette's truncated label, and the level
   ladder's stacked label/number/time. Both were running under the icon. */
.numcell > .pal-btn { padding-right: 26px; }
.numcell > .ladder-tile { padding-right: 28px; }

/* --- secondary filters ---------------------------------------------------- */
.sk-more > summary { cursor: pointer; font-size: var(--size-dense); font-weight: 700; }
.sk-more > summary::marker { color: var(--ink-faint); }
.sk-more > .sk-filters { margin-top: var(--s-3); }

/* Markers sit inside the descriptor block, ruled off from the legislated text
   so there is no chance of reading the gloss as part of the law. */
.marker-note {
  margin-top: var(--s-3); padding-top: var(--s-2);
  border-top: var(--hair);
}
.marker-note p { margin: var(--s-1) 0 0; }

/* --- the correction form --------------------------------------------------
   Inside the commentary block it corrects, so there is never any doubt about
   which sentence is being disputed. Native controls, tokens only — the design
   system carries no form styling because Settings was the only screen with
   any, and this is the second. */
.corr { margin-top: var(--s-2); }
.corr-field { margin-bottom: var(--s-3); }
.corr-field label { display: block; margin-bottom: var(--s-1); }
.corr-field p { margin: 0 0 var(--s-1); }
.corr-in {
  display: block; width: 100%; font: inherit; font-size: var(--size-dense);
  color: var(--ink); background: var(--paper);
  border: var(--hair-strong); border-radius: var(--radius);
  padding: var(--s-2); resize: vertical;
}
.corr-in:focus-visible { outline: var(--focus); outline-offset: 1px; }

/* The level ladder tiles are wide, so the wrapper must not collapse them. */
.numcell:has(> .ladder-tile) { display: inline-block; }
.ladder-tile {
  flex-direction: column; align-items: flex-start;
  height: auto; padding: 9px 28px 9px 13px; gap: 1px; min-width: 104px;
}

/* An item number inside note prose. Underlined because it IS a link inside a
   sentence — the one place the global underline rule is right. Kept in ink so
   a paragraph of guidance does not turn into a field of blue. */
.itemref {
  font-family: var(--font-num);
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.itemref:hover { text-decoration-thickness: 2px; background: var(--paper-sunk); }
.itemref:focus-visible { outline: var(--focus); outline-offset: 2px; }
