/* ==========================================================================
   BP & Blood Sugar Tracking — "Clinical Ledger"
   --------------------------------------------------------------------------
   The system replaces Mater Misericordiae card MH-NUR FM 69: a green, ruled,
   hand-written record carried by the patient. The interface is built in that
   spirit rather than as generic medical software — warm paper stock, ink
   hairlines, tabular figures, folder tabs, rubber stamps.

   Nothing here is skeuomorphic. There are no fake paper textures or drop
   shadows pretending to be sheets. The card's GRAMMAR is borrowed: rules
   instead of boxes, stamps instead of badges, a right-hand initials column,
   and the form code printed where a real form prints it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
    /* White, like the form it replaces. A real clinical form is printed on
       white stock, so the page is white and the structure comes from ruled
       hairlines rather than from tinted panels — which is how a ledger works
       anyway. Sheets are white on white, separated by their borders. */
    --paper:        #FAFBFA;
    --paper-raised: #FFFFFF;
    --paper-sunk:   #F3F6F4;
    --shadow:       0 1px 2px rgba(17, 21, 26, .04), 0 6px 18px -8px rgba(17, 21, 26, .10);
    --shadow-lift:  0 2px 4px rgba(17, 21, 26, .05), 0 14px 32px -12px rgba(17, 21, 26, .16);
    --ink:          #11151A;
    --ink-soft:     #4E5661;
    --ink-faint:    #858E97;

    /* The card is green. This is that green taken down to something that can
       carry body text at 4.5:1 and still read as institutional. */
    --green:        #1B4332;
    --green-mid:    #2D6A4F;
    --green-pale:   #CBDCD0;
    --green-wash:   #E4EDE6;

    /* Sharp accents, used only for clinical state. Never decoration. */
    --vermilion:    #A4161A;
    --vermilion-wash: #F6E3E1;
    --amber:        #8A5200;
    --amber-wash:   #F6EAD6;

    --rule:         #E3E7E9;
    --rule-strong:  #C3CBD0;

    --font-display: "Fraunces", Georgia, serif;
    --font-body:    "Archivo", "Helvetica Neue", sans-serif;
    --font-mono:    "DM Mono", ui-monospace, monospace;

    /* A ledger has one rhythm: the ruled line. Everything sits on it. */
    --line:         2.25rem;
    --gutter:       clamp(1rem, 4vw, 3rem);

    --bs-body-font-family: var(--font-body);
    --bs-body-bg: var(--paper);
    --bs-body-color: var(--ink);
    --bs-border-color: var(--rule);
    --bs-link-color: var(--green);
    --bs-link-hover-color: var(--vermilion);
    --bs-border-radius: 2px;
    --bs-focus-ring-color: color-mix(in srgb, var(--green) 45%, transparent);
}

/* A carbon copy: the same document, duplicated in darkness. Greens hold, the
   paper becomes the graphite it was pressed through. */
:root:not([data-bs-theme="light"]) {
    color-scheme: light;
}

[data-bs-theme="dark"] {
    --paper:        #12161A;
    --paper-raised: #1A2024;
    --paper-sunk:   #0D1013;
    --shadow:       0 1px 2px rgba(0, 0, 0, .3), 0 6px 18px -8px rgba(0, 0, 0, .5);
    --shadow-lift:  0 2px 4px rgba(0, 0, 0, .35), 0 14px 32px -12px rgba(0, 0, 0, .6);
    --ink:          #E8E4D8;
    --ink-soft:     #9AA09A;
    --ink-faint:    #6B716C;

    --green:        #8FC5A6;
    --green-mid:    #6FAE8C;
    --green-pale:   #24382E;
    --green-wash:   #1A241E;

    --vermilion:    #F08A80;
    --vermilion-wash: #2E1A18;
    --amber:        #E0A857;
    --amber-wash:   #2A2114;

    --rule:         color-mix(in srgb, var(--ink) 16%, transparent);
    --rule-strong:  color-mix(in srgb, var(--ink) 32%, transparent);
    color-scheme: dark;
}

/* --------------------------------------------------------------------------
   2. Page
   -------------------------------------------------------------------------- */

html { -webkit-text-size-adjust: 100%; }

body {
    font-family: var(--font-body);
    -webkit-font-smoothing: antialiased;
    background-color: var(--paper);
    color: var(--ink);
    font-size: 0.975rem;
    line-height: 1.62;
    font-synthesis-weight: none;

}

/* The ruled-paper texture and the grain overlay are gone. Both were readable
   on cream and only made white look grubby — on a white page the ruling that
   matters is the one inside the ledger, which is real structure rather than
   decoration. */

::selection { background: var(--green-pale); color: var(--ink); }

:focus-visible {
    outline: 2px solid var(--green);
    outline-offset: 2px;
    border-radius: 1px;
}

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */

h1, h2, h3, h4, .display-face {
    font-family: var(--font-display);
    font-variation-settings: "SOFT" 0, "WONK" 1, "opsz" 36;
    font-weight: 600;
    letter-spacing: -0.012em;
    color: var(--ink);
}

h1, .h1 { font-size: clamp(1.9rem, 4.2vw, 2.9rem); line-height: 1.06; }
h2, .h2 { font-size: clamp(1.35rem, 2.6vw, 1.75rem); line-height: 1.15; }
h3, .h3 { font-size: 1.15rem; }

/* The label that runs above every block — a form's field caption. */
.caption {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-faint);
    display: block;
}

/* Anything a clinician reads as a quantity or an identifier. Tabular figures
   so columns of readings align down the page, as they do on the card. */
.figure-mono,
.ledger td.num,
.patient-no,
.vital-value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.patient-no {
    font-size: 0.82rem;
    letter-spacing: 0.06em;
    color: var(--green);
}

/* Bootstrap resolves link colour through --bs-link-color-rgb, not
   --bs-link-color, so setting only the latter left every link the framework's
   default blue — the one colour that has no meaning in this palette. */
a {
    color: var(--green);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.18em;
}

a:hover, a:focus { color: var(--vermilion); }

/* --------------------------------------------------------------------------
   4. The masthead — a form header, printed
   -------------------------------------------------------------------------- */

.masthead {
    background: var(--green);
    color: var(--green-wash);
    border-bottom: 3px double color-mix(in srgb, var(--green-wash) 40%, transparent);
}

[data-bs-theme="dark"] .masthead {
    background: var(--green-pale);
    color: var(--ink);
}

.masthead-inner {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 1.15rem var(--gutter) 0;
    max-width: 1320px;
    margin-inline: auto;
}

.masthead-title {
    font-family: var(--font-display);
    font-variation-settings: "SOFT" 0, "WONK" 1, "opsz" 48;
    font-weight: 600;
    font-size: 1.32rem;
    line-height: 1;
    letter-spacing: -0.02em;
    color: inherit;
    margin: 0;
    text-decoration: none;
}

.masthead-title:hover { color: inherit; }

/* The form code, set where a real form sets it. This one detail does more to
   place the product than any amount of chrome. */
.form-code {
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    opacity: 0.72;
    display: block;
    margin-top: 0.3rem;
}

/* --------------------------------------------------------------------------
   5. Folder tabs
   -------------------------------------------------------------------------- */

.tabs {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.tabs a {
    display: block;
    padding: 0.5rem 1.05rem 0.55rem;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    color: color-mix(in srgb, currentColor 72%, transparent);
    background: color-mix(in srgb, var(--ink) 14%, transparent);
    border-radius: 3px 3px 0 0;
    border: 1px solid transparent;
    border-bottom: none;
    transition: background 140ms ease, color 140ms ease, transform 140ms ease;
    white-space: nowrap;
}

.tabs a:hover {
    color: inherit;
    background: color-mix(in srgb, var(--ink) 22%, transparent);
    transform: translateY(-2px);
}

.tabs .active a {
    background: var(--paper);
    color: var(--ink);
    transform: translateY(1px);
    box-shadow: 0 -1px 0 var(--rule-strong);
}

/* --------------------------------------------------------------------------
   6. Sheets — the containers
   -------------------------------------------------------------------------- */

main { padding-block: clamp(1.5rem, 4vw, 2.75rem) 4rem; }

.wrap {
    max-width: 1320px;
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.wrap-narrow { max-width: 780px; }

.sheet {
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: clamp(1.15rem, 2.6vw, 1.9rem);
    position: relative;
    box-shadow: var(--shadow);
}

.sheet-marked, .sheet-critical, .sheet-warning { border-left-width: 3px; }

/* A sheet that matters carries a green edge, like a tabbed divider. */
.sheet-marked { border-left: 4px solid var(--green); }
.sheet-critical { border-left: 4px solid var(--vermilion); }
.sheet-warning { border-left: 4px solid var(--amber); }

.sheet-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding-bottom: 0.7rem;
    margin-bottom: 1.1rem;
    border-bottom: 2px solid var(--ink);
}

.sheet-head h2, .sheet-head h1 { margin: 0; }

/* --------------------------------------------------------------------------
   7. The page title block
   -------------------------------------------------------------------------- */

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: clamp(1.25rem, 3vw, 2rem);
    padding-bottom: 0.85rem;
    border-bottom: 3px double var(--rule-strong);
}

.page-head h1 { margin: 0.2rem 0 0; }

/* --------------------------------------------------------------------------
   8. The ledger — the card itself
   -------------------------------------------------------------------------- */

.ledger-wrap {
    border: 1px solid var(--rule);
    border-radius: 6px;
    background: var(--paper-raised);
    overflow-x: auto;
    box-shadow: var(--shadow);
}

table.ledger {
    width: 100%;
    border-collapse: collapse;
    margin: 0;
    font-size: 0.9rem;
}

table.ledger thead th {
    font-family: var(--font-mono);
    font-size: 0.63rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--ink-soft);
    text-align: left;
    padding: 0.78rem 0.95rem;
    background: var(--paper-sunk);
    border-bottom: 2px solid var(--ink);
    white-space: nowrap;
    vertical-align: bottom;
}

table.ledger tbody td {
    padding: 0.78rem 0.95rem;
    border-bottom: 1px solid var(--rule);
    vertical-align: middle;
}

table.ledger tbody tr:last-child td { border-bottom: none; }

/* A vertical rule before the initials column, exactly as the card is ruled. */
table.ledger .col-initials {
    border-left: 1px solid var(--rule-strong);
    text-align: center;
    width: 1%;
    white-space: nowrap;
}

table.ledger tbody tr {
    transition: background 120ms ease;
}

table.ledger tbody tr:hover { background: var(--green-wash); }

/* State is carried by the left edge, not by tinting the whole row — a tinted
   row makes the numbers harder to read, which is the opposite of the point. */
table.ledger tbody tr.is-critical { box-shadow: inset 4px 0 0 var(--vermilion); }
table.ledger tbody tr.is-warning  { box-shadow: inset 4px 0 0 var(--amber); }
table.ledger tbody tr.is-superseded { opacity: 0.5; }
table.ledger tbody tr.is-superseded .bp-value { text-decoration: line-through; }

.bp-value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.02rem;
    letter-spacing: -0.01em;
}

.unit {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-left: 0.22em;
}

/* The nurse's initials, as written in the last column of the card. */
.initials {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--rule-strong);
    border-radius: 50%;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    color: var(--green);
    background: var(--paper);
}

/* --------------------------------------------------------------------------
   9. Stamps
   -------------------------------------------------------------------------- */

.stamp {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    padding: 0.2rem 0.5rem;
    border: 1.5px solid currentColor;
    border-radius: 2px;
    white-space: nowrap;
    line-height: 1.2;
}

.stamp-critical { color: var(--vermilion); background: var(--vermilion-wash); }
.stamp-warning  { color: var(--amber);     background: var(--amber-wash); }
.stamp-normal   { color: var(--green-mid); background: var(--green-wash); }
.stamp-muted    { color: var(--ink-faint); background: transparent; }

/* The big one: pressed at an angle across a sheet, the way a clerk stamps a
   file. Used once per page at most, on a reading that could kill someone. */
.stamp-pressed {
    position: absolute;
    top: 1.1rem;
    right: 1.1rem;
    transform: rotate(-11deg);
    font-family: var(--font-mono);
    font-size: 0.82rem;
    font-weight: 500;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--vermilion);
    border: 2.5px double var(--vermilion);
    border-radius: 3px;
    padding: 0.32rem 0.7rem;
    opacity: 0.85;
    pointer-events: none;
    animation: press 420ms cubic-bezier(0.2, 1.6, 0.4, 1) both;
}

@keyframes press {
    0%   { opacity: 0; transform: rotate(-11deg) scale(2.1); }
    60%  { opacity: 0.95; transform: rotate(-11deg) scale(0.94); }
    100% { opacity: 0.85; transform: rotate(-11deg) scale(1); }
}

/* --------------------------------------------------------------------------
   10. Vitals — the reading, read at arm's length
   -------------------------------------------------------------------------- */

.vitals {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    border-radius: 5px;
    overflow: hidden;
}

.vital {
    background: var(--paper-raised);
    padding: 0.9rem 1rem 1rem;
}

.vital-value {
    font-size: clamp(1.5rem, 3.4vw, 2.1rem);
    line-height: 1;
    letter-spacing: -0.03em;
    display: block;
    margin-top: 0.3rem;
    color: var(--ink);
}

.vital-value.is-critical { color: var(--vermilion); }
.vital-value.is-warning  { color: var(--amber); }
.vital-value.is-empty    { color: var(--ink-faint); font-size: 1.4rem; }

/* --------------------------------------------------------------------------
   11. Forms
   -------------------------------------------------------------------------- */

.form-label {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: 0.3rem;
}

.form-control, .form-select {
    background-color: var(--paper);
    border: 1px solid var(--rule-strong);
    border-radius: 2px;
    color: var(--ink);
    padding: 0.5rem 0.7rem;
    font-size: 0.95rem;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.form-control:focus, .form-select:focus {
    background-color: var(--paper-raised);
    border-color: var(--green);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 18%, transparent);
    color: var(--ink);
}

.form-control::placeholder { color: var(--ink-faint); }

/* Measurements are typed as numbers and should look like numbers while being
   typed — it makes a transposed digit easier to catch. */
input.figure-mono, .form-control.figure-mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.15rem;
    letter-spacing: 0.02em;
}

.form-text { color: var(--ink-faint); font-size: 0.8rem; }
.invalid-feedback { color: var(--vermilion); font-size: 0.8rem; }
.is-invalid { border-color: var(--vermilion) !important; }

/* A field group ruled like a section of the form. */
.field-set {
    border: none;
    border-top: 1px solid var(--rule);
    padding-top: 1.1rem;
    margin-top: 1.4rem;
}

.field-set > legend {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--green);
    width: auto;
    padding-right: 0.7rem;
    float: none;
    margin-bottom: 0.9rem;
}

/* --------------------------------------------------------------------------
   12. Buttons
   -------------------------------------------------------------------------- */

.btn {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    border-radius: 2px;
    padding: 0.55rem 1.1rem;
    border-width: 1px;
    transition: transform 100ms ease, background 140ms ease, color 140ms ease;
}

.btn:active { transform: translateY(1px); }

.btn-ink {
    background: var(--green);
    color: var(--paper-raised);
    border-color: var(--green);
}
.btn-ink:hover, .btn-ink:focus {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper-raised);
}

.btn-outline-ink {
    background: transparent;
    color: var(--ink);
    border-color: var(--rule-strong);
}
.btn-outline-ink:hover, .btn-outline-ink:focus {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}

.btn-danger-ink {
    background: transparent;
    color: var(--vermilion);
    border-color: var(--vermilion);
}
.btn-danger-ink:hover, .btn-danger-ink:focus {
    background: var(--vermilion);
    color: var(--paper-raised);
}

.btn-sm { padding: 0.32rem 0.7rem; font-size: 0.64rem; }

/* --------------------------------------------------------------------------
   13. Alerts and empty states
   -------------------------------------------------------------------------- */

.alert {
    border-radius: 2px;
    border: 1px solid var(--rule-strong);
    border-left-width: 4px;
    background: var(--paper-raised);
    color: var(--ink);
    font-size: 0.92rem;
    padding: 0.8rem 1rem;
}

.alert-success { border-left-color: var(--green); }
.alert-danger  { border-left-color: var(--vermilion); }
.alert-warning { border-left-color: var(--amber); }
.alert-info    { border-left-color: var(--ink-soft); }

.empty {
    text-align: center;
    padding: clamp(2rem, 6vw, 3.5rem) 1rem;
    color: var(--ink-faint);
}

.empty-mark {
    font-family: var(--font-display);
    font-size: 2.6rem;
    font-variation-settings: "WONK" 1;
    color: var(--rule-strong);
    display: block;
    margin-bottom: 0.4rem;
}

/* --------------------------------------------------------------------------
   14. Load choreography
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    .reveal {
        animation: rise 520ms cubic-bezier(0.22, 0.8, 0.3, 1) both;
    }

    /* Ledger rows settle one after another, like a printer laying them down. */
    .ledger tbody tr {
        animation: rule-in 340ms ease-out both;
    }
    .ledger tbody tr:nth-child(1)  { animation-delay: 30ms; }
    .ledger tbody tr:nth-child(2)  { animation-delay: 60ms; }
    .ledger tbody tr:nth-child(3)  { animation-delay: 90ms; }
    .ledger tbody tr:nth-child(4)  { animation-delay: 120ms; }
    .ledger tbody tr:nth-child(5)  { animation-delay: 150ms; }
    .ledger tbody tr:nth-child(6)  { animation-delay: 180ms; }
    .ledger tbody tr:nth-child(7)  { animation-delay: 210ms; }
    .ledger tbody tr:nth-child(8)  { animation-delay: 240ms; }
    .ledger tbody tr:nth-child(n+9) { animation-delay: 270ms; }

    .vital { animation: rise 420ms ease-out both; }
    .vitals .vital:nth-child(2) { animation-delay: 60ms; }
    .vitals .vital:nth-child(3) { animation-delay: 120ms; }
    .vitals .vital:nth-child(4) { animation-delay: 180ms; }
    .vitals .vital:nth-child(5) { animation-delay: 240ms; }
}

@keyframes rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

@keyframes rule-in {
    from { opacity: 0; transform: translateX(-6px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* --------------------------------------------------------------------------
   15. Footer
   -------------------------------------------------------------------------- */

.colophon {
    border-top: 3px double var(--rule-strong);
    padding: 1.2rem 0 2rem;
    margin-top: 3rem;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
}

.colophon a { color: var(--ink-soft); }

/* --------------------------------------------------------------------------
   16. Utilities
   -------------------------------------------------------------------------- */

.rule-top { border-top: 1px solid var(--rule); }
.text-soft { color: var(--ink-soft); }
.text-faint { color: var(--ink-faint); }
.stack > * + * { margin-top: var(--stack-gap, 1rem); }

.tally {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: clamp(2rem, 5vw, 3.1rem);
    line-height: 0.95;
    letter-spacing: -0.04em;
    display: block;
}

.tally-critical { color: var(--vermilion); }
.tally-warning  { color: var(--amber); }
.tally-calm     { color: var(--green); }

@media (max-width: 575.98px) {
    .masthead-inner { padding-inline: 1rem; }
    .tabs { overflow-x: auto; padding-bottom: 0; }
    table.ledger { font-size: 0.82rem; }
    table.ledger thead th,
    table.ledger tbody td { padding: 0.5rem 0.55rem; }
}

/* Bootstrap's own controls, brought onto the paper. */
.form-check-input {
    background-color: var(--paper);
    border: 1px solid var(--rule-strong);
    border-radius: 2px;
    width: 1.05em;
    height: 1.05em;
    margin-top: 0.22em;
}

.form-check-input:checked {
    background-color: var(--green);
    border-color: var(--green);
}

.form-check-input:focus {
    border-color: var(--green);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 18%, transparent);
}

.form-check-label { font-size: 0.9rem; }

/* Pagination, as a run of ruled boxes rather than pills. */
.pagination { gap: 2px; }

.page-link {
    background: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: 2px;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    padding: 0.32rem 0.6rem;
}

.page-link:hover { background: var(--green-wash); color: var(--ink); }

.active > .page-link {
    background: var(--green);
    border-color: var(--green);
    color: var(--paper-raised);
}

.disabled > .page-link { color: var(--ink-faint); background: transparent; }

/* ==========================================================================
   17. Polish — the parts that are only noticed when they are missing
   ========================================================================== */

/* Skip to content. Visible the moment it is focused, and nowhere otherwise. */
.skip-link {
    position: absolute;
    left: 0.5rem;
    top: -4rem;
    z-index: 10000;
    background: var(--ink);
    color: var(--paper);
    padding: 0.6rem 1rem;
    border-radius: 0 0 3px 3px;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    transition: top 140ms ease;
}

.skip-link:focus {
    top: 0;
    color: var(--paper);
}

#main:focus { outline: none; }

/* Sticky masthead. A nurse scrolling sixty lines of card should not have to
   scroll back up to reach the patient list. Kept shallow, and on a phone the
   tab row is the only part that stays. */
.masthead {
    position: sticky;
    top: 0;
    z-index: 1020;
}

/* Touch targets. 44px is the smallest a thumb reliably hits, and this is used
   one-handed while holding a cuff. */
@media (pointer: coarse) {
    .tabs a { padding-block: 0.75rem; }
    .btn { padding-block: 0.7rem; }
    .btn-sm { padding-block: 0.5rem; }
    .initials { width: 2.4rem; height: 2.4rem; }
}

/* Back to top */
#back-to-top {
    position: fixed;
    right: 1.1rem;
    bottom: 1.1rem;
    z-index: 1030;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--ink);
    color: var(--paper);
    border: none;
    border-radius: 2px;
    padding: 0.6rem 0.85rem;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity 180ms ease, transform 180ms ease, visibility 180ms;
}

#back-to-top.is-visible { opacity: 0.92; visibility: visible; transform: none; }
#back-to-top:hover { opacity: 1; background: var(--green); }

/* Copy buttons sit beside the value they copy, not on top of it. */
.copy-btn {
    background: none;
    border: 1px solid var(--rule);
    border-radius: 2px;
    color: var(--ink-faint);
    font-family: var(--font-mono);
    font-size: 0.58rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0.1rem 0.35rem;
    margin-left: 0.4rem;
    cursor: pointer;
    vertical-align: middle;
    transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}

.copy-btn:hover, .copy-btn:focus-visible { color: var(--green); border-color: var(--green); }
.copy-btn.is-copied { color: var(--green); border-color: var(--green); background: var(--green-wash); }
.copy-btn.is-copy-failed { color: var(--vermilion); border-color: var(--vermilion); }

/* A button that is working says so, and cannot be pressed again. */
.btn.is-busy {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}

.btn.is-busy::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 0.95em;
    height: 0.95em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    color: var(--paper-raised);
    animation: spin 620ms linear infinite;
}

.btn-outline-ink.is-busy::after, .btn-danger-ink.is-busy::after { color: var(--ink); }

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .btn.is-busy::after { animation: none; border-top-color: currentColor; opacity: 0.5; }
}

/* The password reveal sits inside the field's trailing edge. */
.field-with-reveal { position: relative; }

.field-with-reveal .form-control { padding-right: 4.2rem; }

.reveal-btn {
    position: absolute;
    right: 0.35rem;
    bottom: 0.35rem;
    background: none;
    border: none;
    color: var(--ink-faint);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0.35rem 0.5rem;
    cursor: pointer;
}

.reveal-btn:hover, .reveal-btn:focus-visible { color: var(--green); }

/* ==========================================================================
   18. Print — the card, on paper again
   --------------------------------------------------------------------------
   This is not a nicety. A patient is discharged, transferred, or goes to a
   clinic with no system, and the card has to travel with them — that is the
   whole reason the paper existed. So printing produces a clean record, not a
   screenshot of an application: no navigation, no forms, no buttons, black on
   white, and every ruled line kept.
   ========================================================================== */

@media print {
    :root {
        --paper: #fff;
        --paper-raised: #fff;
        --paper-sunk: #fff;
        --ink: #000;
        --ink-soft: #333;
        --ink-faint: #555;
        --rule: #999;
        --rule-strong: #333;
        --green: #000;
        --green-wash: #fff;
    }

    @page { margin: 14mm; }

    body {
        background: #fff !important;
        background-image: none !important;
        color: #000;
        font-size: 10.5pt;
    }

    body::before { display: none !important; }

    /* Anything that only exists to be clicked. */
    .masthead .tabs,
    .masthead form,
    .masthead .btn,
    .colophon,
    #back-to-top,
    .copy-btn,
    .reveal-btn,
    .btn,
    .alert,
    form,
    .page-head > div:last-child,
    .sheet-head .caption {
        display: none !important;
    }

    /* The sheet holding the entry form goes with it. */
    #reading-form,
    .sheet:has(#reading-form) { display: none !important; }

    .masthead {
        position: static;
        background: #fff !important;
        color: #000 !important;
        border-bottom: 2px solid #000;
        padding-bottom: 0.4rem;
    }

    .masthead-inner { padding: 0; display: block; }
    .masthead-title { font-size: 13pt; color: #000; }
    .form-code { opacity: 1; color: #000; }

    main { padding: 0; }
    .wrap { max-width: none; padding: 0; }

    /* Let the ledger use the full width once the entry column is gone. */
    .col-lg-8, .col-lg-4 { width: 100% !important; max-width: none !important; flex: 0 0 100% !important; }

    .sheet, .ledger-wrap, .vitals, .vital {
        border-color: #333 !important;
        break-inside: avoid;
    }

    .sheet { padding: 0 0 0.6rem; border: none; border-bottom: 1px solid #999; }

    table.ledger { font-size: 9.5pt; }
    table.ledger thead { display: table-header-group; }
    table.ledger thead th { background: #fff; border-bottom: 1.5pt solid #000; }
    table.ledger tbody tr { break-inside: avoid; box-shadow: none !important; }
    table.ledger tbody td { border-bottom: 0.5pt solid #999; }

    /* State has to survive the loss of colour, so it becomes a printed word. */
    table.ledger tbody tr.is-critical td:first-child::before { content: "!! "; font-weight: 700; }
    table.ledger tbody tr.is-warning td:first-child::before { content: "!  "; }

    .stamp { border-color: #000; color: #000; background: #fff; }
    .stamp-pressed { color: #000; border-color: #000; opacity: 1; animation: none; }
    .initials { border-color: #333; color: #000; }

    a { color: #000; text-decoration: none; }

    /* Say where and when it was printed; a loose page needs to identify itself. */
    .ledger-wrap::after {
        content: "Printed from the Blood Pressure & Blood Sugar Record. Superseded readings are not shown.";
        display: block;
        padding: 6pt 2pt;
        font-size: 8pt;
        color: #555;
        border-top: 0.5pt solid #999;
    }

    .reveal, .vital, .ledger tbody tr { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* The theme toggle. color-mode.js already stored the preference and followed
   the operating system; all that was missing was something to press. */
.theme-toggle {
    background: none;
    border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
    border-radius: 2px;
    color: inherit;
    font-size: 0.82rem;
    line-height: 1;
    padding: 0.42rem 0.55rem;
    cursor: pointer;
    transition: background 140ms ease, border-color 140ms ease;
}

.theme-toggle:hover, .theme-toggle:focus-visible {
    background: color-mix(in srgb, currentColor 14%, transparent);
    border-color: currentColor;
}

@media print { .theme-toggle { display: none !important; } }

/* On a phone the masthead was ~240px tall — a third of the screen, and sticky,
   so it followed you down a sixty-line card. Compact it: the title shrinks to
   one line, the form code steps aside (it is on the printed card anyway), and
   the tab row stays because that is the part worth keeping in reach. */
@media (max-width: 767.98px) {
    .masthead-inner { padding-top: 0.6rem; gap: 0.5rem; }

    .masthead-title {
        font-size: 1rem;
        display: block;
        max-width: 60vw;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .masthead .form-code { display: none; }
    .masthead .d-flex.align-items-center { padding-bottom: 0 !important; }
    .masthead .caption { display: none; }
    .tabs a { padding-block: 0.6rem; font-size: 0.66rem; }
}

/* A table that scrolls sideways should say so. The fade only appears while
   there is more to the right of it. */
.ledger-wrap {
    background-image: linear-gradient(to right, transparent calc(100% - 2.5rem), color-mix(in srgb, var(--ink) 9%, transparent));
    background-repeat: no-repeat;
    background-attachment: local, scroll;
}

@media (min-width: 992px) { .ledger-wrap { background-image: none; } }

/* ==========================================================================
   19. The ledger becomes cards on a phone
   --------------------------------------------------------------------------
   A seven-column table on a 390px screen can only scroll sideways, and a nurse
   reading a card one-handed should not have to drag it about to see the blood
   pressure. Below 768px each row becomes its own card, with the column heading
   carried on each value through data-label — so the same markup serves both
   and there is no second template to keep in step.
   ========================================================================== */

@media (max-width: 767.98px) {
    .ledger-wrap {
        border: none;
        background: none;
        box-shadow: none;
        overflow: visible;
        background-image: none;
    }

    table.ledger,
    table.ledger tbody,
    table.ledger tr,
    table.ledger td {
        display: block;
        width: 100%;
    }

    /* The headings move onto the values themselves. */
    table.ledger thead { display: none; }

    table.ledger tbody tr {
        background: var(--paper-raised);
        border: 1px solid var(--rule);
        border-radius: 6px;
        box-shadow: var(--shadow);
        margin-bottom: 0.75rem;
        padding: 0.15rem 0;
        overflow: hidden;
    }

    table.ledger tbody tr:hover { background: var(--paper-raised); }

    /* State keeps its left edge, which is the one cue worth carrying over.
       A real border rather than an inset shadow: the cells have their own
       backgrounds, and an inset shadow shows through between them as a
       broken line. */
    table.ledger tbody tr.is-critical,
    table.ledger tbody tr.is-warning {
        box-shadow: var(--shadow);
        border-left-width: 4px;
        border-left-style: solid;
    }

    table.ledger tbody tr.is-critical { border-left-color: var(--vermilion); }
    table.ledger tbody tr.is-warning { border-left-color: var(--amber); }

    table.ledger tbody td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 1.25rem;
        padding: 0.6rem 0.95rem;
        border-bottom: 1px solid var(--rule);
        text-align: right;
        max-width: none !important;
    }

    table.ledger tbody td::before {
        content: attr(data-label);
        font-family: var(--font-mono);
        font-size: 0.6rem;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: var(--ink-faint);
        text-align: left;
        flex: 0 0 auto;
    }

    /* A cell with no label is the row's actions: give it the full width. */
    table.ledger tbody td:not([data-label]) {
        display: flex;
        justify-content: flex-end;
        gap: 0.4rem;
        flex-wrap: wrap;
        background: var(--paper-sunk);
        border-bottom: none;
    }

    table.ledger tbody td:not([data-label]):empty { display: none; }

    table.ledger tbody td:last-child { border-bottom: none; }

    /* The first cell is the row's heading: name, or date. */
    table.ledger tbody td:first-child {
        font-size: 1.02rem;
        background: var(--paper-sunk);
        border-bottom: 1px solid var(--rule);
    }

    table.ledger tbody td:first-child::before { align-self: center; }

    /* The initials column loses its rule; it is its own line now. */
    table.ledger .col-initials {
        border-left: none;
        text-align: right;
        width: auto;
    }

    /* Values that were sized for a dense table can breathe. */
    .bp-value { font-size: 1.06rem; }
}

/* ==========================================================================
   20. Charts
   --------------------------------------------------------------------------
   Two categorical hues for systolic and diastolic, validated with the palette
   checker against both surfaces rather than chosen by eye:

     light & dark   #0E8A5F ↔ #8054C7
                    CVD ΔE 18.3 deutan / 12.1 tritan, normal-vision 27.2,
                    both inside the lightness band, both above the chroma
                    floor, both ≥ 3:1 against the surface.

   They are deliberately NOT the status colours. Vermilion and amber mean
   critical and warning on this system; reusing them for "series 2" would make
   a diastolic line look like an alarm.
   ========================================================================== */

:root {
    --series-sys: #0E8A5F;
    --series-dia: #8054C7;
}

/* The same steps pass against the dark surface, so they carry over unchanged
   rather than being flipped to something lighter that fails the band. */
[data-bs-theme="dark"] {
    --series-sys: #0E8A5F;
    --series-dia: #8054C7;
}

.chart { margin: 0; }

.chart-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}

.chart-sub {
    display: block;
    font-size: 0.82rem;
    color: var(--ink-soft);
    margin-top: 0.15rem;
}

.chart-legend {
    display: flex;
    gap: 1rem;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.78rem;
    color: var(--ink-soft);
    flex-wrap: wrap;
}

.chart-legend li { display: flex; align-items: center; gap: 0.4rem; }

.swatch { width: 10px; height: 10px; border-radius: 2px; flex: 0 0 auto; }
.swatch-sys { background: var(--series-sys); }
.swatch-dia { background: var(--series-dia); }
.swatch-target { background: transparent; border-top: 2px dashed var(--ink-faint); height: 0; border-radius: 0; }

.chart-plot { position: relative; }

/* The SVG scales uniformly. preserveAspectRatio="none" would let it fill any
   box, but it stretches the coordinate system — and that squashes the axis
   numbers and the point labels, which are text. Proportional scaling keeps
   them legible at every width. */
.chart-plot svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

/* Recessive chrome: hairlines one shade off the surface, never dashed. */
.grid { stroke: var(--rule); stroke-width: 1; }
.axis { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 10px; }

/* Dashed here is meaningful — it is a threshold, not a gridline. */
.threshold { stroke: var(--ink-faint); stroke-width: 1.5; stroke-dasharray: 5 4; opacity: .75; }

.line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.line-sys { stroke: var(--series-sys); }
.line-dia { stroke: var(--series-dia); }

.area { stroke: none; opacity: .10; }
.area-sys { fill: var(--series-sys); }
.area-dia { fill: var(--series-dia); }

/* A 2px surface ring keeps overlapping markers apart without a border. */
.dot { stroke: var(--paper-raised); stroke-width: 2; }
.dot-sys { fill: var(--series-sys); }
.dot-dia { fill: var(--series-dia); }

.point-label {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    paint-order: stroke;
    stroke: var(--paper-raised);
    stroke-width: 3px;
}

.label-sys { fill: var(--series-sys); }
.label-dia { fill: var(--series-dia); }

.crosshair { stroke: var(--ink-faint); stroke-width: 1; transition: opacity 90ms ease; }

.chart-tip {
    position: absolute;
    z-index: 5;
    pointer-events: none;
    background: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: 4px;
    box-shadow: var(--shadow-lift);
    padding: 0.5rem 0.65rem;
    font-size: 0.78rem;
    white-space: nowrap;
    transform: translate(-50%, -120%);
}

.chart-tip .tip-at {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
    display: block;
    margin-bottom: 0.25rem;
}

.chart-tip .tip-row { display: flex; align-items: center; gap: 0.4rem; }
.chart-tip .tip-row b { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.chart-axis-x {
    display: flex;
    justify-content: space-between;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    color: var(--ink-faint);
    padding: 0.4rem 1rem 0 2.4rem;
}

/* --------------------------------------------------------------------------
   Stat tiles — the headline numbers. A single value is not a chart.
   -------------------------------------------------------------------------- */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0.9rem;
    margin-bottom: 1.25rem;
}

.tile {
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 6px;
    box-shadow: var(--shadow);
    padding: 1rem 1.1rem 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.tile-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.tile-icon {
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 6px;
    background: var(--green-wash);
    color: var(--green);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    font-size: 0.9rem;
}

.tile-value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: clamp(1.5rem, 3vw, 1.95rem);
    line-height: 1.05;
    letter-spacing: -0.03em;
    margin-top: 0.3rem;
}

.tile-value.is-critical { color: var(--vermilion); }
.tile-value.is-warning { color: var(--amber); }
.tile-value.is-empty { color: var(--ink-faint); font-size: 1.2rem; }

.tile-foot {
    font-size: 0.78rem;
    color: var(--ink-soft);
    margin-top: 0.45rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--rule);
}

/* A change pill. Up is not automatically good here — a blood pressure that
   rose is worse — so the arrow states direction and the words state meaning;
   colour alone never carries it. */
.delta {
    display: inline-flex;
    align-items: center;
    gap: 0.22rem;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    padding: 0.12rem 0.36rem;
    border-radius: 3px;
    border: 1px solid currentColor;
    white-space: nowrap;
}

.delta-better { color: var(--green-mid); background: var(--green-wash); }
.delta-worse { color: var(--vermilion); background: var(--vermilion-wash); }
.delta-flat { color: var(--ink-faint); }

/* --------------------------------------------------------------------------
   Control breakdown — how the last readings came out.
   Status colours, each with a written label, never colour alone.
   -------------------------------------------------------------------------- */

.breakdown { list-style: none; margin: 0; padding: 0; }

.breakdown li {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 0.3rem 1rem;
    padding: 0.85rem 0;
    border-top: 1px solid var(--rule);
}

.breakdown li:first-child { border-top: none; padding-top: 0; }

.breakdown .bd-label {
    font-size: 0.95rem;
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

/* A small square of the status colour beside its written label — so the state
   is named, and the colour only reinforces it. */
.breakdown .bd-dot {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    flex: 0 0 auto;
}

.breakdown .bd-count {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.15rem;
}

.breakdown .bd-bar {
    grid-column: 1 / -1;
    height: 5px;
    border-radius: 3px;
    background: var(--paper-sunk);
    overflow: hidden;
    margin-top: 0.1rem;
}

/* Scoped to the bar's own fill. Unscoped, this painted the label, the count
   and the percentage as well, and the row came out as a solid block. */
.breakdown .bd-bar > span { display: block; height: 100%; border-radius: 3px; }

.bd-normal .bd-bar > span, .bd-normal .bd-dot { background: var(--green-mid); }
.bd-warning .bd-bar > span, .bd-warning .bd-dot { background: var(--amber); }
.bd-critical .bd-bar > span, .bd-critical .bd-dot { background: var(--vermilion); }

.breakdown .bd-pct {
    grid-column: 1 / -1;
    font-size: 0.78rem;
    color: var(--ink-faint);
}

/* The SVG scales down to roughly 0.45 at phone width, and its text scales with
   it — a 10px axis label would render at about 4.5px. These are source sizes
   inside the viewBox, so they are chosen to land back at a readable size once
   scaled, not to look right in the markup. */
@media (max-width: 767.98px) {
    .chart-axis-x { padding-left: 2.2rem; }
    .axis { font-size: 21px; }
    .point-label { font-size: 22px; stroke-width: 5px; }
    .dot { r: 6; stroke-width: 4; }
    .line { stroke-width: 4; }
    .grid { stroke-width: 2; }
    .threshold { stroke-width: 3; stroke-dasharray: 10 8; }
}

@media print {
    .chart-tip, .crosshair { display: none !important; }
}

/* ==========================================================================
   21. Mobile first — the caregiver's screen
   --------------------------------------------------------------------------
   Measured before changing anything: the patient page ran to 6,644px at 390px
   wide, which is 7.9 phone screens. The card was 51% of it and the entry form
   another 13%. Those two are what this section addresses; the rest is
   removing repetition and shortening the chrome around them.
   ========================================================================== */

.phone-only { display: none; }

@media (max-width: 991.98px) {
    .desk-only { display: none !important; }
    .phone-only { display: block; }
    /* Inside a line of text it must not become a block. */
    .masthead-title .phone-only, span.phone-only.inline { display: inline; }
}

/* --------------------------------------------------------------------------
   The action bar — the one thing the caregiver came to do
   -------------------------------------------------------------------------- */

.action-bar {
    display: flex;
    gap: 0.5rem;
    align-items: stretch;
    margin-bottom: 1rem;
}

.btn-lg { padding: 0.95rem 1.1rem; font-size: 0.82rem; }

/* Secondary actions behind one control, so they do not compete with the
   primary one. <details> rather than a JS menu: it opens without scripting. */
.more-menu { position: relative; }

.more-menu > summary {
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 3.1rem;
    height: 100%;
    cursor: pointer;
}

.more-menu > summary::-webkit-details-marker { display: none; }

.more-menu-sheet {
    position: absolute;
    right: 0;
    top: calc(100% + 0.35rem);
    z-index: 30;
    min-width: 12rem;
    background: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: 6px;
    box-shadow: var(--shadow-lift);
    padding: 0.35rem;
    display: flex;
    flex-direction: column;
}

.more-menu-sheet a,
.more-menu-sheet .as-link {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.7rem 0.75rem;
    border: none;
    background: none;
    border-radius: 4px;
    color: var(--ink);
    text-decoration: none;
    font-size: 0.95rem;
    cursor: pointer;
}

.more-menu-sheet a:hover,
.more-menu-sheet .as-link:hover { background: var(--green-wash); }

/* --------------------------------------------------------------------------
   Phone layout
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {

    /* Two tiles across rather than four stacked: the same four numbers in a
       quarter of the height, and still large enough to read at arm's length. */
    .tiles {
        grid-template-columns: 1fr 1fr;
        gap: 0.5rem;
        margin-bottom: 1rem;
    }

    .tile { padding: 0.7rem 0.75rem 0.65rem; border-radius: 8px; }
    .tile-value { font-size: 1.3rem; margin-top: 0.2rem; }
    .tile-icon { display: none; }

    /* The footnote is the least of it; keep the number and the change. */
    .tile-foot {
        margin-top: 0.35rem;
        padding-top: 0.35rem;
        font-size: 0.7rem;
        line-height: 1.35;
    }

    .tile-foot .delta { margin-bottom: 0.1rem; }

    /* Headings and page chrome shrink; the content does not. */
    .page-head {
        margin-bottom: 0.9rem;
        padding-bottom: 0.6rem;
        border-bottom-width: 1px;
        border-bottom-style: solid;
    }

    h1, .h1 { font-size: 1.55rem; }
    h2, .h2 { font-size: 1.15rem; }

    main { padding-block: 1rem 5.5rem; }

    .sheet { padding: 0.9rem 0.95rem; border-radius: 8px; }
    .sheet-head { margin-bottom: 0.7rem; padding-bottom: 0.5rem; }
    .row.g-4 { --bs-gutter-y: 0.75rem; }
    section.mb-4, section.mb-5 { margin-bottom: 0.9rem !important; }

    /* ----------------------------------------------------------------------
       The card, compacted
       ----------------------------------------------------------------------
       One reading was a stack of seven labelled rows, about 380px each. It is
       now two lines: the date and blood pressure, then everything else on one
       line beneath. Nothing is dropped — the values that had their own row
       are still here, just set inline.
       ---------------------------------------------------------------------- */

    table.ledger tbody tr {
        display: grid;
        grid-template-columns: 1fr auto;
        align-items: baseline;
        gap: 0.1rem 0.6rem;
        padding: 0.7rem 0.85rem;
        margin-bottom: 0.45rem;
    }

    table.ledger tbody td {
        display: inline;
        padding: 0;
        border: none;
        text-align: left;
        background: none !important;
    }

    /* Labels go, except where a bare number would be ambiguous. */
    table.ledger tbody td::before { content: none; }

    /* Date leads the row. */
    table.ledger tbody td:nth-child(1) {
        grid-column: 1;
        grid-row: 1;
        font-family: var(--font-mono);
        font-size: 0.72rem;
        color: var(--ink-soft);
        letter-spacing: 0.02em;
    }

    table.ledger tbody td:nth-child(1) br { display: none; }
    table.ledger tbody td:nth-child(1) .text-faint::before { content: " · "; }

    /* Blood pressure is the headline. */
    table.ledger tbody td:nth-child(2) {
        grid-column: 1;
        grid-row: 2;
        font-size: 1.25rem;
    }

    table.ledger tbody td:nth-child(2) .bp-value { font-size: 1.25rem; }

    /* HR, sugar and weight run together on one line, each labelled so a bare
       number is never ambiguous. */
    table.ledger tbody td:nth-child(3),
    table.ledger tbody td:nth-child(4),
    table.ledger tbody td:nth-child(5) {
        grid-column: 1;
        grid-row: 3;
        font-family: var(--font-mono);
        font-size: 0.76rem;
        color: var(--ink-soft);
    }

    table.ledger tbody td:nth-child(3)::after { content: " bpm"; opacity: .65; }
    table.ledger tbody td:nth-child(4)::after { content: " mmol · "; opacity: .65; }
    table.ledger tbody td:nth-child(3)::before { content: none; }
    table.ledger tbody td:nth-child(4)::before { content: " · "; opacity: .65; }
    table.ledger tbody td:nth-child(5)::after { content: " kg"; opacity: .65; }

    table.ledger tbody td:nth-child(6) {
        grid-column: 1 / -1;
        grid-row: 4;
        font-size: 0.8rem;
        color: var(--ink-soft);
    }

    table.ledger tbody td:nth-child(6):empty { display: none; }

    /* Initials and the actions ride on the right of the first two rows. */
    table.ledger .col-initials {
        grid-column: 2;
        grid-row: 1 / span 2;
        align-self: center;
    }

    table.ledger tbody td:last-child {
        grid-column: 2;
        grid-row: 3 / span 2;
        align-self: center;
        text-align: right;
        display: flex;
        justify-content: flex-end;
        gap: 0.3rem;
    }

    /* Show the recent few; the rest is one tap away. */
    .ledger-wrap[data-collapsible-rows].is-collapsed tbody tr:nth-child(n + 5) { display: none; }
    .rows-toggle[hidden] { display: none; }

    /* ----------------------------------------------------------------------
       Forms
       ---------------------------------------------------------------------- */

    /* 16px keeps iOS from zooming the page when a field is focused, which
       otherwise throws the layout sideways mid-entry. */
    .form-control, .form-select { font-size: 16px; padding: 0.7rem 0.8rem; }
    input.figure-mono, .form-control.figure-mono { font-size: 1.25rem; }

    .form-label { font-size: 0.66rem; margin-bottom: 0.2rem; }
    .form-text { font-size: 0.76rem; }

    /* Two number fields side by side: systolic and diastolic belong together
       and are read together off the cuff. */
    .pair {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.6rem;
    }

    .pair-sugar { grid-template-columns: 1.4fr 1fr; }

    .field-set { margin-top: 0.9rem; padding-top: 0.8rem; }
    .field-set > legend { margin-bottom: 0.6rem; }
}

/* --------------------------------------------------------------------------
   Collapsible section — for the parts of a form that are usually right
   -------------------------------------------------------------------------- */

.fold {
    border: 1px solid var(--rule);
    border-radius: 6px;
    margin: 0.75rem 0;
    background: var(--paper-sunk);
}

.fold > summary {
    list-style: none;
    cursor: pointer;
    padding: 0.7rem 0.85rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-soft);
}

.fold > summary::-webkit-details-marker { display: none; }

.fold > summary::after {
    content: "▾";
    font-size: 0.8rem;
    transition: transform 160ms ease;
}

.fold[open] > summary::after { transform: rotate(180deg); }

.fold-hint {
    font-size: 0.66rem;
    letter-spacing: 0.04em;
    text-transform: none;
    color: var(--ink-faint);
    margin-left: auto;
    margin-right: 0.4rem;
}

.fold[open] .fold-hint { display: none; }

.fold-body { padding: 0 0.85rem 0.85rem; }

/* --------------------------------------------------------------------------
   Sticky save — never hunt for the button
   -------------------------------------------------------------------------- */

.form-actions { margin-top: 1rem; }

.form-actions-note {
    font-size: 0.74rem;
    color: var(--ink-faint);
    margin: 0.5rem 0 0;
    text-align: center;
}

@media (max-width: 991.98px) {
    .form-actions {
        position: sticky;
        bottom: 0;
        z-index: 25;
        margin: 1rem -0.95rem -0.9rem;
        padding: 0.7rem 0.95rem calc(0.7rem + env(safe-area-inset-bottom));
        background: var(--paper-raised);
        border-top: 1px solid var(--rule);
        box-shadow: 0 -6px 18px -12px rgba(17, 21, 26, .3);
    }

    .form-actions .btn { padding-block: 0.9rem; }
    .form-actions-note { font-size: 0.68rem; margin-top: 0.35rem; }
}

/* --------------------------------------------------------------------------
   Masthead: compact on a phone, full on a wide screen
   -------------------------------------------------------------------------- */

.masthead-brand { min-width: 0; }
.masthead-actions { display: flex; align-items: center; gap: 0.6rem; margin-left: auto; padding-bottom: 0.75rem; }
.masthead-who { text-align: right; }
.masthead-signout { border-color: currentColor; color: inherit; white-space: nowrap; }
.masthead-signout:hover { background: var(--paper); color: var(--green); border-color: var(--paper); }

@media (max-width: 991.98px) {
    /* One line: the name of the thing, the theme control, and the way out.
       Everything else moved to the bottom bar. */
    .masthead-inner {
        padding: 0.55rem 1rem;
        gap: 0.6rem;
        align-items: center;
        flex-wrap: nowrap;
    }

    .masthead-title {
        font-size: 0.92rem;
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .masthead .form-code { display: none; }
    .masthead-actions { padding-bottom: 0; gap: 0.4rem; flex: 0 0 auto; }
    .masthead-signout { font-size: 0.58rem; padding: 0.45rem 0.5rem; letter-spacing: 0.08em; }
    .masthead-brand { flex: 1 1 auto; min-width: 0; }

    /* The trailing explanation on a tile footer wrapped to a second line and
       said little the pill had not. The change itself stays. */
    .tile-foot .foot-note { display: none; }
}

/* --------------------------------------------------------------------------
   Back bar — "where was I?"
   -------------------------------------------------------------------------- */

.back-bar {
    position: sticky;
    top: 0;
    z-index: 1015;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    padding: 0.5rem 1rem;
}

.back-link {
    font-size: 0.88rem;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.3rem 0;
    min-height: 2.5rem;
    align-content: center;
}

/* --------------------------------------------------------------------------
   Bottom navigation
   -------------------------------------------------------------------------- */

.bottom-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1040;
    display: none;
    background: var(--paper-raised);
    border-top: 1px solid var(--rule-strong);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -4px 16px -10px rgba(17, 21, 26, .25);
}

@media (max-width: 991.98px) {
    .bottom-nav { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
}

.bn-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    /* 56px clears the 44px minimum with room to spare — this is tapped with a
       thumb, often one-handed, sometimes in a hurry. */
    min-height: 56px;
    padding: 0.4rem 0.2rem;
    text-decoration: none;
    color: var(--ink-soft);
    border-top: 2px solid transparent;
    transition: color 120ms ease, background 120ms ease;
}

.bn-item:hover { color: var(--green); background: var(--green-wash); }

/* The current section is named as well as coloured. */
.bn-item.is-active {
    color: var(--green);
    border-top-color: var(--green);
    background: var(--green-wash);
    font-weight: 600;
}

.bn-icon { font-size: 1.1rem; line-height: 1; }

.bn-label {
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* The bottom bar and the back-to-top button would otherwise sit on top of
   each other. */
@media (max-width: 991.98px) {
    #back-to-top { bottom: calc(56px + env(safe-area-inset-bottom) + 0.6rem); }
    .colophon { margin-bottom: calc(56px + env(safe-area-inset-bottom)); }
    /* A sticky save bar sits above the navigation, not behind it. */
    .form-actions { bottom: calc(56px + env(safe-area-inset-bottom)); }
}

/* --------------------------------------------------------------------------
   A screen that is a task, not a page
   -------------------------------------------------------------------------- */

.screen-head { margin-bottom: 0.9rem; }
.screen-head h1 { margin: 0.15rem 0 0; }
.screen-sub { color: var(--ink-soft); font-size: 0.9rem; margin: 0.15rem 0 0; }

@media print {
    .bottom-nav, .back-bar { display: none !important; }
}
