h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ADR 0039: refined type scale, spacing, and a label/value pattern for
   read-only detail. Bootstrap's own color tokens stay authoritative --
   this only tightens the type scale/spacing and adds a pattern Bootstrap
   has no equivalent for. */

:root {
    /* Every Bootstrap component already reads this variable (buttons,
       cards, form controls, alerts, CollapsiblePanel's own scoped CSS),
       so this one override reaches the whole app. */
    --bs-border-radius: 0.5rem;
}

h1 {
    font-size: 1.7rem;
    font-weight: 700;
    text-wrap: balance;
    letter-spacing: -0.01em;
}

h2, h3 {
    text-wrap: balance;
}

/* Section headings styled as small uppercase labels rather than a
   default heading treatment -- opt in with this class (e.g. a
   CollapsiblePanel caption, a section inside a panel) rather than a
   blanket h2/h3 override, since not every heading in the app is this
   kind of section label. */
.section-heading {
    font-size: 1rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color);
}

/* Label/value pattern for read-only, scannable detail -- first used by
   the Check-in confirmation screen's PatientIdentitySummary (ADR 0040),
   reusable anywhere a record is displayed rather than edited. */
.field-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem 1.75rem;
}

.field-grid .field.field-wide {
    grid-column: 1 / -1;
}

.field .label,
.form-label {
    display: block;
    /* BL-0129: sentence case at a readable size and weight, not small uppercase capitals (harder to read, and to skim
       across a page of forms). Still clearly quieter than the value beneath it. */
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0;
    /* BL-0075: --bs-tertiary-color (#adb5bd-ish) read as too light for a
       label meant to actually be read, not just implied — --bs-secondary-
       color is Bootstrap's own one-step-darker muted-text token, still
       clearly lighter than body text but legible at this small a size. */
    color: var(--bs-secondary-color, #495057);
    margin-bottom: 0.15rem;
}

/* Bootstrap's own .form-label carries no size/color/weight of its own — it
   inherits full body text, which visually competes with the input below it.
   Sharing the .field .label treatment here (rather than duplicating it) is
   the same "clean, muted micro-label" language for every input caption
   across the app, editable or read-only, not just the Check-in screen it
   was designed for. */
.form-label {
    margin-bottom: 0.35rem;
}

/* BL-0236: caption beside box, for administrators' settings and records (CONVENTIONS.md, "Form layout"): inside .form-beside,
   each .form-row is a caption in a column on the left and its box (with any help text or checkboxes) to the right, the same
   9rem column as the read-only .field-grid; --caption-width widens it where captions are longer (the Form Builder). A row
   without a caption (.form-row-indent) lines up under the boxes. A phone stacks the caption above its box again. Fast daily
   data entry (patients, booking, intake) keeps the caption above; Visit vitals, read like a chart, go beside. */
.form-beside {
    --caption-width: 9rem;
}

.form-beside .form-row {
    display: grid;
    grid-template-columns: var(--caption-width) minmax(0, 1fr);
    column-gap: 0.75rem;
    align-items: baseline;
    margin-bottom: 0.75rem;
}

.form-beside .form-row > .form-label {
    margin-bottom: 0;
}

.form-beside .form-row-indent {
    margin-left: calc(var(--caption-width) + 0.75rem);
    margin-bottom: 0.75rem;
}

@media (max-width: 575.98px) {
    .form-beside .form-row {
        grid-template-columns: minmax(0, 1fr);
    }

    .form-beside .form-row > .form-label {
        margin-bottom: 0.35rem;
    }

    .form-beside .form-row-indent {
        margin-left: 0;
    }
}

/* An inline label beside its control (a filter row: "From", "To") stays light, so a toolbar fits on one row. */
.form-label.mb-0 {
    font-weight: 400;
    font-size: 0.8125rem;
}

.field .value {
    font-size: 1rem;
    color: var(--bs-body-color);
    font-variant-numeric: tabular-nums;
}

.field .value.muted {
    color: var(--bs-secondary-color);
    font-style: italic;
    font-size: 0.92rem;
}

/* BL-0208: the caption column. Each read-only fact is one row: a quiet caption in a column on the left, the value lined up to
   its right and a little heavier, a faint rule underneath, so the eye runs down the values without reading every caption.
   CSS only, over the same .field/.label/.value markup; editable forms' .form-label keeps its own look. The grid keeps its
   two columns of rows (a .field-wide fact spans both); it drops to one column where space is short, and a phone stacks the
   caption above its value again. */
.field-grid {
    row-gap: 0;
    /* Two columns only where the grid itself has room for two caption-and-value rows side by side, not where the window does:
       a grid in a half-width panel (Edit Appointment's Patient panel, the popup) gets one column (BL-0218 follow-up to BL-0208). */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}

.field-grid .field {
    display: grid;
    grid-template-columns: 9rem minmax(0, 1fr);
    column-gap: 0.75rem;
    align-items: baseline;
    padding: 0.45rem 0;
    border-bottom: 1px solid var(--tctmj-rule);
}

/* No rule under the last fact: the panel's own edge or separator follows it. */
.field-grid .field:last-child {
    border-bottom: 0;
}

/* A fact whose value is a little form (the check-in screen's Room picker): its label and controls take the two columns. */
.field-grid .field > form {
    display: contents;
}

.field-grid .field .label {
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--tctmj-muted);
    margin-bottom: 0;
}

.field-grid .field .value {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.field-grid .field .value.muted {
    font-weight: 400;
}

/* A patient's check-in answers: the captions are whole questions, so one column with a wider caption column. */
.field-grid.field-grid-answers {
    grid-template-columns: minmax(0, 1fr);
}

.field-grid.field-grid-answers .field {
    grid-template-columns: minmax(10rem, 40%) minmax(0, 1fr);
}

.field-grid.field-grid-answers .field .value {
    font-weight: 500;
}

/* In the caption column every answer is already on its caption's line; BL-0182's inline variant needs nothing extra. */
.field-grid .field.field-inline-label .value {
    max-width: none;
}

@media (max-width: 420px) {
    .field-grid .field,
    .field-grid.field-grid-answers .field {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* BL-0182: a dynamic form field's label and its answer on one line instead of stacked -- a short
   trailing field (an "Other" Text/Date answer right after a checkbox list, say) reads as a continuation of what's
   above it, not its own full-width section. Used by TabletCheckIn, FormPreviewModal (the Form Builder's own
   Preview) and CheckInSubmissionReview's .field cells alike, so the toggle looks the same everywhere a field
   renders. width:auto overrides Bootstrap's own .form-control width:100%, so max-width actually constrains it. */
.field-inline-label {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.field-inline-label .form-label,
.field-inline-label .label {
    margin-bottom: 0;
    flex: 0 0 auto;
}

.field-inline-label .form-control,
.field-inline-label .value {
    width: auto;
    flex: 0 1 auto;
    min-width: 8rem;
    max-width: 20rem;
}

/* Lets a page lay its CollapsiblePanel sections out side by side on
   laptop/desktop widths instead of one long vertical stack, since the
   page is wide enough there (BL-0477: the full window, up to a cap). Collapses
   to a single column below the breakpoint (narrow window, tablet, phone) --
   trial use: Edit Patient (BL-0043). */
.two-col-sections {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: 0 1.5rem;
}

@media (max-width: 900px) {
    .two-col-sections {
        grid-template-columns: 1fr;
    }
}

/* A full-width divider above the submit button, so it still reads as
   "applies to the whole form" even when .two-col-sections' two columns end
   up very different heights (a short left column otherwise leaves the
   button looking stranded next to empty space). */
.form-footer {
    border-top: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
    padding-top: 1rem;
    margin-top: 1rem;
    /* Symmetric with margin-top — without this, a .form-footer followed by
       anything that doesn't bring its own top margin (e.g. a
       CollapsiblePanel, which only ever sets margin-bottom on itself) sits
       flush against it with no gap. Found on EditPatient.razor's Notes
       panel (BL-0079 follow-up), general enough to fix here once rather
       than per page. */
    margin-bottom: 1rem;
}
/* Bubble that appears after selecting an empty calendar slot (calendar-slot.js, BL-0118). Built by script, so not scoped. */
.cal-slot-bubble {
    position: fixed;
    z-index: 1050;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-width: 18rem;
    padding: 0.6rem 0.75rem;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.18);
}

.cal-slot-bubble-text {
    font-size: 0.85rem;
    color: var(--bs-secondary-color);
}

/* ---- BL-0129: the clinic's identity ------------------------------------------------------------------------------
   The public website's palette (its design tokens), so the staff app looks like the same clinic. The website's own
   primary (#6389e1) is too pale for white button text, so buttons, links and the top bar use its darker blues.
   Bootstrap 5.3 reads --bs-primary for most components, but some parts (buttons, focus rings) hard-code the default
   blue, so those are set here too. */

:root {
    --tctmj-primary: #315bb8;
    --tctmj-primary-dark: #24458f;
    --tctmj-primary-darker: #1d3a78;
    --tctmj-primary-soft: #eef3ff;
    --tctmj-ink: #243033;
    --tctmj-muted: #5f6f73;
    --tctmj-border: #d8e3e5;
    --tctmj-rule: #e6edef;
    --tctmj-warm: #f7f3ec;
    --tctmj-accent: #8a6f3d;

    --bs-primary: #315bb8;
    --bs-primary-rgb: 49, 91, 184;
    --bs-link-color: #315bb8;
    --bs-link-color-rgb: 49, 91, 184;
    --bs-link-hover-color: #24458f;
    --bs-link-hover-color-rgb: 36, 69, 143;
    --bs-body-color: #243033;
    --bs-body-color-rgb: 36, 48, 51;
    --bs-border-color: #d8e3e5;
    --bs-primary-bg-subtle: #eef3ff;
    --bs-primary-border-subtle: #c2d1f3;
    --bs-primary-text-emphasis: #1d3a78;
}

.btn-primary {
    --bs-btn-bg: #315bb8;
    --bs-btn-border-color: #315bb8;
    --bs-btn-hover-bg: #24458f;
    --bs-btn-hover-border-color: #24458f;
    --bs-btn-active-bg: #1d3a78;
    --bs-btn-active-border-color: #1d3a78;
    --bs-btn-disabled-bg: #315bb8;
    --bs-btn-disabled-border-color: #315bb8;
    --bs-btn-focus-shadow-rgb: 99, 137, 225;
}

.btn-outline-primary {
    --bs-btn-color: #315bb8;
    --bs-btn-border-color: #315bb8;
    --bs-btn-hover-bg: #315bb8;
    --bs-btn-hover-border-color: #315bb8;
    --bs-btn-active-bg: #24458f;
    --bs-btn-active-border-color: #24458f;
    --bs-btn-disabled-color: #315bb8;
    --bs-btn-disabled-border-color: #315bb8;
    --bs-btn-focus-shadow-rgb: 99, 137, 225;
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: #6389e1;
    box-shadow: 0 0 0 0.25rem rgba(99, 137, 225, 0.35);
}

.form-check-input:checked {
    background-color: #315bb8;
    border-color: #315bb8;
}

/* The top bar and the wordmark. */
.tctmj-nav {
    background-color: var(--tctmj-primary-dark);
    --bs-navbar-color: rgba(255, 255, 255, 0.82);
    --bs-navbar-hover-color: #fff;
    --bs-navbar-active-color: #fff;
}

/* BL-0345: the menu item the current page belongs to (MainLayout, MenuSections) has a white outline. Every item keeps a transparent one, so
   nothing moves when the outline does. */
.tctmj-nav .nav-link {
    border: 1px solid transparent;
    border-radius: 0.375rem;
}

.tctmj-nav .nav-link.menu-active {
    border-color: #fff;
    color: #fff;
}

.tctmj-wordmark {
    font-weight: 700;
    letter-spacing: -0.01em;
    color: #fff;
}

.tctmj-wordmark small {
    font-weight: 400;
    opacity: 0.8;
}

body {
    background-color: #fbfdfd;
}

/* ---- BL-0129: touch targets ---- a comfortable minimum size (about 44px) for the controls used on a tablet. */
.touch-target {
    min-height: 2.75rem;
}

.btn.touch-target {
    padding-left: 1rem;
    padding-right: 1rem;
    /* A link styled as a button (Visit history) keeps its text at the top of the taller box unless centred; a <button> does this
       on its own. Same treatment as the Today queue's buttons. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3em;   /* the space before a trailing ↗ is not kept between flex items */
}

/* Every control in a Today queue row is finger-sized: the queues are worked from a tablet or a busy front desk. The Appointments
   list's rows are the same two-line rows (BL-0488), so its buttons are too. */
.today-queue .btn,
.appointment-list .btn {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    gap: 0.3em;   /* the space before Chart's ↗ is not kept between flex items */
}

/* ---- BL-0129: contrast and keyboard focus (found with axe-core, tools/a11y-audit) ----
   Bootstrap's secondary grey (#6c757d) is 4.4:1 on the tinted backgrounds (panels, the patient banner): just under the
   4.5:1 WCAG AA needs for small text. A slightly darker grey in the brand's muted tone clears it everywhere. */
:root {
    --bs-secondary: #566468;
    --bs-secondary-rgb: 86, 100, 104;
}

.btn-secondary {
    --bs-btn-bg: #566468;
    --bs-btn-border-color: #566468;
    --bs-btn-hover-bg: #465154;
    --bs-btn-hover-border-color: #465154;
    --bs-btn-active-bg: #3a4447;
    --bs-btn-active-border-color: #3a4447;
    --bs-btn-disabled-bg: #566468;
    --bs-btn-disabled-border-color: #566468;
}

.btn-outline-secondary {
    --bs-btn-color: #566468;
    --bs-btn-border-color: #566468;
    --bs-btn-hover-bg: #566468;
    --bs-btn-hover-border-color: #566468;
    --bs-btn-active-bg: #465154;
    --bs-btn-active-border-color: #465154;
    --bs-btn-disabled-color: #566468;
    --bs-btn-disabled-border-color: #566468;
}

/* Wherever the keyboard lands, it shows: links, folding panel captions and anything focusable get the brand ring.
   Not tabindex="-1": that is Blazor moving focus to the page heading on navigation, which should not draw a box. */
a:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 3px solid #6389e1;
    outline-offset: 2px;
    border-radius: 0.25rem;
}

.btn-outline-success {
    --bs-btn-color: #14683f;
    --bs-btn-border-color: #14683f;
    --bs-btn-hover-bg: #14683f;
    --bs-btn-hover-border-color: #14683f;
    --bs-btn-active-bg: #0f5132;
    --bs-btn-active-border-color: #0f5132;
    --bs-btn-disabled-color: #14683f;
    --bs-btn-disabled-border-color: #14683f;
}

/* ---- BL-0130: the footer sits at the bottom of the window on a short page, and after the content on a long one.
   The page is a column at least as tall as the window; the content takes the spare height, which pushes the footer down. */
.page-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}

.page-shell > .container,
.page-shell > .container-fluid {
    flex: 1 0 auto;
    width: 100%;
}

/* BL-0477: the staff pages' width. The whole window (Bootstrap's .container stepped down to 960px on an iPad in landscape, leaving about a
   fifth of the screen empty), with a small margin each side, up to 1400px: every iPad (the 13" Pro is 1376px) and most of a 14" MacBook Pro
   (1512px) get the room, while a 16" MacBook Pro or a Full HD monitor (1920px) keeps the screens at a width their content suits (owner, PR #51). */
:root {
    --app-max-width: 1400px;
}

/* Placeholder text is a hint, not a value: a light grey, well apart from typed text, so an empty field never looks filled in; an example
   starts "For example:" (docs/UI.md). It goes as soon as the field is clicked into, so it is never mistaken for something typed (owner,
   2026-11-01). */
.form-control::placeholder,
.form-select::placeholder,
textarea::placeholder {
    color: #9aa3ae;
    opacity: 1;
}

.form-control:focus::placeholder,
textarea:focus::placeholder {
    color: transparent;
}

/* The "mm/dd/yyyy" hint of an empty date or time input, dimmed like a placeholder (marked by empty-date-hint.js). */
input[data-empty] {
    color: #9aa3ae;
}

/* A dropdown's "— Select —" / "None" entry (the one with an empty value) reads like a placeholder: in the closed control while
   it is the chosen entry, and in the open list. */
select:has(> option[value=""]:checked) {
    color: #9aa3ae;
}

select option[value=""] {
    color: #9aa3ae;
}

select option:not([value=""]) {
    color: var(--bs-body-color);
}

/* A patient's photo (BL-0143): a small passport-ratio portrait. */
.patient-photo {
    object-fit: cover;
    border-radius: 0.375rem;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
}

.photo-stage video,
.photo-stage canvas {
    display: block;
    max-width: 100%;
    max-height: 60vh;
    border-radius: 0.375rem;
    border: 1px solid var(--bs-border-color);
    background: #000;
}

/* Bootstrap's red (#dc3545) is 4.4:1 on the page background, just under WCAG AA for text; a slightly darker red passes. */
.text-danger {
    color: #b02a37 !important;
}

.btn-outline-danger {
    --bs-btn-color: #b02a37;
    --bs-btn-border-color: #b02a37;
}

/* ---- BL-0223: a personal font (My Profile). Twelve SIL OFL fonts (six more by BL-0255), served from wwwroot/fonts (never from Google: the app
   is on-prem). Most are a variable font (one file for every weight) with an italic file; Latin only, so a rare character
   outside it falls back to the system font. A browser downloads only the file a page actually uses.
   The layouts carry data-app-font when the signed-in person chose a font; :has() puts it on <body> so anything
   attached to the body by a script (the calendar's add bubble) follows too. The sign-in and tablet check-in pages
   never carry it. [data-font] is the profile page's preview of each choice.
   font-size-adjust evens out how big the fonts look at the same size: each is scaled to the same x-height (0.5, about
   Segoe UI's, the system font on the clinic's Windows PCs). */

@font-face {
    font-family: "Atkinson Hyperlegible Next";
    src: url("fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Atkinson Hyperlegible Next";
    src: url("fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Inter";
    src: url("fonts/inter/inter-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Inter";
    src: url("fonts/inter/inter-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Source Sans 3";
    src: url("fonts/source-sans-3/source-sans-3-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Source Sans 3";
    src: url("fonts/source-sans-3/source-sans-3-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Sans";
    src: url("fonts/ibm-plex-sans/ibm-plex-sans-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Sans";
    src: url("fonts/ibm-plex-sans/ibm-plex-sans-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Public Sans";
    src: url("fonts/public-sans/public-sans-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Public Sans";
    src: url("fonts/public-sans/public-sans-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Nunito Sans";
    src: url("fonts/nunito-sans/nunito-sans-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Nunito Sans";
    src: url("fonts/nunito-sans/nunito-sans-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

/* BL-0255: six more. Carlito and Lato come only in fixed weights (regular and bold, with italics): the app's medium and semibold round to
   the nearer of the two. Inconsolata has no italic (the browser slants it). Inconsolata and Intel One Mono are monospaced: every
   character the same width, so text runs wider. */
@font-face {
    font-family: "Roboto Condensed";
    src: url("fonts/roboto-condensed/roboto-condensed-latin-wght-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Roboto Condensed";
    src: url("fonts/roboto-condensed/roboto-condensed-latin-wght-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Inconsolata";
    src: url("fonts/inconsolata/inconsolata-latin-wght-normal.woff2") format("woff2");
    font-weight: 200 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Intel One Mono";
    src: url("fonts/intel-one-mono/intel-one-mono-latin-wght-normal.woff2") format("woff2");
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Intel One Mono";
    src: url("fonts/intel-one-mono/intel-one-mono-latin-wght-italic.woff2") format("woff2");
    font-weight: 300 700;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Carlito";
    src: url("fonts/carlito/carlito-latin-400-normal.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Carlito";
    src: url("fonts/carlito/carlito-latin-400-italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Carlito";
    src: url("fonts/carlito/carlito-latin-700-normal.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Carlito";
    src: url("fonts/carlito/carlito-latin-700-italic.woff2") format("woff2");
    font-weight: 700;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Lato";
    src: url("fonts/lato/lato-latin-400-normal.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Lato";
    src: url("fonts/lato/lato-latin-400-italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Lato";
    src: url("fonts/lato/lato-latin-700-normal.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Lato";
    src: url("fonts/lato/lato-latin-700-italic.woff2") format("woff2");
    font-weight: 700;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Open Sans";
    src: url("fonts/open-sans/open-sans-latin-wght-normal.woff2") format("woff2");
    font-weight: 300 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Open Sans";
    src: url("fonts/open-sans/open-sans-latin-wght-italic.woff2") format("woff2");
    font-weight: 300 800;
    font-style: italic;
    font-display: swap;
}

/* BL-0343: Red Hat Display and Red Hat Text, one family drawn for two uses: Display for headings and large text, Text for
   reading at small sizes. Display is the slightly wider and more open of the two. */
@font-face {
    font-family: "Red Hat Display";
    src: url("fonts/red-hat-display/red-hat-display-latin-wght-normal.woff2") format("woff2");
    font-weight: 300 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Red Hat Display";
    src: url("fonts/red-hat-display/red-hat-display-latin-wght-italic.woff2") format("woff2");
    font-weight: 300 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Red Hat Text";
    src: url("fonts/red-hat-text/red-hat-text-latin-wght-normal.woff2") format("woff2");
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Red Hat Text";
    src: url("fonts/red-hat-text/red-hat-text-latin-wght-italic.woff2") format("woff2");
    font-weight: 300 700;
    font-style: italic;
    font-display: swap;
}

body:has([data-app-font="AtkinsonHyperlegibleNext"]), [data-font="AtkinsonHyperlegibleNext"] {
    --bs-body-font-family: "Atkinson Hyperlegible Next", var(--bs-font-sans-serif);
}

body:has([data-app-font="Inter"]), [data-font="Inter"] {
    --bs-body-font-family: "Inter", var(--bs-font-sans-serif);
}

body:has([data-app-font="SourceSans3"]), [data-font="SourceSans3"] {
    --bs-body-font-family: "Source Sans 3", var(--bs-font-sans-serif);
}

body:has([data-app-font="IbmPlexSans"]), [data-font="IbmPlexSans"] {
    --bs-body-font-family: "IBM Plex Sans", var(--bs-font-sans-serif);
}

body:has([data-app-font="PublicSans"]), [data-font="PublicSans"] {
    --bs-body-font-family: "Public Sans", var(--bs-font-sans-serif);
}

body:has([data-app-font="NunitoSans"]), [data-font="NunitoSans"] {
    --bs-body-font-family: "Nunito Sans", var(--bs-font-sans-serif);
}

body:has([data-app-font="RobotoCondensed"]), [data-font="RobotoCondensed"] {
    --bs-body-font-family: "Roboto Condensed", var(--bs-font-sans-serif);
}

body:has([data-app-font="Inconsolata"]), [data-font="Inconsolata"] {
    --bs-body-font-family: "Inconsolata", var(--bs-font-monospace);
}

body:has([data-app-font="IntelOneMono"]), [data-font="IntelOneMono"] {
    --bs-body-font-family: "Intel One Mono", var(--bs-font-monospace);
}

body:has([data-app-font="Carlito"]), [data-font="Carlito"] {
    --bs-body-font-family: "Carlito", var(--bs-font-sans-serif);
}

body:has([data-app-font="Lato"]), [data-font="Lato"] {
    --bs-body-font-family: "Lato", var(--bs-font-sans-serif);
}

body:has([data-app-font="OpenSans"]), [data-font="OpenSans"] {
    --bs-body-font-family: "Open Sans", var(--bs-font-sans-serif);
}

body:has([data-app-font="RedHatDisplay"]), [data-font="RedHatDisplay"] {
    --bs-body-font-family: "Red Hat Display", var(--bs-font-sans-serif);
}

body:has([data-app-font="RedHatText"]), [data-font="RedHatText"] {
    --bs-body-font-family: "Red Hat Text", var(--bs-font-sans-serif);
}

body:has([data-app-font]), [data-font] {
    font-family: var(--bs-body-font-family);
    font-size-adjust: 0.5;
}

[data-font="System"] {
    --bs-body-font-family: var(--bs-font-sans-serif);
    font-size-adjust: none;
}

/* Downtime papers (BL-0107): pages meant to be printed, blank or with the day's appointments, for running the clinic on paper while the app
   is down. On screen they read as the paper will; printed, the menu, footer and buttons (.no-print) are left off and the page uses the
   sheet's full width. */
.paper {
    max-width: 54rem;
}

.paper-header {
    border-bottom: 2px solid #212529;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
}

.paper-section {
    margin-top: 1.25rem;
    break-inside: avoid;
}

.paper-section h2 {
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
}

/* A caption with a line to write on, beside it ("Patient name ________"). */
.paper-field {
    display: flex;
    gap: 0.5rem;
    align-items: flex-end;
    margin-bottom: 0.65rem;
}

.paper-field > .paper-label {
    white-space: nowrap;
}

.paper-field > .paper-line {
    flex: 1;
}

.paper-line {
    border-bottom: 1px solid #6c757d;
    min-height: 1.9rem;
}

/* A box to tick, before an option. */
.paper-box {
    display: inline-block;
    width: 1em;
    height: 1em;
    border: 1px solid #212529;
    margin-right: 0.35em;
    vertical-align: -0.15em;
}

.paper-table td {
    height: 2.1rem;
}

@media print {
    .tctmj-nav, .app-footer, .no-print, #blazor-error-ui {
        display: none !important;
    }

    body, .page-shell {
        background: #fff !important;
    }

    .container, .container-fluid, .paper {
        max-width: none !important;
        padding: 0 !important;
    }

    a {
        color: inherit;
        text-decoration: none;
    }

    .day-sheet {
        font-size: 9.5pt;
    }

    .paper-table, .paper-table th, .paper-table td {
        border-color: #6c757d !important;
    }
}

/* The Visit's documents (BL-0071 handout, BL-0072 referral letter): printed pages like the downtime papers, with typed text kept as written
   (its line breaks, and its indentation: a caption's phrases are indented under it, BL-0467), and a draft banner while the Visit is not signed. */
.document-text {
    white-space: pre-wrap;
}

/* A table heading that sorts (sortable-table.js; BL-0363, the Patients list too since BL-0472) looks like a heading, with an arrow for the order
   it is in (aria-sort). */
.sort-button {
    border: 0;
    background: none;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: inherit;
}

.sort-button:hover,
.sort-button:focus-visible {
    text-decoration: underline;
}

th[aria-sort="ascending"] .sort-button::after {
    content: " \25B2";
    font-size: 0.7em;
}

th[aria-sort="descending"] .sort-button::after {
    content: " \25BC";
    font-size: 0.7em;
}

/* ==== BL-0502 (owner 2026-10-27): "simple" means simple to use, not plain to look at ===========================
   Pleasing and professional, with nothing that carries no meaning: a soft page with content on white cards, a clear order of
   importance, colour that says something (states, "needs you"), icons beside the words that staff look for, the clinic's identity.
   The app-wide look (CONVENTIONS.md, "Look and feel"); a page's own refinements stay in its scoped CSS. */

:root {
    /* BL-0508: the logo's teal, a second accent used for meaning only: today, the current tab, and patients (staff stay blue). The plain teal
       is for lines and fills (4:1 on white); text in teal uses the darker one (6:1). */
    --tctmj-teal: #108c98;
    --tctmj-teal-dark: #0b6e78;
    --tctmj-teal-soft: #e6f4f5;
    /* BL-0524: the band under a caption: table column captions, the Visit's narrative sections, the phrase library's captions. */
    --ui-caption-band: #e9eff6;
    --ui-caption-ink: #2b3f52;
    --ui-page: #f3f6fa;
    --ui-card: #fff;
    --ui-card-border: #e1e8ee;
    --ui-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 2px 6px rgba(16, 24, 40, 0.05);
    --ui-radius: 0.75rem;
    --ui-heading: #172a3a;
    /* BL-0665: the "done" green, the ink of the Ok status badge (StatusBadge.razor.css), for a done step's disc. */
    --ui-ok: #14532d;
}

body {
    background-color: var(--ui-page);
}

h1 {
    color: var(--ui-heading);
    font-weight: 700;
    letter-spacing: -0.015em;
}

/* --- The top bar: the clinic's logo, an icon beside each menu item, the current one as a soft pill, the person's name and initials. --- */
.tctmj-nav {
    background: var(--tctmj-primary-dark);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 2px 8px rgba(16, 24, 40, 0.12);
}

/* The clinic's logo, a draft until the clinic finalises it (wwwroot/images): clinic-logo.png in full on Log in; clinic-logo-small.png (the
   face only, its lines a little heavier, so it reads at 36 px) in the top bar and the browser tab. Round and white inside, so it reads on
   the blue bar. It sits beside the clinic's name, so it has no alt text. */
.tctmj-logo {
    width: 2.25rem;
    height: 2.25rem;
    margin-right: 0.6rem;
    vertical-align: middle;
}

.tctmj-nav .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    border: 0;
    border-radius: 999px;
    padding: 0.4rem 0.85rem !important;
    color: rgba(255, 255, 255, 0.85);
    transition: background-color 0.15s;
}

.tctmj-nav .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.1);
    color: #fff;
}

.tctmj-nav .nav-link.menu-active {
    background-color: rgba(255, 255, 255, 0.18);
    color: #fff;
    font-weight: 600;
}

.tctmj-nav .navbar-nav {
    gap: 0.15rem;
}

/* BL-0681: how many wait behind a menu item (Intake), a small white circle beside its name. */
.tctmj-nav .nav-count {
    display: inline-grid;
    place-items: center;
    min-width: 1.3rem;
    height: 1.3rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: #fff;
    color: var(--tctmj-primary-darker);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
}

/* Every table: no zebra stripes (they read as a spreadsheet); thin rules part the rows and a soft highlight follows the pointer.
   Its column captions are small, uppercase and on a light band of their own. */
.table {
    --bs-table-striped-bg: transparent;
    --bs-table-border-color: #edf1f5;
}

.table > tbody > tr:hover > * {
    --bs-table-bg-state: #f5f8ff;
}

/* The owner (2026-10-27): uppercase, but darker and on a band of their own, so the captions read clearly above the rows. */
.table > thead > tr > th {
    --bs-table-bg: var(--ui-caption-band);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ui-caption-ink);
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid #d5dfea;
    white-space: nowrap;
}

/* A table straight on the page is a card of its own; one inside a panel, a box or a card is already on one. */
.table:not(:is(.collapsible-panel, .attention-box, .card, .list-group, .paper, .modal, dialog, .today-hero, .day-card, .list-card) .table) {
    border-collapse: separate;
    border-spacing: 0;
    background: var(--ui-card);
    border: 1px solid var(--ui-card-border);
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow);
    overflow: hidden;
}

.table:not(:is(.collapsible-panel, .attention-box, .card, .list-group, .paper, .modal, dialog, .today-hero, .day-card, .list-card) .table) > :is(thead, tbody) > tr > :first-child {
    padding-left: 1rem;
}

.table:not(:is(.collapsible-panel, .attention-box, .card, .list-group, .paper, .modal, dialog, .today-hero, .day-card, .list-card) .table) > :is(thead, tbody) > tr > :last-child {
    padding-right: 1rem;
}

.table > tbody > tr:last-child > * {
    border-bottom: 0;
}

/* --- Headings inside a page: weight and the heading colour, not Bootstrap's light default. --- */
h2, .h2, h3, .h3 {
    color: var(--ui-heading);
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* The Admin page's group captions ("PEOPLE AND ACCESS"): small, spaced and quiet. */
.section-heading {
    letter-spacing: 0.06em;
    font-size: 0.78rem !important;
    font-weight: 700 !important;
    color: var(--tctmj-muted);
}

/* A list of links (the Admin page): a card, each row lifting a little under the pointer, a chevron saying it opens. */
.list-group {
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow);
    --bs-list-group-border-color: #edf1f5;
}

.list-group-item-action {
    position: relative;
    padding-right: 2.5rem;
    transition: background-color 0.15s;
}

.list-group-item-action::after {
    content: "";
    position: absolute;
    right: 1.1rem;
    top: 50%;
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid var(--tctmj-border);
    border-bottom: 2px solid var(--tctmj-border);
    transform: translateY(-50%) rotate(-45deg);
}

.list-group-item-action:hover {
    background-color: #f5f8ff;
}

.list-group-item-action:hover::after {
    border-color: var(--tctmj-primary);
}

/* --- Secondary buttons: white, a light border and a little depth, instead of a grey outline. --- */
.btn-outline-secondary {
    --bs-btn-color: var(--tctmj-ink);
    --bs-btn-bg: #fff;
    --bs-btn-border-color: #d3dce4;
    --bs-btn-hover-color: var(--tctmj-ink);
    --bs-btn-hover-bg: #f1f5f9;
    --bs-btn-hover-border-color: #c3ced8;
    --bs-btn-active-color: var(--tctmj-ink);
    --bs-btn-active-bg: #e7edf3;
    --bs-btn-active-border-color: #c3ced8;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
}

.btn-outline-primary,
.btn-outline-danger {
    --bs-btn-bg: #fff;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
}

/* --- Alerts: rounded like the cards, with a coloured edge. --- */
.alert {
    border-radius: var(--ui-radius);
    border-left-width: 4px;
}

/* The Appointments list: each day on its own card, its heading on a quiet band in the clinic's blue (owner 2026-10-27). Every day's table
   has the same fixed column widths, so times, statuses and buttons line up from one card to the next; a narrow screen scrolls the table
   sideways rather than squeezing it. */
.day-card,
.list-card {
    background: var(--ui-card);
    border: 1px solid var(--ui-card-border);
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow);
    margin-bottom: 1rem;
    overflow: hidden;
}

.day-card > .day-heading,
.list-card > .list-card-heading {
    margin: 0;
    padding: 0.7rem 1rem;
    font-size: 1rem;
    font-weight: 700;
    color: var(--tctmj-primary-darker);
    background: #f3f6fb;
    border-bottom: 1px solid #e3eaf3;
}

/* --- Tabs: an underline under the current one, no boxes. --- */
.nav-tabs {
    --bs-nav-tabs-border-color: var(--ui-card-border);
    gap: 0.25rem;
}

.nav-tabs .nav-link {
    border: 0;
    border-bottom: 3px solid transparent;
    color: var(--tctmj-muted);
    font-weight: 500;
    padding: 0.5rem 0.9rem;
    border-radius: 0;
}

.nav-tabs .nav-link:hover {
    color: var(--tctmj-primary);
    border-bottom-color: var(--tctmj-border);
}

.nav-tabs .nav-link.active {
    color: var(--tctmj-primary-darker);
    background: transparent;
    border-bottom-color: var(--tctmj-teal);
    font-weight: 600;
}

/* The quick date ranges (Today, This Week, This Month, Upcoming) as one segmented control; the phrase pages' service lines (BL-0624) too. */
[aria-label="Quick date ranges"],
.segmented-control {
    gap: 0 !important;
    background: #e9eef4;
    border-radius: 999px;
    padding: 0.2rem;
}

[aria-label="Quick date ranges"] > .btn,
.segmented-control > .btn {
    border: 0;
    border-radius: 999px;
    color: var(--tctmj-ink);
    background: transparent;
}

[aria-label="Quick date ranges"] > .btn[aria-current="true"],
.segmented-control > .btn[aria-current="true"] {
    background: #fff;
    color: var(--tctmj-primary-darker);
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(16, 24, 40, 0.15);
}

/* BL-0636: a plain form's pressed button while its post is on its way (submit-once.js), as ActionButton's spinner: after a moment, so a quick
   answer doesn't flicker. */
.submit-spinner {
    display: inline-block;
    margin-right: 0.35rem;
    opacity: 0;
    animation: submit-spinner-appear 0s linear 0.3s forwards;
}

@keyframes submit-spinner-appear {
    to { opacity: 1; }
}

/* BL-0644 (owner 2026-11-03): a list's row actions, Open / Continue / View Visit and Check in / Review / View check-in, are one width, wide
   enough for the longest, so they line up down a column whatever each says. */
.btn.row-action {
    min-width: 8rem;   /* "Review check-in", the longest, is 122 px at the small size */
    text-align: center;
    justify-content: center;   /* in the lists the buttons are flex boxes (.today-queue .btn), where text-align does nothing */
    white-space: nowrap;
}

/* Buttons: the main action has a little depth. */
.btn-primary {
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.15);
}

/* A patient's name in a list is bold and blue, so it reads as a link without a heavy underline; the underline comes back on hover. */
.appointment-list a.fw-semibold,
.today-queue a.fw-semibold {
    text-decoration: none;
}

.appointment-list a.fw-semibold:hover,
.today-queue a.fw-semibold:hover {
    text-decoration: underline;
}

/* A sortable column caption (a button inside the heading) looks like the other captions. */
.table > thead > tr > th .sort-button {
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    color: inherit;
}

/* Small uppercase group captions (the Admin page's "People and access"): spaced and firm enough to read as captions. */
.h6.text-uppercase {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
}

/* A search or filter bar (Patients, Staff, Audit Log, the Appointments list, the calendar's providers): its own panel, a light blue-grey
   band with no shadow, so it reads as the controls and the white cards below it as the results (owner, 2026-10-27). */
.search-panel {
    background: #e9eff6;
    border: 1px solid #d9e3ee;
    border-radius: var(--ui-radius);
    padding: 0.75rem 1rem;
}

/* BL-0574: a page in parts with a list on the left (side-menu.js), the same look as the Visit's workspace (BL-0476). On a narrow screen the
   list becomes a row across the top. */
.side-menu-page {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

.side-menu {
    position: sticky;
    top: 1rem;
    border-right: 1px solid var(--bs-border-color, #d8e3e5);
    padding-right: 0.75rem;
}

.side-menu ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.side-menu a {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.4rem 0.6rem;
    border-radius: 0.4rem;
    color: inherit;
    text-decoration: none;
}

.side-menu a:hover,
.side-menu a:focus-visible {
    background: var(--bs-tertiary-bg, #eef3f4);
}

/* The chosen item keeps the others' weight, so a long name doesn't widen and wrap when chosen (owner, 2026-11-01, BL-0621): the tint, the
   blue bar and the clinic's dark blue show it. */
.side-menu a.current {
    background: color-mix(in srgb, var(--tctmj-primary, #315bb8) 12%, #fff);
    color: var(--tctmj-primary-darker, #1d3a78);
    box-shadow: inset 3px 0 0 var(--tctmj-primary, #315bb8);
}

.side-menu-part-intro {
    color: var(--bs-secondary-color, #566468);
    margin-bottom: 1rem;
}

@media (max-width: 900px) {
    .side-menu-page {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.75rem;
    }

    .side-menu {
        position: static;
        border-right: 0;
        padding-right: 0;
    }

    .side-menu ul {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
    }

    .side-menu a {
        border: 1px solid var(--bs-border-color, #d8e3e5);
        border-radius: 999px;
        background: var(--bs-body-bg, #fff);
    }
}

/* A search box whose matches drop down right under it, picked with a click or tap (BL-0083): Billing codes, and Prescriptions' drug list
   (BL-0617). An option may be a button, so a keyboard reaches it too. */
.search-combobox {
    position: relative;
}

.search-results {
    position: absolute;
    z-index: 20;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 0.25rem;
    max-height: 16rem;
    overflow-y: auto;
    background-color: var(--bs-body-bg, #fff);
    border: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius, 0.375rem);
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* BL-0662 (owner's QA, 2026-11-04): a panel clips what passes its rounded edge, so a search list in a short panel (Billing codes' "Show all
   codes") showed one line. A panel holding an open search list lets it drop over what is below, as a dropdown does; its caption keeps the
   rounded top corners the clipping used to give it. */
/* (Element plus class, so it outranks the panel's own scoped style, CollapsiblePanel.razor.css.) */
:is(details, div).collapsible-panel:has(.search-results) {
    overflow: visible;
}

:is(details, div).collapsible-panel:has(.search-results) > :is(summary, .panel-summary) {
    border-radius: var(--ui-radius, 0.75rem) var(--ui-radius, 0.75rem) 0 0;
}

.search-option {
    display: block;
    width: 100%;
    padding: 0.4rem 0.75rem;
    border: 0;
    background: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.search-option:hover,
.search-option:focus-visible,
.search-option.active {
    background-color: var(--bs-tertiary-bg, #f8f9fa);
}

/* BL-0661 (owner 2026-11-04): the clinic's printed documents (prescription, fax cover sheet, Visit summary, referral letter) as clinic stationery,
   not a browser print. A US Letter sheet, on screen too; printed, the page has no browser margins, so the browser has no room for its own header
   and footer (the date, the title, the app's address), and the sheet's padding is the margin, repeated on every page. Navy and teal are the
   logo's; both print dark enough to fax. */
:root {
    --paper-ink: #1b2533;
    --paper-navy: #1d3461;
    --paper-teal: #12868c;
    --paper-muted: #55606e;
    --paper-rule: #c9d1db;
}

@page stationery {
    size: letter;
    margin: 0;
}

.stationery {
    background: #fff;
    color: var(--paper-ink);
    width: 8.5in;
    max-width: 100%;
    min-height: 11in;
    margin: 0 auto 2rem;
    padding: 0.6in 0.7in 0.75in;
    box-shadow: 0 1px 3px rgba(16, 24, 40, 0.12), 0 8px 24px rgba(16, 24, 40, 0.08);
    font-size: 10.5pt;
    line-height: 1.45;
    display: flex;
    flex-direction: column;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}

.stationery-toolbar {
    width: 8.5in;
    max-width: 100%;
    margin: 0 auto 0.75rem;
}

/* The letterhead: the logo, the clinic's name, and its address and numbers on the right, over a navy rule with a teal line under it. */
.letterhead {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 0.9rem;
    padding-bottom: 0.7rem;
    border-bottom: 2.5pt solid var(--paper-navy);
    box-shadow: 0 2pt 0 0 #fff, 0 3pt 0 0 var(--paper-teal);
    margin-bottom: 1.4rem;
}

.letterhead-logo {
    width: 0.8in;
    height: 0.8in;
}

.letterhead-name {
    color: var(--paper-navy);
    font-size: 17pt;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: 0.01em;
}

.letterhead-tagline {
    color: var(--paper-teal);
    font-size: 8.5pt;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    margin-top: 0.2rem;
}

.letterhead-contact {
    text-align: right;
    font-size: 9pt;
    color: var(--paper-muted);
    line-height: 1.45;
    white-space: pre-line;
}

/* A small caption over a value, as on a printed form. */
.doc-label {
    display: block;
    font-size: 7.5pt;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--paper-muted);
    margin-bottom: 0.1rem;
}

.doc-value {
    font-size: 10.5pt;
}

.doc-title {
    color: var(--paper-navy);
    font-size: 16pt;
    font-weight: 700;
    margin: 0 0 1rem;
}

/* A row of captioned values with hairlines between, for who and when. */
.doc-fields {
    display: grid;
    grid-template-columns: repeat(var(--cols, 3), 1fr);
    border-top: 1px solid var(--paper-rule);
    border-bottom: 1px solid var(--paper-rule);
    margin-bottom: 1.2rem;
}

.doc-fields > div {
    padding: 0.45rem 0.6rem;
}

.doc-fields > div + div {
    border-left: 1px solid var(--paper-rule);
}

.doc-fields > div:first-child {
    padding-left: 0;
}

.stationery .paper-section h2 {
    color: var(--paper-navy);
    font-size: 11pt;
    font-weight: 700;
    border-bottom: 1px solid var(--paper-rule);
    padding-bottom: 0.2rem;
    margin-bottom: 0.45rem;
}

/* While the Visit is not signed: a plain boxed line under the letterhead. */
.document-draft {
    border: 1.5pt solid var(--paper-ink);
    border-radius: 3px;
    font-weight: 600;
    padding: 0.35rem 0.75rem;
    margin-bottom: 1.2rem;
    text-align: center;
}

/* At the foot of the document (of the sheet, for a one-page one): the clinic, in small type above a hairline. */
.stationery-footer {
    margin-top: auto;
    padding-top: 1.5rem;
}

.stationery-footer > div:last-child {
    border-top: 1px solid var(--paper-rule);
    padding-top: 0.35rem;
    font-size: 7.5pt;
    color: var(--paper-muted);
    text-align: center;
}

@media print {
    /* The whole document on stationery pages: naming the page on the sheet alone made the browser break to a fresh page after it. */
    html:has(.stationery),
    html:has(.stationery) body {
        page: stationery;
    }

    .stationery {
        width: auto;
        min-height: 0;
        margin: 0;
        box-shadow: none;
        padding: 0.6in 0.7in 0.85in !important;
    }

    /* Nothing of the app's own layout around the sheet (its bottom padding alone made a blank second page). */
    body:has(.stationery) .page-shell,
    body:has(.stationery) .page-shell > .container-fluid {
        padding: 0 !important;
        margin: 0 !important;
        min-height: 0 !important;
    }

    /* The sheet is at least one page tall, so a short document's footer sits at the foot of the page. */
    .stationery {
        min-height: 10.95in;
    }

    .stationery-toolbar {
        display: none !important;
    }
}

@media screen and (max-width: 8.6in) {
    .stationery {
        padding: 1.25rem;
        min-height: 0;
    }
}

/* BL-0658, BL-0661, BL-0671: a fax cover sheet (prescriptions, letters), laid out as a standard fax cover, dark on white so it faxes cleanly.
   Here, not in a component's own CSS, as the prescriptions' cover and the letters' share it. */
.fax-title {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    border-bottom: 1px solid var(--paper-rule);
    padding-bottom: 0.4rem;
    margin-bottom: 1rem;
}

.fax-title h1 {
    color: var(--paper-navy);
    font-size: 34pt;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1;
    margin: 0;
}

.fax-title span {
    color: var(--paper-muted);
    font-size: 11pt;
}

.fax-grid {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1.4rem;
}

.fax-grid th,
.fax-grid td {
    border: 1px solid var(--paper-rule);
    padding: 0.45rem 0.6rem;
    vertical-align: top;
}

.fax-grid th {
    width: 0.8in;
    background: #eef2f7;
    color: var(--paper-navy);
    font-size: 8pt;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.fax-sub {
    font-size: 9pt;
    color: var(--paper-muted);
}

.fax-number {
    font-size: 12pt;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.fax-heading {
    color: var(--paper-navy);
    font-size: 11pt;
    font-weight: 700;
    margin-bottom: 0.4rem;
}

.fax-list {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1rem;
}

.fax-list th {
    font-size: 7.5pt;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--paper-muted);
    border-bottom: 1.5pt solid var(--paper-navy);
    padding: 0.3rem 0.5rem 0.3rem 0;
    text-align: left;
}

.fax-list td {
    border-bottom: 1px solid var(--paper-rule);
    padding: 0.4rem 0.5rem 0.4rem 0;
}

.fax-note {
    font-size: 9.5pt;
}

/* The notice sits at the foot of the sheet (in the footer), boxed, as on a fax cover. */
.fax-confidential {
    margin-bottom: 0.5rem;
    border: 1.5pt solid var(--paper-ink);
    border-radius: 4px;
    padding: 0.6rem 0.8rem;
    font-size: 9pt;
}

/* BL-0671: a document of more than one sheet (a letter after its fax cover): each sheet starts a new page. */
.stationery + .stationery {
    break-before: page;
}

/* A line the reader should not miss (the handout's "Questions? Call us"). */
.stationery .doc-callout {
    border-left: 3pt solid var(--paper-teal);
    padding: 0.35rem 0 0.35rem 0.75rem;
    background: #f1f7f8;
}

/* BL-0664 (owner 2026-11-04): a work page's building blocks, first on Send prescriptions, for any page where something is reviewed on the left
   and done in steps on the right. A white card with a heading row (title, a short line under it, a count on the right); numbered steps; a
   caption beside a bold value. */
.work-card {
    background: var(--ui-card, #fff);
    border: 1px solid var(--ui-card-border, #e1e8ee);
    border-radius: var(--ui-radius, 0.75rem);
    box-shadow: var(--ui-shadow, none);
}

.work-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.25rem 0.85rem;
    border-bottom: 1px solid var(--ui-card-border, #e1e8ee);
}

.work-card-head h2 {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--ui-heading, #172a3a);
    margin: 0;
}

.work-card-head p {
    margin: 0.1rem 0 0;
    font-size: 0.85rem;
    color: var(--tctmj-muted, #5f6f73);
}

.count-pill {
    flex: none;
    min-width: 1.9rem;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--tctmj-primary-soft, #eef3ff);
    color: var(--tctmj-primary, #315bb8);
    font-weight: 700;
    text-align: center;
}

/* A numbered step: the number in a navy disc, the step's name, and a line saying what it is for. Done, the disc turns green with a tick;
   not yet possible, the step is greyed. */
.step-heading {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    margin-bottom: 0.75rem;
}

.step-heading h3 {
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--ui-heading, #172a3a);
    margin: 0;
}

.step-heading p {
    margin: 0.1rem 0 0;
    font-size: 0.85rem;
    color: var(--tctmj-muted, #5f6f73);
}

.step-num {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 1.6rem;
    height: 1.6rem;
    margin-top: 0.05rem;
    border-radius: 50%;
    background: var(--tctmj-primary-darker, #1d3a78);
    color: var(--ui-card, #fff);
    font-size: 0.8rem;
    font-weight: 700;
}

.step-heading.done .step-num {
    background: var(--ui-ok);
}

.step-heading.waiting {
    opacity: 0.55;
}

.step-divider {
    border-top: 1px solid var(--ui-card-border, #e1e8ee);
    margin: 1.25rem 0;
}

/* "Quantity 5   Refills 0": a muted caption beside a bold value, pairs spaced apart. */
.label-values {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.5rem;
    margin: 0;
}

.label-values > div {
    display: flex;
    gap: 0.35rem;
}

.label-values dt {
    font-weight: 400;
    color: var(--tctmj-muted, #5f6f73);
}

.label-values dd {
    margin: 0;
    font-weight: 700;
}

/* BL-0665: the work page's layout, shared by Send prescriptions, the intake reviews and Check out (UI.md, "A work page"): the heading with the
   patient's card beside it; what is handled on the left; the actions in a card on the right that stays in view; one column, actions below, on
   an upright iPad. The patient's card uses the patients' teal (BL-0508), as the Patients list's initials do. */
.work-heading {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem 2rem;
    margin-bottom: 1.5rem;
}

.work-heading h1 {
    margin-bottom: 0.25rem;
}

.work-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 26rem;
    gap: 1.5rem;
    align-items: start;
}

.work-panel {
    position: sticky;
    top: 5.5rem;
}

.work-card-body {
    padding: 1.1rem 1.25rem 1.25rem;
}

.patient-chip {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    background: var(--ui-card, #fff);
    border: 1px solid var(--ui-card-border, #e1e8ee);
    border-radius: var(--ui-radius, 0.75rem);
    box-shadow: var(--ui-shadow, none);
}

.patient-chip-avatar {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 2.3rem;
    height: 2.3rem;
    border-radius: 50%;
    background: var(--tctmj-teal-soft, #e6f4f5);
    color: var(--tctmj-teal-dark, #0b6e78);
    font-size: 0.85rem;
    font-weight: 700;
}

/* A record's details as rows: the caption on the left, muted; the value on the right; a hairline between rows. */
.detail-rows {
    display: grid;
    grid-template-columns: minmax(9rem, 14rem) 1fr;
    margin: 0;
}

.detail-rows > dt,
.detail-rows > dd {
    margin: 0;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--tctmj-rule, #e6edef);
}

.detail-rows > dt {
    font-weight: 400;
    color: var(--tctmj-muted, #5f6f73);
    padding-right: 1rem;
}

.detail-rows > dt:last-of-type,
.detail-rows > dd:last-of-type {
    border-bottom: 0;
}

/* "or" between two alternative actions (Schedule, or Decline). */
.or-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.1rem 0;
    color: var(--tctmj-muted, #5f6f73);
    font-size: 0.85rem;
}

.or-divider::before,
.or-divider::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--ui-card-border, #e1e8ee);
}

@media (max-width: 991.98px) {
    .work-layout {
        grid-template-columns: 1fr;
    }

    .work-panel {
        position: static;
    }
}

@media (max-width: 575.98px) {
    .detail-rows {
        grid-template-columns: 1fr;
    }

    .detail-rows > dt {
        border-bottom: 0;
        padding-bottom: 0;
    }
}

/* BL-0676: a popup (ModalDialog.razor): the browser's modal dialog, over everything with the page dimmed; a fixed size, its body scrolling. */
dialog.app-dialog {
    width: min(46rem, calc(100% - 2rem));
    max-width: none;
    height: min(80vh, 38rem);
    max-height: none;
    margin: 8vh auto auto;
    padding: 0;
    border: 0;
    border-radius: var(--bs-border-radius-lg, 0.5rem);
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.25);
    background-color: var(--bs-body-bg, #fff);
    color: inherit;
}

dialog.app-dialog[open] {
    display: flex;
    flex-direction: column;
}

dialog.app-dialog::backdrop {
    background-color: rgba(0, 0, 0, 0.45);
}

.app-dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1.25rem;
    border-bottom: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
}

.app-dialog-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 1rem 1.25rem;
}

/* BL-0682 (owner 2026-11-04, mockup #3): each address on the patient forms a plain block, a rule between two. */
.address-block + .address-block {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--ui-card-border, #e1e8ee);
}
