*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    --bg: #f8f9fa;
    --surface: #ffffff;
    --border: #dee2e6;
    --text: #212529;
    --text-muted: #6c757d;
    --primary: #2563eb;
    --primary-hover: #1d4ed8;
    --success: #16a34a;
    --warning: #d97706;
    --danger: #dc2626;
    --green-bg: #dcfce7;
    --yellow-bg: #fef9c3;
    --red-bg: #fee2e2;
    --radius: 8px;
    --shadow: 0 1px 3px rgba(0,0,0,0.1);
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.5;
    min-height: 100vh;
}

.container { max-width: 960px; margin: 0 auto; padding: 0 24px; }
.container-wide { max-width: 1100px; margin: 0 auto; padding: 0 24px; }
.container-narrow { max-width: 480px; margin: 0 auto; padding: 0 16px; }

.header,
.marketing-header {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 12px 0;
    position: sticky;
    top: 0;
    z-index: 100;
}

.header-inner,
.marketing-header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* The breakpoint above decides when the drawer takes over. These two make
       the header structurally unable to push the page sideways whatever the
       breakpoint says: flex children default to min-width: auto and refuse to
       shrink below their content, which is how a 604px nav overflowed a 700px
       viewport instead of wrapping. */
    flex-wrap: wrap;
    min-width: 0;
    /* Matches .container-wide -- schedule.html (and now every other core
       practice page) is 1100px, and a narrower header above a wider page body
       reads as misaligned rather than intentional. */
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 24px;
}

.header-brand,
.marketing-header .header-brand {
    font-size: 18px;
    font-weight: 700;
    color: var(--primary);
    text-decoration: none;
}

.header-nav {
    display: flex;
    flex-wrap: wrap;
    min-width: 0;
    gap: 16px;
    align-items: center;
}

.header-nav a,
.marketing-nav a {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    padding: 6px 10px;
    border-radius: var(--radius);
    transition: color 0.15s;
}

.header-nav a:hover,
.marketing-nav a:hover { color: var(--text); }

.header-nav a.nav-active { color: var(--primary); font-weight: 600; }

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    box-shadow: var(--shadow);
    margin-bottom: 16px;
}

/* ── Primary card layout ────────────────────────────────────────────── */
.wk-card {
    display: flex;
    align-items: center;
    gap: 28px;
    padding: 20px 24px;
    cursor: pointer;
    user-select: none;
    transition: border-color 0.15s;
}
/* Hover only applies to interactive (non-complete) cards. State styling lives in
   the [data-state="…"] rules below — the single source of truth. */
.wk-card:not(.wk-card--done):hover { border-color: var(--primary); }

/* LEFT column: identity stacked, then the big clock UNDER it. */
.wk-left {
    flex-shrink: 0;
    width: 150px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
.wk-t { font-size: 18px; font-weight: 600; color: var(--text); }
.wk-room { font-size: 14px; color: var(--text-muted); }
.wk-status {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* status color by state (running green, holding muted, idle muted) */
.wk-status.idle, .wk-card[data-state="upcoming"] .wk-status { color: var(--text-muted); }
.wk-status.running { color: var(--success); }
.wk-status.paused { color: var(--text-muted); }
/* The big clock, BELOW the status. Tabular so digits don't jitter as it ticks. */
.wk-num {
    font-size: 44px;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    margin-top: 2px;
}
.wk-num.running { color: var(--success); }
.wk-num.paused { color: var(--primary); }

/* MIDDLE column: control rows stacked. */
.wk-controls {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* RIGHT column: actions, separated by a left border. */
.wk-actions {
    flex-shrink: 0;
    width: 160px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-left: 24px;
    border-left: 1px solid var(--border);
}

/* Legacy status pill retained for the COMPLETE slim row only. */
.wk-card-state.complete { color: var(--text-muted); background: var(--bg);
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
    font-weight: 600; padding: 2px 8px; border-radius: 4px; }

/* ── Board card states (emphasis + height only; NEVER position) ──────────────
   The card's vertical slot is fixed by appointment time. These four states change
   how a card LOOKS in that slot, not where it sits. */

/* RUNNING — the one active treatment. Emphasized IN PLACE: a 2px green border and a
   faint green tint so it stands out without jumping to the top of the board. */
.wk-card[data-state="running"] {
    border-color: var(--success);
    border-width: 2px;
    background: #f0fdf4;                        /* subtle green tint */
}

/* PAUSED — started, holding accumulated time. Calm NEUTRAL (approved): 1px neutral
   border, no colored side bar. The status/clock carry the "come back" cue instead. */
.wk-card[data-state="paused"] {
    border-color: var(--border);
    background: #fff;
}

/* UPCOMING — not started. Calm neutral default; clock reads 00:00. */
.wk-card[data-state="upcoming"] {
    border-color: var(--border);
    background: #fff;
}

/* COMPLETE — collapses to a slim single-row summary IN ITS SAME SLOT. Documented;
   read-only. Height shrinks; position does not move. */
.wk-card--done {
    display: block;
    padding: 10px 16px;
    cursor: default;
    border-color: var(--border);
    background: var(--bg);
}
.wk-slim {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.wk-slim-time { font-weight: 700; font-size: 14px; color: var(--text); }
.wk-slim-room { font-size: 13px; color: var(--text-muted); }
.wk-slim-done {
    font-size: 12px;
    font-weight: 600;
    color: var(--success);
    background: var(--green-bg);
    padding: 2px 8px;
    border-radius: 4px;
}
.wk-slim-metrics {
    font-size: 13px;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.wk-slim-spacer { flex: 1; }
.wk-slim-action { flex: 0 0 auto; }

/* ── Control-row buttons ────────────────────────────────────────────── */
.wk-row { display: flex; gap: 10px; }

.wk-btn {
    flex: 1;
    min-width: 0;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
    color: var(--text-muted);
    font-family: inherit;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.wk-btn--a { height: 48px; font-size: 15px; }
.wk-btn--b { height: 44px; font-size: 14px; }
.wk-btn--c      { height: 40px; font-size: 13px; color: var(--text-muted); background: var(--bg); }

.wk-btn:hover { background: var(--bg); }
.wk-btn--c:hover { background: #eef0f2; }

/* Secondary row: separated by a top border. Wraps 2x2 on narrow screens. */
.wk-row--c {
    padding-top: 12px;
    border-top: 1px solid var(--border);
    margin-top: 2px;
}

/* Selected states. */
.wk-btn.sel-accent {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
    font-weight: 600;
}
.wk-btn.sel-green {
    background: var(--success);
    border-color: var(--success);
    color: #fff;
    font-weight: 600;
}
.wk-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ── Action column: hero on top, Done below (separated), secondary row bottom. ── */
.wk-hero {
    height: 58px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 8px;
    background: var(--primary);
    color: #fff;
    font-family: inherit;
    font-size: 19px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background 0.12s;
}
.wk-hero:hover { background: var(--primary-hover); }
.wk-hero:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; }

/* DONE — ends the visit. Outlined (not filled), on its OWN row below the hero so it
   can never be mis-tapped for Pause. */
.wk-done {
    height: 46px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--text);
    border-radius: 8px;
    background: #fff;
    color: var(--text);
    font-family: inherit;
    font-size: 16px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.wk-done:hover { background: var(--bg); }
.wk-done:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

/* Secondary row: Reschedule / Reset. Reset is RIGHT-aligned (right-thumb reach) on
   running/paused via --end. */
.wk-sec-row { display: flex; gap: 8px; }
.wk-sec-row--end { justify-content: flex-end; }
.wk-secondary {
    flex: 1;
    min-width: 0;
    height: 38px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.wk-secondary:hover { background: var(--bg); color: var(--text); }
.wk-secondary--danger { color: var(--danger); flex: 0 0 auto; padding: 0 16px; }
.wk-secondary--danger:hover { background: #fef2f2; color: var(--danger); }
.wk-secondary:focus-visible { outline: 2px solid var(--text-muted); outline-offset: 1px; }

/* ── Responsive: stack to the approved mobile layout ≤900px ──────────────────
   Stacks at 900px (not 760px) so the three-column band never squeezes the middle
   column enough to ellipsize "Auricular" — below this width the card is vertical
   and every control row spans the full card. */
@media (max-width: 900px) {
    .wk-card {
        flex-direction: column;
        align-items: stretch;
        gap: 14px;
    }
    /* identity row: time left, status right; clock centered under it. */
    .wk-left {
        width: auto;
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas: "time status" "room status" "clock clock";
        column-gap: 8px;
        row-gap: 2px;
        align-items: center;
    }
    .wk-t   { grid-area: time; }
    .wk-room   { grid-area: room; }
    .wk-status { grid-area: status; justify-self: end; align-self: start; }
    .wk-num  { grid-area: clock; text-align: center; margin-top: 6px; }
    /* actions: full width, separated by a TOP border instead of a left one. */
    .wk-actions {
        width: auto;
        padding-left: 0;
        padding-top: 14px;
        border-left: none;
        border-top: 1px solid var(--border);
    }
}

/* Very small: wraps 2x2. No abbreviation. */
@media (max-width: 400px) {
    .wk-row--c { flex-wrap: wrap; }
    .wk-row--c .wk-btn--c { flex: 1 1 calc(50% - 5px); }
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 8px 16px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.15s;
    text-decoration: none;
    line-height: 1.4;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover:not(:disabled) { background: var(--primary-hover); }
.btn-success { background: var(--success); color: white; }
.btn-success:hover:not(:disabled) { background: #15803d; }
.btn-danger { background: var(--danger); color: white; }
.btn-danger:hover:not(:disabled) { background: #b91c1c; }
.btn-outline {
    background: transparent;
    color: var(--text);
    border-color: var(--border);
}
.btn-outline:hover:not(:disabled) { background: var(--bg); }
.btn-sm { padding: 4px 10px; font-size: 13px; }
.btn-lg { padding: 12px 24px; font-size: 16px; }
.btn-block { width: 100%; }

.btn-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.btn-option {
    padding: 8px 14px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.15s ease;
    white-space: nowrap;
    user-select: none;
}
.btn-option:hover {
    border-color: var(--primary);
    color: var(--primary);
}
.btn-option.selected {
    background: var(--primary);
    border-color: var(--primary);
    color: white;
}

.check-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.check-option {
    padding: 7px 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
    transition: all 0.15s ease;
    user-select: none;
}
.check-option:hover {
    border-color: var(--primary);
    color: var(--primary);
}
.check-option.selected {
    background: var(--primary);
    border-color: var(--primary);
    color: white;
}

.pain-scale {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}
.pain-btn {
    width: 40px;
    height: 40px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.15s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}
.pain-btn:hover { border-color: var(--primary); }
.pain-btn.selected { background: var(--primary); border-color: var(--primary); color: white; }
.pain-btn[data-value="8"],
.pain-btn[data-value="9"],
.pain-btn[data-value="10"] { border-color: var(--danger); color: var(--danger); }
.pain-btn[data-value="8"].selected,
.pain-btn[data-value="9"].selected,
.pain-btn[data-value="10"].selected { background: var(--danger); border-color: var(--danger); color: white; }

.visit-toggle {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}
.visit-toggle-btn {
    padding: 14px;
    border: 2px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
    transition: all 0.15s ease;
}
.visit-toggle-btn.selected {
    border-color: var(--primary);
    color: var(--primary);
    background: var(--bg);
}

.form-group { margin-bottom: 16px; }
.form-label {
    display: block;
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 4px;
    color: var(--text);
}
.form-label .required { color: var(--danger); }
.form-control {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    /* A <textarea> defaults to monospace while an <input> does not, so the four
       narrative boxes on the patient form rendered in a different typeface from
       the twelve fields above them. */
    font-family: inherit;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text);
    background: var(--surface);
    transition: border-color 0.15s;
}
.form-control:focus,
select.form-control:focus,
textarea.form-control:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(37,99,235,0.12);
}
select.form-control {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236c757d' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 32px;
}
textarea.form-control { resize: vertical; min-height: 80px; }

.form-row { display: flex; gap: 16px; }
.form-row > .form-group { flex: 1; }

.form-help {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 4px;
}

.badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.badge-green { background: var(--green-bg); color: var(--success); }
.badge-yellow { background: var(--yellow-bg); color: var(--warning); }
.badge-red { background: var(--red-bg); color: var(--danger); }
.badge-gray { background: #f1f3f5; color: var(--text-muted); }

/* A badge that's also a click target -- strips button chrome so a <button>
   wrapping a .badge looks identical to a plain one, just clickable. */
.btn-link-badge {
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    font: inherit;
}

.cell-flagged { background: var(--yellow-bg); color: var(--warning); font-weight: 600; }

.alert {
    padding: 12px 16px;
    border-radius: var(--radius);
    margin-bottom: 16px;
    font-size: 14px;
}
.alert-danger { background: var(--red-bg); color: var(--danger); border: 1px solid #fca5a5; }
.alert-warning { background: var(--yellow-bg); color: var(--warning); border: 1px solid #fde68a; }
.alert-success { background: var(--green-bg); color: var(--success); border: 1px solid #86efac; }
.alert-info { background: #dbeafe; color: var(--primary); border: 1px solid #93c5fd; }
/* The secondary line inside the unlinked-visit banner: what is merely
   worth knowing, kept visually below what is actually wrong. */
.alert-aside { margin-top: 6px; font-size: 13px; opacity: 0.85; }

.doc-section { margin-bottom: 20px; }
.doc-section h3 {
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin-bottom: 8px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border);
}
.doc-section p { font-size: 14px; line-height: 1.7; }

.code-list { list-style: none; }
.code-item {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;                 /* the code and its description had none, so at
                                  390 "97810" and the description it belongs to
                                  overlapped into an unreadable smear */
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.code-item:last-child { border-bottom: none; }
.code-value { font-weight: 600; font-family: monospace; flex-shrink: 0; }
/* Below 600 the description gets the full width under its code rather than
   fighting it for a 390px line. */
@media (max-width: 600px) {
    .code-item { flex-direction: column; gap: 2px; }
}

.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td {
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid var(--border);
}
.table th {
    font-weight: 600;
    color: var(--text-muted);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.table tr:hover td { background: var(--bg); }
.table .clickable { cursor: pointer; }

.loading-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}
.loading-box {
    background: var(--surface);
    padding: 32px;
    border-radius: var(--radius);
    text-align: center;
    box-shadow: 0 4px 24px rgba(0,0,0,0.15);
}
.spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--border);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
    margin: 0 auto 12px;
}
@keyframes spin { to { transform: rotate(360deg); } }

.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}
.modal {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 24px;
    max-width: 480px;
    width: 90%;
    box-shadow: 0 4px 24px rgba(0,0,0,0.15);
    /* Every modal before the intake-review one was short enough that this
       was never needed -- a coverage form, a confirm dialog. That one's
       content (a per-field comparison table plus a submitted-responses
       section) can run taller than the viewport, and .modal-overlay's
       align-items:center with no scroll boundary on .modal itself left its
       own action buttons rendered below the visible screen with no way to
       reach them. max-height/overflow-y is a no-op for every existing
       shorter modal and the general fix for any future tall one. */
    max-height: 90vh;
    overflow-y: auto;
}
.modal-wide { max-width: 800px; }
.modal h3 { margin-bottom: 12px; }
.modal-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 20px;
}

.page-header {
    display: flex;
    flex-direction: row;
    /* WRAP. `nowrap` plus `min-width: 0; overflow: hidden` on the h1 meant the
       heading absorbed every pixel the controls beside it wanted — measured at
       0px wide on /history at 430, 390 and 360, which is why "Note History"
       rendered as "N... H...". The heading takes its own line instead. */
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin: 24px 0 16px;
}
/* Heading takes remaining space and truncates if needed; it must never push the
   button to a new row. */
.page-header h1 {
    font-size: 22px;
    font-weight: 700;
    /* No longer shrinkable to nothing: it wraps to its own line first. */
    min-width: max-content;
}
/* + Add Patient keeps its intrinsic size and its label on one line at every width. */
.page-header .btn {
    flex-shrink: 0;
    white-space: nowrap;
}

.daily-summary {
    display: flex;
    gap: 24px;
    padding: 16px 0;
    border-bottom: 1px solid var(--border);
    margin-bottom: 16px;
}
.summary-stat { text-align: center; }
.summary-stat .value { font-size: 24px; font-weight: 700; }
.summary-stat .label { font-size: 12px; color: var(--text-muted); text-transform: uppercase; }

/* A FIXED TRACK COUNT STRANDS ANY CARD COUNT THAT IS NOT A MULTIPLE OF IT.
   This was `repeat(4, 1fr)`, with a comment saying "never 3+1" — and the
   affiliate dashboard renders FIVE cards, so it was 4+1 at every width above
   640px, the fifth sitting alone at quarter width with a 696px hole beside it.
   Below 640 the override made it `repeat(2, 1fr)`, which is 2+2+1: stranded
   again. The count was never the problem; committing to a count was.

   Flex with a basis instead: the number per row follows the space, and the last
   row STRETCHES to fill, so no card count can strand. Identical to the fix
   applied to .adm-stat-grid, for the identical reason.
   min-width: 0 on the card, because a flex child defaults to min-width: auto
   and will refuse to shrink below its content, which is the other half of the
   same defect. */
.stat-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-bottom: 24px;
}
.stat-card {
    /* 140px, not 168px. At 390 the content box is ~342px and 168+168+gap did
       not fit, so three cards stacked one per row and the board became a
       column of single numbers. 140 fits two across with room to spare and
       still holds the longest label on this row. */
    flex: 1 1 140px;
    min-width: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px 16px;
    text-align: center;
    box-shadow: var(--shadow);
}
.stat-value {
    font-size: 32px;
    font-weight: 700;
    color: var(--primary);
    line-height: 1;
}
.stat-label {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 6px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.disclaimer {
    font-size: 11px;
    color: var(--text-muted);
    border-top: 1px solid var(--border);
    padding-top: 16px;
    margin-top: 24px;
    line-height: 1.6;
}

.auth-container {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    padding: 48px 24px;
}
.auth-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
    width: 100%;
    max-width: 400px;
    box-shadow: var(--shadow);
}
.auth-box-wide { max-width: 580px; }
.auth-box h1 {
    font-size: 22px;
    text-align: center;
    margin-bottom: 24px;
}
.auth-box .auth-link {
    text-align: center;
    margin-top: 16px;
    font-size: 14px;
}
.auth-box .auth-link a { color: var(--primary); }

.hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 36px;
    height: 36px;
    cursor: pointer;
    background: none;
    border: none;
    padding: 4px;
    border-radius: var(--radius);
}
.hamburger:hover { background: var(--bg); }
.hamburger span {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--text);
    border-radius: 2px;
    transition: all 0.2s ease;
}

.mobile-nav-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 200;
}
.mobile-nav-overlay.open { display: block; }

.mobile-nav-drawer {
    position: fixed;
    /* TOP AND BOTTOM, not a vh max-height. `max-height: 60vh` capped the drawer
       at 60% of the screen and then scrolled the links inside it — on a 667px
       phone that is 400px of drawer holding 368px of links in a 339px box,
       scrolling, with 267px of empty screen below it. A fixed element pinned
       top and bottom fills the viewport it is actually in, which is also
       correct on mobile browsers whose 100vh includes a URL bar that is not
       there. overflow-y on the links stays as the backstop for a screen too
       short for seven of them. */
    top: 0;
    bottom: 0;
    right: -280px;
    width: 260px;
    height: auto;
    background: var(--surface);
    border-left: 1px solid var(--border);
    z-index: 201;
    transition: right 0.25s ease;
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}
.mobile-nav-drawer.open { right: 0; }

.mobile-nav-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px;
    border-bottom: 1px solid var(--border);
}
.mobile-nav-header .brand {
    font-size: 17px;
    font-weight: 700;
    color: var(--primary);
    text-decoration: none;
}
.mobile-nav-close {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 20px;
    padding: 4px 8px;
    border-radius: var(--radius);
    line-height: 1;
}
.mobile-nav-close:hover { background: var(--bg); color: var(--text); }

.mobile-nav-links {
    display: flex;
    flex-direction: column;
    padding: 8px 0;
    flex: 1;
    overflow-y: auto;
}
.mobile-nav-links a {
    display: block;
    padding: 13px 20px;
    color: var(--text);
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    border-bottom: 1px solid var(--border);
}
.mobile-nav-links a:last-child { border-bottom: none; }
.mobile-nav-links a:hover { background: var(--bg); }
.mobile-nav-links a.nav-active {
    color: var(--primary);
    font-weight: 600;
    background: var(--bg);
}
.mobile-nav-links a.nav-cta-mobile {
    color: white;
    background: var(--primary);
    font-weight: 600;
    margin: 8px 16px;
    padding: 12px 20px;
    border-radius: var(--radius);
    text-align: center;
    border-bottom: none;
}
.mobile-nav-links a.nav-cta-mobile:hover {
    background: var(--primary-hover);
}
.mobile-nav-links a.nav-signout {
    color: var(--danger);
    border-top: 2px solid var(--border);
    margin-top: 4px;
}

.header-nav .nav-logout {
    background: transparent;
    border: 1px solid var(--danger);
    border-radius: var(--radius);
    color: var(--danger);
    font-size: 13px;
    font-weight: 500;
    padding: 4px 14px;
    cursor: pointer;
    margin-left: 4px;
    line-height: 1.5;
}
.header-nav .nav-logout:hover {
    background: var(--danger);
    color: #fff;
}

.page-body { padding-top: 24px; padding-bottom: 72px; }

h1 { font-size: 22px; font-weight: 700; line-height: 1.3; }
h2 { font-size: 18px; font-weight: 600; line-height: 1.3; }
h3 { font-size: 16px; font-weight: 600; line-height: 1.3; }

/* THE DRAWER TAKES OVER AT 768, NOT 640.
   .header-nav measures 599-604px of links, and the header adds a brand and a
   Log Out button beside it. At 640 < width < ~730 the desktop nav was therefore
   still displayed and did not fit: measured at 700px, every authenticated page
   pushed the document 19-24px wider than the viewport and scrolled sideways.
   A breakpoint chosen below the width the content actually needs is not a
   breakpoint.
   768 is above the measured requirement with room for another nav item, and the
   header itself now wraps rather than overflowing (see .header-inner), so the
   next item added cannot reintroduce this silently. */
@media (max-width: 768px) {
    .hamburger { display: flex; }
    .header-nav { display: none; }
    .form-row { flex-direction: column; gap: 0; }
    .daily-summary { flex-wrap: wrap; gap: 16px; }
    /* .page-header intentionally stays a horizontal row (heading left, button right)
       at ALL widths — do NOT re-add flex-direction: column here. */
    /* The `repeat(2, 1fr)` override that used to sit here is DELETED, not
       adjusted. It set grid-template-columns on an element that is now
       display:flex, where the property does nothing — and while it did apply,
       it produced 2+2+1 for a five-card grid, stranding the fifth for the same
       reason the desktop rule stranded it. The flex basis handles every width;
       a second definition of the column count is what caused this. */
    /* Card stacking is handled by its own @media (max-width:760px) block. */
}

@media (min-width: 768px) {
    .card { padding: 24px; margin-bottom: 20px; }
    .form-row { flex-direction: row; gap: 20px; }
    /* .page-header is already row/center from the base rule; only the heading grows. */
    .page-header h1 { font-size: 26px; }
    .wk-card { padding: 20px 24px; }
    .daily-summary { gap: 40px; padding: 20px 0; }
    .summary-stat .value { font-size: 32px; }
    .btn-lg { padding: 14px 28px; font-size: 16px; }

    .settings-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 20px;
    }
    .settings-grid .card { margin-bottom: 0; }
    .settings-full { grid-column: 1 / -1; }
}

.hidden { display: none !important; }

html, body { height: 100%; }
body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
.site-content { flex: 1; }

.marketing-nav {
    display: flex;
    align-items: center;
    gap: 8px;
}

.marketing-nav .nav-cta {
    background: var(--primary);
    color: white !important;
    padding: 7px 16px;
    border-radius: var(--radius);
    font-weight: 600;
}

.marketing-nav .nav-cta:hover {
    background: var(--primary-hover);
}

.site-footer {
    background: var(--surface);
    border-top: 1px solid var(--border);
    padding: 16px 0;
}
.site-footer-inner {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 24px;
    display: flex;
    align-items: center;
}
.site-footer-copy {
    margin-left: auto;
    font-size: 14px;
    color: var(--text-muted);
}
.site-footer-copy a {
    color: var(--primary);
    text-decoration: none;
    font-weight: 700;
}
.site-footer-copy a:hover { color: var(--primary-hover); }
.site-footer-links {
    display: flex;
    gap: 20px;
}
.site-footer-links a {
    font-size: 13px;
    color: var(--text-muted);
    text-decoration: none;
}
.site-footer-links a:hover { color: var(--text); }

@media (max-width: 640px) {
    .site-footer-inner { flex-direction: column; gap: 12px; }
    .site-footer-copy { margin-left: 0; text-align: center; }
    .marketing-nav { display: none; }
}

.cookie-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--surface);
    border-top: 1px solid var(--border);
    z-index: 9999;
    padding: 12px 0;
    transition: opacity 0.3s;
}
.cookie-banner-inner {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 24px;
    display: flex;
    align-items: center;
    gap: 16px;
}
.cookie-banner-text {
    flex: 1;
    font-size: 14px;
    color: var(--text-muted);
}
.cookie-banner-text a {
    color: var(--primary);
    text-decoration: none;
}
.cookie-banner-text a:hover { color: var(--primary-hover); }

.marketing-hero {
    text-align: center;
    padding: 80px 24px 60px;
    max-width: 1100px;
    margin: 0 auto;
}
.marketing-hero h1 {
    font-size: 42px;
    font-weight: 800;
    line-height: 1.15;
    margin-bottom: 20px;
    color: var(--text);
}
.marketing-hero .hero-sub {
    font-size: 20px;
    color: var(--text-muted);
    margin-bottom: 32px;
    line-height: 1.5;
}
.marketing-hero .hero-note {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 12px;
}
.hero-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}

.marketing-section {
    max-width: 1100px;
    margin: 0 auto;
    padding: 48px 24px 96px;
}
.marketing-section h2 {
    font-size: 28px;
    font-weight: 700;
    margin-bottom: 24px;
}
.marketing-section h3 {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 8px;
    margin-top: 28px;
}
.marketing-section p {
    font-size: 15px;
    line-height: 1.7;
    color: var(--text-muted);
    margin-bottom: 12px;
}
.marketing-section ul {
    padding-left: 20px;
    margin-bottom: 12px;
}
.marketing-section ul li {
    font-size: 15px;
    line-height: 1.7;
    color: var(--text-muted);
    margin-bottom: 6px;
}

.feature-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 24px 60px;
}
.feature-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px;
}
.feature-card h3 {
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 8px;
}
.feature-card p {
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.6;
}

.divider {
    border: none;
    border-top: 1px solid var(--border);
    margin: 0;
}

.pricing-cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin-top: 16px;
}

.pricing-card {
    border: 1.5px solid #93b5e6;
    border-radius: var(--radius);
    padding: 20px 16px;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pricing-card-featured {
    border-color: var(--primary);
    background: #f0f5ff;
    position: relative;
    padding-top: 20px;
}

.pricing-badge {
    position: absolute;
    top: -11px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #fff;
    background: var(--primary);
    padding: 3px 12px;
    border-radius: 20px;
    white-space: nowrap;
}

.pricing-features { text-align: left; }
.pricing-seat-section { text-align: center; }
.pricing-payg-section { text-align: left; }
.pricing-summary { text-align: left; }

.pricing-tier {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    text-align: center;
}

.pricing-price {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    line-height: 1;
    margin: 8px 0 4px;
}

.price-currency {
    font-size: 1.1rem;
    font-weight: 600;
    margin-top: 0.5rem;
    line-height: 1;
    display: inline-block;
}

.price-amount {
    font-size: 2.75rem;
    font-weight: 700;
    line-height: 1;
}

.price-period {
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--text-muted);
    align-self: flex-end;
    margin-bottom: 0.2rem;
    margin-left: 2px;
}

.price-amount-text {
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.2;
}

.pricing-notes {
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 8px;
    text-align: center;
}

.pricing-cards-page .pricing-card {
    padding: 28px 20px;
}

.pricing-features {
    list-style: none;
    text-align: left;
    margin-bottom: 16px;
    flex: 1;
}

.pricing-features li {
    font-size: 14px;
    color: var(--text-muted);
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
}

.pricing-features li:last-child {
    border-bottom: none;
}

@media (max-width: 640px) {
    .pricing-cards {
        grid-template-columns: 1fr;
    }
    .feature-grid {
        grid-template-columns: 1fr;
    }
    .pricing-page-grid {
        grid-template-columns: 1fr !important;
    }
}

/* Onboarding modal */
.onboarding-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1100;
}

.onboarding-modal {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 28px 28px 24px;
    max-width: 540px;
    width: calc(100% - 32px);
    box-shadow: 0 8px 32px rgba(0,0,0,0.18);
    position: relative;
    animation: ob-fadein 0.2s ease;
}

@keyframes ob-fadein {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.ob-step-content {
    animation: ob-fadein 0.2s ease;
}

.ob-step-content h3 {
    margin: 0 0 10px;
    font-size: 18px;
}

.ob-step-content p {
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1.6;
    margin: 0;
}

/* The always-available exit. Present on every step, including the last. */
.ob-close {
    position: absolute;
    top: 12px;
    right: 12px;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    padding: 6px 8px;
    border-radius: var(--radius);
}

.ob-close:hover { color: var(--text); background: var(--bg); }

/* Moved out of the top-right corner, which the close control now owns. */
.ob-skip {
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
    padding: 4px 0;
}

.ob-skip:hover { color: var(--text); text-decoration: underline; }

.ob-actions {
    display: flex;
    gap: 8px;
}

.ob-visual {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    margin: 20px 0;
}

.ob-mock {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 16px;
}

.ob-mock-label {
    flex: 1;
    font-size: 14px;
    color: var(--text-muted);
}

.ob-mock-display {
    font-size: 18px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.03em;
}

.ob-field-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ob-field-row {
    height: 36px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0 12px;
    display: flex;
    align-items: center;
    font-size: 13px;
    color: var(--text-muted);
    background: var(--surface);
}

.ob-btn-pair {
    display: flex;
    gap: 10px;
    justify-content: center;
}

.ob-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 20px;
}

.ob-footer-spacer { width: 80px; }

.ob-dots {
    display: flex;
    gap: 6px;
}

.ob-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--border);
    transition: background 0.2s;
}

.ob-dot-active { background: var(--primary); }

/* Chip row used by the tour's step illustrations */
.ob-id-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
}

.ob-id-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 14px;
    min-width: 60px;
}

.ob-id-box-result {
    border-color: var(--primary);
    background: rgba(24, 95, 165, 0.06);
}

.ob-id-icon {
    font-size: 20px;
    line-height: 1;
}

.ob-id-label {
    font-size: 11px;
    color: var(--text-muted);
    text-align: center;
    white-space: nowrap;
}

.ob-id-op {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-muted);
    padding: 0 2px;
}

/* The patient card heading on the "Your patients live here" step */
.ob-patient-head {
    margin: 0 auto 12px;
    width: max-content;
}

/* ─── Shared utilities ─────────────────────────────────────────── */

#turnstile-container { margin-bottom: 16px; display: flex; justify-content: center; }
.auth-subtitle { text-align: center; color: var(--text-muted); font-size: 14px; margin-top: -12px; margin-bottom: 24px; }
.text-muted-sm { color: var(--text-muted); font-size: 13px; }
.field-note { font-weight: 400; color: var(--text-muted); font-size: 13px; }
.mt-section { margin-top: 40px; }
.card-flush { padding: 0; overflow: hidden; }
.form-control-auto { width: auto; }
.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.table-empty { text-align: center; color: var(--text-muted); padding: 24px; }
.table-error { text-align: center; color: var(--danger); padding: 24px; }
.audit-list { margin: 8px 0 0 16px; font-size: 14px; }
/* WRAPS. The date inputs plus the Search button are 425px wide and pushed the
   page 35-65px sideways on /revenue at 390 and 360, taking the header and nav
   with them. */
.filter-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-width: 0; }
.filter-row .form-control-auto { min-width: 0; }
.color-success { color: var(--success); }
.color-muted { color: var(--text-muted); }

/* ─── JS-toggled hidden elements ───────────────────────────────── */

#checkout-card { display: none; }
#compliance-preview { display: none; }
#audit-banner { display: none; }
#success-message { display: none; text-align: center; padding: 32px 0; }
#success-message p { font-size: 16px; color: var(--text); }
#char-count { text-align: right; font-size: 12px; color: var(--text-muted); margin-top: 4px; }
#empty-state { display: none; text-align: center; padding: 48px 20px; color: var(--text-muted); }
#empty-history { text-align: center; padding: 32px; color: var(--text-muted); }
#subscription-info { margin-bottom: 16px; }
#referral-box { display: none; }
#referral-edit-mode { display: none; margin-top: 6px; }

/* ─── Note page ────────────────────────────────────────────────── */

.note-header { display: flex; justify-content: space-between; align-items: center; }
.section-h3 { margin-bottom: 12px; }
.form-row-mt { margin-top: 16px; }
.check-group-sm { margin-bottom: 8px; }
.note-actions { display: flex; gap: 12px; margin-bottom: 32px; }
.btn-flex { flex: 1; }
.compliance-list { margin: 4px 0 0 16px; }
.compliance-note { font-size: 13px; color: var(--text-muted); }
.compliance-badge { margin-bottom: 12px; }

/* ─── Output page ──────────────────────────────────────────────── */

/* Nine buttons. Without wrap this row was 989px inside a 390px viewport and
   pushed the whole page sideways, and at 1440px it consumed every pixel of the
   header so the "SOAP Note" heading was squeezed to zero width and vanished. */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* ── TOOLBAR ─────────────────────────────────────────────────────────────────
   One primary action on the right, secondary actions on the left. Wrapping nine
   equal-weight buttons across three rows was the previous shape and made the
   primary indistinguishable from four exports.

   NOTE: none of this touches .wk-* — the timer's rules are untouched. */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 16px;
}
.toolbar-secondary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.toolbar-primary { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* Mobile: every button the same width, evenly spaced, label centred. Stacked
   rather than a 2-up grid on purpose — .hidden buttons are display:none but are
   still counted by :nth-child, so an odd/even rule for the last cell would
   silently mis-size whenever the edit buttons swap in. */
@media (max-width: 600px) {
    .toolbar { flex-direction: column; align-items: stretch; gap: 10px; }
    .toolbar-secondary,
    .toolbar-primary { flex-direction: column; align-items: stretch; margin-left: 0; gap: 8px; }
    .toolbar .btn,
    .toolbar .menu,
    .toolbar .menu-toggle {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
    }
}

/* ── DISCLOSURE MENU ─────────────────────────────────────────────────────── */
.menu { position: relative; display: inline-block; }
.menu-caret { font-size: 10px; opacity: .7; margin-left: 5px; }
.menu-list {
    position: absolute;
    top: calc(100% + 4px);
    /* Left-aligned to the toggle. The toggle sits at the LEFT end of the
       toolbar, so right:0 hung the panel leftward across the page. */
    left: 0;
    min-width: 224px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 6px 20px rgba(0,0,0,.14);
    padding: 4px;
    z-index: 60;
}
.menu-item {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    padding: 9px 12px;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    border-radius: 6px;
    cursor: pointer;
}
.menu-item:hover:not(:disabled) { background: var(--bg); }
.menu-item:disabled { color: var(--text-muted); cursor: not-allowed; }
@media (max-width: 600px) {
    /* Full width under the toggle rather than a 224px box hanging off one edge. */
    .menu-list { left: 0; right: 0; min-width: 0; }
    .menu-item { text-align: center; }
}

/* Cancel / Save at the foot of a full-page form. */
.form-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    align-items: center;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
@media (max-width: 600px) {
    .form-actions { flex-direction: column-reverse; align-items: stretch; }
    .form-actions .btn { width: 100%; text-align: center; justify-content: center; }
}

/* ── CALENDAR ────────────────────────────────────────────────────────────────
   Time down the left, rooms (day) or days (week) as columns, one block per
   visit. The grid scrolls sideways INSIDE .cal-scroll; the page never does. The
   time gutter is sticky so a scrolled-to room column still has its hour. */
.cal-bar {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}
.cal-nav, .cal-views { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cal-datepick { width: auto; min-width: 150px; }
.cal-views .btn.is-active {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
.cal-caption {
    font-weight: 600;
    font-size: 15px;
    margin: 0 0 10px;
    color: var(--text);
}
.cal-card { padding: 0; overflow: hidden; }
.cal-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cal-grid {
    display: grid;
    grid-template-columns: 68px repeat(var(--cal-cols), minmax(132px, 1fr));
    min-width: min-content;
}
.cal-corner {
    position: sticky; left: 0; z-index: 3;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--border);
}
.cal-colhead {
    padding: 10px 8px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: center;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    border-left: 1px solid var(--border);
    white-space: nowrap;
}
.cal-colhead--today { color: var(--primary); }
.cal-daylink { color: inherit; text-decoration: none; }
.cal-daylink:hover { text-decoration: underline; }
.cal-time {
    position: sticky; left: 0; z-index: 2;
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 2px 8px 0 0;
    text-align: right;
    font-size: 11px;
    color: var(--text-muted);
    min-height: 44px;
}
.cal-time--hour { color: var(--text); font-weight: 600; }
.cal-cell {
    border-left: 1px solid var(--border);
    border-top: 1px dotted var(--border);
    min-height: 44px;
    padding: 2px;
    position: relative;
}
.cal-cell--hour { border-top: 1px solid var(--border); }

/* The click target for an empty slot. Invisible until hovered or focused so an
   empty day is not a wall of plus signs, but reachable by keyboard. */
.cal-add {
    position: absolute; inset: 2px;
    width: calc(100% - 4px);
    border: 1px dashed transparent;
    background: none;
    border-radius: 6px;
    color: var(--text-muted);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
}
.cal-add:hover, .cal-add:focus { opacity: 1; border-color: var(--primary); color: var(--primary); }

/* THERE IS NO HOVER ON A PHONE. The button that books an empty slot was
   opacity: 0 until :hover, so on any touch device the calendar was a grid of
   empty cells with no visible way to book one — the control existed, was wired,
   and could not be seen. A pointer: coarse device gets a permanently visible
   (if quiet) affordance instead of one that reveals on an event it cannot
   generate. */
@media (pointer: coarse) {
    .cal-add { opacity: 0.45; border-color: var(--border); }
}

.cal-block {
    display: block;
    width: 100%;
    text-align: left;
    border: 1px solid var(--border);
    border-left: 3px solid var(--text-muted);
    border-radius: 6px;
    background: var(--surface);
    padding: 4px 6px;
    margin-bottom: 2px;
    cursor: pointer;
    font: inherit;
    overflow: hidden;
}
.cal-block:hover { box-shadow: var(--shadow); }
.cal-block-time { display: block; font-size: 10px; color: var(--text-muted); }
.cal-block-room { display: block; font-size: 10px; color: var(--text-muted); }
.cal-block-name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-block-status {
    display: block;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
}
.cal-block--idle     { border-left-color: var(--text-muted); }
.cal-block--running  { border-left-color: var(--success); background: var(--green-bg); }
.cal-block--paused   { border-left-color: var(--warning); background: var(--yellow-bg); }
.cal-block--complete { border-left-color: var(--primary); }
.cal-block--unassigned .cal-block-name { color: var(--warning); font-style: italic; }

.cal-empty { padding: 16px; color: var(--text-muted); font-size: 14px; }

/* A visit's actions, as a list rather than a row of equal buttons. */
.action-list { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.action-item {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
}
.action-item:hover:not(:disabled) { border-color: var(--primary); background: var(--bg); }
.action-item:disabled { color: var(--text-muted); cursor: not-allowed; background: var(--bg); }
.action-item--danger { color: var(--danger); }
.action-item--danger:hover:not(:disabled) { border-color: var(--danger); }
.action-hint {
    display: block;
    font-weight: 400;
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

/* The output page's header, which holds .btn-row. A MODIFIER rather than a
   change to .page-header, which nine pages share and which is deliberately
   nowrap so "+ Book a Visit" can never drop below the heading. */
.doc-header { flex-wrap: wrap; align-items: flex-start; }
.doc-header h1 { overflow: visible; text-overflow: clip; }

/* The identity block on the note screen. Composed at render from the chart —
   never stored, and never sent to the model. */
.note-identity { padding-top: 14px; padding-bottom: 14px; }
.note-identity .kv-grid { gap: 6px 24px; }
.note-identity .kv-k {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
}
.note-identity .kv-v { font-weight: 600; }

/* Filing an unfiled note from the header, without going back to the schedule. */
.identity-attach {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.identity-attach-note { font-size: 13px; color: var(--text); margin: 0 0 8px; }
.identity-attach-row { display: flex; gap: 8px; align-items: flex-start; }
/* The field grows, the button keeps its label on one line. position:relative so
   the picker's absolutely-positioned results hang off the input, not the card. */
.identity-attach-field { position: relative; flex: 1; min-width: 0; }
.identity-attach-row .btn { flex-shrink: 0; white-space: nowrap; }
@media (max-width: 600px) {
    .identity-attach-row { flex-direction: column; }
    .identity-attach-row .btn { width: 100%; justify-content: center; }
}

/* Any table that cannot narrow further scrolls inside its own box rather than
   taking the page with it. The page must never scroll sideways; a table may. */
.doc-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.output-cols { display: flex; flex-wrap: wrap; gap: 32px; }
/* CPT and ICD-10 sat in two columns at every width, so at 390 the code and its
   description overlapped. Below 600 they stack. */
@media (max-width: 600px) {
    .output-cols { flex-direction: column; gap: 16px; }
}
.output-col { flex: 1; }
.output-col-label { font-size: 13px; color: var(--text-muted); margin-bottom: 8px; }
.modal-desc { font-size: 14px; color: var(--text-muted); margin-bottom: 16px; }

/* ─── Setup / settings pages ───────────────────────────────────── */

.page-h1 { margin-bottom: 20px; }
.section-h3-lg { margin-bottom: 16px; }
.section-h3-sm { margin-bottom: 8px; }
.setup-actions { margin-top: 20px; margin-bottom: 48px; }
.settings-desc { color: var(--text-muted); font-size: 14px; margin-bottom: 20px; }
.billing-info { display: flex; flex-direction: column; gap: 8px; font-size: 14px; }
.billing-label { color: var(--text-muted); }
.billing-pricing-note { font-size: 13px; color: var(--text-muted); margin-top: 12px; }
.error-text { color: var(--danger); font-size: 14px; }
.status-active { color: var(--success); }
.status-trial { color: var(--warning); }
.status-past-due { color: var(--danger); }
.status-cancelled { color: var(--danger); }

/* ─── Checkout page ────────────────────────────────────────────── */

.checkout-wrapper { max-width: 480px; margin: 40px auto; }
.checkout-title { text-align: center; margin-bottom: 32px; }
.checkout-price-center { text-align: center; margin-bottom: 24px; }
.checkout-tier-label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 8px; }
.checkout-price-display { font-size: 36px; font-weight: 700; line-height: 1; }
.checkout-price-period { font-size: 14px; color: var(--text-muted); margin-top: 8px; }
.checkout-section { border-top: 1px solid var(--border); padding-top: 16px; margin-bottom: 24px; }
.checkout-row { display: flex; justify-content: space-between; font-size: 14px; margin-bottom: 8px; }
.checkout-row-last { display: flex; justify-content: space-between; font-size: 14px; }
.checkout-total-row { display: flex; justify-content: space-between; font-size: 16px; font-weight: 600; }
.checkout-label { color: var(--text-muted); }
.checkout-manage-link { display: block; text-align: center; margin-top: 12px; font-size: 14px; color: var(--text-muted); }

/* ─── Pricing page ─────────────────────────────────────────────── */

.pricing-hero-flush { padding-bottom: 24px; }
.pricing-page-section { max-width: 1100px; margin: 0 auto; padding: 0 24px 60px; }
.pricing-toggle-row { display: flex; justify-content: center; align-items: center; margin-bottom: 32px; }
.pricing-toggle { display: inline-flex; border: 1.5px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.pricing-toggle-btn { padding: 9px 22px; font-size: 14px; font-weight: 600; border: none; cursor: pointer; background: transparent; color: var(--text-muted); display: flex; align-items: center; gap: 8px; transition: background 0.15s, color 0.15s; }
.pricing-toggle-btn.active { background: var(--primary); color: #fff; }
.pricing-save-badge { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; color: #fff; background: #22c55e; padding: 2px 8px; border-radius: 20px; line-height: 1.6; }
.pricing-page-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; align-items: stretch; }
.pricing-page-grid-2col { grid-template-columns: 1fr 1fr; max-width: 760px; margin: 0 auto; }
.pricing-page-grid-1col { grid-template-columns: 1fr; max-width: 460px; margin: 0 auto; }
.pricing-card-col { display: flex; flex-direction: column; }
.pricing-card-col > .btn-block,
.pricing-card-col > a.btn-block { margin-top: auto; }
.pricing-features-flex { flex: 1; margin-bottom: 24px; }
.pricing-summary { border-top: 1px solid var(--border); padding-top: 16px; display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.pricing-summary-row { display: flex; justify-content: space-between; }
.pricing-muted { color: var(--text-muted); }
.pricing-bold { font-weight: 600; }
.pricing-bolder { font-weight: 700; }
.pricing-total-row { display: flex; justify-content: space-between; font-size: 16px; margin-top: 2px; }
.pricing-footer-note { text-align: center; margin-top: 40px; color: var(--text-muted); font-size: 14px; }
.pricing-footer-note p + p { margin-top: 16px; }
.pricing-cards-2col { grid-template-columns: 1fr 1fr; }

/* ─── Admin page (moved from inline <style>) ───────────────────── */

.stat-box { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; text-align: center; }
.stat-box .value { font-size: 28px; font-weight: 700; color: var(--primary); }
.stat-box .label { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.practice-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.practice-table th { text-align: left; padding: 8px 12px; border-bottom: 2px solid var(--border); color: var(--text-muted); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
.practice-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.practice-table tr:hover td { background: var(--bg); cursor: pointer; }
.badge-trial { background: var(--yellow-bg); color: var(--warning); }
.badge-active { background: var(--green-bg); color: var(--success); }
.badge-cancelled { background: var(--red-bg); color: var(--danger); }
.detail-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.detail-overlay.open { display: flex; }
.detail-panel { background: var(--surface); border-radius: var(--radius); padding: 24px; width: 100%; max-width: 480px; max-height: 80vh; overflow-y: auto; }
.detail-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.detail-row:last-child { border-bottom: none; }
.detail-label { color: var(--text-muted); }
.npi-unverified { color: var(--danger); font-weight: 600; }
.tabs { display: flex; gap: 4px; margin-bottom: 20px; border-bottom: 1px solid var(--border); }
.tab { padding: 8px 16px; cursor: pointer; font-size: 14px; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--text-muted); }
.tab.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
.tab-content { display: none; }
.tab-content.active { display: block; }
.detail-actions { margin-top: 16px; display: flex; gap: 8px; flex-wrap: wrap; }
.td-muted-sm { font-size: 13px; color: var(--text-muted); }
.td-xs-muted { font-size: 12px; color: var(--text-muted); }
.td-sm { font-size: 13px; }
.td-mono-sm { font-family: monospace; font-size: 13px; }
.td-bold { font-weight: 600; }
.td-nowrap { white-space: nowrap; }
.td-plan-cell { font-size: 13px; color: var(--text-muted); max-width: 220px; }

/* ─── Affiliate pages ──────────────────────────────────────────── */

.affiliate-stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 24px; max-width: 960px; margin: 0 auto 60px; }
.affiliate-stat-card { text-align: center; }
.affiliate-stat-value { font-size: 36px; font-weight: 800; color: var(--primary); line-height: 1; }
.affiliate-stat-label { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-top: 6px; }
.affiliate-stat-desc { font-size: 14px; color: var(--text-muted); margin-top: 12px; }
.affiliate-how-section { max-width: 720px; margin: 0 auto; }
.affiliate-cta-row { margin-top: 40px; text-align: center; }
.referral-link-box { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius); padding: 20px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 32px; flex-wrap: wrap; }
.referral-url { font-size: 16px; font-weight: 600; color: var(--primary); word-break: break-all; }
.referral-link-meta { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-muted); margin-bottom: 6px; }
.referral-flex-col { flex: 1; }
.referral-domain-prefix { color: var(--text-muted); font-size: 14px; white-space: nowrap; }
.referral-code-input-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.referral-code-availability { font-size: 13px; }
.referral-code-edit-actions { margin-top: 10px; display: flex; gap: 8px; }
.referral-link-actions { display: flex; gap: 8px; align-self: flex-start; }
.affiliate-payout-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.affiliate-payout-table th { text-align: left; padding: 10px 16px; border-bottom: 2px solid var(--border); color: var(--text-muted); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; }
.affiliate-payout-table td { padding: 10px 16px; border-bottom: 1px solid var(--border); }
.payout-status-paid { color: var(--success); font-weight: 600; }
.payout-status-pending { color: var(--warning); font-weight: 600; }
.referral-code-display { font-size: 20px; font-weight: 700; color: var(--primary); font-family: monospace; margin: 8px 0; }
.referral-code-note { font-size: 13px; color: var(--text-muted); margin: 0; }
.stripe-status { margin-bottom: 16px; font-size: 14px; }
.stripe-connected { color: var(--success); font-weight: 600; }
.stripe-not-connected { color: var(--text-muted); }
.code-status-row { display: flex; align-items: center; gap: 10px; }
.code-status { font-size: 13px; white-space: nowrap; min-width: 80px; }
.code-help { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.promo-count { font-weight: 400; color: var(--text-muted); font-size: 13px; float: right; }
.apply-success { text-align: center; padding: 32px 0; }
.apply-success-icon { font-size: 48px; margin-bottom: 16px; }
.apply-success p { color: var(--text-muted); }

/* ─── Admin panel ──────────────────────────────────────────────── */

.adm-page { overflow: hidden; }

.adm-layout { display: flex; height: 100vh; overflow: hidden; }

.adm-sidebar {
    width: 220px;
    flex-shrink: 0;
    background: #0F1117;
    display: flex;
    flex-direction: column;
    height: 100vh;
    overflow-y: auto;
}
.adm-sidebar-brand {
    padding: 22px 20px 18px;
    font-size: 17px;
    font-weight: 700;
    color: #fff;
    letter-spacing: -0.2px;
    border-bottom: 1px solid rgba(255,255,255,0.08);
}
.adm-nav { padding: 6px 0; flex: 1; }
.adm-nav-item {
    display: flex;
    align-items: center;
    padding: 10px 20px;
    font-size: 13.5px;
    color: #9CA3AF;
    text-decoration: none;
    border-left: 3px solid transparent;
    transition: background 0.12s, color 0.12s;
    user-select: none;
}
.adm-nav-item:hover { color: #E5E7EB; background: rgba(255,255,255,0.05); }
.adm-nav-item.active {
    color: #fff;
    background: rgba(37,99,235,0.18);
    border-left-color: #2563eb;
    font-weight: 500;
}
.adm-sidebar-footer {
    padding: 14px 20px;
    border-top: 1px solid rgba(255,255,255,0.08);
}
.adm-user-email {
    font-size: 11px;
    color: #6B7280;
    margin-bottom: 6px;
    word-break: break-all;
    line-height: 1.4;
}
.adm-sign-out { color: #6B7280; text-decoration: none; font-size: 12px; }
.adm-sign-out:hover { color: #fff; }

.adm-main {
    flex: 1;
    overflow-y: auto;
    /* overflow-x stays auto as a BACKSTOP, but nothing should reach it:
       every section below wraps or scrolls internally. It is also why the
       first sweep read zero — the page never scrolls because this absorbs it. */
    background: #F4F5F7;
    padding: 2rem;
    min-width: 0;
}

.adm-mobile-header {
    display: none;
    align-items: center;
    gap: 12px;
    margin-bottom: 1.5rem;
    font-size: 15px;
    font-weight: 600;
    color: #0F1117;
}
.adm-hamburger {
    background: none;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    padding: 5px 10px;
    cursor: pointer;
    font-size: 16px;
    color: #374151;
    line-height: 1;
}
.adm-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 199;
}
.adm-overlay.open { display: block; }

.adm-section { min-width: 0; display: none; }
.adm-section.active { display: block; }

.adm-section-title {
    font-size: 16px;
    font-weight: 600;
    color: #0F1117;
    margin-bottom: 1rem;
}

.adm-stat-grid {
    /* FLEX, not grid. auto-fit was the right instinct and still leaves a HOLE:
       with four cards and room for three, the fourth takes one track and the
       remaining two sit empty — which is the "ANNUAL alone on its own row"
       symptom. Grid tracks are uniform by construction, so the last row cannot
       absorb the leftover space.

       `flex: 1 1 168px` gives the same "count per row follows the space"
       behaviour AND lets the final row stretch to fill, so a lone card spans
       the width instead of leaving two thirds blank. 168px is the measured
       minimum for the longest label, NOTES THIS MONTH, at 11px uppercase with
       0.05em tracking plus 32px of card padding — below that the label is cut
       inside its own box. */
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 10px;
}
.adm-stat-card {
    background: #fff;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    padding: 14px 16px;
    /* grow | shrink | basis. The basis is the minimum readable width; growing
       is what fills the last row. min-width:0 keeps a long value ($1,494,000)
       from setting a floor the row cannot shrink past. */
    flex: 1 1 168px;
    min-width: 0;
}
.adm-stat-card .value, .adm-stat-card .label { overflow-wrap: anywhere; }
/* If a label ever does exceed its track, it WRAPS rather than being cut: a
   wrapped label is legible and a clipped one is a silent lie about the number
   beside it. */
.adm-stat-card .label { white-space: normal; }
.adm-summary-item .s-label, .adm-summary-item .s-value { overflow-wrap: anywhere; }
.adm-stat-card .label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #6B7280;
    margin-bottom: 6px;
    font-weight: 500;
}
.adm-stat-card .value {
    font-size: 28px;
    font-weight: 600;
    color: #1A5EAB;
    line-height: 1.1;
}

.adm-summary-row {
    display: flex;
    flex-wrap: wrap;          /* was wrap only under a max-width query */
    gap: 10px;
    margin-top: 12px;
    margin-bottom: 2rem;
}
.adm-summary-item { min-width: 0; flex: 1 1 168px; }
.adm-summary-item {
    background: #fff;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    padding: 12px 16px;
    flex: 1;
}
.adm-summary-item .s-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: #6B7280; margin-bottom: 4px; font-weight: 500; }
.adm-summary-item .s-value { font-size: 20px; font-weight: 600; color: #0F1117; }

.adm-toolbar { display: flex; gap: 10px; margin-bottom: 1rem; align-items: center; }
.adm-search {
    padding: 7px 12px;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    font-size: 13px;
    color: #374151;
    background: #fff;
    width: 300px;
}
.adm-search:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
.adm-filter-select {
    padding: 7px 12px;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    font-size: 13px;
    color: #374151;
    background: #fff;
    cursor: pointer;
}
.adm-filter-select:focus { outline: none; border-color: #2563eb; }

.adm-table-wrap {
    overflow-x: auto;
    /* A grid or flex child defaults to min-width:auto, which means "as wide as
       my content" — so a scrolling wrapper inside a grid track still forces the
       track open and the scrollbar never appears. This is what makes "tables
       scroll inside their own container" actually true. */
    min-width: 0;
    max-width: 100%;
    background: #fff;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
}
.adm-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.adm-table th {
    padding: 10px 14px;
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #6B7280;
    background: #F9FAFB;
    border-bottom: 1px solid #E5E7EB;
    white-space: nowrap;
}
.adm-table td {
    padding: 10px 14px;
    border-bottom: 1px solid #F3F4F6;
    color: #374151;
    vertical-align: middle;
}
.adm-table tbody tr:nth-child(even) td { background: #FAFAFA; }
.adm-table tbody tr:hover td { background: #F0F7FF; }
.adm-table tbody tr:last-child td { border-bottom: none; }
.adm-table .td-muted { color: #6B7280; }
.adm-table .td-mono { font-family: monospace; font-size: 12px; }
.adm-table .td-nowrap { white-space: nowrap; }

.adm-empty {
    text-align: center;
    color: #9CA3AF;
    font-size: 14px;
    padding: 3rem 1rem;
    background: #fff;
}
.adm-empty-error { color: var(--danger); }

.adm-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 100px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
}
.adm-badge-trial     { background: #FEF3C7; color: #92400E; }
.adm-badge-active    { background: #D1FAE5; color: #065F46; }
.adm-badge-expired   { background: #FEE2E2; color: #991B1B; }
.adm-badge-cancelled { background: #F3F4F6; color: #6B7280; }
.adm-badge-green     { background: #D1FAE5; color: #065F46; }
.adm-badge-yellow    { background: #FEF3C7; color: #92400E; }
.adm-badge-red       { background: #FEE2E2; color: #991B1B; }
.adm-badge-individual { background: #DBEAFE; color: #1E40AF; }
.adm-badge-practice   { background: #EDE9FE; color: #5B21B6; }
.adm-badge-payg       { background: #FEF3C7; color: #92400E; }
.adm-badge-approved   { background: #D1FAE5; color: #065F46; }
.adm-badge-pending    { background: #FEF3C7; color: #92400E; }
.adm-badge-past_due   { background: #FEE2E2; color: #991B1B; }
.adm-badge-suspended  { background: #FEE2E2; color: #991B1B; }
.adm-badge-rejected   { background: #FEE2E2; color: #991B1B; }

.adm-btn {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 5px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    line-height: 1.4;
    transition: opacity 0.12s;
}
.adm-btn:hover { opacity: 0.82; }
.adm-btn-view    { background: #EFF6FF; color: #1D4ED8; border: 1px solid #BFDBFE; }
.adm-btn-approve { background: #D1FAE5; color: #065F46; border: 1px solid #6EE7B7; }
.adm-btn-reject  { background: #FEE2E2; color: #991B1B; border: 1px solid #FCA5A5; }

.adm-row-fade { transition: opacity 0.4s; }
.adm-row-fade.fading { opacity: 0; }

/* Revenue section */
/* auto-fit so the two columns become one when there is no room for two. The
   fixed `1fr 1.5fr` could not wrap: at 1024 the second column was squeezed to
   77px and at 768 the single track was 862px wide inside a 736px section. */
.adm-rev-cols {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 24px; margin: 20px 0; align-items: start;
}
.adm-rev-col { min-width: 0; }
.adm-rev-subtitle { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-muted); margin-bottom: 10px; }
.adm-rev-stripe-section { margin-top: 28px; }
.adm-rev-total-row td { border-top: 2px solid var(--border); font-weight: 600; }
.adm-bar-chart { display: flex; align-items: flex-end; gap: 6px; min-height: 120px; padding: 16px 16px 12px; }
.adm-bar-chart.is-empty { align-items: center; justify-content: center; }
.adm-bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 3px; }
.adm-bar-fill { background: var(--primary); border-radius: 3px 3px 0 0; width: 100%; min-height: 4px; }
.adm-bar-val { font-size: 11px; font-weight: 600; color: var(--text); }
.adm-bar-lbl { font-size: 10px; color: var(--text-muted); white-space: nowrap; text-align: center; }

@media (max-width: 768px) {
    .adm-sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        z-index: 200;
        transform: translateX(-100%);
        transition: transform 0.25s;
    }
    .adm-sidebar.open { transform: translateX(0); }
    .adm-mobile-header { display: flex; }
    .adm-main { padding: 1rem; }
    /* `grid-template-columns: repeat(3, 1fr)` used to sit here and it OVERRODE
       the auto-fit rule above. Three fixed tracks cannot respond to the space:
       with four cards it put Total Practices / Active / Monthly on one row and
       stranded ANNUAL alone on the next, and it made each track too narrow for
       a label like NOTES THIS MONTH, which was then clipped inside its own card
       — visible as text sliced at the right edge. The auto-fit rule already
       does the right thing at every width, so this override is deleted rather
       than adjusted; a second definition of the column count is what caused it.
       Only the type size still changes here. */
    .adm-stat-card .value { font-size: 22px; }
    .adm-search { width: 100%; }
    /* Same reason: .adm-rev-cols is auto-fit above and does not need a second,
       narrower opinion that cannot adapt. */
}

/* ── Multi-complaint rows + grouped points selector (note form) ───────────── */
.complaint-row {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 12px;
  background: var(--surface);
}

.complaint-row-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}

.complaint-row-label {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

.remove-complaint {
  background: none;
  border: none;
  color: var(--danger);
  font-size: 13px;
  cursor: pointer;
  padding: 2px 6px;
}

.remove-complaint:hover { text-decoration: underline; }

#add-complaint-2,
#add-complaint-3 {
  width: 100%;
  margin-bottom: 12px;
  border: 1.5px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 14px;
  padding: 10px;
  border-radius: var(--radius);
  cursor: pointer;
  display: block;
}

#add-complaint-2:hover,
#add-complaint-3:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.points-group { margin-bottom: 8px; }

.points-group-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  user-select: none;
  font-size: 13px;
  font-weight: 600;
}

.points-group-header:hover { background: var(--border); }

.points-group-title { color: var(--text); }

.points-group-meta {
  font-size: 12px;
  color: var(--primary);
  font-weight: 500;
}

.points-group-chevron {
  font-size: 11px;
  color: var(--text-muted);
  transition: transform 0.15s;
  display: inline-block;
}

.points-group-chevron.open { transform: rotate(180deg); }

.points-group-body {
  display: none;
  padding: 10px 4px 4px;
}

.points-group-body.open { display: block; }

.points-clear {
  font-size: 13px;
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: underline;
  margin-bottom: 8px;
  display: inline-block;
}

.points-clear:hover { color: var(--danger); }

#points-other { margin-top: 10px; }
.tcm-other { margin-top: 8px; }

/* ── Case linkage: pending follow-ups + case badge ────────────────────────── */
.pending-heading {
  font-size: 18px;
  font-weight: 700;
  margin: 24px 0 12px;
  color: var(--text);
}
.pending-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.pending-info {
  display: flex;
  align-items: center;
  gap: 10px;
}
.pending-label {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.badge-case {
  background: #dbeafe;
  color: #1e40af;
}
.case-badge { cursor: pointer; }
.case-badge:hover { background: #bfdbfe; }

/* ── Claim outcome UI ─────────────────────────────── */
.st-quick-set { display: flex; gap: 4px; }
.st-btn { font-size: 11px; padding: 3px 8px; white-space: nowrap; }
.st-btn-pos { color: var(--success); border-color: var(--success); }
.st-btn-pos:hover { background: var(--green-bg); }
.st-btn-neg { color: var(--danger); border-color: var(--danger); }
.st-btn-neg:hover { background: var(--red-bg); }
.st-badge { font-size: 11px; }
.denial-reason-btn.selected { background: var(--primary); color: white; border-color: var(--primary); }

/* ── Patients & scheduling ────────────────────────────────────────────────── */
/* Added with the patient entity. Every class here is one the patient, schedule
   and chart screens reference; before this they rendered unstyled. */

/* Referenced by claims.html's claim-detail modal (5 sites) since that
   modal was first built, and never actually defined -- every "Service
   lines" / "Patient responsibility" / "Work items" heading in it was
   rendering as plain, unstyled paragraph text, indistinguishable from
   the content below it. The border-top gives the modal's long single
   scroll real visual sections instead of one undifferentiated stream;
   :first-of-type drops it so the label right under the claim header
   doesn't start with a redundant divider. */
.section-label {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-muted);
    margin: 20px 0 10px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
.section-label:first-of-type {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

/* A clean, bordered-row list for the claim-detail modal's payments/
   work-items/timeline <ul>s -- default browser bullets read as a raw
   data dump next to the rest of the app's card/table styling. */
.detail-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.detail-list li {
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.detail-list li:last-child { border-bottom: none; }

/* Same warning colors as .cell-flagged (a <td> background), but as a
   standalone inline pill -- for the claim-detail modal's "Contracted
   total" line when an open underpayment work item makes it worth
   calling out. Replaces what used to be a one-off inline style
   (display/padding/border-radius repeated by hand on that element). */
.flag-pill {
    display: inline-block;
    background: var(--yellow-bg);
    color: var(--warning);
    font-weight: 600;
    padding: 2px 10px;
    border-radius: 4px;
}

/* A small top margin for an action button that follows a paragraph or
   list inside a modal (Record Payment, Check Claim Status) -- replaces
   inline style="margin-bottom:12px" on each one. */
.modal-action-btn { margin-top: 4px; }

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}
.data-table thead th {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 2px solid var(--border);
    color: var(--text-muted);
    font-weight: 600;
    white-space: nowrap;
}
.data-table tbody td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--bg); }
.data-table td.empty,
.data-table .empty {
    text-align: center;
    color: var(--text-muted);
    padding: 24px 12px;
}

.muted { color: var(--text-muted); }

/* Key/value grid for the chart header. Two columns on desktop, stacked on
   narrow screens so a phone at the front desk stays readable. */
.kv-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 24px;
}
.kv {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.kv-k {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
}
.kv-v {
    font-size: 15px;
    color: var(--text);
    overflow-wrap: anywhere;
}
@media (max-width: 640px) {
    .kv-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Patient search picker. The results panel overlays what follows it, so the
   containing form-group is the positioning context. */
.form-group { position: relative; }

.picker-results {
    position: absolute;
    z-index: 30;
    left: 0;
    right: 0;
    top: 100%;
    margin-top: 2px;
    max-height: 260px;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.picker-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 9px 12px;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
}
.picker-row:last-child { border-bottom: none; }
.picker-row:hover { background: var(--bg); }
.picker-dob {
    font-size: 12px;
    color: var(--text-muted);
    white-space: nowrap;
}
.picker-empty {
    padding: 12px;
    color: var(--text-muted);
    font-size: 14px;
}
.picker-hint {
    margin-top: 6px;
    font-size: 13px;
    color: var(--text-muted);
}

/* Required marker and in-modal validation. The error holds the dialog open
   rather than closing it and discarding what was typed. */
.req { color: var(--danger); }
.modal-error {
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: var(--radius);
    background: var(--red-bg);
    color: var(--danger);
    border: 1px solid #fca5a5;
    font-size: 14px;
}

/* ── admin: the new-practice form ────────────────────────────────────────────
   Practices are created here and nowhere else — there is no practitioner-facing
   registration. The form lives inside the Practices section so creating one and
   seeing the list are the same screen. */
.adm-hidden { display: none; }
.adm-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px;
    margin: 12px 0 18px;
}
.adm-card-title { font-size: 16px; font-weight: 700; margin: 0 0 12px; }
.adm-card-subtitle {
    font-size: 13px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: var(--text-muted); margin: 18px 0 6px;
}
.adm-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px 16px;
}
.adm-field { display: flex; flex-direction: column; gap: 4px; position: relative; }
.adm-field > span { font-size: 12px; font-weight: 600; color: var(--text-muted); }
.adm-field input, .adm-field select {
    width: 100%; padding: 8px 10px; font: inherit; font-size: 14px;
    border: 1px solid var(--border); border-radius: 6px;
    background: var(--surface); color: var(--text);
}
.adm-hint { font-size: 12px; color: var(--text-muted); margin: 8px 0 0; }

/* NPPES is advisory. Styled as information, never as a validation state, so it
   cannot read as a blocker. */
.adm-nppes { margin-top: 10px; font-size: 13px; min-height: 18px; }
.adm-nppes-row { margin: 2px 0; }

.adm-picker {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,.14);
    max-height: 260px; overflow-y: auto;
}
.adm-picker-row { padding: 8px 10px; cursor: pointer; font-size: 13px; }
.adm-picker-row:hover { background: var(--bg); }
.adm-picker-empty { padding: 8px 10px; font-size: 13px; color: var(--text-muted); }
.adm-chosen { font-size: 13px; margin-top: 6px; color: var(--success); }

.adm-error {
    margin-top: 10px; padding: 8px 10px; font-size: 13px;
    color: var(--danger); background: var(--red-bg);
    border: 1px solid var(--danger); border-radius: 6px;
}
.adm-form-actions {
    display: flex; gap: 8px; justify-content: flex-end;
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
}
.adm-btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.adm-badge-warn { background: var(--yellow-bg); color: var(--warning); }

.adm-result {
    margin-top: 16px; padding: 14px; border-radius: var(--radius);
    background: var(--green-bg); border: 1px solid var(--success); font-size: 14px;
}
/* The payment link is displayed as well as emailed: some of this happens live
   on a call, and it has to be readable off the screen while the mail is still
   in flight — or when the send failed. */
.adm-result-link { margin: 10px 0 8px; }
.adm-result-link input {
    width: 100%; padding: 8px 10px; font-family: monospace; font-size: 12px;
    border: 1px solid var(--border); border-radius: 6px; background: var(--surface);
}
@media (max-width: 600px) {
    .adm-form-grid { grid-template-columns: 1fr; }
    .adm-form-actions { flex-direction: column-reverse; }
    .adm-form-actions .adm-btn { width: 100%; }
}

/* ── the signing screen ──────────────────────────────────────────────────────
   Three numbered steps because they are three separate legal acts: consent to
   electronic records, reading, and the signature itself. Collapsing them into
   one "I agree" would evidence none of them. */
.sign-check {
    display: flex; gap: 10px; align-items: flex-start;
    margin-top: 12px; font-size: 14px; line-height: 1.5; cursor: pointer;
}
.sign-check input { margin-top: 3px; flex-shrink: 0; width: 16px; height: 16px; }
.sign-check input:disabled + span { color: var(--text-muted); }

.doc-block { margin-bottom: 22px; }
.doc-block-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-bottom: 8px;
}
.doc-block-head h3 { font-size: 15px; margin: 0; }
.doc-block-head .btn { margin-left: auto; }
/* The document is scrollable rather than truncated: a "read more" that hides
   the text is the opposite of what a signature is supposed to evidence. */
.doc-scrollbox {
    max-height: 340px; overflow-y: auto;
    border: 1px solid var(--border); border-radius: var(--radius);
    padding: 14px 16px; background: var(--bg);
    font-size: 13px; line-height: 1.6; white-space: pre-wrap;
}

/* Settings: the real signing state, not a static notice. */
.sig-row {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14px;
}
.sig-row:last-child { border-bottom: none; }
.sig-row .sig-name { font-weight: 600; }
.sig-row .sig-meta { color: var(--text-muted); font-size: 13px; }
.sig-row a { margin-left: auto; }
@media (max-width: 600px) {
    .doc-block-head .btn, .sig-row a { margin-left: 0; }
}

/* EDIT HISTORY. A <details> rather than a toggle button: the open/closed state
   is the browser's, so there is no second definition of "is it expanded" to
   drift from the DOM, and it prints expanded in the PDF path browsers use. */
.edit-history-summary {
    display: flex; align-items: baseline; gap: 10px; cursor: pointer;
    font-size: 15px; font-weight: 600; color: var(--text);
    list-style: none;
}
.edit-history-summary::-webkit-details-marker { display: none; }
.edit-history-summary::before {
    content: "▸"; display: inline-block; color: var(--text-muted);
    font-weight: 400; transition: transform 0.12s ease;
}
details[open] > .edit-history-summary::before { transform: rotate(90deg); }
.edit-history-summary .muted { font-size: 13px; font-weight: 400; }
.edit-history-note { font-size: 13px; margin: 10px 0 16px; }
/* DELIBERATELY NOT styled like the note above it. Expanded, this panel used to
   be visually identical to the confirmed note two inches higher on the page —
   same headings, same body type — and the only thing separating a signed record
   from a superseded draft was a collapsed summary line. Muted, indented and
   ruled, so the two cannot be confused at a glance or in a screenshot. */
#edit-history-body {
    border-left: 3px solid var(--border);
    padding-left: 16px;
    margin-left: 2px;
}
#edit-history-body .doc-section p,
#edit-history-body .code-item { color: var(--text-muted); }
#edit-history-body .doc-section:last-child { margin-bottom: 0; }

/* WHOSE CLOCK IS RUNNING. Above the room and the time because it is the thing
   being looked for; a practitioner scanning four cards is looking for a person,
   not a room number. */
.wk-who {
    font-size: 15px; font-weight: 600; color: var(--text);
    line-height: 1.25; margin-bottom: 2px;
    overflow-wrap: anywhere;
}
.wk-who--none { font-weight: 400; font-size: 13px; color: var(--text-muted); font-style: italic; }
.wk-slim-who {
    font-weight: 600; color: var(--text); min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 600px) {
    .wk-slim-who { max-width: 40%; }
}

/* One toolbar shape for every filtered list: patients, history, admin. */
.list-toolbar {
    display: flex; align-items: center; gap: 12px; margin-bottom: 14px;
}
.list-toolbar .form-control { flex: 1; min-width: 0; max-width: 460px; }
.list-count { font-size: 13px; white-space: nowrap; }
@media (max-width: 600px) {
    .list-toolbar { flex-wrap: wrap; }
    .list-toolbar .form-control { max-width: none; }
}

/* The admin practices table is 1008px wide inside a scrolling wrapper, so below
   ~1260px the Actions column sits off the right edge. The row is clickable so
   opening a practice never depends on reaching that column. */
.adm-row-click { cursor: pointer; }
.adm-row-click:hover td { background: #F9FAFB; }

/* SCOPED. This was `.adm-table { min-width: 860px }` — every admin table, added
   for the ten-column practices table and inherited by all six, including the
   three-column tier breakdown that sits inside a half-width Revenue column. It
   pinned that column at 862px, crushed the chart beside it to 77px at 1024, and
   pushed the section past the viewport at 768 and 390. A width chosen for one
   table is not a property of tables. */
.adm-table--wide { min-width: 860px; }

/* Edit / Save / Cancel sit at the TOP of the detail panel, above the fields
   they act on — at the bottom they were below a dozen read-only rows and read
   as belonging to the tier controls. */
.detail-actions--top {
    display: flex; gap: 8px; justify-content: flex-end;
    margin: 0 0 12px; padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}
.detail-row .form-control-auto { max-width: 260px; }
@media (max-width: 600px) {
    .detail-row .form-control-auto { max-width: none; width: 100%; }
}

/* ONE RULE, EVERY TABLE. /history's table was not in a scroll container at all,
   so at 390px it dragged the whole document 540px sideways and took the header
   and nav with it. Rather than wrapping each table by hand and missing one,
   every .table and .data-table gets a scrolling parent — and the rule that
   makes the parent able to scroll is min-width:0, without which a flex or grid
   child is sized by its content and the scrollbar never appears. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    min-width: 0;
    max-width: 100%;
}
.table-scroll > table { min-width: 640px; }
@media (max-width: 600px) {
    /* Below this the columns cannot be read anyway; let the container scroll
       rather than pretending nine columns fit on a phone. */
    .table-scroll > table { min-width: 720px; }
}

/* Internal and soft-deleted practices are SHOWN and MARKED, not hidden. The
   query used to filter them out, which left the panel administering an empty
   set on the one box where all the data lives. */
.adm-mark {
    display: inline-block; margin-left: 8px; padding: 1px 6px;
    border-radius: 4px; font-size: 10px; font-weight: 700;
    letter-spacing: 0.06em; vertical-align: middle;
}
.adm-mark--internal { background: #EEF2FF; color: #4338CA; }
.adm-mark--deleted  { background: #FEF2F2; color: #B91C1C; }
.adm-row--deleted td { opacity: 0.62; }

/* Pager. The state line names the range AND the page, because "48 patients"
   over 50 rows is ambiguous about whether there is more. */
.pager { display: flex; align-items: center; justify-content: center;
         gap: 12px; flex-wrap: wrap; padding: 14px 0 2px; }
.pager-state { font-size: 13px; color: var(--text-muted); }

/* Public booking page (/book/{slug}): new/returning toggle, week-paged slot
   picker, contact form. */
.booking-type-toggle {
    display: flex; gap: 8px; margin-bottom: 20px;
}
.booking-type-toggle .btn { flex: 1; }
.booking-type-toggle .btn-toggle-active {
    background: var(--primary); color: #fff; border-color: var(--primary);
}

.slot-week-nav {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; margin-bottom: 14px;
}
.slot-week-nav .slot-week-label { font-weight: 600; font-size: 14px; }

.slot-days {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 10px; margin-bottom: 18px;
}
.slot-day {
    border: 1px solid var(--border); border-radius: var(--radius);
    padding: 10px;
}
.slot-day-label {
    font-weight: 600; font-size: 13px; margin-bottom: 8px; text-align: center;
}
.slot-btn-list { display: flex; flex-direction: column; gap: 6px; }
.slot-btn {
    display: block; width: 100%; padding: 6px 8px; font-size: 13px;
    border: 1.5px solid var(--border); border-radius: 6px; background: #fff;
    cursor: pointer; text-align: center;
}
.slot-btn:hover { border-color: var(--primary); }
.slot-btn.slot-btn-selected {
    background: var(--primary); color: #fff; border-color: var(--primary);
}

.slot-selected-summary {
    padding: 10px 14px; border-radius: var(--radius); background: var(--bg);
    border: 1px solid var(--border); margin-bottom: 18px; font-size: 14px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 DESIGN SYSTEM LAYER  (Stage 1, 2026-08-30)
   Appended, not surgical: the whole file above is untouched, so removing
   this block reverts everything. Refines tokens + core primitives + a
   1100px contained shell (fluid on mobile). Same #2563eb accent and grey
   family as before,
   tighter radius, a real type + space scale. Class names are unchanged.
   Dark mode is NOT wired here yet — the file above still has ~40 literal
   light colours; that is its own follow-up stage after a literal sweep.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --bg:            #f5f6f8;
  --surface:       #ffffff;
  --surface-2:     #f7f8fa;
  --border:        #e4e6ea;
  --border-strong: #d4d7dd;
  --text:          #1f2328;
  --text-muted:    #656d76;
  --text-subtle:   #8b929b;

  --primary:       #2563eb;
  --primary-hover: #1d4ed8;
  --primary-tint:  #eef3ff;
  --success:       #1a7f37;
  --success-tint:  #e6f4ea;
  --warning:       #9a6700;
  --warning-tint:  #fdf3d6;
  --danger:        #cf222e;
  --danger-tint:   #fdecee;
  /* keep the old alias names working for rules that still reference them */
  --green-bg:  var(--success-tint);
  --yellow-bg: var(--warning-tint);
  --red-bg:    var(--danger-tint);

  --fs-11: 11px; --fs-12: 12px; --fs-13: 13px; --fs-14: 14px;
  --fs-16: 16px; --fs-20: 20px; --fs-26: 26px;
  --mono: ui-monospace, "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;

  --r-sm: 4px; --r: 6px; --r-lg: 10px;
  --radius: 6px;                        /* old token, tightened 8 -> 6 */
  --sh-1: 0 1px 2px rgba(16,24,40,.06);
  --sh-2: 0 6px 24px rgba(16,24,40,.12);
  --shadow: var(--sh-1);                /* old token */
  --ring: 0 0 0 3px rgba(37,99,235,.28);

  --gutter: 12px;
  --control-h: 32px;
}
@media (max-width: 640px) { :root { --gutter: 8px; --control-h: 34px; } }

body { font-size: var(--fs-13); line-height: 1.45; -webkit-font-smoothing: antialiased; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ── shell: a 1100px centred column on desktop — header, body and footer
   all align to the same column — and fluid full-width with a small edge
   gutter on mobile. (The Stage-1 full-bleed override is retired.) ── */
.container        { max-width: 960px; }
.container-wide   { max-width: 1100px; }
.container-narrow { max-width: 480px; }
.container,
.container-wide,
.container-narrow { width: 100%; margin-inline: auto; padding: 0 var(--gutter); }
.header,
.marketing-header { padding: 0; }
.header-inner,
.marketing-header-inner { max-width: 1100px; margin-inline: auto; padding: 6px var(--gutter); min-height: 44px; }
.site-footer-inner { max-width: 1100px; margin-inline: auto; padding: 0 var(--gutter); }
.page-body { padding: var(--gutter) var(--gutter) 64px; }

/* ── buttons ── */
.btn {
  height: var(--control-h); padding: 0 12px; gap: 6px;
  font-size: var(--fs-13); font-weight: 500; line-height: 1;
  border: 1px solid var(--border-strong); border-radius: var(--r);
  background: var(--surface); color: var(--text);
  transition: background .12s, border-color .12s, color .12s;
}
.btn:hover:not(:disabled) { background: var(--surface-2); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--primary-hover); border-color: var(--primary-hover); }
.btn-success { background: var(--success); border-color: var(--success); color: #fff; }
.btn-success:hover:not(:disabled) { background: #15803d; border-color: #15803d; }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger:hover:not(:disabled) { filter: brightness(.94); }
.btn-outline { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.btn-outline:hover:not(:disabled) { background: var(--surface-2); }
.btn-sm { height: 26px; padding: 0 9px; font-size: var(--fs-12); }
.btn-lg { height: 40px; padding: 0 18px; font-size: var(--fs-14); }

/* ── form controls ── */
.form-group { margin-bottom: var(--sp-3); }
.form-label { font-size: var(--fs-12); font-weight: 550; color: var(--text-muted); margin-bottom: var(--sp-1); }
.form-control {
  height: var(--control-h); padding: 0 10px;
  font-size: var(--fs-13); line-height: 1.45;
  border: 1px solid var(--border-strong); border-radius: var(--r);
  background: var(--surface); color: var(--text);
  transition: border-color .12s, box-shadow .12s;
}
textarea.form-control { height: auto; min-height: 76px; padding: 8px 10px; }
select.form-control { padding-right: 30px; }
.form-control:focus,
select.form-control:focus,
textarea.form-control:focus { outline: none; border-color: var(--primary); box-shadow: var(--ring); }
.form-control::placeholder { color: var(--text-subtle); }
.form-help { font-size: var(--fs-12); color: var(--text-subtle); margin-top: var(--sp-1); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.form-row > .form-group { flex: none; }
@media (max-width: 520px) { .form-row { grid-template-columns: 1fr; } }

/* ── card ── */
.card {
  border: 1px solid var(--border); border-radius: var(--r);
  padding: var(--sp-4); box-shadow: var(--sh-1); margin-bottom: var(--sp-3);
}

/* ── badges: pill, tint bg, semantic text ── */
.badge {
  gap: 4px; padding: 3px 7px; border-radius: 999px;
  font-size: var(--fs-11); font-weight: 600; line-height: 1;
  background: var(--surface-2); color: var(--text-muted);
}
.badge-green  { background: var(--success-tint); color: var(--success); }
.badge-yellow { background: var(--warning-tint); color: var(--warning); }
.badge-red    { background: var(--danger-tint);  color: var(--danger); }
.badge-gray   { background: var(--surface-2);    color: var(--text-muted); }
.badge-blue,
.badge-case   { background: var(--primary-tint); color: var(--primary); }
.badge-trial     { background: var(--warning-tint); color: var(--warning); }
.badge-active    { background: var(--success-tint); color: var(--success); }
.badge-cancelled { background: var(--danger-tint);  color: var(--danger); }
.badge-dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; display: inline-block; }

/* ── alerts: tint bg, no literal borders (dark-safe) ── */
.alert { padding: 8px 12px; border: 1px solid transparent; border-radius: var(--r); font-size: var(--fs-13); margin-bottom: var(--sp-3); }
.alert-info    { background: var(--primary-tint); color: var(--primary); }
.alert-success { background: var(--success-tint); color: var(--success); }
.alert-warning { background: var(--warning-tint); color: var(--warning); }
.alert-danger  { background: var(--danger-tint);  color: var(--danger); }

/* ── data table: full-bleed, dense, sticky header; stacks on mobile ── */
.data-table thead th {
  position: sticky; top: 0; z-index: 1;
  font-size: var(--fs-11); font-weight: 600; letter-spacing: .3px; text-transform: uppercase;
  color: var(--text-subtle); background: var(--surface-2);
  padding: 7px 10px; border-bottom: 1px solid var(--border);
}
.data-table td { padding: 7px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; overflow-wrap: anywhere; }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td,
.data-table tbody tr:hover { background: var(--surface-2); }
.t-name { font-weight: 550; }
.t-sub  { color: var(--text-muted); font-size: var(--fs-12); }
.t-dob  { display: block; margin-top: 2px; color: var(--text-muted); font-size: var(--fs-12); font-variant-numeric: tabular-nums; }
.table-scroll { border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); }
@media (min-width: 641px) { .table-scroll { overflow-x: auto; } }

@media (max-width: 640px) {
  .table-scroll { border: none; background: transparent; border-radius: 0; overflow: visible; }
  .data-table thead { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }
  .data-table, .data-table tbody, .data-table tr, .data-table td { display: block; width: 100%; }
  .data-table tr {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); box-shadow: var(--sh-1); margin-bottom: var(--sp-2);
  }
  .data-table tr:last-child { margin-bottom: 0; }
  .data-table tbody tr:hover,
  .data-table tbody tr:hover td { background: var(--surface); }
  .data-table td {
    border: none; border-top: 1px solid var(--border);
    padding: var(--sp-2) var(--sp-3); text-align: left; white-space: normal;
  }
  .data-table td:first-child { border-top: none; }
  .data-table td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 2px;
    font-size: var(--fs-11); font-weight: 600; letter-spacing: .5px;
    text-transform: uppercase; color: var(--text-subtle);
  }
  .data-table td:first-child .t-name { font-size: var(--fs-14); font-weight: 650; }
  .data-table td.actions,
  .data-table td:last-child { padding: var(--sp-3); }
  .data-table td.actions .btn,
  .data-table td:last-child .btn { flex: 1 1 auto; min-width: 130px; }
}

/* ── .table (history, reports, revenue) gets the same dense header + mobile
   row-stacking as .data-table, so a 10-column report stops side-scrolling on
   a phone. app.js's auto-labeler also stamps table.table now. ── */
.table thead th {
  position: sticky; top: 0; z-index: 1;
  font-size: var(--fs-11); font-weight: 600; letter-spacing: .3px; text-transform: uppercase;
  color: var(--text-subtle); background: var(--surface-2);
  padding: 7px 10px; border-bottom: 1px solid var(--border);
}
.table td { padding: 7px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; overflow-wrap: anywhere; }
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover td,
.table tbody tr:hover { background: var(--surface-2); }

@media (max-width: 640px) {
  .table-scroll > table { min-width: 0; }   /* retire the forced 640/720 scroll width */
  .table thead { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table tr {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); box-shadow: var(--sh-1); margin-bottom: var(--sp-2);
  }
  .table tr:last-child { margin-bottom: 0; }
  .table tbody tr:hover,
  .table tbody tr:hover td { background: var(--surface); }
  .table td {
    border: none; border-top: 1px solid var(--border);
    padding: var(--sp-2) var(--sp-3); text-align: left; white-space: normal;
  }
  .table td:first-child { border-top: none; }
  .table td[style*="text-align:right"],
  .table td[style*="text-align: right"] { text-align: left !important; }
  .table td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 2px;
    font-size: var(--fs-11); font-weight: 600; letter-spacing: .5px;
    text-transform: uppercase; color: var(--text-subtle);
  }
  .table td.actions, .table td:last-child { padding: var(--sp-3); }
}

/* ── tabs ── */
.tabs { gap: var(--sp-1); }
.tab { padding: 7px 10px; font-size: var(--fs-13); font-weight: 500; color: var(--text-muted); }
.tab.active { color: var(--text); border-bottom-color: var(--primary); font-weight: 600; }

/* ── modal: crisper border/shadow, actions bar bleeds to the edges ── */
.modal { border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-2); }
.modal-actions {
  flex-wrap: wrap;   /* a 6-button claim-detail footer wrapped >800px and clipped on a phone */
  margin: var(--sp-4) calc(-1 * var(--sp-6)) calc(-1 * var(--sp-6));
  padding: var(--sp-3) var(--sp-6);
  border-top: 1px solid var(--border); background: var(--surface-2);
}
@media (max-width: 640px) {
  .modal { padding: var(--sp-4); }
  .modal-actions {
    justify-content: flex-start;
    margin: var(--sp-3) calc(-1 * var(--sp-4)) calc(-1 * var(--sp-4));
    padding: var(--sp-3) var(--sp-4);
  }
  .modal-actions .btn { flex: 1 1 140px; }   /* wrap 2-up, stay tappable */
}

/* ── section labels / empty states ── */
.section-label { font-size: var(--fs-11); font-weight: 600; letter-spacing: .4px; color: var(--text-subtle); }
.table-empty, .table-error, .empty { padding: var(--sp-8) var(--sp-4); }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — shared page chrome  (Stage 4, 2026-08-30)
   Appended: refines the header row, the summary tiles, the filter row and
   the empty states every app page shares, onto the token scale above.
   Class names unchanged; ~16 pages pick this up at once for a consistent
   frame around each page's own content.
   ═══════════════════════════════════════════════════════════════════════════ */

/* page header: one calm line — title left, primary action right */
.page-header { margin: 0 0 var(--sp-4); gap: var(--sp-2) var(--sp-3); }
.page-header h1,
.page-h1 { font-size: var(--fs-20); font-weight: 650; line-height: 1.2; }
.page-h1 { margin: 0 0 var(--sp-4); }   /* Settings: a bare h1, not a .page-header row */
.page-header .count,
.page-header .page-sub { font-size: var(--fs-12); color: var(--text-subtle); font-weight: 500; }

/* summary tiles (dashboard, revenue, admin): tighter, quieter label */
.stat-grid { gap: var(--sp-3); margin-bottom: var(--sp-4); }
.stat-card {
  padding: var(--sp-4);
  border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: var(--sh-1);
}
.stat-value { font-size: var(--fs-26); line-height: 1; }
.stat-label {
  font-size: var(--fs-11); margin-top: var(--sp-1);
  color: var(--text-subtle); font-weight: 600; letter-spacing: .4px;
}

/* filter / date-nav row */
.filter-row { gap: var(--sp-2); margin-bottom: var(--sp-3); }

/* section header (label left, control right) + inline list headings */
.section-header { margin-bottom: var(--sp-3); }
.pending-heading { font-size: var(--fs-16); font-weight: 650; margin: var(--sp-6) 0 var(--sp-3); }

/* empty / error blocks: centred, subtle, on the token scale */
.table-empty, .table-error { color: var(--text-subtle); padding: var(--sp-6) var(--sp-4); }
.table-error { color: var(--danger); }
#empty-state { padding: var(--sp-8) var(--sp-4); color: var(--text-subtle); }
#empty-history { padding: var(--sp-6) var(--sp-4); color: var(--text-subtle); }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — card interiors + key/value grids  (Stage 4, 2026-08-30)
   The patient chart, note identity block and settings sections are stacks of
   cards, each led by a heading and often a label/value grid. Denser, quieter
   titles and tighter grids so a full chart reads at a glance.
   ═══════════════════════════════════════════════════════════════════════════ */

/* card section title: compact, no longer an 18px page-weight heading */
.card > h2:first-child,
.card > h3:first-child,
.card > div:first-child > h2 { margin-top: 0; }
.card h2, .card h3 {
  font-size: var(--fs-14); font-weight: 650; line-height: 1.3;
  color: var(--text); margin: 0 0 var(--sp-3);
}
@media (max-width: 640px) { .card { padding: var(--sp-3); } }

/* key/value grid (patient demographics, note identity, intake reason-for-visit) */
.kv-grid { gap: var(--sp-3) var(--sp-6); }
.kv-k { font-size: var(--fs-11); letter-spacing: .04em; color: var(--text-subtle); }
.kv-v { font-size: var(--fs-14); }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — public / token pages  (Stage 4 · T2, 2026-08-30)
   intake, book, portal, login, forgot/reset-password, staff-invite,
   confirm-email-change: a centred card in a padded shell. Reclaim the edge
   padding on a phone (a long intake form was losing 48px of screen), and
   bring the title to the app's 20px.
   ═══════════════════════════════════════════════════════════════════════════ */
.auth-container { padding: var(--sp-6) var(--gutter); }
.auth-box {
  padding: var(--sp-5); border-radius: var(--r); box-shadow: var(--sh-1);
}
.auth-box h1 { font-size: var(--fs-20); font-weight: 650; margin-bottom: var(--sp-5); }
@media (max-width: 640px) {
  .auth-container { padding: var(--sp-4) var(--gutter); }
  .auth-box { padding: var(--sp-4); }
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — cross-links  (Stage 4 · T2, 2026-08-30)
   One consistent look for every "jump to the related record" link — a patient
   name in a claims row, a claim badge in History, the visit-note link in the
   claim modal — whether it sits in a table cell or a meta line.
   ═══════════════════════════════════════════════════════════════════════════ */
.data-table a:not(.btn),
.table a:not(.btn),
.lnk { color: var(--primary); text-decoration: none; }
.data-table a:not(.btn):hover,
.table a:not(.btn):hover,
.lnk:hover { text-decoration: underline; }
.data-table a.t-name,
.table a.t-name { font-weight: 550; }   /* a linked patient name still reads as the row title */

/* the identity / "related records" line under a record's heading
   (claim-detail modal, note header) */
.record-meta {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 2px var(--sp-3); margin: 0 0 var(--sp-3);
  font-size: var(--fs-13); color: var(--text-muted);
}
.record-meta .sep { color: var(--border-strong); }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — patient chart normalisation  (Stage 4, 2026-08-30)
   The chart's header had 3 actions that collapsed into a narrow right-aligned
   column on a phone, and its demographics grid had no row separation. Bring
   both in line with the rest of the app.
   ═══════════════════════════════════════════════════════════════════════════ */

/* header action cluster on mobile: a full-width wrapping row of equal
   buttons — same treatment as the modal footer and table row-actions —
   not a narrow column hugging the right edge */
@media (max-width: 768px) {
  .page-header .toolbar-primary,
  .page-header .toolbar,
  .page-header .btn-row {
    width: 100%; flex-flow: row wrap; align-items: stretch;
    justify-content: flex-start; gap: var(--sp-2); margin-left: 0;
  }
  .page-header .toolbar-primary > .btn,
  .page-header .toolbar > .btn,
  .page-header .btn-row > .btn { flex: 1 1 140px; }
}

/* key/value grid on mobile: hairline-divided rows, like the stacked table
   cards elsewhere (patient demographics, note identity, intake summary) */
@media (max-width: 640px) {
  .kv-grid { gap: 0; }
  .kv-grid > .kv {
    padding: var(--sp-2) 0;
    border-top: 1px solid var(--border);
  }
  .kv-grid > .kv:first-child { border-top: none; padding-top: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — schedule time gutter  (Stage 4, 2026-08-30)
   The sticky time column was 68px, right-aligned, with dead space on its
   left. Narrow it, left-justify the labels (now "8:00AM", practice-local),
   and label the whole column "EST" once in the grid corner.
   ═══════════════════════════════════════════════════════════════════════════ */
.cal-grid { grid-template-columns: 50px repeat(var(--cal-cols), minmax(132px, 1fr)); }
.cal-time {
  text-align: left;
  padding: 2px 2px 0 4px;
  white-space: nowrap;
}
.cal-corner {
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0 0 6px;
  font-size: 10px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-subtle);
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — button state fixes  (Stage 4, 2026-08-30)
   Two real bugs: (1) a button that ended up with BOTH a solid variant and
   .btn-outline rendered WHITE, because .btn-outline is declared last and won
   the equal-specificity tie; (2) a disabled #2563eb button at opacity .5 over
   a white surface read as blank/white. Pin the solid variants above
   .btn-outline, and give disabled solids a lightened fill instead of a
   near-transparent one.
   ═══════════════════════════════════════════════════════════════════════════ */
.btn.btn-primary  { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn.btn-success  { background: var(--success); border-color: var(--success); color: #fff; }
.btn.btn-danger   { background: var(--danger);  border-color: var(--danger);  color: #fff; }
.btn.btn-primary:hover:not(:disabled)  { background: var(--primary-hover); border-color: var(--primary-hover); }
.btn.btn-success:hover:not(:disabled)  { background: #15803d; border-color: #15803d; }

.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn.btn-primary:disabled, .btn.btn-primary[disabled] {
  opacity: 1; background: #9cbdf3; border-color: #9cbdf3; color: #fff;
}
.btn.btn-success:disabled, .btn.btn-success[disabled] {
  opacity: 1; background: #8ec7a2; border-color: #8ec7a2; color: #fff;
}
.btn.btn-danger:disabled, .btn.btn-danger[disabled] {
  opacity: 1; background: #e6a2a8; border-color: #e6a2a8; color: #fff;
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — DARK MODE  (Stage 5, 2026-08-31; made the default 2026-09-01)
   Attribute-driven, never @media (prefers-color-scheme). Dark is now the
   DEFAULT: the inline <head> boot script stamps data-theme="dark" on load
   unless the viewer has explicitly toggled to light (stored as
   notyme_theme="light"). The bare :root palette below is still the light
   one — it applies under data-theme="light" and as the pre-JS fallback.
   Appended, not surgical: deleting this block reverts dark mode entirely.

   Two parts:
     1. the dark token palette — body / header / cards / tables / buttons /
        badges / forms / the whole Stage-1..4 v2 layer all flow from these
        tokens, so redefining them flips ~80% of the app in one place.
     2. targeted overrides for the ~25 base rules that hard-code a colour
        (literal white surfaces, tint literals, black scrims, weak rings).
        Rules already re-declared with tokens by the v2 layer (.alert*,
        .badge-gray, .badge-case bg/text, .modal shadow) are NOT repeated here.

   Scope: the practitioner + patient app and the marketing components
   (.marketing-*, .feature-grid, .pricing-*, all token-based or listed below).
   The .adm-* admin design system is deliberately EXCLUDED — its content area
   is a separate pass alongside the admin JS de-inline; its nav is already dark.
   ═══════════════════════════════════════════════════════════════════════════ */

:root,
:root[data-theme="light"] { color-scheme: light; }

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:            #0e1116;
  --surface:       #161b22;
  --surface-2:     #1c232d;
  --border:        #2a313c;
  --border-strong: #3b4351;
  --text:          #e6e9ef;
  --text-muted:    #9aa3b2;
  --text-subtle:   #7c8695;   /* AA on --surface-2 (table headers, tiny labels) */

  --primary:       #5b8def;   /* lifted from #2563eb for AA contrast on dark */
  --primary-hover: #7aa3f2;
  --primary-tint:  #17233d;
  --success:       #46c07a;
  --success-tint:  #12251b;
  --warning:       #d9a441;
  --warning-tint:  #2a2413;
  --danger:        #f0616b;
  --danger-tint:   #2c1619;
  /* --green-bg / --yellow-bg / --red-bg alias to the *-tint tokens in the
     v2 :root and resolve against these values at use time — no re-declare. */

  --sh-1: 0 1px 2px rgba(0,0,0,.55);
  --sh-2: 0 10px 34px rgba(0,0,0,.6);
  --shadow: var(--sh-1);
  --ring: 0 0 0 3px rgba(91,141,239,.4);
}

:root[data-theme="dark"] ::selection { background: rgba(91,141,239,.32); }

/* ── overlays / scrims: a deeper black on dark so the dialog still lifts ── */
[data-theme="dark"] .loading-overlay,
[data-theme="dark"] .modal-overlay,
[data-theme="dark"] .mobile-nav-overlay,
[data-theme="dark"] .onboarding-overlay,
[data-theme="dark"] .detail-overlay { background: rgba(0,0,0,.7); }

/* ── dashboard visit ("wk") cards + control buttons: literal #fff / tints ── */
[data-theme="dark"] .wk-card[data-state="paused"],
[data-theme="dark"] .wk-card[data-state="upcoming"],
[data-theme="dark"] .wk-btn,
[data-theme="dark"] .wk-done       { background: var(--surface); }
[data-theme="dark"] .wk-card[data-state="running"] { background: var(--success-tint); }
[data-theme="dark"] .wk-btn--c:hover               { background: var(--surface-2); }
[data-theme="dark"] .wk-secondary--danger:hover    { background: var(--danger-tint); }

/* ── booking slot buttons ── */
[data-theme="dark"] .slot-btn { background: var(--surface); }

/* ── weak literal focus ring on inputs → the token ring ── */
[data-theme="dark"] .form-control:focus,
[data-theme="dark"] select.form-control:focus,
[data-theme="dark"] textarea.form-control:focus { box-shadow: var(--ring); }

/* ── in-modal validation error box: drop the light-pink literal border ── */
[data-theme="dark"] .modal-error { border-color: transparent; }

/* ── onboarding + loading dialogs: literal black shadow → token ── */
[data-theme="dark"] .onboarding-modal,
[data-theme="dark"] .loading-box { box-shadow: var(--sh-2); }
[data-theme="dark"] .ob-id-box-result { background: var(--primary-tint); }

/* ── clickable case badge hover (v2 handles its base bg/text) ── */
[data-theme="dark"] .badge-case:hover { background: #1e2f4d; }

/* ── disabled solid buttons: the Stage-4 light fills read as "enabled" on
      dark — desaturate them instead ── */
[data-theme="dark"] .btn.btn-primary:disabled,
[data-theme="dark"] .btn.btn-primary[disabled] { background: #2f3f5e; border-color: #2f3f5e; color: #aeb8c7; }
[data-theme="dark"] .btn.btn-success:disabled,
[data-theme="dark"] .btn.btn-success[disabled] { background: #26402f; border-color: #26402f; color: #aeb8c7; }
[data-theme="dark"] .btn.btn-danger:disabled,
[data-theme="dark"] .btn.btn-danger[disabled]  { background: #43262a; border-color: #43262a; color: #aeb8c7; }

/* ── marketing components (notyme.co shares this sheet; goes dark deliberately
      when its pages next ship on Miami with data-theme="dark") ── */
[data-theme="dark"] .pricing-card          { border-color: var(--border-strong); }
[data-theme="dark"] .pricing-card-featured { background: var(--primary-tint); }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — DARK-MODE TOGGLE CONTROL  (Stage 6, 2026-08-31)
   The toggle is placed inside the nav, never as a header-bar sibling:
   · .header-nav / .marketing-nav  → a compact icon button at the end (this
     nav is display:none < 768px, so on mobile the drawer row takes over)
   · .mobile-nav-links (the drawer) → a full-width row matching the other rows
   Works in both themes — all colours are tokens.
   ═══════════════════════════════════════════════════════════════════════════ */

.header-nav .theme-toggle,
.marketing-nav .theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; flex: none;
  font-size: 14px; line-height: 1; cursor: pointer;
  color: var(--text-muted); background: none;
  border: 1px solid var(--border-strong); border-radius: var(--r);
  transition: color .12s, border-color .12s;
}
.header-nav .theme-toggle:hover,
.marketing-nav .theme-toggle:hover { color: var(--text); border-color: var(--text-subtle); }
.header-nav .theme-toggle:focus-visible,
.marketing-nav .theme-toggle:focus-visible { outline: none; box-shadow: var(--ring); }

.mobile-nav-links .theme-toggle {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 13px 20px; font: inherit; font-size: 15px; font-weight: 500;
  text-align: left; cursor: pointer;
  color: var(--text); background: none;
  border: none; border-top: 1px solid var(--border);
}
.mobile-nav-links .theme-toggle:hover { background: var(--bg); }
.mobile-nav-links .theme-toggle span { font-weight: 500; }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — MARKETING PAGES  (Stage 7, 2026-08-31)
   Appended, not surgical. Aligns notyme.co to the app: one 1100px column,
   the token gutter/space scale, tokenised colours. And makes the HOME hero a
   full-viewport panel so the feature cards sit a deliberate scroll below it
   (100svh: guaranteed one screenful even with mobile browser chrome showing).
   ═══════════════════════════════════════════════════════════════════════════ */

/* one shared column width + gutter for every marketing block */
.marketing-hero,
.feature-grid,
.marketing-section,
.pricing-page-section,
.pricing-page-grid { max-width: 1100px; margin-inline: auto; }

/* ── HOME hero: fills the screen; cards are below the fold ── */
.marketing-hero {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; position: relative;
  min-height: 100vh;          /* fallback */
  min-height: 100svh;
  padding: var(--sp-8) var(--gutter) calc(var(--sp-8) * 2);
  gap: var(--sp-5);
}
.marketing-hero > * { max-width: 760px; }
.marketing-hero h1 {
  font-size: clamp(28px, 6vw, 44px); font-weight: 800; line-height: 1.12;
  letter-spacing: -0.02em; margin: 0; color: var(--text);
}
.marketing-hero .hero-sub {
  font-size: clamp(15px, 2.4vw, 19px); line-height: 1.55;
  color: var(--text-muted); margin: 0;
}
.marketing-hero .hero-note { font-size: var(--fs-12); color: var(--text-subtle); margin: 0; }
.hero-actions { display: flex; gap: var(--sp-3); justify-content: center; flex-wrap: wrap; margin-top: var(--sp-2); }

/* scroll affordance — sits just under the CTAs (a bottom-pinned cue collides
   with the fixed cookie banner on a first visit). "there's more below." */
.hero-scroll {
  display: inline-flex; padding: 6px; margin-top: var(--sp-4);
  color: var(--text-subtle);
  animation: hero-bob 1.8s ease-in-out infinite;
}
.hero-scroll:hover { color: var(--text-muted); }
@keyframes hero-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .hero-scroll { animation: none; } }

/* the standalone <hr> under the hero is redundant once the hero is 100svh —
   the viewport edge is the separator; the feature band carries its own top rule */
.marketing-hero + .divider { display: none; }

/* ── feature cards: a distinct band, clearly below the hero ── */
.feature-grid {
  padding: calc(var(--sp-8) * 1.5) var(--gutter) calc(var(--sp-8) * 1.5);
  gap: var(--sp-4);
  border-top: 1px solid var(--border);
}
.feature-card { border-radius: var(--r); padding: var(--sp-5); }
.feature-card h3 { font-size: var(--fs-16); font-weight: 650; margin: 0 0 var(--sp-2); color: var(--text); }
.feature-card p  { font-size: var(--fs-13); line-height: 1.6; color: var(--text-muted); margin: 0; }
@media (max-width: 900px) { .feature-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .feature-grid { grid-template-columns: 1fr; padding-block: var(--sp-8); } }

/* ── the text/section pages (about, faq, privacy, terms, contact) ── */
.marketing-section { padding: var(--sp-8) var(--gutter) calc(var(--sp-8) * 2); }
.marketing-section h2 { font-size: var(--fs-26); font-weight: 700; margin: 0 0 var(--sp-4); line-height: 1.2; }
.marketing-section h3 { font-size: var(--fs-16); font-weight: 650; margin: var(--sp-6) 0 var(--sp-2); }
.marketing-section p,
.marketing-section ul li { font-size: var(--fs-14); line-height: 1.7; color: var(--text-muted); }

/* ── tokenise the pricing-card literals (light + dark consistent) ── */
.pricing-card { border: 1px solid var(--border-strong); }
.pricing-card-featured { border-color: var(--primary); background: var(--primary-tint); }
[data-theme="dark"] .pricing-card-featured { background: var(--primary-tint); }

/* hero shrinks its vertical rhythm on short/mobile screens but stays full-height */
@media (max-width: 560px) {
  .marketing-hero { gap: var(--sp-4); padding-top: var(--sp-6); }
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — LANDING SCROLL MOTION  (Stage 8, 2026-08-31, rev 2)
   (1) hero parallax — content holds, then drifts up + fades as the hero
       scrolls away. Pure CSS scroll-driven animation; unsupported = static.
   (2) feature section is now a SINGLE COLUMN — one card per row, ~720px
       centred, ~40vh of air between them so each is met one at a time.
       Each card slides in from alternating sides + fades as it enters view.
   Count-agnostic (keys off every .feature-card / :nth-child parity).
   Card motion is gated behind `.js-reveal` on <html> (set by landing.html's
   <head> script): no JS, or prefers-reduced-motion → static, all visible.
   ═══════════════════════════════════════════════════════════════════════════ */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .marketing-hero { view-timeline: --hero block; }
    .marketing-hero > h1,
    .marketing-hero > .hero-sub,
    .marketing-hero > .hero-actions {
      animation: hero-parallax linear both;
      animation-timeline: --hero;
      animation-range: exit 0% exit 100%;
    }
    @keyframes hero-parallax {
      0%, 32% { transform: none;              opacity: 1; }
      100%    { transform: translateY(-34px); opacity: 0; }
    }
    .marketing-hero > .hero-sub     { animation-name: hero-parallax; animation-range: exit 6% exit 100%; }
    .marketing-hero > .hero-actions { animation-range: exit 12% exit 100%; }
  }
}

/* ── single-column feature stack ── */
.feature-grid {
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(160px, 40vh, 380px);
  padding: 14vh var(--gutter) 16vh;
  overflow-x: clip;                 /* contain the horizontal slide-in */
  border-top: 1px solid var(--border);
}
.feature-card {
  max-width: 720px; width: 100%;
  padding: var(--sp-6);
  scroll-margin-top: 12vh;
}

/* ── alternating slide-in reveal ── */
.js-reveal .feature-card {
  opacity: 0;
  transform: translateX(-52px);
  transition: opacity .6s ease, transform .7s cubic-bezier(.22, 1, .36, 1);
  will-change: opacity, transform;
}
.js-reveal .feature-card:nth-child(even) { transform: translateX(52px); }
.js-reveal .feature-card.is-visible      { opacity: 1; transform: none; }

@media (max-width: 640px) {
  .feature-grid { gap: clamp(110px, 26vh, 230px); padding-block: 9vh 12vh; }
  .js-reveal .feature-card             { transform: translateX(-26px); }
  .js-reveal .feature-card:nth-child(even) { transform: translateX(26px); }
}
@media (prefers-reduced-motion: reduce) {
  .js-reveal .feature-card { opacity: 1; transform: none; transition: none; }
}

/* ── pricing page: the pricing block gets its own full-height panel so the
      three cards land CENTRED in the viewport (not parked at the bottom of a
      short page), and by the time you've scrolled a screen the hero has faded.
      The three cards rise + fade in TOGETHER when the grid reaches mid-view. ── */
.pricing-page-section {
  min-height: 100vh;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-block: 10vh;
}
.pricing-page-grid { margin-inline: auto; justify-content: center; scroll-margin-top: 12vh; }
.pricing-footer-note { margin-top: var(--sp-8); }

.js-reveal .pricing-page-grid > .pricing-card {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .6s ease, transform .7s cubic-bezier(.22, 1, .36, 1);
  will-change: opacity, transform;
}
.js-reveal .pricing-page-grid > .pricing-card.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js-reveal .pricing-page-grid > .pricing-card { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 640px) {
  .pricing-page-section { min-height: 0; padding-block: 8vh 12vh; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — provider-app polish  (Stage 9, 2026-09-01)
   Appended, delete to revert. Both themes:
     1. real breathing room between the sticky header and the page heading —
        every provider page wraps its content in .page-body, so one rule
        covers all of them.
     2. in-content links (patient names in a table, cross-record jumps) read
        as TEXT, not saturated accent-blue; they reveal as links on hover.
        The active-nav cue and the brand wordmark keep the accent.
     3. stat-tile numbers use the text colour, not the accent.
   ═══════════════════════════════════════════════════════════════════════════ */

.page-body { padding-top: var(--sp-6); }                  /* was --gutter (12px) */
@media (min-width: 768px) { .page-body { padding-top: 40px; } }

.data-table a:not(.btn),
.table a:not(.btn),
.lnk {
  color: var(--text);
  text-decoration: none;
}
.data-table a:not(.btn):hover,
.table a:not(.btn):hover,
.lnk:hover {
  color: var(--primary);
  text-decoration: underline;
}

.stat-value,
.summary-stat .value { color: var(--text); }


/* ═══════════════════════════════════════════════════════════════════════════
   v2 — one control row per page  (Stage 10, 2026-09-01)
   The page heading sits alone directly under the app header; every button,
   date picker, view toggle and quick-range chip for that page lives on a
   single .page-toolbar row below it (wrapping as needed). Replaces the
   per-page mix of page-header-with-a-button / .cal-bar / .list-toolbar /
   loose .filter-row on Dashboard / Schedule / Patients / History / Revenue.
   Claims + Reports already carry an h1-only .page-header. Appended, revert
   by deleting.
   ═══════════════════════════════════════════════════════════════════════════ */

.page-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin: 0 0 var(--sp-5);
}
/* keep a cluster (date nav, view toggles, a date range + its Search button)
   visually together while the row as a whole wraps */
.page-toolbar .tb-group {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-1);
}
.page-toolbar .tb-group > span { color: var(--text-muted); font-size: var(--fs-12); }
/* the "filter the rows already loaded" search — fills the slack, yields first */
.page-toolbar .tb-search { flex: 1 1 200px; min-width: 0; max-width: 360px; }
.page-toolbar .tb-count { font-size: var(--fs-12); color: var(--text-subtle); white-space: nowrap; }
/* the page's primary action snaps to the right edge of the row */
.page-toolbar > .btn-primary { margin-left: auto; }

@media (max-width: 600px) {
  .page-toolbar > .btn-primary { margin-left: 0; width: 100%; justify-content: center; }
  .page-toolbar .tb-search { max-width: none; flex-basis: 100%; }
  .page-toolbar .tb-group { width: 100%; }
}
