﻿/* Phone-first records surface, on paper. Deliberately small — this client shares nothing with the
   manager console's design system.

   COLOUR RULE: every colour in this sheet resolves through a custom property declared once below.
   There is ONE palette — the app is pinned to a single light theme (HQU-280) — so a colour literal
   in a rule outside the palette block is a value that can never be re-pointed. Don't add one. */

/* ── Webfonts ──────────────────────────────────────────────────────────────
   Public Sans (body) and Archivo (display), self-hosted beside this sheet at
   _content/Hque.Aspire.Records.UI/fonts/. Declared HERE rather than left to the
   host page because this RCL is rendered by two apps: the standalone records
   PWA, which loads nothing but this stylesheet, and the portal, which has its
   own identical copy. Same family names, so in the portal the browser matches
   one @font-face and downloads one file — the duplicate declaration costs
   bytes on disk, not on the wire.

   Both are VARIABLE fonts: one file per family per subset covers 400–700. */
@font-face {
    font-family: 'Archivo';
    font-style: normal; font-weight: 400 700; font-display: swap;
    src: url('../fonts/archivo-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Archivo';
    font-style: normal; font-weight: 400 700; font-display: swap;
    src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Public Sans';
    font-style: normal; font-weight: 400 700; font-display: swap;
    src: url('../fonts/publicsans-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Public Sans';
    font-style: normal; font-weight: 400 700; font-display: swap;
    src: url('../fonts/publicsans-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* Surfaces */
    --rec-bg: #f1f4f1;
    --rec-surface: #fff;
    --rec-raised: #f7f9f7;          /* run rows, pick entries, tiles */
    --rec-sunken: #e9edea;          /* statements, notes */
    --rec-hover: #e9edea;
    --rec-row-hover: #e9edea;
    --rec-shadow: rgba(22, 33, 29, 0.10);

    /* Ink */
    --rec-text: #16211d;
    --rec-body: #33443c;
    --rec-muted: #47574f;
    --rec-faint: #627268;

    /* Lines */
    --rec-border: #d3dad5;
    --rec-border-soft: #e4e9e5;
    --rec-edge: #bcc7c0;            /* the 4px left edge on a card row */

    /* Accents */
    --rec-accent: #16211d;
    --rec-accent-hover: #0b120f;    /* the ink primary button, pressed */
    --rec-accent-soft: #e5eae7;
    --rec-accent-dim: #e4e9e5;
    --rec-link: #2563eb;
    --rec-danger: #a31212;
    --rec-danger-edge: #a31212;
    --rec-danger-surface: #fbe4e2;
    --rec-danger-border: #eec3bf;

    /* Run-status pills (RecordRunTone → tone-*) — the RECORD-lifecycle axis.
       Earth-and-safety, and deliberately NOT blue: blue belongs to the screen-mode
       axis below, and a glance at the colour has to say which of the two questions
       you are looking at the answer to (HQU-296). "Active" was #1d4ed8 blue, which
       put a lifecycle state in mode's colour; it is now the mockup's amber. */
    --rec-tone-neutral-bg: #e5eae7;  --rec-tone-neutral-fg: #55665f;
    --rec-tone-active-bg: #fce9dd;   --rec-tone-active-fg: #a93b08;
    --rec-tone-positive-bg: #dcebe1; --rec-tone-positive-fg: #12603b;
    --rec-tone-warning-bg: #fbe4e2;  --rec-tone-warning-fg: #a31212;
    --rec-tone-muted-bg: #e9edea;    --rec-tone-muted-fg: #627268;

    /* Verdict banner (StatusTone → tone-*) */
    --rec-v-success-bg: #dcebe1; --rec-v-success-bd: #bcd6c6; --rec-v-success-fg: #12603b;
    --rec-v-danger-bg: #fbe4e2;  --rec-v-danger-bd: #eec3bf;  --rec-v-danger-fg: #a31212;
    --rec-v-warning-bg: #fff6de; --rec-v-warning-bd: #e8d08a; --rec-v-warning-fg: #6b4a00;
    --rec-v-neutral-bg: #f1f4f1; --rec-v-neutral-bd: #e4e9e5; --rec-v-neutral-fg: #47574f;

    /* Status dots (StatusTone → tone-*) — also the record axis, so Info moves off
       blue for the same reason the Active pill did. Teal, not slate: it still has
       to separate from the neutral dot beside it. */
    --rec-dot-success: #12603b;
    --rec-dot-danger: #a31212;
    --rec-dot-warning: #a93b08;
    --rec-dot-info: #0e5a66;
    --rec-dot-neutral: #627268;

    /* ── Screen mode — the SECOND axis (HQU-296) ────────────────────────────────
       What YOU are doing: View → Edit → Saving → Saved → View. Ink blue, and no
       status, tone, pill, dot or verdict may borrow it — that exclusivity is the
       whole mechanism, because it lets the colour alone report the mode without
       the reader hunting for a label.

       Not to be confused with --rec-accent/--rec-link, which are chrome and links
       rather than either axis. Those stay where they are; the wider repalette of
       this surface against the shell mockups belongs to the parent epic. */
    --rec-mode: #27348f;             /* Edit — band, save-bar rule, primary button */
    --rec-mode-strong: #1b2668;      /* Saving — one step deeper, so the step reads */
    --rec-mode-soft: #e5e8f6;        /* tinted field backgrounds while editing */
    --rec-mode-on: #fff;
    /* Saved resolves green rather than ink blue. It is the one deliberate exception
       and it comes from the spec screen: a confirmation that reads as anything but
       "done" gets misread, and the band is gone moments later either way. */
    --rec-mode-saved: #12603b;
    --rec-mode-saved-soft: #dcebe1;

    /* Type. Same pairing as the portal: Public Sans for running text,
       Archivo for the few pieces of display type. The fallbacks matter more
       here than in the portal — this surface is used on a phone in the field,
       where the font may not have arrived yet. */
    --rec-font-body: 'Public Sans', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --rec-font-display: 'Archivo', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

    /* Minimum tap target. Declared here because the PWA loads no other stylesheet; in the portal the
       identical --tap-min already exists and the two agree. */
    --rec-tap: 46px;
}

html, body {
    margin: 0;
    font-family: var(--rec-font-body);
    background: var(--rec-bg);
    min-height: 100vh;
}

/* The PWA shell. COLUMN, not row: a screen is free to emit more than one top-level
   element (the run wizard emits its stepper AND the step's card) and they must STACK.
   As a row they became sibling flex items sitting side by side, which squeezed the
   stepper into a narrow column beside the run card — the Portal, whose own layout
   wraps pages in a normal block, never showed the fault. */
.record-shell {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    min-height: 100vh;
    padding: 24px 16px;
}

/* Focus mode: the capture screen IS the shell. Drop the centring gutter and the padding so
   the sticky header and foot sit on the viewport edges, exactly as they do on the portal. */
.record-shell--focus {
    align-items: stretch;
    padding: 0;
}

/* ── The tile, and the page ─────────────────────────────────────────────────
   .record-card is the centered single-message TILE, and now nothing else: the name/PIN sign-in, the
   session splash, enrolment, device management, the one-time PIN reveal — a message that owns an
   otherwise empty screen, in the PWA only.

   It is deliberately NOT what a screen renders on. A page-sized rounded white slab behind the whole
   screen is a shape the shell mockups do not have (mockups/venuehq-shell run-detail-view.html): a
   screen there is a head, then sections, and each SECTION carries the surface. HQU-428 moved four
   screens onto that paper; the rest followed, so no page-sized card is left on this surface in
   either host. The rules below give the screens on paper the box the page card used to provide:
   .record-page .record-state for the non-list outcomes, .record-page .record-panel for the titled
   sections that hang off a body. */

.record-card {
    width: 100%;
    max-width: 420px;
    background: var(--rec-surface);
    border-radius: 16px;
    box-shadow: 0 2px 16px var(--rec-shadow);
    padding: 32px 24px;
    margin-top: 8vh;
    text-align: center;
}

/* The screen on paper. Same column as .record-screen, and for the same reason: the portal host
   widened .rec-page to --page-max (1440px) so records share the authoring surface's working area,
   while the PWA's .record-shell is a centred flex column that caps nothing. So the cap lives on the
   screen and follows the host: --page-max in the portal, the 940px fallback where that token isn't
   defined (the Staff PWA), which on a phone never bites anyway.

   The two names are now the same thing wearing two words — .record-page is what a screen wraps
   itself in, .record-screen what RecordScreenHead's own screens carried — and collapsing them is a
   tidy-up for whoever touches this next, not a change of shape. */
.record-page {
    width: 100%;
    max-width: var(--page-max, 940px);
    text-align: left;
}

/* The TILE's heading, and the headline of a state block — centred, because both of those are
   centred things. A SCREEN's title is not one of them: it is .record-head-title, left-aligned on
   paper, and RecordScreenHead is the only thing that draws it. */
.record-title {
    font-family: var(--rec-font-display);
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.012em;
    margin: 8px 0 12px;
    text-align: center;
    color: var(--rec-text);
}

/* The icon-only twin of .record-btn: same border, same surface, same tap height, square rather
   than label-wide. A back affordance is a CONTROL like every other one on this surface, so it wears
   the surface's control shape — a bare glyph at Size.Small read as a stray icon beside a page title
   rather than as the button it is. Worn by RecordScreenHead's optional back button, which is the
   surface's one remaining back affordance now that every screen is on paper. */
.record-icon-btn.mud-icon-button {
    width: var(--rec-tap);
    height: var(--rec-tap);
    padding: 0;
    border: 1px solid var(--rec-border);
    border-radius: 6px;
    background: var(--rec-surface);
    color: var(--rec-text);
}

.record-icon-btn.mud-icon-button:hover { background: var(--rec-hover); }

/* Filters that outlive the body's loading + error states. */
.record-page-toolbar {
    margin-top: 4px;
    margin-bottom: 8px;
}

/* Loading / error / empty / not-found — every non-list outcome, centered in the card. */
.record-state {
    text-align: center;
    padding: 16px 4px 8px;
}

.record-muted {
    color: var(--rec-muted);
}

.record-hero-icon {
    font-size: 56px !important;
    width: 56px;
    height: 56px;
    color: var(--rec-muted);
}

/* One-time generated-PIN reveal on the enrolment screen. */
.record-pin-reveal {
    margin: 12px auto 16px;
    font-size: 2.6rem;
    font-weight: 700;
    letter-spacing: 0.3em;
    font-variant-numeric: tabular-nums;
    color: var(--rec-accent);
}

/* On-device enrolment at the empty-device gate. Every control is at least the shared
   phone tap target; the camera handoff is prose, not a competing action. */
.record-enrol-entry {
    margin-top: 20px;
    text-align: left;
}

.record-enrol-action.mud-button-root {
    min-height: var(--rec-tap);
}

.record-enrol-camera {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 20px;
    padding: 14px;
    border-radius: 10px;
    background: var(--rec-sunken);
    color: var(--rec-body);
    font-size: 0.88rem;
    line-height: 1.5;
    text-align: left;
}

.record-enrol-camera .mud-icon-root {
    flex: none;
    margin-top: 1px;
}

/* Tile grid: tap your name, then enter your PIN. */
.record-tile-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    margin-top: 8px;
}

.record-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 18px 8px;
    border: 1px solid var(--rec-border);
    border-radius: 12px;
    background: var(--rec-raised);
    font: inherit;
    font-weight: 600;
    color: var(--rec-text);
    cursor: pointer;
}

.record-tile:hover {
    background: var(--rec-hover);
    border-color: var(--rec-edge);
}

.record-tile .mud-icon-root {
    font-size: 34px;
    color: var(--rec-muted);
}

/* Authenticated chrome: the signed-in top bar (name + sign-out). Rendered only for a
   signed-in principal — the anonymous tile screen has no chrome. */
.record-topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px 8px 16px;
    background: var(--rec-surface);
    border-bottom: 1px solid var(--rec-border);
}

/* A procedure removes every navigation escape, but not its location context. */
.record-topbar--context {
    justify-content: flex-start;
    min-height: 48px;
}

/* Left cluster: the always-available Home affordance, then who's signed in. */
.record-topbar-left {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.record-topbar-home { color: var(--rec-muted); }
.record-topbar-home:hover { color: var(--rec-accent); }

.record-topbar-name {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    color: var(--rec-text);
}

/* ── Worklist count pill ──────────────────────────────────────────────────────
   Rides beside a landing-page button's label to show there is work waiting.
   Rendered ONLY for a non-zero count — an empty worklist shows no pill at all. */
.record-count-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    margin-left: 8px;
    border-radius: 999px;
    background: var(--rec-accent);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* Anything overdue turns the pill urgent — same count, louder. */
.record-count-pill.is-overdue { background: var(--rec-v-danger-fg); }

/* ── "Add to home screen" (InstallAppPrompt) ──────────────────────────────────
   Sits under the setup-path content on the enrol and tile screens, ruled off so it
   reads as an aside rather than a step. Absent entirely once the app is installed. */
.record-install {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--rec-border);
}

.record-install-steps {
    margin: 12px 0 0;
    padding-left: 22px;
    text-align: left;
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--rec-body);
}

.record-install-note {
    margin: 8px 0 0;
    font-size: 0.8rem;
    color: var(--rec-muted);
}

/* Manage-device row: name + remove control. */
.record-manage-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}

/* ── Worklist run rows (Scheduled + Requested) ────────────────────────────
   ONE card of rows, per mockups/venuehq-shell runs.html — not a stack of cards. The list owns the
   border box; a run owns only its content and, past due, its left edge. The child selector rather
   than .record-run + .record-run because Scheduled wraps each run in .record-run-item to carry the
   decline editor below it, and both hosts' lists have to divide the same way. */

.record-run-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--rec-border);
    border-radius: 10px;
    overflow: hidden;
    background: var(--rec-surface);
}

.record-run-list > * + * {
    border-top: 1px solid var(--rec-border-soft);
}

.record-run {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    min-height: 68px;
    padding: 12px 16px;
    /* Reserved rather than drawn: a 4px edge on every row would be noise, but a row that gains one
       when it falls overdue would also shift its text 4px sideways. */
    border-left: 4px solid transparent;
    background: var(--rec-surface);
}

/* Past-due runs get a warm edge so the list scans at a glance. */
.record-run.is-overdue {
    border-left-color: var(--rec-danger-edge);
    background: var(--rec-danger-surface);
}

/* Due soon is deliberately distinct from overdue: a calm accent, never the danger surface. */
.record-run.is-due-soon {
    border-left-color: var(--rec-tone-active-fg);
}

.record-run-body {
    min-width: 0; /* let long names ellipsize instead of pushing the meta column */
    flex: 1 1 auto;
}

/* The body is a tap target (opens a run of this procedure, carrying the instance ref). Reset the
   <button> chrome so it reads as the card body, not a button; subtle hover cue on the title. */
.record-run-open {
    appearance: none;
    border: none;
    background: none;
    margin: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    display: block;
    width: 100%;
}
.record-run-open:hover .record-run-procedure {
    text-decoration: underline;
}

.record-run-procedure {
    font-weight: 600;
    color: var(--rec-text);
    line-height: 1.3;
}

.record-run-subjects {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

.record-run-subject {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--rec-hover);
    color: var(--rec-body);
    font-size: 0.8rem;
    font-weight: 500;
}

.record-run-subject.is-empty {
    background: var(--rec-sunken);
    color: var(--rec-body);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    letter-spacing: 0.02em;
}

.record-run-context {
    margin-top: 7px;
    font-size: 0.78rem;
    color: var(--rec-muted);
}

/* Requested runs only: who asked + their note. Both sit in the body column so the note
   wraps to the body width rather than blowing out the card. */
.record-run-requester {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 8px;
    font-size: 0.8rem;
    color: var(--rec-muted);
}

.record-run-requester-icon {
    font-size: 16px !important;
    width: 16px;
    height: 16px;
}

.record-run-note {
    margin-top: 6px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--rec-sunken);
    color: var(--rec-body);
    font-size: 0.82rem;
    line-height: 1.4;
    /* Unknown length, user-authored: preserve the author's newlines, wrap, and break
       even an unbroken string so a long note never overflows the card horizontally. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* One line, not a stacked column: on a card of rows the meta reads across the end of its row the way
   the mockup's pill does, and a stack of three made every run three times taller than it needed to
   be. Wraps rather than squeezing when the row is narrow. */
.record-run-meta {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 4px 10px;
    flex: 0 0 auto;
    text-align: right;
}

.record-run-status {
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Status tones — semantic, mapped from RecordRunPresentation.RecordRunTone via RecordTone.Class. */
.record-run-status.tone-neutral  { background: var(--rec-tone-neutral-bg);  color: var(--rec-tone-neutral-fg); }
.record-run-status.tone-active   { background: var(--rec-tone-active-bg);   color: var(--rec-tone-active-fg); }
.record-run-status.tone-positive { background: var(--rec-tone-positive-bg); color: var(--rec-tone-positive-fg); }
.record-run-status.tone-warning  { background: var(--rec-tone-warning-bg);  color: var(--rec-tone-warning-fg); }
.record-run-status.tone-muted    { background: var(--rec-tone-muted-bg);    color: var(--rec-tone-muted-fg); }

/* A phone has no room for the meta beside the title: on one line it squeezes the run's NAME down to
   two words to keep a date whole. Stack it back into a column there — the row grows taller, which is
   the cheaper of the two costs. Phone layouts proper are HQU-299. */
@media (max-width: 600px) {
    .record-run {
        align-items: flex-start;
        gap: 10px;
    }
    .record-run-meta {
        flex-direction: column;
        align-items: flex-end;
        gap: 6px;
    }
}

/* An overdue row is painted in the danger surface, which is ALSO tone-warning's pill background — so
   an "Overdue" pill on an overdue row disappears into it and reads as loose red text beside its
   neighbours' pills. Lift it back onto the card's own surface. */
.record-run.is-overdue .record-run-status.tone-warning {
    background: var(--rec-surface);
}

.record-run-due {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 0.78rem;
    color: var(--rec-muted);
    white-space: nowrap;
}

.record-run-due.is-overdue {
    color: var(--rec-danger);
    font-weight: 600;
}

.record-run-due.is-due-soon {
    color: var(--rec-tone-active-fg);
    font-weight: 600;
}

.record-run-due-icon {
    font-size: 15px !important;
    width: 15px;
    height: 15px;
}

/* ── Won't Complete: a wrapper holds the run row + its optional inline reason editor. ──
   The wrapper is the list child, so the row and its editor divide from the NEXT run together
   rather than the editor reading as a row of its own. */
.record-run-item {
    display: flex;
    flex-direction: column;
}

/* The small top-right decline affordance. Muted by default so a worklist of runs
   isn't a wall of red; reddens on hover to signal the destructive intent. */
.record-run-decline-btn,
.record-run-decline-btn .mud-icon-root {
    color: var(--rec-faint) !important;
}
.record-run-decline-btn:hover,
.record-run-decline-btn:hover .mud-icon-root {
    color: var(--rec-danger) !important;
}

.record-run-decline-panel {
    /* Inset to the row's text column (16px padding past the 4px reserved edge), because the row
       itself no longer carries the padding a card used to give it. */
    margin: 0 16px 14px 20px;
    border: 1px solid var(--rec-danger-border);
    border-radius: 10px;
    background: var(--rec-danger-surface);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.record-run-decline-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--rec-danger);
}

.record-run-decline-error {
    font-size: 0.8rem;
    color: var(--rec-danger);
}

.record-run-decline-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* ── Procedure picker (the catalogue screen + the wizard's step 1) ────────── */

/* One card of rows, per mockups/venuehq-shell procedures.html — the same shape the worklists take,
   because a list of procedures and a list of runs are read the same way. The list owns the border
   box; an entry owns only its content. Not NavRow: a procedure's description is user-authored prose
   that wraps to whatever length it is, where a NavRow's supporting line is a single truncating line. */
.record-pick-list {
    display: flex;
    flex-direction: column;
    margin-top: 12px;
    border: 1px solid var(--rec-border);
    border-radius: 10px;
    overflow: hidden;
    background: var(--rec-surface);
}

/* Behaviour groups in the catalogue picker (Procedures / Incidents, HQU-461): the group heading
   is InfoList's own (Boxed=false), so this only spaces one group's list off the previous group. */
.record-pick-group + .record-pick-group {
    margin-top: 20px;
}

.record-pick-entry {
    display: block;
    width: 100%;
    text-align: left;
    font: inherit;
    cursor: pointer;
    min-height: 68px;
    padding: 12px 16px;
    border: 0;
    background: var(--rec-surface);
}

.record-pick-entry + .record-pick-entry {
    border-top: 1px solid var(--rec-border-soft);
}

.record-pick-entry:hover {
    background: var(--rec-row-hover);
}

.record-pick-entry.is-unavailable,
.record-pick-entry.is-unavailable:hover {
    cursor: not-allowed;
    background: var(--rec-sunken);
}

.record-pick-entry.is-unavailable .record-pick-name,
.record-pick-entry.is-unavailable .record-pick-description {
    color: var(--rec-muted);
}

.record-pick-availability {
    margin-top: 8px;
    font-size: 0.8rem;
    line-height: 1.4;
    font-weight: 600;
    color: var(--rec-body);
    overflow-wrap: anywhere;
}

.record-pick-name {
    font-weight: 600;
    color: var(--rec-text);
    line-height: 1.3;
}

.record-pick-description {
    margin-top: 6px;
    font-size: 0.85rem;
    line-height: 1.4;
    color: var(--rec-body);
    /* User-authored, unknown length: wrap and break so a long description can't overflow. */
    overflow-wrap: anywhere;
}

.record-pick-pager {
    display: flex;
    justify-content: center;
    margin-top: 16px;
}

/* ── Run form + item viewer: fields, sections, statements ─────────────────── */

.record-run-description {
    margin: 4px 0 12px;
    font-size: 0.9rem;
    line-height: 1.45;
    color: var(--rec-body);
    overflow-wrap: anywhere; /* user-authored, unknown length */
}

/* How many steps this is, read BEFORE starting. It sets the expectation the focus screen's
   progress bar then keeps, which is the point of showing it here rather than only in there. */
.record-run-steps-note {
    margin: 10px 0 0;
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--rec-faint);
}

/* ── The run's opening screen: purpose and guardrails (read-only) ─────────── */

/* Goal / Applies to / Done when ride the standard read rows; the block only needs to sit
   clear of the card header the way the description above it does. */
.record-purpose {
    margin-top: 4px;
}

.record-purpose-block {
    margin-top: 18px;
}

/* One authored line per item. No bullets: these are sentences an operator wrote, not a
   checklist — nothing here is tickable, and it must not look like it is. */
.record-purpose-lines {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* HQU-526: the lines sit plainly on the group's white card now — no tinted pill, no accent
   edge. The card and its heading carry the block; the surface behind the lines is white to
   match the "Subjects" / "Description" cards on the same screen. */
.record-purpose-lines li {
    color: var(--rec-text);
    font-size: 0.92rem;
    line-height: 1.45;
    overflow-wrap: anywhere; /* user-authored, unknown length */
}

/* The run form's field list. The rows and the group are <InfoRow>/<InfoList> now (see the
   --row-* block at the foot of this sheet), so all that is left here is the offset from the
   block above it. */
.record-form-fields {
    margin-top: 16px;
}

/* The read viewer's value blocks — one per authored step (see RecordItemScreen). Each is an
   <InfoList> and carries its own heading and row separators; this only spaces them, the way the
   mockup's stacked <section>s do. */
.record-value-groups {
    display: grid;
    gap: 20px;
    margin-top: 16px;
}

/* Step instruction/description text under a field's label. */
.record-form-instr {
    font-size: 0.82rem;
    line-height: 1.4;
    color: var(--rec-muted);
    overflow-wrap: anywhere;
}

/* Statement: render-only audit text, no input. */
.record-form-statement {
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--rec-sunken);
    border-left: 3px solid var(--rec-edge);
}

.record-form-statement-label {
    font-weight: 600;
    color: var(--rec-text);
    line-height: 1.35;
}

/* Disabled-with-note for deferred field types (FileUpload / RelatedEntity). */
.record-form-unsupported {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--rec-sunken);
    color: var(--rec-faint);
    font-size: 0.85rem;
    font-style: italic;
}

.record-form-unsupported .mud-icon-root {
    font-size: 18px;
}

/* YesNo radios sit in a row on a phone width. */
.record-form-yesno {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 4px;
}

/* ── "Unknown" wants a reason ─────────────────────────────────────────────────
   The box only exists while Unknown is chosen, so it is drawn as a well that hangs
   off that answer rather than as a field that appeared from nowhere: a tinted panel
   with an ink edge on the left, a real label above it, and a white input inside so
   the part you can type in still reads as the part you can type in.

   Quiet, not amber. Same reasoning as .rec-focus-required — "unknown" is a legitimate
   answer, not a mistake, and nothing has gone wrong on this screen yet. The only
   colour in here is the Required pill, and that leaves as soon as it is satisfied. */
.record-form-why {
    margin-top: 10px;
    padding: 12px 14px 14px;
    border: 1px solid var(--rec-border-soft);
    border-left: 3px solid var(--rec-edge);
    border-radius: 8px;
    background: var(--rec-raised);
    animation: record-why-in 140ms ease-out;
}

.record-form-why-label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 600;
    color: var(--rec-body);
}

/* Rendered ONLY while the box is empty (see RecordRunScreen), so it is a live piece of
   state, not decoration: it disappearing is the acknowledgement that the rule is met. */
.record-form-why-req {
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--rec-tone-warning-bg);
    color: var(--rec-tone-warning-fg);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

/* The input is the lit surface inside the well — MudBlazor's outlined variant is
   transparent, which on a tinted panel reads as a disabled field. */
.record-form-why .mud-input.mud-input-outlined {
    border-radius: 6px;
    background: var(--rec-surface);
}

.record-form-why .mud-input-control {
    min-height: 0;
}

@keyframes record-why-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .record-form-why { animation: none; }
}

/* DateTime field: the date and time pickers sit side by side, each taking half the row (HQU-257). */
.record-form-datetime-row {
    display: flex;
    gap: 8px;
}

.record-form-datetime-row > * {
    flex: 1 1 0;
    min-width: 0;
}

/* Asset autocomplete option: name over a muted module line. */
.record-asset-option {
    display: flex;
    flex-direction: column;
}

.record-asset-name {
    font-weight: 500;
    color: var(--rec-text);
}

.record-asset-module {
    font-size: 0.76rem;
    color: var(--rec-faint);
}

/* ── Single-item read-only viewer ─────────────────────────────────────────── */

/* The viewer's own meta row is gone — the identifier and the module moved into the page head's
   eyebrow (RecordScreenHead). The separator stays: the activity rows still use it. */
.record-item-sep { opacity: 0.5; }

/* Asset-first run launcher — sits between the verdict banner and the fields. */
.record-item-launch { margin: 4px 0 14px; }

/* The authoring exit, under the launcher. Pulled up tight against it (the launcher's own bottom
   margin is what separates the pair from the record below) and NOT full width: the launcher is the
   thumb target on this screen and a second full-bleed button beside it would read as a second one. */
.record-item-authoring { margin: -8px 0 14px; }

/* ── The closed record's immutability tag (HQU-297) ───────────────────────────
   A BLOCK, not the small .record-status-tag capsule, and that is the point: it
   occupies the slot an edit control would have taken on an open record, so it has
   to be big enough to be what the eye lands on there. Nothing sits beside it —
   there is no disabled edit button to explain, which is the whole design.

   Lifecycle family, so it borrows the same tone-* palette .record-status-tag uses
   (--rec-tag-*), one axis, one vocabulary. Never blue: blue is screen mode. */
.record-lock {
    margin: 4px 0 14px;
    padding: 14px 16px;
    border-radius: 10px;
    border: 1px solid currentColor;
}

.record-lock-state {
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
}

/* The dashed rule is load-bearing: it separates the state (what this record IS)
   from the attribution and the promise (why there is nothing to press). */
.record-lock-rule {
    height: 0;
    margin: 11px 0 9px;
    border-top: 1px dashed currentColor;
    opacity: 0.35;
}

.record-lock-line {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.85rem;
    line-height: 1.45;
    opacity: 0.92;
}

.record-lock.tone-neutral { background: var(--rec-tag-neutral-bg); color: var(--rec-tag-neutral-fg); }
.record-lock.tone-info    { background: var(--rec-tag-info-bg);    color: var(--rec-tag-info-fg); }
.record-lock.tone-warning { background: var(--rec-tag-warning-bg); color: var(--rec-tag-warning-fg); }
.record-lock.tone-success { background: var(--rec-tag-success-bg); color: var(--rec-tag-success-fg); }
.record-lock.tone-danger  { background: var(--rec-tag-danger-bg);  color: var(--rec-tag-danger-fg); }

/* ── The OPEN record's block (RecordInProgressPanel) ──────────────────────────
   The twin of .record-lock and deliberately built on it: same slot, same tone
   palette, same dashed rule between "what this record IS" and the detail under
   it. What differs is the only thing that should — a closed record has nothing
   to press, and an open one has the two things you can do about it.

   Side by side above ~560px, stacked below: on a phone the actions belong under
   the state they act on, and a 50/50 split there gives two buttons too narrow
   to carry their own labels.

   The row itself draws NOTHING — it is the mockup's .recordhead (mockups/venuehq-shell
   run-detail-view.html), a tinted tag beside a column of plain actions, not one tinted box around
   both. The tone belongs to the state, because it is what makes "In progress" read as a status;
   wrapping the buttons in it made the two exits look like part of the status rather than the
   answer to it. So the box lives on .record-open-state. */
.record-open {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 20px;
    margin: 4px 0 14px;
}

/* The tag: sized by its content, never stretched to half the row. */
.record-open-state {
    flex: 0 0 auto;
    min-width: 264px;
    padding: 14px 16px;
    border-radius: 10px;
    border: 1px solid currentColor;
}

@media (max-width: 559px) {
    .record-open { gap: 14px; }
    .record-open-state,
    .record-open-acts { flex-basis: 100%; min-width: 0; }
    .record-open-acts { max-width: none; }
}

.record-open-status {
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
}

.record-open-rule {
    height: 0;
    margin: 11px 0 9px;
    border-top: 1px dashed currentColor;
    opacity: 0.35;
}

.record-open-line {
    font-size: 0.85rem;
    line-height: 1.45;
    opacity: 0.92;
}

/* The actions take the rest of the row, and stack full-width once it runs out. */
/* A stacked pair of calls-to-action, not a banner: bounded so the two exits read
   as buttons beside the state tag rather than sprawling the full content column.
   The flex-basis floors the width so they never crowd the tag; the max-width caps
   it so "Continue this Procedure" doesn't stretch to 1100px. */
.record-open-acts {
    flex: 1 1 360px;
    min-width: 260px;
    max-width: 420px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
}

/* The stacked pair fills the column so its height tracks the state tag beside it,
   rather than floating short at the top with the tag towering over two small
   buttons (HQU-497). The column is already as tall as the tag (align-items:stretch
   on .record-open); flex:1 splits that height between the two buttons. */
.record-open-acts .mud-button-root {
    flex: 1 1 0;
    min-height: 0;
}

/* Cancelling is a real action, not a mistake — so it is a legible outlined
   button rather than a hidden one. It reads as danger, and it is second. */
.record-open-cancel.mud-button-outlined {
    border-color: var(--rec-danger);
    color: var(--rec-danger);
}

/* Tone sits on the row so currentColor resolves inside the tag; only the TAG paints it. */
.record-open.tone-neutral { color: var(--rec-tag-neutral-fg); }
.record-open.tone-info    { color: var(--rec-tag-info-fg); }
.record-open.tone-warning { color: var(--rec-tag-warning-fg); }
.record-open.tone-success { color: var(--rec-tag-success-fg); }
.record-open.tone-danger  { color: var(--rec-tag-danger-fg); }

.record-open.tone-neutral .record-open-state { background: var(--rec-tag-neutral-bg); }
.record-open.tone-info    .record-open-state { background: var(--rec-tag-info-bg); }
.record-open.tone-warning .record-open-state { background: var(--rec-tag-warning-bg); }
.record-open.tone-success .record-open-state { background: var(--rec-tag-success-bg); }
.record-open.tone-danger  .record-open-state { background: var(--rec-tag-danger-bg); }


/* Read-only field value (the staff twin of the Web ReadOnlyValue) — the content of an <InfoRow>'s
   value slot. Size, weight and colour come from the ROW it sits in (--row-read-*): restating them
   here is what let this renderer drift away from the label it belongs to. Only what the row cannot
   know stays — the wrap and the line height. */
.record-rov-value {
    line-height: 1.4;
    overflow-wrap: anywhere;
}

.record-rov-value a { color: var(--rec-link); text-decoration: underline; overflow-wrap: anywhere; }

/* Nothing recorded. Matches <InfoRow>'s own em-dash, because it IS the same statement. */
.record-rov-empty {
    font-weight: 400;
    color: var(--row-empty-fg, var(--rec-faint));
}

/* The mockup's .field-note — the Yes/No comment under its answer. It sits inside the value slot,
   so it has to say its own weight back down: the value above it is the thing being scanned. */
.record-rov-note {
    margin-top: 3px;
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.4;
    color: var(--rec-faint);
    overflow-wrap: anywhere;
}

/* Hash-free tamper verdict banner. Tone classes carry the colour. */
.record-verdict {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border-radius: 10px;
    border: 1px solid transparent;
    margin: 4px 0 14px;
}

/* The reassuring verdict rides at the FOOT of the item viewer, under the last panel — so it needs
   the gap above it that its top-slot twin gets below. */
.record-verdict-foot { margin-top: 18px; }
.record-verdict-foot .record-verdict { margin: 0; }

.record-verdict-text { display: flex; flex-direction: column; gap: 2px; }
.record-verdict-headline { font-weight: 600; line-height: 1.3; }
.record-verdict-sub { font-size: 0.85rem; line-height: 1.4; opacity: 0.9; }

.record-verdict.tone-success { background: var(--rec-v-success-bg); border-color: var(--rec-v-success-bd); color: var(--rec-v-success-fg); }
.record-verdict.tone-danger  { background: var(--rec-v-danger-bg);  border-color: var(--rec-v-danger-bd);  color: var(--rec-v-danger-fg); }
.record-verdict.tone-warning { background: var(--rec-v-warning-bg); border-color: var(--rec-v-warning-bd); color: var(--rec-v-warning-fg); }
.record-verdict.tone-neutral { background: var(--rec-v-neutral-bg); border-color: var(--rec-v-neutral-bd); color: var(--rec-v-neutral-fg); }

/* ── Panels: relations, activity, related assets, the wizard's tree ───────── */

.record-panel {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--rec-border-soft);
}

.record-panel-title {
    font-weight: 600;
    color: var(--rec-text);
    margin-bottom: 8px;
}

.record-panel-empty {
    font-size: 0.88rem;
    color: var(--rec-faint);
}

/* On paper the panel is a card of its own, because its rows are transparent: a relation row and an
   activity row draw nothing but their hover, and with the page card gone they would sit straight on
   the paper with nothing under them. The top rule above becomes the card's own edge — a rule AND a
   border is two lines saying one thing. Same shape the mockup's sections take
   (mockups/venuehq-shell run-detail-view.html: an <h2> over a .card). */
.record-page .record-panel {
    padding: 14px 16px 16px;
    background: var(--rec-surface);
    border: 1px solid var(--rec-border);
    border-radius: 10px;
}

/* ── Linked-item dropdown (RecordRelatedItemPicker) ────────────────────────────
   Its failure + truncation lines sit INSIDE a form field, so they stay small and
   inline — the full-height RecordAsyncView states belong to screens, not fields. */
.record-picker-error {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 0.88rem;
    color: var(--rec-v-danger-fg);
}

.record-picker-hint {
    margin-top: 4px;
    font-size: 0.78rem;
    color: var(--rec-faint);
}

/* Relation row — the navigate link is its own button; the tree's checkbox sits to its LEFT
   (the .record-rel-row flex leaves that slot) without disturbing the link. */
.record-rel-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.record-rel-open {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 6px;
    background: none;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
    min-width: 0;
}

.record-rel-open:hover { background: var(--rec-row-hover); }

.record-rel-icon { font-size: 1.1rem; color: var(--rec-muted); flex: none; }

.record-rel-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--rec-text);
}

.record-rel-kind {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--rec-faint);
    flex: none;
}

.record-activity-list { display: flex; flex-direction: column; gap: 2px; }

.record-activity-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 6px;
    background: none;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
    width: 100%;
}

.record-activity-row:hover { background: var(--rec-row-hover); }

.record-activity-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }

.record-activity-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; }

.record-activity-proc {
    font-weight: 500;
    color: var(--rec-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.record-activity-status { font-size: 0.78rem; color: var(--rec-muted); flex: none; }

.record-activity-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8rem;
    color: var(--rec-muted);
}

.record-activity-more {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    margin-top: 6px;
    padding: 8px;
    background: none;
    border: 1px solid var(--rec-border-soft);
    border-radius: 8px;
    cursor: pointer;
    color: var(--rec-link);
    font: inherit;
}

.record-activity-more:hover { background: var(--rec-row-hover); }

/* Status dot — 8px round, tone-coloured (shared by the activity list). */
.record-status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
    margin-top: 6px;
    background: var(--rec-dot-neutral);
}

.record-status-dot.tone-success { background: var(--rec-dot-success); }
.record-status-dot.tone-danger  { background: var(--rec-dot-danger); }
.record-status-dot.tone-warning { background: var(--rec-dot-warning); }
.record-status-dot.tone-info    { background: var(--rec-dot-info); }
.record-status-dot.tone-neutral { background: var(--rec-dot-neutral); }

/* ── Record Activity/comment feed (HQU-547) — the staff mirror of the console's FeedTimeline. The
   panel itself is the shared .record-panel card; these style the composer and the entry rows. ── */
.record-comment-box {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 8px 10px;
    background: var(--rec-surface);
    border: 1px solid var(--rec-border);
    border-radius: 10px;
    margin-bottom: 12px;
}

.record-comment-input {
    flex: 1;
    min-width: 0;
    border: none;
    background: none;
    resize: none;
    font: inherit;
    color: var(--rec-text);
    line-height: 1.45;
    max-height: 160px;
    outline: none;
}

.record-comment-input::placeholder { color: var(--rec-faint); }

/* The composer is a borderless textarea INSIDE .record-comment-box, so the visible box IS the
   container's border. The textarea already drops its own outline, but the portal's universal
   `*:focus-visible` (hque-overrides.css) still box-shadows the textarea itself on focus, drawing a
   SECOND, inset box within the container — the "double selected box" (HQU-574). Kill that inner
   ring and let the container carry the single focus affordance via :focus-within, the same way the
   authoring composer's own bordered textarea does. */
.record-comment-input:focus,
.record-comment-input:focus-visible {
    outline: none;
    box-shadow: none;
}

.record-comment-box:focus-within { border-color: var(--rec-accent); }

.record-comment-send {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 8px;
    background: var(--rec-text);
    color: #fff;
    cursor: pointer;
}

.record-comment-send:disabled { opacity: 0.6; cursor: default; }

/* HQU-683: the keyboard-shortcut hint under the composer, so it's clear how a comment is posted. */
.record-comment-hint {
    margin-top: 4px;
    font-size: var(--text-xs, 12px);
    color: var(--rec-faint);
}

.record-comment-hint kbd {
    font-family: inherit;
    font-size: 0.9em;
    padding: 0 4px;
    border: 1px solid var(--rec-border, var(--border-default));
    border-radius: 3px;
    background: var(--rec-subtle, var(--canvas-subtle));
    color: var(--rec-ink, var(--fg-muted));
}

.record-activity-feed-list { display: flex; flex-direction: column; gap: 4px; }

.record-activity-feed-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 6px;
}

.record-activity-feed-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }

.record-activity-feed-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; flex-wrap: wrap; }

.record-activity-feed-action { font-weight: 500; color: var(--rec-text); font-size: 0.9rem; }

.record-activity-feed-user { font-size: 0.8rem; color: var(--rec-muted); }

.record-activity-feed-comment {
    font-size: 0.9rem;
    color: var(--rec-body);
    line-height: 1.45;
    overflow-wrap: anywhere; /* user-authored, unknown length */
}

.record-activity-feed-time { font-size: 0.78rem; color: var(--rec-muted); }

/* ── QR scanner ───────────────────────────────────────────────────────────── */

.record-scan-viewport {
    position: relative;
    width: 100%;
    max-width: 420px;
    margin: 8px auto 0;
    aspect-ratio: 1 / 1;
    border-radius: 12px;
    overflow: hidden;
    background: #000;
}

.record-scan-viewport.is-hidden { display: none; }

.record-scan-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* A centred square reticle to aim the code into. Pointer-transparent overlay. */
.record-scan-reticle {
    position: absolute;
    inset: 18%;
    border: 3px solid rgba(255, 255, 255, 0.9);
    border-radius: 12px;
    box-shadow: 0 0 0 100vmax rgba(22, 33, 29, 0.28);
    pointer-events: none;
}

/* ── Focus mode: the record being filled in ───────────────────────────────────
   mockups/venuehq-shell/execute.html (.focus / .steps / .focus-*). The one state on
   this surface that is not a card on a page — it IS the page, and both hosts take
   their chrome away for it (RecordFocusState).

   Two fixed edges and a scrolling middle: the header says which record and how far
   through, the foot holds the only two moves, and the body is the single step. On a
   phone that means the primary action is always under the thumb no matter how long
   the step's instruction runs. */
.rec-focus {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    width: 100%;
    min-height: 100%;
    background: var(--rec-surface);
}

.rec-focus-top {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 24px;
    background: var(--rec-surface);
    border-bottom: 1px solid var(--rec-border);
}

/* The leave affordance. A <button> and not a link, because leaving has to pass through
   the screen's own handler for the unsaved-work guard to run. Reset hard: a UA button
   centres its text and brings its own font, neither of which belongs in a header row. */
.rec-focus-leave {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    min-height: var(--rec-tap);
    padding: 0 14px 0 10px;
    border: 1px solid var(--rec-border);
    border-radius: 6px;
    background: var(--rec-surface);
    color: var(--rec-text);
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}

.rec-focus-leave:hover {
    background: var(--rec-sunken);
}

.rec-focus-title {
    min-width: 0;
    font-family: var(--rec-font-display);
    font-weight: 600;
    font-size: 16px;
    color: var(--rec-text);
}

/* The record's name can be long and the subject line longer. One line, clipped —
   the header must not grow a second row and push the step off the fold. */
.rec-focus-title > span {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* One line, always. A wrapped reassurance line pushes the step's heading below the fold on a
   phone, which trades the thing being read for a line about how it is saved. */
.rec-focus-title small {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--rec-font-body);
    font-weight: 400;
    font-size: 14px;
    color: var(--rec-faint);
}

.rec-focus-count {
    margin-left: auto;
    flex: 0 0 auto;
    font-size: 15px;
    font-weight: 600;
    color: var(--rec-body);
}

/* The progress bar. Ticks rather than a percentage: "step 5 of 9" is a promise about
   how much is left, and nine segments make that legible at a glance where a bar at 44%
   does not. Lifecycle colours, not the pen family — these report what the RECORD is. */
.rec-focus-steps {
    display: flex;
    gap: 4px;
    padding: 12px 24px 0;
}

.rec-focus-steps i {
    flex: 1 1 0;
    height: 6px;
    border-radius: 999px;
    background: var(--rec-sunken);
}

.rec-focus-steps i.is-done {
    background: var(--rec-dot-success);
}

.rec-focus-steps i.is-now {
    background: var(--rec-dot-warning);
}

/* 704px is the mockup's, and it is a reading measure rather than a layout: one step
   is one question, and a control stretched across a 1400px monitor reads as a form. */
.rec-focus-body {
    flex: 1 1 auto;
    width: 100%;
    max-width: 704px;
    padding: 26px 24px 34px;
}

.rec-focus-body h1 {
    margin: 0;
    font-family: var(--rec-font-display);
    font-size: 27px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.012em;
    color: var(--rec-text);
}

.rec-focus-help {
    margin: 10px 0 0;
    font-size: 16px;
    color: var(--rec-body);
}

/* A step that captures nothing. Muted and italic so it reads as the screen telling you
   something rather than as a value someone recorded. */
.rec-focus-noinput {
    margin: 18px 0 0;
    font-size: 15px;
    font-style: italic;
    color: var(--rec-faint);
}

/* A Statement in the step body is an instruction card, not an input, so it renders bare — without
   the .rec-focus-input wrapper that carries the spacing below. Give it the same top gap so back-to-back
   instructions (and an instruction following a question) breathe instead of stacking flush (HQU-728). */
.rec-focus-body .record-form-statement {
    margin-top: 24px;
}

.rec-focus-input {
    margin-top: 24px;

    /* MudBlazor paints a ticked checkbox and a chosen radio in the theme primary, which on this host
       is the console's accent blue — the one colour the records palette does not use. Re-point the
       palette variable over this subtree so a value you record carries the same ink as the button
       that commits it. TOKENS ONLY: not one MudBlazor rule is restated here. */
    --mud-palette-primary: var(--rec-accent);
    --mud-palette-primary-rgb: 22, 33, 29;
}

.rec-focus-input > label {
    display: block;
    margin-bottom: 8px;
    font-size: 15px;
    color: var(--rec-body);
}

.rec-focus-req {
    margin-left: 3px;
    color: var(--rec-danger);
}

/* The authored instruction under a field's prompt. Quieter than the prompt and tighter to it than
   to the control, so it reads as part of the question. `anywhere` because these are routinely a
   pasted document URL, which would otherwise run off a phone screen. */
.rec-focus-fieldhelp {
    margin: -2px 0 8px;
    font-size: 14px;
    line-height: 1.45;
    color: var(--rec-muted);
    overflow-wrap: anywhere;
}

/* Stands in for the prompt on a step whose heading already asked the question. Quiet on purpose:
   it is a note about the field, not a warning — the loud version of this read as an error on a
   screen where nothing had gone wrong yet. */
.rec-focus-required {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    color: var(--rec-faint);
}

.rec-focus-required::before {
    content: "*";
    margin-right: 4px;
    color: var(--rec-danger);
}

.rec-focus-error {
    margin-top: 6px;
    font-size: 13px;
    color: var(--rec-danger);
}

/* The controls sit at floor scale here, not at form scale: this is one question read at arm's
   length with gloves on, so the input is the biggest thing under the heading.

   The element selectors are load-bearing. MudBlazor styles its slot as `.mud-input > input`, which
   out-specifies a plain two-class rule — the first version of this block set 18px and the input
   stayed at 14, silently. Keep the tag on the slot selectors. */
.rec-focus-input .mud-input input.mud-input-slot,
.rec-focus-input .mud-input textarea.mud-input-slot,
.rec-focus-input .mud-input div.mud-input-slot {
    font-size: 18px;
    min-height: 44px;
}

.rec-focus-input .mud-input-control {
    min-height: 60px;
}

.rec-focus-input .mud-radio p.mud-typography,
.rec-focus-input .mud-checkbox p.mud-typography,
.rec-focus-input .mud-radio span.mud-typography,
.rec-focus-input .mud-checkbox span.mud-typography {
    font-size: 17px;
}

/* The mockup's .bigchoice. A yes/no is the commonest thing anyone records on a phone, and a 20px
   radio dot is not a target for someone in gloves — so each option becomes a full-height bordered
   box that splits the row. The radio itself stays: the semantics (and the keyboard) are the
   MudRadioGroup's, and only the size and the box are ours. */
/* MudRadioGroup renders THREE nested boxes before the options: the class we set lands on the outer
   .mud-input-control, then .mud-input-control-input-container, then .mud-radio-group — and only the
   innermost one is the row the radios sit in. Styling either wrapper laid out a single child and
   left the options at their natural width inside it (measured, not assumed). So the two wrappers
   only pass the width down, and the row rules go on .mud-radio-group. */
.rec-focus-input .record-form-yesno,
.rec-focus-input .record-form-yesno .mud-input-control-input-container,
.rec-focus-input .record-form-yesno .mud-radio-group {
    width: 100%;
}

.rec-focus-input .record-form-yesno .mud-radio-group {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 12px;
}

/* And each option brings its OWN .mud-input-control pair, so the flex item in that row is the
   wrapper, not the <label class="mud-radio"> the box is drawn on. Sizing the label alone left three
   content-width boxes in a 656px row; the label still takes flex:1 to fill the wrapper it sits in. */
.rec-focus-input .record-form-yesno .mud-radio-group > .mud-input-control {
    flex: 1 1 0;
    min-width: 0;
}

.rec-focus-input .record-form-yesno .mud-radio {
    flex: 1 1 0;
    min-width: 0;
    min-height: 62px;
    margin: 0;
    padding: 0 10px;
    justify-content: center;
    border: 1px solid var(--rec-border);
    border-radius: 6px;
    background: var(--rec-surface);
}

.rec-focus-input .record-form-yesno .mud-radio:hover {
    background: var(--rec-sunken);
}

/* The chosen one carries the ink edge, so which option is selected reads from across a deck rather
   than from a 10px dot. :has is the whole mechanism — MudBlazor puts no class on the outer label —
   and a browser without it simply keeps the plain boxes and the dot, which is the old behaviour. */
.rec-focus-input .record-form-yesno .mud-radio:has(input:checked) {
    border-color: var(--rec-accent);
    box-shadow: inset 0 0 0 1px var(--rec-accent);
    background: var(--rec-accent-soft);
}

/* The reason box is SUBORDINATE to the answer above it, so it does not take the 18px
   floor scale the primary controls get — 16px, still a comfortable phone target, and the
   difference is what says "this belongs to the Unknown you just pressed". The element
   selector and the .rec-focus-input prefix are both load-bearing: they have to out-specify
   the block above, which sets every input slot on this screen to 18px. */
.rec-focus-input .record-form-why .mud-input textarea.mud-input-slot {
    font-size: 16px;
    min-height: 0;
}

/* A lone checkbox gets the tap target too, without the split-the-row treatment: there is only one,
   so it sizes to its label rather than spanning the column. DESCENDANT, not child — MudCheckBox
   buries its <label class="mud-checkbox"> under the same .mud-input-control pair the radios use
   (see the note above), so a `>` here matches nothing at all. */
.rec-focus-input .mud-checkbox {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    min-height: 62px;
    margin: 0;
    padding: 0 16px 0 6px;
    border: 1px solid var(--rec-border);
    border-radius: 6px;
    background: var(--rec-surface);
}

.rec-focus-input .mud-checkbox:hover {
    background: var(--rec-sunken);
}

.rec-focus-input .mud-checkbox:has(input:checked) {
    border-color: var(--rec-accent);
    box-shadow: inset 0 0 0 1px var(--rec-accent);
    background: var(--rec-accent-soft);
}

.rec-focus-foot {
    position: sticky;
    bottom: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 24px;
    background: var(--rec-surface);
    border-top: 1px solid var(--rec-border);
}

/* Trailing, not leading: the actions cluster at the LEFT margin — under the column of
   questions they belong to — and this eats whatever is left over on the right. */
.rec-focus-spacer {
    flex: 1 1 auto;
}

.rec-focus-back {
    min-height: var(--rec-tap);
    padding: 0 18px;
    white-space: nowrap;
    border: 1px solid var(--rec-border);
    border-radius: 6px;
    background: var(--rec-surface);
    color: var(--rec-text);
    font-family: inherit;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
}

.rec-focus-back:hover {
    background: var(--rec-sunken);
}

/* The mockup's .btn-lg. The step's one forward move, so it is the largest target on the
   screen and it never shrinks to its label. */
.rec-focus-go.mud-button-root {
    min-height: 56px;
    min-width: 220px;
    padding: 0 26px;
    font-size: 17px;
    white-space: nowrap;
}

/* Save-and-stay. Sized to the primary rather than to Back, because the two of them are the
   pair an operator chooses between; Back is a different kind of thing. Quiet by weight —
   outlined against the primary's fill — so the row still has exactly one obvious move. */
.rec-focus-save.mud-button-root {
    min-height: 56px;
    min-width: 128px;
    padding: 0 22px;
    font-size: 17px;
    white-space: nowrap;
    border-color: var(--rec-border);
    color: var(--rec-text);
}

.rec-focus-save.mud-button-root:hover {
    background: var(--rec-sunken);
    border-color: var(--rec-border);
}

/* Phone: the foot leaves the flow and pins to the viewport, and the body buys back the
   room it now covers — otherwise the last control on a long step sits under the button
   that submits it. */
@media (max-width: 760px) {
    .rec-focus-top { padding: 10px 14px; }
    .rec-focus-title { font-size: 15px; }
    .rec-focus-leave span { display: none; } /* the arrow alone; the title needs the width */

    /* The reassurance line is desktop furniture. On a phone the header row has to hold the record's
       name AND the step count in 390px, and the guard dialog says the same thing at the moment it
       actually matters — when someone presses Leave with work outstanding. */
    .rec-focus-title small { display: none; }

    .rec-focus-steps { padding: 10px 14px 0; }
    .rec-focus-body { padding: 20px 14px 180px; } /* clears the wrapped two-row foot */
    .rec-focus-body h1 { font-size: 23px; }

    /* Three options at 390px would be three unreadable slivers, so let them wrap onto a second row
       at full tap height. Two (a plain yes/no) still fit side by side, which is why this wraps
       rather than forcing a column. */
    .rec-focus-input .record-form-yesno .mud-radio-group { flex-wrap: wrap; }
    .rec-focus-input .record-form-yesno .mud-radio-group > .mud-input-control { flex: 1 1 140px; }

    .rec-focus-foot {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
    }

    /* Both feet on one row: nowrap and a tighter scale, rather than flex-growing the primary until
       its label breaks over two lines. flex 0 1 auto lets it shrink its padding, never its words. */
    .rec-focus-back { padding: 0 12px; font-size: 15px; }
    .rec-focus-save.mud-button-root,
    .rec-focus-go.mud-button-root { min-width: 0; flex: 0 1 auto; padding: 0 14px; font-size: 16px; min-height: 52px; }

    /* Three controls will not fit on one 390px row, and none of them can be dropped — this runs
       installed as a PWA, where there is no browser back to fall back on. So the foot wraps and
       Back takes a full-width row of its own UNDER the two save actions: still a full tap target,
       still reachable, just not competing with them for the row that matters. */
    .rec-focus-foot { flex-wrap: wrap; }
    .rec-focus-foot .rec-focus-back { order: 2; flex: 1 1 100%; }
    .rec-focus-foot .rec-focus-save.mud-button-root { min-width: 96px; }
}

/* ── Run wizard ───────────────────────────────────────────────────────────────
   The stepper doubles as the between-steps back affordance (a prior step is a
   button; the current + future ones are inert). Sits above each step's card. */
.record-wizard-context {
    display: flex;
    align-items: center;
    gap: 10px;
    width: min(100%, 620px);
    margin: 0 auto 12px;
    padding: 10px 12px;
    border: 1px solid var(--rec-border);
    border-radius: 10px;
    background: var(--rec-surface);
    color: var(--rec-body);
    text-align: left;
}

.record-wizard-context .mud-icon-root {
    flex: none;
    color: var(--rec-muted);
}

.record-wizard-context > div {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.record-wizard-context-flow {
    font-size: 0.76rem;
    color: var(--rec-muted);
}

.record-wizard-context strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--rec-text);
}

.record-wizard-steps {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    margin: 0 auto 10px;
    flex-wrap: wrap;
}

.record-wizard-step {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px;
    background: none;
    border: none;
    border-radius: 8px;
    font: inherit;
    color: var(--rec-faint);
    cursor: default;
}

.record-wizard-step.is-reachable {
    color: var(--rec-accent);
    cursor: pointer;
}

.record-wizard-step.is-reachable:hover { background: var(--rec-hover); }

.record-wizard-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--rec-accent-dim);
    color: var(--rec-muted);
    flex: none;
}

.record-wizard-step.is-current .record-wizard-step-num { background: var(--rec-accent); color: #fff; }
.record-wizard-step.is-reachable .record-wizard-step-num { background: var(--rec-accent-soft); color: var(--rec-accent); }

.record-wizard-step-label { font-size: 0.85rem; font-weight: 500; }
.record-wizard-step.is-current .record-wizard-step-label { color: var(--rec-text); }

.record-wizard-sep { font-size: 1rem; color: var(--rec-edge); flex: none; }

/* A run/wizard step's primary action sits at the trailing edge — the auto-width .record-btn, not a
   full-bleed bar (step 2's "Continue", step 3's "Start this Procedure"). A flex row rather than
   text-align so the button keeps its own width and the row owns the gap above. */
.record-actions-end {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
}

/* ── Asset-selection tree (wizard step 2) ─────────────────────────────────────
   Reuses .record-rel-row via <RecordRelationRow>: the reserved LEFT slot carries the
   subject checkbox, and the link becomes the expander. */
.record-tree-level { display: flex; flex-direction: column; }

.record-tree-check { margin: 0; flex: none; }

/* Keeps a non-tickable (structural) row's label aligned with tickable siblings. */
.record-tree-check-spacer { width: 30px; flex: none; }

.record-tree-open { padding-left: 0; }

.record-tree-caret { color: var(--rec-faint); }

.record-tree-note {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 6px;
    font-size: 0.85rem;
}

.record-tree-muted { color: var(--rec-faint); }

#blazor-error-ui {
    background: #ffffe0;
    color: #000;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(22, 33, 29, 0.2);
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

/* ── Tablet (≥768px): the sign-in tile gets room to breathe. Phone stays kiosk-tight.
   Widens the tile moderately and gives the name-tile grid a third column (the screen that benefits
   most on a mounted tablet). .record-card is PWA-only now, so this no longer reaches the portal
   at all — the screens there are on paper and take their width from .record-page. */
@media (min-width: 768px) {
    .record-card {
        max-width: 560px;
        padding: 40px 36px;
    }
    .record-tile-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 14px;
    }
    .record-run,
    .record-pick-entry { padding: 16px 18px; }
}

/* ============================================================================
   NavRow — one navigation row, shared by BOTH surfaces (see NavRow.razor).

   Every colour here resolves through a --nr-* property declared below, and each of
   those defaults to the manager console's token with the records palette as the
   fallback: var(--console-token, var(--rec-token)). On the portal, hque-tokens.css
   has defined the console token, so the row reads as console chrome; in the PWA it
   is undefined and the staff value applies. Both themes come free, because BOTH
   palettes re-point their own properties in their own dark blocks.

   That is also the extension point: a surface wrapper re-points --nr-* over a
   subtree rather than restating any rule below.
   ============================================================================ */
:root {
    --nr-surface:      var(--canvas-default, var(--rec-surface));
    --nr-surface-hover: var(--canvas-subtle, var(--rec-row-hover));
    --nr-border:       var(--border-default, var(--rec-border));
    --nr-title:        var(--fg-default, var(--rec-text));
    --nr-support:      var(--fg-muted, var(--rec-muted));
    --nr-chevron:      var(--fg-subtle, var(--rec-faint));
    --nr-accent:       var(--accent-fg, var(--rec-accent));
    --nr-icon-bg:      var(--canvas-inset, var(--rec-sunken));
    --nr-radius:       var(--radius-md, 8px);
    --nr-focus:        var(--focus-ring, 0 0 0 3px rgba(37, 99, 235, 0.30));
    /* Thumb-sized. The settings data tables this replaces were ~34px rows. */
    --nr-min-height:   56px;

    /* Metrics, tokenised for the same reason the colours are: the records surface renders these rows
       at the shell mockup's scale (68px, 16px title) and the authoring surface at the console's, and
       a surface must be able to say so by re-pointing properties rather than restating rules. */
    --nr-pad-y:        10px;
    --nr-pad-x:        14px;
    --nr-gap:          12px;
    --nr-title-size:   14px;
    --nr-support-size: 12px;
    /* The line BETWEEN rows. Defaults to the card's own border; a surface can soften it so a run of
       rows reads as one card with divisions rather than a stack of boxes. */
    --nr-divider:      var(--nr-border);
}

/* The list container. Rows share one border box so a run of them reads as one list
   rather than a stack of cards. */
.navrow-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--nr-border);
    border-radius: var(--nr-radius);
    overflow: hidden;
    background: var(--nr-surface);
}
.navrow-list > .navrow + .navrow {
    border-top: 1px solid var(--nr-divider);
}

.navrow {
    display: flex;
    align-items: stretch;
    background: var(--nr-surface);
    min-height: var(--nr-min-height);
}
.navrow.is-inactive .navrow-title,
.navrow.is-inactive .navrow-support { opacity: 0.55; }

/* The navigating element itself — <a> or <button>, reset to look like neither. */
.navrow-go {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--nr-gap);
    padding: var(--nr-pad-y) var(--nr-pad-x);
    background: none;
    border: 0;
    border-radius: 0;
    font: inherit;
    color: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.12s ease;
}
/* The app's global a:hover underlines links. A row is a surface, not a phrase — underlining
   its title AND its supporting line on hover reads as two links, so the hover is the
   background plus the title colour, and nothing else. */
.navrow-go:hover { background: var(--nr-surface-hover); text-decoration: none; }
.navrow-go:focus-visible {
    outline: none;
    box-shadow: var(--nr-focus);
    /* Above the sibling row's border so the ring is never clipped by it. */
    position: relative;
    z-index: 1;
}
.navrow-go:hover .navrow-title { color: var(--nr-accent); }
/* A row that goes nowhere is not a control: no pointer, no hover, no chevron. */
.navrow-go--static { cursor: default; }
.navrow-go--static:hover { background: none; }
.navrow-go--static:hover .navrow-title { color: var(--nr-title); }

.navrow-lead { flex: 0 0 auto; display: flex; align-items: center; }
.navrow-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--nr-radius);
    background: var(--nr-icon-bg);
    color: var(--nr-support);
}

.navrow-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.navrow-title {
    font-size: var(--nr-title-size);
    font-weight: 600;
    color: var(--nr-title);
    transition: color 0.12s ease;
    /* One line. A wrapping title turns a scannable list into a paragraph. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.navrow-support {
    font-size: var(--nr-support-size);
    color: var(--nr-support);
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    min-width: 0;
}

.navrow-trail {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--nr-support-size);
    color: var(--nr-support);
}

.navrow-chev {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    color: var(--nr-chevron);
    transition: transform 0.15s ease;
}

/* Disclosure rows (<NavRow Expanded>) turn the same glyph a quarter turn rather than swapping
   in ExpandMore — one chevron, drawn one way, whether the row goes somewhere or opens
   something. */
.navrow-chev.is-open { transform: rotate(90deg); }

/* Per-row controls. Outside .navrow-go, so a tap here never navigates. */
.navrow-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 12px 0 0;
}

/* Phone: the supporting line and trailing meta compete for a width that isn't there.
   Keep the title and the chevron; let the rest stack. */
@media (max-width: 600px) {
    .navrow-go { padding: 10px 12px; gap: 10px; }
    .navrow-trail { display: none; }
}

/* …except on the RECORDS surface, where the trailing content is the record's lifecycle tag and
   dropping it takes the answer off a screen whose whole question is "what state is this in". The
   mockup's phone treatment instead (phone.css .row): two columns — everything about the row on the
   left, the forward chevron on the right — with the tag moving under the meta line rather than
   fighting the title for width.

   Structure is untouched: this is the same markup laid out differently, which is the one thing a
   surface is allowed to do to a shared primitive. */
@media (max-width: 600px) {
    .hq-surface--record .navrow-go {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "main chev"
            "trail chev";
        column-gap: 12px;
        row-gap: 0;
        align-items: center;
        min-height: 74px;
        padding: 13px 14px;
    }

    .hq-surface--record .navrow-main { grid-area: main; }

    /* A row WITH a leading icon needs a fourth area; without :has() the icon and the title would be
       placed in the same cell and overlap. Rows on this surface rarely carry one, so the two-column
       form above stays the default and this only pays where it applies. */
    .hq-surface--record .navrow-go:has(.navrow-lead) {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "lead main chev"
            "lead trail chev";
    }

    .hq-surface--record .navrow-lead { grid-area: lead; }

    .hq-surface--record .navrow-trail {
        display: flex;
        grid-area: trail;
        justify-self: start;
        margin-top: 9px;
    }

    .hq-surface--record .navrow-chev { grid-area: chev; align-self: center; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   THE label-and-value row (<InfoRow>) and its group (<InfoList>).

   One row, one group, both surfaces, both modes. This block lives in records.css because that
   sheet is loaded by BOTH apps — the PWA's index.html and the portal's (line 20) — so the
   primitive is styled once for everything that renders it.

   Everything below resolves through the --row-* semantic properties declared here. A surface
   wrapper re-points those properties over its subtree and nothing else; it never changes what
   renders. Adding a colour literal to a rule below re-opens the drift this whole block exists
   to close, so don't.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

/* The defaults ARE the authoring (manager console) values, so a caller with NO surface wrapper
   — a pre-login page, a dialog outside a layout — renders exactly as it did before. The literal
   fallbacks are for the PWA, which has no --fg- or --canvas- tokens of its own; it is wrapped
   in a RecordSurface at its root, so they should never actually be reached.

   Do NOT write a token glob as `--fg-*` immediately before a slash: the `*` plus the `/` is a
   comment terminator, and the rest of this comment then parses as CSS. That is what happened
   here — the stray text became a selector, this whole :root block became its body, and every
   --row-* default silently vanished. Nothing errored; the surfaces and .hq-rows-card happened
   to re-declare most of them, so only an unwrapped row (no surface, no card) showed it, by
   losing --row-pad-x and dropping its padding entirely. */
:root {
    --row-label-fg: var(--fg-muted, #47574f);
    --row-label-size: var(--text-sm, 13px);
    --row-label-weight: 500;
    --row-label-spacing: 0;
    --row-value-fg: var(--fg-default, #16211d);
    --row-value-size: var(--text-md, 14px);
    --row-help-fg: var(--fg-muted, #47574f);
    --row-help-size: var(--text-2xs, 11px);
    --row-required-fg: var(--danger-fg, #a31212);
    --row-error-fg: var(--danger-fg, #a31212);
    --row-empty-fg: var(--fg-subtle, #627268);
    --row-line: var(--border-muted, #e4e9e5);
    --row-pad-y: 14px;
    --row-pad-x: 0px;
    --row-group-bg: var(--canvas-default, #fff);
    --row-group-line: var(--border-default, #d3dad5);
    --row-group-radius: var(--radius-lg, 10px);
    --row-group-fg: var(--fg-default, #16211d);
    --row-group-title-size: var(--text-md, 14px);

    /* Read-mode deltas. Label and value are the SAME size here (15px, the mockup's .field);
       what separates them is weight and colour — the label recedes to --ink-3 at 400, the
       value carries 500 in full ink, because what is being scanned down a column of these is
       the values. An edit row borrows this SIZE (the two modes share a label column, so the
       label must not resize when you flip between them) but keeps --row-label-fg/-weight: it
       identifies a control you are about to use, not a value you are scanning. */
    --row-read-label-fg: var(--fg-subtle, #627268);
    --row-read-label-weight: 400;
    --row-read-label-size: var(--text-15, 15px);
    --row-read-value-size: var(--text-15, 15px);

    /* A read row is INLINE — label in the left column, value beside it — which is the
       mockup's .field. The two tracks are a 40/60 split (2fr:3fr of the row, once the gap
       is taken out) so a field value gets the wider share (HQU-511).
       --row-read-columns is the whole layout switch: set it to a single
       track and the row stacks again, which is what the phone surface and the narrow
       breakpoint below do. The value carries weight because it is what gets scanned down a
       column of these; the label is the thing you already know you are looking for. */
    --row-read-columns: minmax(0, 2fr) minmax(0, 3fr);
    --row-read-gap: 20px;
    --row-read-value-weight: 500;

    /* An edit row takes the SAME two tracks (the mockup's .field-edit) — label left, control
       right — so flipping a page between reading and editing does not re-flow the labels out
       from beside their values to above them. Which is also why the edit label now takes the
       read label's SIZE: it is the same furniture in the same column, and only the value slot
       changes. It keeps its own weight and colour, because it still identifies a control you
       are about to use rather than a value you are scanning.

       An edit row aligns to START, not baseline: a grid item's first baseline can come from a
       <textarea>, whose baseline is its BOTTOM edge, so a 5-line multiline field would drag
       its label to the foot of the row. --row-edit-label-offset is what buys back the optical
       alignment a baseline would have given — it is the distance from the top of a dense
       outlined control to its first line of text — and it goes to 0 wherever the row stacks. */
    --row-edit-columns: 300px minmax(0, 1fr);
    --row-edit-gap: 20px;
    --row-edit-label-offset: 8px;
}

/* display:contents — a surface must not add a box. It exists to scope custom properties over
   its subtree, and custom properties inherit straight through it, so the layout the wrapper
   sits in is untouched. */
.hq-surface {
    display: contents;
}

.hq-surface--record {
    /* NavRow at the shell mockup's scale (mockups/venuehq-shell app.css, .row): a 68px row, a 16px
       title, a 14px meta line. The authoring console keeps the smaller default — a records row is
       read at arm's length on site, a settings row at a desk. TOKENS ONLY: not one rule below is
       restated here, which is the guard rail that stopped the four label/value families drifting. */
    --nr-min-height: 68px;
    --nr-pad-y: 12px;
    --nr-pad-x: 16px;
    --nr-gap: 16px;
    --nr-title-size: 16px;
    --nr-support-size: 14px;
    --nr-radius: 10px;
    --nr-surface: var(--rec-surface);
    --nr-surface-hover: var(--rec-row-hover);
    --nr-border: var(--rec-border);
    /* Softer between rows than around the card, so a run of rows reads as one card. */
    --nr-divider: var(--rec-border-soft);
    --nr-title: var(--rec-text);
    --nr-support: var(--rec-faint);
    --nr-chevron: var(--rec-faint);
    /* Hovering a row must not recolour its title toward the link blue — on this surface the title is
       the record's name, and the row is a surface rather than a phrase. */
    --nr-accent: var(--rec-text);
    --nr-icon-bg: var(--rec-sunken);

    /* No type overrides. A record's label-and-value rows render at the AUTHORING scale —
       same label column, same sizes, same weights — because they are the same rows: a manager
       reading a value on /records and reading it in the console must not see two typographies
       of the same fact. The surface's own scale lives in --nr-* above, where it belongs: a
       NavRow is a touch target read at arm's length, a field row is text.

       The --rec-* palette this surface would have pointed the colour tokens at is byte-identical
       to the authoring defaults anyway (#16211d / #47574f / #627268 / #d3dad5 / #e4e9e5 / #fff),
       so dropping them changed no colour. The PWA, which defines no --fg- or --canvas- tokens,
       lands on the literal fallbacks in the :root block above — the same values again. */

    /* The one exception, and it is layout rather than type: an EDIT row stays stacked here.
       Capture on this surface is focus mode — one step per screen, label over control, thumb-
       sized targets — so a 300px label column beside the input is the wrong shape for it. What
       a reader sees is identical to authoring; what a recorder touches is not. */
    --row-edit-columns: minmax(0, 1fr);
    --row-edit-gap: 0px;
    --row-edit-label-offset: 0px;
}

/* Restates the defaults so authoring content nested inside a record surface wins back. */
.hq-surface--authoring {
    --row-label-fg: var(--fg-muted);
    --row-label-size: var(--text-sm);
    --row-label-weight: 500;
    --row-label-spacing: 0;
    --row-value-fg: var(--fg-default);
    --row-value-size: var(--text-md);
    --row-help-fg: var(--fg-muted);
    --row-help-size: var(--text-2xs);
    --row-required-fg: var(--danger-fg);
    --row-error-fg: var(--danger-fg);
    --row-empty-fg: var(--fg-subtle);
    --row-line: var(--border-muted);
    --row-group-bg: var(--canvas-default);
    --row-group-line: var(--border-default);
    --row-group-radius: var(--radius-lg);
    --row-group-fg: var(--fg-default);
    --row-group-title-size: var(--text-md);

    --row-read-label-fg: var(--fg-subtle);
    --row-read-label-weight: 400;
    --row-read-label-size: var(--text-15);
    --row-read-value-size: var(--text-15);
    --row-read-columns: minmax(0, 2fr) minmax(0, 3fr);
    --row-read-gap: 20px;
    --row-read-value-weight: 500;
    --row-edit-columns: 300px minmax(0, 1fr);
    --row-edit-gap: 20px;
    --row-edit-label-offset: 8px;
}

/* ── The group ─────────────────────────────────────────────────────────────────────────── */

/* A plain container. Rows carry their own separators, so the group draws none — which is also
   why it does not care whether every child is a row (a statement or a picker can sit between
   two of them). */
.hq-rows {
    display: grid;
    gap: 0;
}

.hq-rows-card {
    --row-pad-x: 16px;
    background: var(--row-group-bg);
    border: 1px solid var(--row-group-line);
    border-radius: var(--row-group-radius);
    overflow: hidden;
}

.hq-rows-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 0 6px;
    color: var(--row-group-fg);
}

.hq-rows-card > .hq-rows-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--row-line);
}

/* A boxed group on the records surface holds things that are NOT rows — an asset picker, a row of
   chips, a BelongsTo tree, a Statement's own tinted block. A row pads itself with --row-pad-x; those
   do not, so inside a card they would sit flush against its edge. The group insets them instead of
   each caller remembering to.

   Scoped to this surface's screens (.record-page / .record-screen) on purpose: <InfoList> is shared
   with the authoring console, where boxed groups are hand-composed forms that already handle their
   own non-row children. */
.record-page .hq-rows-card > .hq-rows > :not(.hq-row),
.record-screen .hq-rows-card > .hq-rows > :not(.hq-row) {
    margin: 12px var(--row-pad-x);
}

.hq-rows-title {
    font-weight: 600;
    font-size: var(--row-group-title-size);
    line-height: 1.3;
}

.hq-rows-hint {
    font-weight: 400;
    font-size: var(--row-help-size);
    color: var(--row-help-fg);
}

/* ── The row ───────────────────────────────────────────────────────────────────────────── */

.hq-row {
    margin: 0;
    padding: var(--row-pad-y) var(--row-pad-x);
    border-bottom: 1px solid var(--row-line);
}

.hq-row:last-child {
    border-bottom: 0;
}

/* Both modes are the same two-track row — label left, value right. They differ in breathing
   room and in what the value track holds: an edit row hosts a control, a read row hosts text.
   Same markup, same furniture, same columns; only the value slot changes. */
.hq-row--edit {
    --row-pad-y: 14px;
    display: grid;
    grid-template-columns: var(--row-edit-columns);
    column-gap: var(--row-edit-gap);
    row-gap: 4px;
    align-items: start;
}

.hq-row--read {
    --row-pad-y: 14px;
    display: grid;
    grid-template-columns: var(--row-read-columns);
    column-gap: var(--row-read-gap);
    row-gap: 4px;
    align-items: baseline;
}

/* The mockup's .field: label in the left track, value beside it, baselines aligned. The sizes,
   the colour, the weights and the track list all come from the surface (see --row-read-*), so
   the phone keeps its stacked rows without a second rule here. row-gap is what separates them
   when the track list collapses to one column — the label's own 4px margin would double it. */
.hq-row--read .hq-row-label {
    margin: 0;
    color: var(--row-read-label-fg);
    font-size: var(--row-read-label-size);
    font-weight: var(--row-read-label-weight);
}

.hq-row--read .hq-row-value {
    font-size: var(--row-read-value-size);
    font-weight: var(--row-read-value-weight);
}

/* The label sits in the left track, so its stacked bottom margin goes (row-gap covers the
   collapsed case) and the offset takes over: it drops the label to meet the first line of
   text inside the control beside it. Size comes from the READ token on purpose — see the
   --row-edit-* comment; weight and colour stay the edit label's own. */
.hq-row--edit .hq-row-label {
    margin: 0;
    padding-top: var(--row-edit-label-offset);
    font-size: var(--row-read-label-size);
}

/* A row with no label renders no <dt>, so the value would otherwise land in the LABEL track and
   be squeezed to it. Nothing but the value means nothing to align to — take both. */
.hq-row-value:only-child {
    grid-column: 1 / -1;
}

/* Not enough width for two tracks — the threshold tracks the label column, so it moved up with
   it. Flipping the ONE token is the whole change. */
@media (max-width: 860px) {
    .hq-row--read {
        --row-read-columns: minmax(0, 1fr);
        --row-read-gap: 0px;
    }

    .hq-row--edit {
        --row-edit-columns: minmax(0, 1fr);
        --row-edit-gap: 0px;
        --row-edit-label-offset: 0px;
    }
}

/* The breakpoint is on the VIEWPORT, so a row in a narrow BOX inside a wide window — a dialog,
   a drawer — has to say so itself: <InfoList Class="hq-rows--stacked">. */
.hq-rows--stacked {
    --row-read-columns: minmax(0, 1fr);
    --row-read-gap: 0px;
    --row-edit-columns: minmax(0, 1fr);
    --row-edit-gap: 0px;
    --row-edit-label-offset: 0px;
}

.hq-row-label {
    display: block;
    margin: 0 0 4px;
    font-size: var(--row-label-size);
    font-weight: var(--row-label-weight);
    letter-spacing: var(--row-label-spacing);
    line-height: 1.3;
    color: var(--row-label-fg);
}

.hq-row-required {
    margin-left: 3px;
    color: var(--row-required-fg);
}

.hq-row-help {
    display: block;
    margin-top: 3px;
    font-size: var(--row-help-size);
    font-weight: 400;
    letter-spacing: 0;
    line-height: 1.45;
    color: var(--row-help-fg);
}

.hq-row-value {
    margin: 0;
    min-width: 0;
    font-size: var(--row-value-size);
    line-height: 1.45;
    color: var(--row-value-fg);
}

/* Read values are user-authored text of unknown length and shape. */
.hq-row--read .hq-row-value {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.hq-row-empty {
    color: var(--row-empty-fg);
    font-style: italic;
    font-weight: 400;
}

.hq-row-error {
    margin-top: 4px;
    font-size: var(--row-help-size);
    font-weight: 600;
    color: var(--row-error-fg);
}

/* ── Screen mode: the band, the save bar and the leave guard (HQU-296) ──────────
   Every colour below resolves through --rec-mode-*, which nothing else in this
   sheet may reference. That is what makes the mode readable at a glance: if it is
   ink blue you are doing something, and if it is not you are reading. */

/* width/align-self because the PWA shell is a CENTERED flex column: without them the band
   shrinks to its text and floats mid-screen instead of reading as a strip across the top. */
.record-mode-band {
    position: sticky;
    top: 0;
    z-index: 19;
    width: 100%;
    align-self: stretch;
    box-sizing: border-box;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    padding: 12px 16px;
    color: var(--rec-mode-on);
    background: var(--rec-mode);
}

.record-mode-band strong {
    font-size: 0.98rem;
    font-weight: 700;
}

.record-mode-band span {
    font-size: 0.9rem;
    opacity: 0.92;
}

/* Saving steps one shade deeper rather than changing hue: the operator should read it
   as "the same thing, further along", not as a new state that needs interpreting. */
.record-mode-band--saving {
    background: var(--rec-mode-strong);
}

.record-mode-band--saved {
    background: var(--rec-mode-saved);
}

/* The edit bar brackets the screen with the band: rule at the top in the mode colour,
   so the two ends of a long form both report the mode without the middle needing to. */
.record-edit-bar {
    position: sticky;
    bottom: 0;
    z-index: 18;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: var(--rec-surface);
    border-top: 2px solid var(--rec-mode);
    box-shadow: 0 -6px 18px var(--rec-shadow);
}

/* MudBlazor's Color.Primary would paint the surface accent here. The save button has to
   carry the MODE colour instead — the button colour is one of the three things reporting
   the mode, and an accent-coloured one reports nothing. */
.record-edit-bar-save.mud-button-filled {
    background-color: var(--rec-mode);
    color: var(--rec-mode-on);
}

.record-edit-bar-save.mud-button-filled:hover:not(:disabled) {
    background-color: var(--rec-mode-strong);
}

.record-edit-bar-cancel {
    color: var(--rec-body);
}

.record-edit-bar-spacer {
    flex: 1 1 auto;
}

.record-edit-bar-hint {
    font-size: 0.85rem;
    color: var(--rec-muted);
}

/* On a phone the hint wraps to its own line under the buttons rather than squeezing them:
   the actions are what the thumb needs, the hint is what the eye needs. */
@media (max-width: 560px) {
    .record-edit-bar-spacer {
        display: none;
    }

    .record-edit-bar-hint {
        flex: 1 0 100%;
        order: 3;
    }
}

.record-guard {
    position: fixed;
    inset: 0;
    z-index: 100;
}

.record-guard-scrim {
    position: fixed;
    inset: 0;
    background: rgba(22, 33, 29, 0.45);
}

.record-guard-box {
    position: relative;
    z-index: 1;
    margin: 14vh auto 0;
    max-width: 440px;
    padding: 20px;
    border-radius: 14px;
    background: var(--rec-surface);
    box-shadow: 0 20px 50px var(--rec-shadow);
}

.record-guard-title {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--rec-text);
}

.record-guard-body {
    margin: 8px 0 18px;
    font-size: 0.92rem;
    line-height: 1.45;
    color: var(--rec-body);
}

.record-guard-acts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Keeping the work is the primary; discarding it is quiet and reads as danger. */
.record-guard-stay.mud-button-filled {
    background-color: var(--rec-mode);
    color: var(--rec-mode-on);
}

.record-guard-stay.mud-button-filled:hover:not(:disabled) {
    background-color: var(--rec-mode-strong);
}

.record-guard-leave {
    color: var(--rec-danger);
}

/* ============================================================================
   HQU-298 — Today, and the records list.

   The two screens people arrive on. Everything below serves one of three things:
   the lifecycle tag that says what a record IS, the sectioned Today layout, and
   the records list's filter chips.
   ============================================================================ */

/* ── The lifecycle tag (RecordStatusTag) ──────────────────────────────────────
   The FILLED earth-and-safety pill, on the StatusTone axis (BehaviourFlagDefinitions
   → StatusTone → tone-*). Distinct from .record-run-status above, which is the
   worklist card's pill on RecordRunPresentation's own five-tone vocabulary; both
   land on tone-* classes, and each scopes its own palette off the same suffix.

   Strictly the lifecycle family: never blue. Blue is the screen-MODE axis, and a
   glance at the colour has to say which of the two questions is being answered. */
:root {
    --rec-tag-neutral-bg: #e5eae7; --rec-tag-neutral-fg: #55665f;
    --rec-tag-info-bg:    #ddeef0; --rec-tag-info-fg:    #0e5a66;
    --rec-tag-warning-bg: #fce9dd; --rec-tag-warning-fg: #a93b08;
    --rec-tag-success-bg: #dcebe1; --rec-tag-success-fg: #12603b;
    --rec-tag-danger-bg:  #fbe4e2; --rec-tag-danger-fg:  #a31212;
}

.record-status-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: var(--text-sm, 13px);
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

/* The dot carries the tone at small sizes, where the fill alone is too little colour
   to read at a glance down a long list. */
.record-status-tag::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.record-status-tag.tone-neutral { background: var(--rec-tag-neutral-bg); color: var(--rec-tag-neutral-fg); }
.record-status-tag.tone-info    { background: var(--rec-tag-info-bg);    color: var(--rec-tag-info-fg); }
.record-status-tag.tone-warning { background: var(--rec-tag-warning-bg); color: var(--rec-tag-warning-fg); }
.record-status-tag.tone-success { background: var(--rec-tag-success-bg); color: var(--rec-tag-success-fg); }
.record-status-tag.tone-danger  { background: var(--rec-tag-danger-bg);  color: var(--rec-tag-danger-fg); }

/* ── Rows (RecordRowList) ─────────────────────────────────────────────────────
   The rows themselves are NavRow and are styled above; only the overdue accent is
   new. It is a LEFT EDGE, not a recolour of the row or the tag: the tag says what
   the record is, and lateness is a separate fact that must not overwrite it. */
.record-row-list .navrow.is-overdue {
    box-shadow: inset 3px 0 0 0 var(--rec-tag-danger-fg);
}

.record-row-list .navrow.is-overdue .navrow-support {
    color: var(--rec-tag-danger-fg);
}

/* ── The asset register (RecordAssetsScreen) ──────────────────────────────────
   Rows are NavRow in the shared .navrow-list card, so nothing here restyles them. The only
   addition is the truncation note under the card: it is a footnote about the LIST, not a row in
   it, so it sits outside the card and reads at the muted size. */
.record-asset-capped {
    margin: 10px 2px 0;
    font-size: 14px;
}

/* ── Button ─────────────────────────────────────────────────────────────
   The shell mockup's .btn / .btn-primary (app.css). A primary action here is INK, not the brand
   accent — the mockups have no accent at all, and on this surface colour is spent on what a record
   IS (the lifecycle family) and what you are DOING to it (the ink-blue mode family). A blue CTA
   would put a third colour family on a screen whose other two are load-bearing.

   Renders on an <a> as readily as a <button>, so a control that navigates can stay a real link.
   Note the explicit justify/align: a UA centres a flex <button>'s content for you and does NOT do
   the same for an <a>, so leaving it out gives two shapes for one class. */
.record-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--rec-tap);
    padding: 0 18px;
    border: 1px solid var(--rec-border);
    border-radius: 6px;
    background: var(--rec-surface);
    color: var(--rec-text);
    font-family: var(--rec-font-body);
    font-size: 16px;
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.record-btn:hover { background: var(--rec-hover); text-decoration: none; }

.record-btn--primary {
    background: var(--rec-accent);
    border-color: var(--rec-accent);
    color: var(--rec-surface);
}

.record-btn--primary:hover { background: var(--rec-accent-hover); }

.record-btn .record-btn-icon { font-size: 20px; color: inherit; }

/* ── The screen on paper: head, sections, states ─────────────────────────
   mockups/venuehq-shell app.css (.page / .pagehead / .section). Every screen on this surface is an
   eyebrow / title / one-line-sub head, then sections, each section a card of rows — deliberately NOT
   RecordPageScaffold's centred header and NOT a .record-card, because these are screens being READ
   on paper rather than drill-ins being navigated.

   These classes belong to RecordScreenHead, not to any one screen: Today wore them first under
   .record-today-* names, and HQU-428 gave the same head to the four screens inside the shell.

   The screens render in two hosts: the portal's /records column, where the layout supplies the page
   padding and the width cap, and the PWA's centred .record-shell, where it does not. The cap below
   is what makes one screen behave in both. */
.record-screen {
    width: 100%;
    max-width: var(--page-max, 940px);
}

.record-head {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

/* Pulled up and out so the glyph sits on the title's line and on the column's left edge, rather
   than indenting the h1 everything below it is aligned to. */
.record-head-back {
    flex: 0 0 auto;
    margin: 10px 0 0 -8px;
}

.record-headline {
    flex: 1 1 260px;
    min-width: 0;
}

.record-eyebrow {
    margin: 0 0 4px;
    font-size: 14px;
    color: var(--rec-faint);
    /* Reserve the line so the head doesn't jump when the date arrives with the data. */
    min-height: 1.2em;
}

.record-head-title {
    margin: 0;
    font-family: var(--rec-font-display);
    font-size: 30px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.012em;
    color: var(--rec-text);
}

.record-head-sub {
    margin: 6px 0 0;
    font-size: 16px;
    color: var(--rec-muted);
    min-height: 1.4em;
}

/* NOTHING in the headline is interactive, so nothing in it should ever wear a focus ring — and
   yet a pale blue rounded box turns up around the title now and then. Focus lands on the h1
   (a dialog closing and restoring focus onto a node that has since re-rendered is the usual
   way), and both hosts then draw it:

     · the portal, from hque-overrides.css's universal `*:focus-visible`, which rings ANY
       element focus reaches — box-shadow in the tenant accent at 30%, radius 6px, which is
       exactly the box;
     · the PWA, from the browser's own default `outline: auto`, since it loads no overrides.

   So both are killed here rather than in either host: this is the RCL's own head, it is the
   same defect on both surfaces, and a class selector out-specifies the universal rule wherever
   the two stylesheets happen to land in the cascade. Real controls in the head — the back
   button, the actions slot — are untouched and keep their rings. */
.record-eyebrow:focus,
.record-eyebrow:focus-visible,
.record-head-title:focus,
.record-head-title:focus-visible,
.record-head-sub:focus,
.record-head-sub:focus-visible {
    outline: none;
    box-shadow: none;
}

/* Aligned with the title rather than the eyebrow — the head's optical baseline is the h1. */
.record-head-actions {
    flex: 0 0 auto;
    margin-top: 18px;
}

.record-section {
    margin-top: 28px;
}

.record-section-head {
    margin: 0 0 10px;
    font-family: var(--rec-font-display);
    font-size: 15px;
    font-weight: 600;
    color: var(--rec-muted);
}

.record-count {
    color: var(--rec-faint);
    font-weight: 500;
    margin-left: 4px;
}

/* On paper there is no card, so every NON-list outcome — loading, failure, empty, no-match — gets
   the box the rows' card would otherwise have provided. One rule rather than a wrapper per screen:
   RecordAsyncView owns two of these states, so a screen cannot box them all from the outside.
   Both paper columns take it: .record-screen (the converted screens) and .record-page (the
   scaffolded ones, which lost their page card with it). */
.record-screen .record-state,
.record-page .record-state {
    margin-top: 28px;
    padding: 22px 16px;
    background: var(--rec-surface);
    border: 1px solid var(--rec-border);
    border-radius: 10px;
}

@media (max-width: 600px) {
    .record-head { gap: 14px; }
    .record-head-title { font-size: 25px; }
    /* Full-bleed on a phone: the primary action is the one thing a thumb reaches for. */
    .record-head-actions { width: 100%; margin-top: 0; }
    .record-head-actions > .record-btn { width: 100%; }
    .record-section { margin-top: 22px; }
}

/* ── The records list ─────────────────────────────────────────────────────────
   The whole filter block — chips plus the module selector — held apart from the list it filters.
   It sits ABOVE the async view rather than inside it, so a filter somebody just changed does not
   vanish while the re-fetch it triggered is in flight. */
.record-filter-bar {
    margin-bottom: 14px;
}

/* Search — a display-name filter above the chips (HQU-496), the records-surface twin of the
   management list's .til-search: same shape, painted in the paper palette instead of the admin
   tokens so it belongs on this surface. */
.record-search-wrap {
    position: relative;
    max-width: 360px;
    margin-bottom: 12px;
}

/* Positioning only — size and colour are set inline on the MudIcon so the icon-size utility
   class can't win a specificity fight over them (the management search does the same). */
.record-search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
}

.record-search {
    width: 100%;
    padding: 8px 12px 8px 38px;
    background: var(--rec-surface);
    border: 1px solid var(--rec-border);
    border-radius: 8px;
    color: var(--rec-text);
    font-size: var(--text-sm, 14px);
    outline: none;
    transition: border-color 0.15s;
}

.record-search::placeholder {
    color: var(--rec-faint);
}

.record-search:focus {
    border-color: var(--rec-muted);
}

/* Filter chips. They scroll horizontally on a phone rather than wrapping to three
   rows and pushing the list itself below the fold. */
.record-filters {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
}

.record-chip {
    flex: none;
    padding: 6px 14px;
    min-height: 34px;
    border: 1px solid var(--rec-border);
    border-radius: 999px;
    background: var(--rec-surface);
    color: var(--rec-muted);
    font-size: var(--text-sm, 13px);
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
}

.record-chip:hover {
    background: var(--rec-row-hover);
    color: var(--rec-text);
}

/* The selected chip is filled ink, not a tinted lifecycle colour: which filter is on
   is something YOU did, and the lifecycle family is reserved for what records are. */
.record-chip.is-on {
    background: var(--rec-text);
    border-color: var(--rec-text);
    color: var(--rec-surface);
    font-weight: 600;
}

.record-filters-modules {
    margin-top: 10px;
    max-width: 320px;
}

.record-list-more {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: 16px;
}

.record-list-count {
    font-size: var(--text-sm, 13px);
    color: var(--rec-faint);
}

/* The PWA landing's secondary links, below Today. */
.record-home-links {
    margin-top: 16px;
}
