/* ── Brand Tokens ──────────────────────────────────────── */
:root {
    --color-primary: #018c91;
    --color-primary-dark: #026e73;
    --color-primary-contrast: #fff;
    --sidebar-width: 220px;
    --topbar-height: 56px;
    --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --color-bg: #f4f7f8;
    --color-surface: #fff;
    --color-text: #1a1d1e;
    --color-text-muted: #6c757d;
    --color-border: #e4e8ea;
    /* Radius scale: controls default 10px, cards/dropdowns 16px, buttons/chips full pill. */
    --radius: 10px;
    --radius-sm: 7px;
    --radius-lg: 16px;
    --radius-pill: 999px;
    --shadow-sm: 0 1px 3px rgba(16,42,45,.05);
    --shadow: 0 4px 16px rgba(16,42,45,.07);
    --shadow-lg: 0 10px 32px rgba(16,42,45,.14);
    /* Translucent primary tints — used for hovers/selection so they layer on any surface. */
    --primary-tint: rgba(1,140,145,.08);
    --primary-tint-weak: rgba(1,140,145,.04);
    --primary-tint-strong: rgba(1,140,145,.14);
    --focus-ring: rgba(1,140,145,.18);
    /* Extended palette — every color in the app goes through these tokens so the
       dark theme below can restyle everything in one place. */
    --color-surface-alt: #f9fafb;
    --color-hover: #f3f4f6;
    --color-border-2: #e5e7eb;
    --color-border-strong: #c0c8cc;
    --color-text-faint: #9ca3af;
    --danger: #dc2626;
    --danger-fg: #b91c1c;
    --danger-bg: #fee2e2;
    --danger-border: #fca5a5;
    --success: #059669;
    --success-fg: #166534;
    --success-bg: #d1fae5;
    --success-border: #86efac;
    --warn-bg: #fef3c7;
    --warn-fg: #b45309;
    --warn-border: #fdba74;
    --accent-bg: #e6f7f7;
    --info-bg: #f0f4ff;
    --info-fg: #3b5bdb;
}

/* ── Dark Theme ────────────────────────────────────────── */
[data-theme="dark"] {
    color-scheme: dark;
    --color-primary: #2bb3b8;
    --color-primary-dark: #22999e;
    --color-bg: #101415;
    --color-surface: #191f21;
    --color-surface-alt: #1f2629;
    --color-hover: #242c2f;
    --color-text: #e7ebec;
    --color-text-muted: #9aa5a8;
    --color-text-faint: #79848a;
    --color-border: #2a3336;
    --color-border-2: #2f393d;
    --color-border-strong: #46545a;
    --shadow-sm: 0 1px 3px rgba(0,0,0,.35);
    --shadow: 0 4px 16px rgba(0,0,0,.45);
    --shadow-lg: 0 10px 32px rgba(0,0,0,.55);
    --primary-tint: rgba(43,179,184,.12);
    --primary-tint-weak: rgba(43,179,184,.06);
    --primary-tint-strong: rgba(43,179,184,.2);
    --focus-ring: rgba(43,179,184,.28);
    --danger: #f87171;
    --danger-fg: #fca5a5;
    --danger-bg: #3d1f1f;
    --danger-border: #7f1d1d;
    --success: #34d399;
    --success-fg: #86efac;
    --success-bg: #14352a;
    --success-border: #14532d;
    --warn-bg: #3a2c12;
    --warn-fg: #fbbf24;
    --warn-border: #92400e;
    --accent-bg: #123539;
    --info-bg: #1c2540;
    --info-fg: #93b0f5;
}

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

body {
    font-family: var(--font);
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 14px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

h1 { font-size: 1.55rem; font-weight: 700; letter-spacing: -0.015em; }
h2 { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.01em; }
/* FocusOnNavigate lands on the page h1; the UA focus rectangle is just noise there. */
h1:focus, .auth-title:focus { outline: none; }

/* ── App Layout ────────────────────────────────────────── */
.app-layout {
    display: grid;
    /* minmax(0, 1fr), not 1fr: a grid track's automatic minimum is its content's intrinsic width,
       so one unshrinkable child — the topbar's user block, a wide table — pushed the whole column
       past the viewport and gave every page a sideways scroll on a phone. Letting the track go
       below its content hands the overflow back to the children, which already have their own
       scroll contexts (.admin-card is overflow-x:auto under 900px). */
    grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
    grid-template-rows: var(--topbar-height) 1fr;
    grid-template-areas:
        "sidebar topbar"
        "sidebar content";
    min-height: 100vh;
}

/* ── Collapsed sidebar (rail) ──────────────────────────── */
/* Icons only, with the label shown on hover. The pin is remembered per browser. */
.app-layout.rail { --sidebar-width: 60px; }
.app-layout.rail .nav-label,
.app-layout.rail .nav-section { display: none; }
/* The "Setup" flyout has its own room and shows on hover regardless of rail/docked state — the
   blanket .nav-label hiding above is only meant for the 60px icon strip itself, not the popup
   its items open into, so restore labels for anything inside it. */
.app-layout.rail .nav-submenu .nav-label { display: inline; }
/* At 60px there isn't room for the wordmark, but the brand must not vanish with it: the
   square "D" mark takes over, stacked above the pin so expanding again stays obvious. */
.app-layout.rail .sidebar-logo { display: none; }
.app-layout.rail .sidebar-mark { display: block; height: 26px; }
.app-layout.rail .sidebar-pin {
    position: static; transform: none; margin: 0 auto; width: 26px; height: 26px; font-size: 0.9rem;
}
.app-layout.rail .sidebar-header {
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    height: auto;
    padding: 12px 8px;
}
[dir="rtl"] .app-layout.rail .sidebar-pin { transform: scaleX(-1); }
.app-layout.rail .nav-links li a { justify-content: center; gap: 0; padding: 10px 0; margin: 2px 8px; }
/* Collapsing the menu is a request for room to work in, so hand the reclaimed width to the
   page instead of leaving it as margin — otherwise the 1200px cap swallows the whole gain
   and docking the menu looks like it did nothing. */
.app-layout.rail .content-body { max-width: none; }
.app-layout.rail .nav-links { overflow: visible; }
.app-layout.rail .nav-links li { position: relative; }
.app-layout.rail .nav-links li a::after {
    content: attr(data-label);
    position: absolute; inset-inline-start: calc(100% + 8px); top: 50%; transform: translateY(-50%);
    background: var(--color-text); color: var(--color-surface);
    padding: 4px 10px; border-radius: var(--radius-sm); font-size: 0.8125rem; white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity .12s; z-index: 50; box-shadow: var(--shadow);
}
.app-layout.rail .nav-links li a:hover::after,
.app-layout.rail .nav-links li a:focus-visible::after { opacity: 1; }

.sidebar-header { position: relative; }
.sidebar-pin {
    position: absolute; inset-inline-end: 6px; top: 50%; transform: translateY(-50%);
    background: rgba(255,255,255,.12); border: none; color: #fff; cursor: pointer;
    width: 20px; height: 20px; border-radius: 50%; font-size: 0.75rem; line-height: 1;
    display: flex; align-items: center; justify-content: center;
}
.sidebar-pin:hover { background: rgba(255,255,255,.28); }
/* The arrow points the way it will move, which flips with direction. */
[dir="rtl"] .sidebar-pin { transform: translateY(-50%) scaleX(-1); }

/* ── Sidebar ───────────────────────────────────────────── */
.sidebar {
    grid-area: sidebar;
    background: linear-gradient(180deg, var(--color-primary), var(--color-primary-dark));
    color: var(--color-primary-contrast);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    /* Must stay fully visible, not auto: an auto/scroll value on either axis forces the other
       axis to auto too (CSS overflow spec), which would clip the "Setup" flyout submenu — it
       pops out past the sidebar's right edge via position:absolute. Rail mode relied on this
       same fix before it was unconditional; nav item count is short enough that giving up
       independent sidebar scrolling here is a non-issue in practice. */
    overflow: visible;
    /* position:sticky makes the sidebar its own stacking context, so the "Setup" flyout's
       z-index only ranks it against other sidebar children — against the page it sat at the
       sidebar's own level (auto = 0), and any positioned element in the content area (a sticky
       table header, a search box) painted over the popup. Above the topbar (10), below drawers
       (40+), modals (50+) and toasts. */
    z-index: 20;
}

.sidebar-header {
    padding: 14px 16px;
    border-bottom: 1px solid rgba(255,255,255,.15);
    display: flex;
    align-items: center;
    height: var(--topbar-height);
}

.sidebar-logo {
    height: 32px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

/* The compact mark exists only for the rail; the expanded sidebar shows the wordmark. */
.sidebar-mark { display: none; }

.nav-links {
    list-style: none;
    padding: 10px 0;
    flex: 1;
}

/* Nav items are inset rounded pills; margin-inline keeps RTL mirroring automatic. */
.nav-links li a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    margin: 2px 10px;
    color: rgba(255,255,255,.82);
    font-size: 0.875rem;
    transition: background .18s, color .18s;
    border-radius: var(--radius);
}

.nav-links li a:hover {
    background: rgba(255,255,255,.1);
    color: #fff;
    text-decoration: none;
}

.nav-links li a.active {
    background: rgba(255,255,255,.18);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,.08);
}

.nav-section {
    padding: 14px 22px 4px;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: rgba(255,255,255,.55);
}

.nav-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    opacity: .85;
}

/* ── "Setup" hover flyout ──────────────────────────────── */
/* A single grouped item revealed on hover/focus instead of a permanent flat block — these are
   pages visited to configure the clinic, not day-to-day work. The trigger reuses the same look
   as a plain nav link; the flyout itself borrows the themed surface/shadow tokens (not the
   sidebar's own dark rgba tones) since it pops out over the light/dark content area, not the
   sidebar background. */
.nav-group { position: relative; }
.nav-group-toggle {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 10px;
    padding: 9px 12px;
    margin: 2px 10px;
    color: rgba(255,255,255,.82);
    font: inherit;
    font-size: 0.875rem;
    text-align: start;
    background: none;
    border: none;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background .18s, color .18s;
}
.nav-group-toggle:hover,
.nav-group-toggle:focus-visible,
.nav-group:focus-within .nav-group-toggle {
    background: rgba(255,255,255,.1);
    color: #fff;
}
.nav-caret {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    opacity: .7;
    margin-inline-start: auto;
    transition: transform .15s;
}
.nav-group.open .nav-caret { transform: rotate(90deg); }
.nav-submenu {
    display: none;
    list-style: none;
    margin: 0;
    padding: 6px;
    position: absolute;
    inset-inline-start: calc(100% + 6px);
    /* "Setup" is always the last item in the nav list (admin panels stack several sections
       above it), so anchoring from the bottom and growing upward keeps the menu on-screen —
       anchoring from the top instead cut off its lower items below the viewport. The max-height
       + scroll is a safety net for a short viewport even a bottom anchor can't fully avoid. */
    bottom: 0;
    max-height: calc(100vh - 16px);
    overflow-y: auto;
    min-width: 13rem;
    z-index: 40;
    background: var(--color-surface);
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.nav-group:hover .nav-submenu,
.nav-group:focus-within .nav-submenu,
.nav-group.open .nav-submenu {
    display: block;
}
.nav-submenu li a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    margin: 0;
    border-radius: var(--radius-sm);
    color: var(--color-text);
    font-size: 0.875rem;
}
.nav-submenu li a:hover {
    background: var(--primary-tint-weak);
    /* Without this, the only matching :hover color rule left is the dark sidebar's own
       ".nav-links li a:hover" (this popup's <li><a> still lives inside .nav-links in the DOM) —
       white text on this light popup surface, invisible in light mode. */
    color: var(--color-text);
    text-decoration: none;
}
.nav-submenu li a.active {
    background: var(--primary-tint);
    color: var(--color-primary-dark);
    font-weight: 600;
}
.nav-submenu .nav-icon { opacity: .7; }
/* Collapsed rail: the flyout still opens (same absolute anchor), the toggle just loses its
   label/caret and centers its icon like every other rail link. */
.app-layout.rail .nav-group-toggle { justify-content: center; gap: 0; padding: 10px 0; margin: 2px 8px; }
.app-layout.rail .nav-caret { display: none; }

/* ── Top Bar ───────────────────────────────────────────── */
.topbar {
    grid-area: topbar;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    padding: 0 20px;
    box-shadow: var(--shadow-sm);
    position: sticky;
    top: 0;
    z-index: 10;
}

.topbar-user {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
}

/* Bare buttons in the topbar (theme toggle, sign out) render as ghost pills. */
.topbar-user button {
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    color: var(--color-text);
    font-size: 0.8125rem;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.topbar-user button:hover { background: var(--color-hover); border-color: var(--color-border-strong); }

.topbar-username {
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* ── Content ───────────────────────────────────────────── */
.content {
    grid-area: content;
    padding: 28px 32px;
    overflow-y: auto;
}

.content-body {
    max-width: 1200px;
}

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 24px;
}

/* The text block (title + description) is what should give way to a long
   description wrapping onto more lines — the action button/link(s) on the
   right must never squeeze down to the point their own label wraps. */
.page-header > *:last-child { flex-shrink: 0; }

.page-header h1 {
    color: var(--color-text);
}

.page-header p {
    color: var(--color-text-muted);
    margin-top: 4px;
}

/* ── Search ────────────────────────────────────────────── */
.search-wrapper {
    position: relative;
    width: 280px;
}

.search-input {
    width: 100%;
    padding: 8px 14px 8px 34px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    font-size: 0.875rem;
    background: var(--color-bg);
    color: var(--color-text);
    outline: none;
    transition: border-color .15s, box-shadow .15s, background .15s;
}

.search-input:focus {
    border-color: var(--color-primary);
    background: var(--color-surface);
    box-shadow: 0 0 0 3px var(--focus-ring);
}

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

.search-icon {
    position: absolute;
    left: 9px;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    color: var(--color-text-muted);
    pointer-events: none;
}

.search-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    z-index: 100;
    /* Scrolls instead of growing without limit when a query matches a lot. */
    max-height: min(60vh, 30rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 4px 0;
}

/* Category filter badges, pinned above the scrolling results. */
.search-filters {
    display: flex; flex-wrap: wrap; gap: 0.25rem;
    padding: 6px 10px 8px;
    border-bottom: 1px solid var(--color-border-2);
    position: sticky; top: 0; background: var(--color-surface); z-index: 1;
}
.search-filter {
    border: 1px solid var(--color-border); background: var(--color-surface);
    color: var(--color-text-muted); border-radius: var(--radius-pill);
    padding: 2px 10px; font-size: 0.75rem; font-weight: 500; cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}
.search-filter:hover { border-color: var(--color-primary); color: var(--color-primary); }
.search-filter.active {
    background: var(--color-primary); border-color: var(--color-primary);
    color: var(--color-primary-contrast);
}
.search-more {
    display: block; width: 100%; text-align: center; cursor: pointer;
    background: none; border: none; border-top: 1px solid var(--color-border-2);
    padding: 8px; font-size: 0.8125rem; font-weight: 600; color: var(--color-primary);
}
.search-more:hover { background: var(--primary-tint-weak); }

.search-empty { padding: 12px; text-align: center; font-size: 0.82rem; color: var(--color-text-muted); }

/* Patient picker inside the appointment panel — same visual language as the top search
   dropdown, but a plain custom list rather than a native <datalist> (see AppointmentPanel.razor
   for why: a datalist re-populated on every keystroke closes its own popup in most browsers). */
.patient-search-wrapper { position: relative; }
.patient-search-dropdown {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); z-index: 20;
    max-height: 14rem; overflow-y: auto; padding: 4px 0;
}
.patient-search-result {
    display: block; width: 100%; text-align: left; background: none; border: none;
    padding: 8px 12px; font-size: 0.875rem; color: var(--color-text); cursor: pointer;
}
.patient-search-result:hover { background: var(--color-hover); }

.search-result {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    font-size: 0.875rem;
    color: var(--color-text);
    transition: background .1s;
    cursor: pointer;
}

.search-result:hover {
    background: var(--color-hover);
    text-decoration: none;
}

.search-result-icon {
    width: 14px;
    height: 14px;
    color: var(--color-text-muted);
    flex-shrink: 0;
}

/* ── Dashboard ─────────────────────────────────────────── */
.dashboard-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 300px;
    text-align: center;
    color: var(--color-text-muted);
}

.dashboard-empty svg {
    width: 72px;
    height: 72px;
    margin-bottom: 18px;
    padding: 16px;
    color: var(--color-primary);
    background: var(--accent-bg);
    border-radius: 50%;
    opacity: .9;
}

.dashboard-empty h2 {
    font-size: 1.1rem;
    font-weight: 500;
    color: var(--color-text);
    margin-bottom: 6px;
}

/* ── Blazor Built-ins ──────────────────────────────────── */
#blazor-error-ui {
    background: #b32121;
    color: white;
    padding: 10px 16px;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    font-size: 0.875rem;
    display: none;
}

#blazor-error-ui a { color: #fff; text-decoration: underline; }

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--success); }
.invalid { outline: 1px solid var(--danger); }
.validation-message { color: var(--danger); font-size: 0.8125rem; margin-top: 2px; }

/* ── Utility ───────────────────────────────────────────── */
.text-muted   { color: var(--color-text-muted); }
.text-success { color: var(--success-fg); }
.text-danger  { color: var(--danger); }
.btn-primary {
    background: var(--color-primary);
    color: var(--color-primary-contrast);
    border: none;
    padding: 8px 18px;
    border-radius: var(--radius-pill);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .18s, box-shadow .18s, transform .18s;
}
.btn-primary:hover:not(:disabled) {
    background: var(--color-primary-dark);
    box-shadow: var(--shadow);
    transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) { transform: translateY(0); box-shadow: none; }
.btn-primary:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.btn-primary.btn-sm { padding: 5px 12px; font-size: 0.8rem; }
.btn-primary:disabled { opacity: .5; cursor: default; }

/* ── Patient Grid ──────────────────────────────────────── */
.patients-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}

.search-wrapper.inline { position: relative; }
.search-wrapper.inline .search-input { padding-left: 32px; width: 260px; }
.search-wrapper.inline .search-icon {
    position: absolute;
    left: 8px; top: 50%;
    transform: translateY(-50%);
    width: 16px; height: 16px;
    color: var(--color-text-muted);
    pointer-events: none;
}

.btn-columns {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    padding: 6px 14px;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--color-text);
    cursor: pointer;
    transition: border-color .15s, color .15s;
}
.btn-columns:hover { border-color: var(--color-primary); color: var(--color-primary); }

.column-toggle-wrap { position: relative; }

.backdrop {
    position: fixed;
    inset: 0;
    z-index: 10;
    background: transparent;
}

.column-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 6px 0;
    min-width: 160px;
    max-height: 55vh;
    overflow-y: auto;
    z-index: 11;
    box-shadow: var(--shadow-lg);
}

.column-menu-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    font-size: 0.875rem;
    cursor: pointer;
    user-select: none;
}
.column-menu-item:hover { background: var(--color-bg); }

/* ── Localized date picker ─────────────────────────────── */
.ldp-wrap { position: relative; display: inline-block; width: 100%; }
.ldp-input-group { position: relative; }
/* .ldp-input-group input.ldp-input, not .ldp-input: both ".field-input" and the more specific
   ".field input" (line ~923) also set this element's padding — same "class + element type"
   specificity as a bare "input.ldp-input", so whichever of those was declared LAST in this file
   silently won and collapsed this back to 12px on both sides. That stayed invisible wherever
   AllowClear was off (nothing on the right to collide with) or no icon existed yet (nothing on
   the left) — exactly why it went unnoticed until the calendar icon added a second element
   competing for the space. Scoping to the wrapper class makes this strictly more specific than
   either competitor, so it wins regardless of source order. */
.ldp-input-group input.ldp-input { cursor: pointer; background: var(--color-surface); padding-left: 30px; padding-right: 26px; }
.ldp-input[disabled] { cursor: not-allowed; }
.ldp-icon {
    position: absolute;
    left: 9px;
    top: 50%;
    transform: translateY(-50%);
    width: 15px;
    height: 15px;
    color: var(--color-text-muted);
    pointer-events: none;
}
.ldp-clear {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    border: none;
    background: none;
    color: var(--color-text-muted);
    cursor: pointer;
    font-size: 0.72rem;
    line-height: 1;
    padding: 4px;
}
.ldp-clear:hover { color: var(--color-text); }
.ldp-popup {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 8px;
    z-index: 11;
    box-shadow: var(--shadow-lg);
    width: 17rem;
}
.ldp-popup-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
    font-size: 0.8125rem;
    font-weight: 500;
    margin-bottom: 6px;
}
.ldp-mini-select {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.8125rem;
    font-weight: 500;
    padding: 2px 4px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
}
.ldp-popup-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.ldp-dow { text-align: center; font-size: 0.7rem; color: var(--color-text-muted); padding: 2px 0; }
.ldp-day {
    text-align: center;
    font-size: 0.8125rem;
    padding: 6px 0;
    border-radius: var(--radius);
    cursor: pointer;
}
.ldp-day:hover { background: var(--color-bg); }
.ldp-day.outside { color: var(--color-text-muted); opacity: .5; }
.ldp-day.today { font-weight: 700; }
.ldp-day.selected { background: var(--color-primary); color: #fff; }

/* Was flex:1 1 auto — on a half-width field the date box stretched to fill the whole row while
   showing an 8-character date, leaving a wide dead gap next to the compact time box. Capping it
   keeps both fields close to their actual content width, so the pair reads as one balanced
   control instead of one oversized box next to a small one. */
/* The two halves of one control, so they have to read as one control. A native <input type="time">
   carries intrinsic height from its browser-drawn clock and inner spinner fields — it rendered
   ~4px taller than the plain text date input beside it, which made the time half look like the
   bigger, more important field. Stretching both to the row's height keeps them identical without
   pinning a magic pixel value that a font or padding change would silently break. */
.ldtp-wrap { display: flex; gap: 6px; align-items: stretch; }
.ldtp-wrap .ldp-wrap { flex: 1 1 11rem; min-width: 0; }
.ldtp-wrap .ldp-input-group { height: 100%; }
.ldtp-wrap input.ldp-input { height: 100%; }
.ldtp-time { flex: 0 0 7rem; }
/* Centres the time text against the taller box so it doesn't sit high next to the date. */
.ldtp-time::-webkit-datetime-edit { display: flex; align-items: center; }

.grid-wrap {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    transition: opacity .15s;
}
.grid-loading-overlay { opacity: .5; pointer-events: none; }

.patient-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.patient-table thead th {
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    font-weight: 600;
    font-size: 0.8125rem;
    padding: 11px 14px;
    text-align: start;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.patient-table th.sortable { cursor: pointer; user-select: none; }
.patient-table th.sortable:hover { color: var(--color-primary); }
.patient-table th.sorted { color: var(--color-primary); }
.sort-arrow { margin-left: 4px; font-size: 0.7rem; }

.patient-table tbody td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
    vertical-align: middle;
}
.patient-table tbody tr:last-child td { border-bottom: none; }
.patient-table tbody tr:hover td { background: var(--primary-tint-weak); }

.grid-loading {
    padding: 48px;
    text-align: center;
    color: var(--color-text-muted);
    font-size: 0.875rem;
}
.grid-empty {
    padding: 48px;
    text-align: center;
    color: var(--color-text-muted);
}

.pagination {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 16px;
}

.page-btn {
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 0.875rem;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}
.page-btn:hover:not(:disabled) {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.page-btn.active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-primary-contrast);
    font-weight: 600;
}
.page-btn:disabled { opacity: .4; cursor: default; }
.page-ellipsis { color: var(--color-text-muted); padding: 0 4px; }

.pagination-info {
    margin-top: 8px;
    font-size: 0.8125rem;
    color: var(--color-text-muted);
}

/* ── Auth / Login ──────────────────────────────────────── */
.auth-layout {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: var(--color-bg);
}

.auth-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 44px 40px;
    width: 100%;
    max-width: 400px;
}

/* Registration: too many fields for the narrow login-sized card — a wide card plus the
   .form-grid two-column layout keeps it readable at half the scroll length. */
.auth-card-wide { max-width: 880px; }

.auth-title {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--color-primary);
    margin-bottom: 4px;
}

.auth-subtitle {
    color: var(--color-text-muted);
    font-size: 0.875rem;
    margin-bottom: 24px;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 16px;
}

.field label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--color-text);
}

.field input {
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.875rem;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
    background: var(--color-surface);
    color: var(--color-text);
    width: 100%;
}

.field input:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--focus-ring);
}

/* Checkboxes and radios must not inherit the text-input box above — `width: 100%` plus
   8px/12px padding stretched them across their whole grid cell and shoved the label away.
   The attribute selector outranks `.field input`, so source order doesn't matter. */
.field input[type="checkbox"],
.field input[type="radio"] {
    width: auto;
    padding: 0;
    margin: 0;
    inline-size: 15px;
    block-size: 15px;
    flex: 0 0 auto;
    border-radius: 3px;
    accent-color: var(--color-primary);
}
.field input[type="checkbox"]:focus,
.field input[type="radio"]:focus { box-shadow: 0 0 0 3px var(--focus-ring); }

.field-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 20px;
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

.field-row label {
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}

/* "Remember me" left, "Forgot password?" right. */
.auth-row-split { justify-content: space-between; }
.auth-row-split .btn-link { font-size: 0.8125rem; }

.auth-card .btn-primary {
    width: 100%;
    padding: 10px;
    font-size: 0.9375rem;
    font-weight: 500;
}

.error-message {
    color: var(--danger-fg);
    font-size: 0.8125rem;
    margin-bottom: 14px;
    padding: 9px 14px;
    background: var(--danger-bg);
    border-radius: var(--radius);
    border: 1px solid var(--danger-border);
}

/* ── Buttons (shared) ──────────────────────────────────── */
.btn-secondary {
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    padding: 8px 18px;
    border-radius: var(--radius-pill);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: background .18s, border-color .18s, box-shadow .18s;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.btn-secondary:hover { background: var(--color-hover); border-color: var(--color-border-strong); text-decoration: none; }
.btn-secondary:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }

.btn-outline {
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    padding: 6px 14px;
    border-radius: var(--radius-pill);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background .18s, border-color .18s, color .18s;
}
.btn-outline:hover, .btn-outline.active {
    background: var(--primary-tint-weak);
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.btn-outline:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }

.btn-sm { padding: 5px 14px; font-size: 0.8125rem; }

.btn-link {
    background: none;
    border: none;
    padding: 0;
    color: var(--color-primary);
    font-size: 0.8125rem;
    cursor: pointer;
    text-decoration: underline;
}
.btn-link:hover { color: var(--color-primary-dark); }

.btn-icon-xs {
    background: none;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    width: 22px;
    height: 22px;
    padding: 0;
    font-size: 0.75rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    transition: background .12s;
}
.btn-icon-xs:hover:not(:disabled) { background: var(--color-bg); color: var(--color-text); }
.btn-icon-xs:disabled { opacity: .35; cursor: default; }

/* ── Patient Form ──────────────────────────────────────── */
.patient-form-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 28px;
    max-width: 1100px;
}

.patient-form-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    margin-bottom: 20px;
}

.field-label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--color-text);
    margin-bottom: 4px;
    display: block;
}

.field-input {
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.875rem;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
    background: var(--color-surface);
    color: var(--color-text);
    width: 100%;
    font-family: inherit;
}
.field-input:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--focus-ring);
}
.field-input[disabled] { background: var(--color-bg); opacity: .6; cursor: not-allowed; }
textarea.field-input { resize: vertical; min-height: 80px; }
select.field-input { appearance: auto; cursor: pointer; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 16px 28px;
    margin-bottom: 24px;
}

@media (max-width: 600px) {
    .form-grid { grid-template-columns: 1fr; }
    .form-grid > * { grid-column: 1 / -1 !important; }
}

/* The grid's row-gap already spaces rows; .field's own margin double-counted it. */
.form-grid > .field { margin-bottom: 0; }

.field-w-full    { grid-column: span 12; }
.field-w-half    { grid-column: span 6; }
.field-w-third   { grid-column: span 4; }
.field-w-quarter { grid-column: span 3; }
/* Checkbox/yes-no fields are narrow: four to a row rather than two half-empty ones. */
.field-w-check   { grid-column: span 3; }
@media (max-width: 1100px) {
    .field-w-check { grid-column: span 4; }
}
/* kept for any legacy usage */
.field-full { grid-column: span 12; }

/* A checkbox row is a single line, so it aligns to the height of a text input beside it. */
.field.field-check { justify-content: center; min-height: 34px; }
.field.field-check .toggle-label { color: var(--color-text); white-space: normal; }

.form-actions {
    display: flex;
    gap: 12px;
    padding-top: 4px;
}

/* ── Field Config Panel ────────────────────────────────── */
.field-config-panel {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 20px;
}

.field-config-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    font-size: 0.875rem;
}

.field-config-list { display: flex; flex-direction: column; gap: 6px; }

.field-config-item {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 8px 12px;
    font-size: 0.8125rem;
}

.field-config-reorder { display: flex; gap: 3px; }

.field-config-name {
    flex: 1;
    font-weight: 500;
    color: var(--color-text);
}

.toggle-label {
    display: flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* ── Admin Pages ───────────────────────────────────────── */

/* Toolbar */
.admin-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
}

/* Card */
.admin-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 22px 26px;
    box-shadow: var(--shadow-sm);
}

.admin-card-title {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--color-text);
    margin-bottom: 16px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--color-border);
}

/* Table */
.admin-table-wrap {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.admin-table thead th {
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    font-weight: 600;
    font-size: 0.8125rem;
    padding: 11px 16px;
    text-align: start;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.admin-table tbody td {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    vertical-align: middle;
}

.admin-table tbody tr:last-child td { border-bottom: none; }
.admin-table tbody tr:hover td { background: var(--primary-tint-weak); }
.admin-table tbody tr.row-expanded td { background: var(--primary-tint-weak); }
.admin-table tbody tr.row-selected td { background: var(--primary-tint); }

/* Detail panel (expanded row) */
.detail-row > td { padding: 0 !important; }

.detail-panel {
    background: var(--color-bg);
    border-top: 2px solid var(--color-primary);
    padding: 20px 24px;
}

.detail-panel-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-primary);
    margin-bottom: 14px;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* User cell */
.user-cell {
    display: flex;
    align-items: center;
    gap: 10px;
}

.user-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--color-primary);
    color: #fff;
    font-size: 0.8125rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    letter-spacing: .02em;
}

.user-info {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.user-name {
    font-weight: 500;
    color: var(--color-text);
}

.user-email {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Badges */
.badge {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    white-space: nowrap;
}

.badge-active   { background: var(--success-bg); color: var(--success-fg); }
.badge-inactive { background: var(--danger-bg); color: var(--danger-fg); }
.badge-role     { background: var(--primary-tint); color: var(--color-primary-dark); margin-right: 4px; }
.badge-system   { background: var(--info-bg); color: var(--info-fg); }
.badge-org-name { font-size: 0.75rem; color: var(--color-text-muted); }
/* Pinned to the far side of its toolbar via auto-margin rather than a container-level
   justify-content, so the layout doesn't jump when the badge is absent (a brand-new
   patient has no MRN yet — it's assigned by the server on first save). */
.badge-mrn {
    margin-inline-end: auto;
    background: var(--warn-bg);
    color: var(--warn-fg);
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: .02em;
    padding: 4px 12px;
}

/* Row actions */
.row-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

.action-btn {
    background: none;
    border: none;
    padding: 3px 2px;
    font-size: 0.8125rem;
    color: var(--color-primary);
    cursor: pointer;
    transition: color .12s;
}

.action-btn:hover { color: var(--color-primary-dark); text-decoration: underline; }
.action-btn.active { font-weight: 600; color: var(--color-primary-dark); }
.action-btn.danger, .action-btn-danger { color: var(--danger); }
.action-btn.danger:hover, .action-btn-danger:hover { color: var(--danger-fg); }

.action-sep { color: var(--color-border); font-size: 0.75rem; user-select: none; }

.col-actions { width: 130px; white-space: nowrap; }
.col-select { width: 34px; text-align: center; }

/* ── Confirm dialog ────────────────────────────────────── */
.modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.35); z-index: 50; }
.modal-dialog {
    position: fixed;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    z-index: 51;
    width: min(440px, 92vw);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 1.25rem 1.4rem 1.1rem;
}
.modal-title { margin: 0 0 0.6rem; font-size: 1.05rem; font-weight: 600; }
.modal-text  { margin: 0 0 0.7rem; font-size: 0.875rem; line-height: 1.45; }
.modal-note  { margin: 0.7rem 0 0; font-size: 0.8rem; color: var(--color-text-muted); }
.modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1.1rem; }

.delete-impact {
    margin: 0;
    padding: 0.6rem 0.9rem;
    list-style: none;
    background: var(--danger-bg);
    border: 1px solid var(--danger-border);
    border-radius: var(--radius);
    color: var(--danger-fg);
    font-size: 0.85rem;
}
.delete-impact li { padding: 1px 0; }

.alert-error {
    background: var(--danger-bg);
    border: 1px solid var(--danger-border);
    color: var(--danger-fg);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.875rem;
}

.alert-success {
    background: var(--success-bg);
    border: 1px solid var(--success-border);
    color: var(--success-fg);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.875rem;
}

/* "Heads up" rather than "you broke something" — e.g. editing a template that live automated
   sends draw from. Amber like every other --warn token in the app. */
.alert-warn {
    background: var(--warn-bg);
    border: 1px solid var(--warn-border);
    color: var(--warn-fg);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.875rem;
}

.tools-section { display: flex; flex-direction: column; gap: 16px; max-width: 640px; }

.tool-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

.tool-card-body { padding: 20px 24px; }

.tool-card-body h3 { margin: 0 0 6px; font-size: 1rem; font-weight: 600; }

.tool-card-body p { margin: 0 0 14px; }

/* Confirm inline */
.confirm-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--warn-bg);
    border: 1px solid var(--warn-border);
    border-radius: var(--radius-pill);
    padding: 4px 12px;
    font-size: 0.8125rem;
}

.confirm-inline span { color: var(--warn-fg); }

/* Danger button */
.btn-danger {
    background: var(--danger);
    color: #fff;
    border: none;
    padding: 8px 16px;
    border-radius: var(--radius-pill);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .18s, box-shadow .18s;
}

.btn-danger:hover { background: var(--danger-fg); box-shadow: var(--shadow); }
.btn-danger.btn-sm { padding: 5px 12px; font-size: 0.8rem; }

/* Toggle switch inline */
.toggle-switch {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 0.875rem;
    color: var(--color-text);
    padding-top: 8px;
}

.toggle-switch input { accent-color: var(--color-primary); width: 16px; height: 16px; cursor: pointer; }

/* Loading / empty */
.admin-loading {
    padding: 48px;
    text-align: center;
    color: var(--color-text-muted);
    font-size: 0.875rem;
}

.admin-empty {
    padding: 64px 24px;
    text-align: center;
    color: var(--color-text-muted);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.admin-empty svg {
    width: 56px;
    height: 56px;
    padding: 13px;
    color: var(--color-primary);
    background: var(--accent-bg);
    border-radius: 50%;
    margin-bottom: 12px;
    display: block;
    margin-inline: auto;
}

.admin-empty p { font-size: 0.875rem; }

/* Toast */
.toast {
    position: fixed;
    bottom: 20px;
    right: 20px;
    background: var(--color-text);
    color: var(--color-bg);
    padding: 11px 20px;
    border-radius: var(--radius-lg);
    font-size: 0.875rem;
    font-weight: 500;
    box-shadow: var(--shadow-lg);
    z-index: 1000;
}

.toast.toast-error { background: var(--danger); }

/* Pagination */
.admin-pagination {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 14px;
}

/* Fallback data-table (used by orgs/groups pages) */
.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
    background: var(--color-surface);
}

.data-table thead th {
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    font-weight: 600;
    font-size: 0.8125rem;
    padding: 11px 14px;
    text-align: start;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.data-table tbody td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--color-border);
    vertical-align: middle;
}

.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td { background: var(--primary-tint-weak); }

/* Wide tables (the configurable visits grid) scroll inside their card rather than
   pushing the page sideways. */
.table-scroll { overflow-x: auto; }
.row-clickable { cursor: pointer; }
/* Free-text clinical columns get room but stay one line — the full value is in the tooltip. */
.data-table th.col-wide { min-width: 12rem; }
.data-table td.cell-clip { max-width: 20rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.table-wrap {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    margin-bottom: 16px;
}

/* Inline form (orgs/groups pages) */
.inline-form {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 8px;
    padding: 10px 12px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.inline-form select,
.inline-form input {
    padding: 5px 9px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.8125rem;
    background: var(--color-surface);
    color: var(--color-text);
    outline: none;
    transition: border-color .15s;
}

.inline-form select:focus,
.inline-form input:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px var(--focus-ring);
}

.toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
}

.share-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.share-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 6px 10px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.85rem;
}
.share-row > span:first-child { font-weight: 600; min-width: 0; }
.share-row .btn-link { margin-inline-start: auto; }

.sub-form {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin: 6px 0;
}

.claims-panel {
    background: var(--color-bg);
    border-top: 1px solid var(--color-border);
    padding: 12px 16px;
}

.tab-btn {
    background: none;
    border: none;
    padding: 6px 14px;
    font-size: 0.875rem;
    color: var(--color-text-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    margin-right: 4px;
    transition: color .15s, border-color .15s, background .15s;
}

.tab-btn:hover { color: var(--color-text); background: var(--primary-tint-weak); }
.tab-btn.tab-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
    font-weight: 500;
}

.claim-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--primary-tint);
    color: var(--color-primary-dark);
    border-radius: var(--radius-pill);
    padding: 2px 10px;
    font-size: 0.775rem;
    font-weight: 500;
    margin: 2px;
}

.claim-chip button {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--color-primary-dark);
    font-size: 0.75rem;
    padding: 0 2px;
    line-height: 1;
    opacity: .7;
}

.claim-chip button:hover { opacity: 1; }

.loading-spinner {
    padding: 32px;
    text-align: center;
    color: var(--color-text-muted);
    font-size: 0.875rem;
}

/* ── Filter select (admin toolbars) ──────────────────── */
.filter-select {
    height: 34px;
    padding: 0 28px 0 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 0.8125rem;
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 20 20' fill='%23999'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.17l3.71-3.94a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    max-width: 200px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-select:focus {
    outline: none;
    border-color: var(--color-primary);
}

/* ── Checkbox column ──────────────────────────────────── */
.col-check {
    width: 36px;
    padding-left: 12px !important;
    padding-right: 4px !important;
}

.col-check input[type="checkbox"] {
    accent-color: var(--color-primary);
    width: 15px;
    height: 15px;
    cursor: pointer;
    vertical-align: middle;
}

/* ── Bulk action bar ──────────────────────────────────── */
.bulk-action-bar {
    position: sticky;
    bottom: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 18px;
    background: var(--color-surface);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    margin-top: 12px;
    font-size: 0.875rem;
}

.bulk-action-bar .bulk-count {
    font-weight: 600;
    color: var(--color-primary-dark);
    white-space: nowrap;
}

.bulk-action-bar .bulk-divider {
    width: 1px;
    height: 22px;
    background: var(--color-border);
    flex-shrink: 0;
}

.bulk-action-bar label {
    font-size: 0.8125rem;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.bulk-action-bar .filter-select {
    max-width: 180px;
}

/* ── Patient count badge (Users page) ─────────────────── */
.patient-count-badge {
    display: inline-block;
    min-width: 28px;
    text-align: center;
    background: var(--primary-tint);
    color: var(--color-primary-dark);
    border-radius: var(--radius-pill);
    padding: 2px 8px;
    font-size: 0.8125rem;
    font-weight: 600;
}

/* Patient avatar variant (muted teal) */
.user-avatar.patient-avatar {
    background: #5ba6a9;
}

/* Access table nested inside detail panel */
.access-table {
    background: var(--color-surface);
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--color-border);
}

.access-table thead th {
    background: var(--accent-bg);
    font-size: 0.7rem;
}

.access-table tbody td {
    padding: 9px 12px;
    font-size: 0.8125rem;
}

/* ─── Clinical (visits, sections, charge lines) ─────────────────────────── */
.section-group { margin-bottom: 1rem; }
.section-group-title {
    font-size: 0.78rem; font-weight: 600; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--color-text-muted); margin: 0.75rem 0 0.5rem;
    border-bottom: 1px solid var(--color-border-2); padding-bottom: 0.25rem;
}
/* Yes / No / Not asked — a segmented control built on real radios so keyboard and
   screen-reader behaviour comes for free. Unanswered is visually distinct from "No". */
.yesno-group {
    display: flex; align-items: center; gap: 0.3rem;
    border: 1px solid var(--color-border); border-radius: var(--radius-pill);
    padding: 2px; width: fit-content; background: var(--color-surface);
}
.yesno-group.unanswered { border-style: dashed; border-color: var(--warn-border); }
.yesno-option {
    display: flex; align-items: center; gap: 4px; cursor: pointer;
    padding: 2px 10px; border-radius: var(--radius-pill); font-size: 0.8125rem;
    color: var(--color-text-muted); transition: background .15s, color .15s;
}
.yesno-option:hover { background: var(--color-hover); }
.yesno-option input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.yesno-option.selected { font-weight: 600; }
.yesno-option.selected.yes { background: var(--danger-bg); color: var(--danger-fg); }
.yesno-option.selected.no  { background: var(--success-bg); color: var(--success-fg); }
.yesno-option:focus-within { box-shadow: 0 0 0 3px var(--focus-ring); }
.yesno-hint { font-size: 0.72rem; color: var(--warn-fg); padding-right: 0.4rem; }
.yesno-clear { font-size: 0.72rem; padding-right: 0.4rem; }

.field-readonly {
    padding: 0.45rem 0.6rem; background: var(--color-surface-alt); border: 1px solid var(--color-border-2);
    border-radius: 6px; min-height: 2.1rem; white-space: pre-wrap; font-size: 0.9rem;
}
.panel-header-row {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 0.75rem; gap: 0.5rem;
}
.patient-alert-badge {
    display: inline-flex; align-items: center; justify-content: center;
    width: 17px; height: 17px; border-radius: 50%; font-size: 0.7rem; font-weight: 700;
    margin-inline-end: 5px; cursor: help; vertical-align: -2px;
}
.patient-alert-badge.has-alert  { background: var(--danger-bg); color: var(--danger-fg); border: 1px solid var(--danger-border); }
.patient-alert-badge.unanswered { background: var(--warn-bg);   color: var(--warn-fg);   border: 1px dashed var(--warn-border); }

/* Clinical alerts for the visit — deliberately loud, and above the fold. */
/* Who this is, kept on screen for the whole visit. Scrolling into the fourth section and no
   longer being able to see whose chart you are in is how notes end up on the wrong patient. */
.visit-header-sticky {
    position: sticky;
    top: var(--topbar-height);            /* clears the topbar, which is sticky at 0 */
    z-index: 9;                           /* under the topbar (10) and the nav panel (30) */
    background: var(--color-bg);
    padding-block: 0.5rem;
    margin-block-start: -0.5rem;
    border-bottom: 1px solid var(--color-border);
}
/* .content carries overflow-y:auto, which makes it a scroll container — and since .app-layout is
   min-height (not height) it grows with its content and never actually scrolls, so the document
   scrolls instead. A sticky child sticks to its nearest scroll container, so the header was
   pinned to something that never moves and scrolled away regardless. Opting this one page out
   hands it back to the document. Scoped with :has() rather than dropping the overflow globally,
   the same way .content-body:has(.visit-nav) already reserves the navigator's column.

   Only above the width where the header is actually sticky. Setting one axis to visible forces
   the other to compute visible too, so below 700px — where the header is static anyway — this
   would buy nothing and cost .content its horizontal containment, pushing the visit's wide form
   rows out into a page-wide sideways scroll. */
@media (min-width: 701px) {
    .content:has(.visit-header-sticky) { overflow-y: visible; }
}
/* The mark beside the name: for when the strip below has been scanned past. */
.visit-header-warnicon {
    font-size: 0.85em; color: var(--warn-fg); margin-inline-start: 0.4rem;
    vertical-align: middle; cursor: default;
}
/* Answered allergies and flags, directly under the date of birth. Reference material rather than
   a warning to be dismissed — hence yellow but flat, with no border demanding a decision. */
.visit-header-alerts {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem;
    margin-block: 0.15rem; color: var(--warn-fg); font-size: 0.85rem;
}
.visit-header-alert {
    background: var(--warn-bg); border-radius: var(--radius-pill);
    padding: 1px 9px; font-weight: 600;
    max-width: 22rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Answered on this visit, so the chip opens the field it came from. */
.visit-header-alert-link {
    border: none; font: inherit; font-weight: 600; color: inherit; cursor: pointer;
    text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px;
}
.visit-header-alert-link:hover { background: var(--warn-border); }
/* On a phone the header must not eat the screen — the name and the alerts are what matter. */
@media (max-width: 700px) {
    .visit-header-sticky { position: static; }
    .visit-header-alert { max-width: 100%; }
}

/* A reminder, not an emergency. These flags are worth seeing before a visit is signed off, but
   they're read on every single visit that has them — and red-on-red at the top of the page, every
   time, is the alarm nobody hears any more. Softened to the warning palette: still the first thing
   noticed, no longer something that looks like it went wrong. */
.visit-alerts {
    display: flex; align-items: flex-start; gap: 0.55rem; margin-bottom: 0.9rem;
    padding: 0.5rem 0.75rem; border-radius: var(--radius);
    background: var(--warn-bg); border: 1px solid var(--warn-border); color: var(--warn-fg);
    font-size: 0.875rem;
}
.visit-alerts-icon { font-size: 0.95rem; line-height: 1.3; flex-shrink: 0; opacity: 0.85; }
.visit-alerts-body { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; min-width: 0; }
.visit-alert-chip {
    background: var(--color-surface); border: 1px solid var(--warn-border);
    border-radius: var(--radius-pill); padding: 1px 9px; font-size: 0.8rem; font-weight: 600;
}


/* Section chips: adding and removing live in one control, one click each. */
.section-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-bottom: 0.9rem; }
.section-chips-label { font-size: 0.78rem; font-weight: 600; color: var(--color-text-muted); margin-right: 0.2rem; }
.section-chip {
    display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer;
    border: 1px dashed var(--color-border-strong); background: var(--color-surface);
    color: var(--color-text-muted); border-radius: var(--radius-pill);
    padding: 4px 12px; font-size: 0.8125rem; font-weight: 500;
    transition: background .15s, color .15s, border-color .15s;
}
.section-chip:hover:not(:disabled) { border-color: var(--color-primary); color: var(--color-primary); }
.section-chip:disabled { opacity: .5; cursor: default; }
.section-chip.active {
    border-style: solid; border-color: transparent;
    background: var(--primary-tint-strong); color: var(--color-primary-dark);
}
.section-chip-mark { font-size: 0.7rem; opacity: .7; }

/* The overflow drawer for other professions' templates — reachable, not in the way. */
.section-chip-more { border-style: solid; font-weight: 600; }
.section-more-panel {
    margin: -0.4rem 0 0.9rem;
    padding: 0.6rem 0.7rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}
.section-more-panel .field-input { max-width: 18rem; margin-bottom: 0.5rem; }
.section-more-list { display: flex; flex-wrap: wrap; gap: 0.4rem; }

/* Collapsible section card — the whole title row is the toggle. */
.section-toggle {
    display: flex; align-items: center; gap: 0.45rem; flex: 1; min-width: 0;
    background: none; border: none; padding: 0; cursor: pointer; color: var(--color-text);
    font: inherit; text-align: start;
}
.section-caret { font-size: 0.7rem; color: var(--color-text-muted); width: 0.8rem; flex-shrink: 0; }
.section-filled { font-size: 0.75rem; }
.section-dirty { color: var(--warn-fg); font-size: 0.7rem; }

.charge-total { font-weight: 600; color: var(--color-primary); }
.add-line-form { margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px dashed var(--color-border-2); }
/* Wraps: the admin migration card puts nine buttons in this row, and the card clips. */
.visit-status-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.admin-card { background: var(--color-surface); border: 1px solid var(--color-border-2); border-radius: var(--radius-lg); padding: 1.35rem 1.5rem; margin-bottom: 1rem; box-shadow: var(--shadow-sm); }

/* ─── Patient hub + timeline ────────────────────────────────────────────── */
.patient-hub-grid { display: grid; grid-template-columns: 280px 1fr; gap: 1rem; align-items: start; }
@media (max-width: 900px) { .patient-hub-grid { grid-template-columns: 1fr; } }
.summary-list { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 0.9rem; font-size: 0.88rem; }
.summary-list dt { color: var(--color-text-muted); }
.summary-list dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.hub-tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--color-border-2); margin-bottom: 1rem; }
.hub-tab {
    background: none; border: none; padding: 0.5rem 0.9rem; cursor: pointer;
    font-size: 0.9rem; color: var(--color-text-muted); border-bottom: 2px solid transparent;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0; transition: background .15s, color .15s;
}
.hub-tab:hover { background: var(--primary-tint-weak); color: var(--color-text); }
.hub-tab.active { color: var(--color-primary); border-bottom-color: var(--color-primary); font-weight: 600; }
.timeline { display: flex; flex-direction: column; gap: 0.6rem; }
.timeline-entry {
    display: flex; gap: 0.9rem; padding: 0.85rem 1rem; background: var(--color-surface);
    border: 1px solid var(--color-border-2); border-radius: var(--radius-lg); cursor: pointer;
    transition: border-color .18s, box-shadow .18s, transform .18s;
}
.timeline-entry:hover { border-color: var(--color-primary); box-shadow: var(--shadow); transform: translateY(-1px); }
.timeline-date { display: flex; flex-direction: column; align-items: center; min-width: 3.4rem; }
.timeline-day { font-size: 1.3rem; font-weight: 700; color: var(--color-primary); line-height: 1.1; }
.timeline-month { font-size: 0.7rem; color: var(--color-text-muted); text-transform: uppercase; }
.timeline-body { flex: 1; min-width: 0; }
.timeline-title-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.15rem; }
.timeline-meta { font-size: 0.78rem; color: var(--color-text-faint); margin-top: 0.15rem; }
.timeline-field-label { font-weight: 700; }

/* ─── Calendar (TimeGrid) ───────────────────────────────────────────────── */
.timegrid-wrap { overflow-x: auto; background: var(--color-surface); border: 1px solid var(--color-border-2); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
/* Columns and row height are set inline by TimeGrid (day view = 1 column, 30-min rows). */
.timegrid { display: grid; min-width: 860px; --slot-h: 3rem; }
.timegrid.timegrid-single { min-width: 0; }
.timegrid-gutter { padding-top: 2rem; }
.timegrid-hour-label { height: var(--slot-h); font-size: 0.68rem; color: var(--color-text-faint); text-align: right; padding-right: 0.4rem; transform: translateY(-0.5em); }
.timegrid-day { border-left: 1px solid var(--color-hover); }
.timegrid-day.today .timegrid-day-header { color: var(--color-primary); font-weight: 700; }
.timegrid-day-header { height: 2rem; display: flex; align-items: center; justify-content: center; font-size: 0.8rem; color: var(--color-text-muted); border-bottom: 1px solid var(--color-border-2); position: sticky; top: 0; background: var(--color-surface); }
.timegrid-day-body { position: relative; }
.timegrid-slot { height: var(--slot-h); border-bottom: 1px solid var(--color-hover); cursor: pointer; transition: background .12s; }
.timegrid-slot.half { border-bottom-style: dashed; }
.timegrid-slot:hover { background: var(--primary-tint-weak); }
.timegrid-event {
    position: absolute; left: 2px; right: 2px; background: var(--accent-bg); border-left: 3px solid var(--color-primary);
    border-radius: 4px; padding: 2px 5px; font-size: 0.72rem; overflow: hidden; cursor: pointer;
    display: flex; flex-direction: column; min-height: 1.1rem; line-height: 1.25;
}
.timegrid-event:hover { filter: brightness(1.04); box-shadow: var(--shadow-sm); }
.timegrid-event-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
.timegrid-event-time { font-weight: 600; color: var(--color-primary-dark); flex-shrink: 0; }
/* min-width:0 so the name ellipsises inside the chip instead of the chip clipping it
   mid-glyph — a 15-minute appointment in a narrow column has very little room. */
.timegrid-event-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* A one-line chip puts the name next to the time instead of stacking it out of sight. */
.timegrid-event.chip-compact { padding: 1px 4px; container-type: inline-size; }
.timegrid-event.chip-compact .timegrid-event-row { flex: 1; min-width: 0; gap: 3px; }
.timegrid-event.chip-compact .timegrid-event-title { font-weight: 500; }
/* In a narrow column the time plus the department dot alone exceed the chip, and the chip
   clips rather than ellipsising. Below that width the time wins: the department is still in
   the tooltip, and the appointment stays readable instead of being sheared off. */
@container (max-width: 58px) {
    .timegrid-event.chip-compact .dept-dot { display: none; }
}
/* Status colour-coding, shared by the week/day chips, the month chips and the legend.
   Each status gets its own fill AND its own left bar, so they stay distinguishable in dark
   mode and for the red/green colour-blind (fill lightness differs, not just hue). */
/* Selectors are paired with the element class so they beat `.month-event`'s own background
   regardless of where they sit in the file. */
.timegrid-event.status-booked,    .month-event.status-booked,    .legend-swatch.status-booked
    { background: var(--info-bg);    border-left-color: var(--info-fg); }
.timegrid-event.status-confirmed, .month-event.status-confirmed, .legend-swatch.status-confirmed
    { background: var(--success-bg); border-left-color: var(--success); }
.timegrid-event.status-arrived,   .month-event.status-arrived,   .legend-swatch.status-arrived
    { background: var(--warn-bg);    border-left-color: var(--warn-fg); }
.timegrid-event.status-completed, .month-event.status-completed, .legend-swatch.status-completed
    { background: var(--color-surface-alt); border-left-color: var(--color-border-strong); }
.timegrid-event.status-completed, .month-event.status-completed { opacity: .75; }
.timegrid-event.status-noshow,    .month-event.status-noshow,    .legend-swatch.status-noshow
    { background: var(--danger-bg);  border-left-color: var(--danger); }

/* Ring the chip a search result linked to. */
.timegrid-event-linked {
    outline: 3px solid var(--color-primary); outline-offset: 1px;
    animation: linked-pulse 1.3s ease-in-out 2;
}
@keyframes linked-pulse { 50% { outline-color: transparent; } }

.calendar-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin-bottom: 0.7rem; }
.legend-item { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.72rem; color: var(--color-text-muted); }
.legend-swatch {
    width: 14px; height: 11px; border-radius: 3px; display: inline-block;
    border-left: 3px solid var(--color-primary); background: var(--accent-bg);
}
.legend-sep { width: 1px; height: 0.9rem; background: var(--color-border); }

/* ─── Side panel ────────────────────────────────────────────────────────── */
.side-panel-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.25); z-index: 40; }
.side-panel {
    position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 92vw); background: var(--color-surface);
    z-index: 41; padding: 1.4rem; overflow-y: auto; box-shadow: var(--shadow-lg);
    border-start-start-radius: var(--radius-lg); border-end-start-radius: var(--radius-lg);
}
.status-button-row { display: flex; gap: 0.3rem; flex-wrap: wrap; margin-bottom: 0.9rem; }

/* VisitPage section card → the template editor, where per-field carry-forward is decided. */
.section-carry-link { font-size: 0.78rem; white-space: nowrap; margin-inline-start: 0.6rem; text-decoration: none; }

/* ─── Past-visits drawer (VisitPage → PastVisitsPanel) ─────────────────── */
/* Wider than the default drawer: it shows whole visits, label + value + "now" side by side. */
.past-visits-panel { width: min(560px, 94vw); }
.past-visits-toolbar { display: flex; gap: 0.5rem; align-items: center; margin: 0.8rem 0 0.9rem; }
.past-visits-toolbar .field-input { flex: 1; }
.past-visit-entry { cursor: default; }
.past-visit-entry:hover { transform: none; box-shadow: none; border-color: var(--color-border); }
.past-visit-fields { display: flex; flex-direction: column; gap: 0.2rem; margin-top: 0.4rem; }
.past-visit-field {
    display: grid; grid-template-columns: minmax(7rem, 38%) 1fr; gap: 0.2rem 0.6rem; align-items: baseline;
    padding: 0.2rem 0.4rem; border-radius: var(--radius-sm); font-size: 0.82rem;
    border-inline-start: 3px solid transparent;
}
.past-visit-label { color: var(--color-text-muted); }
.past-visit-value { color: var(--color-text); white-space: pre-wrap; word-break: break-word; }
/* The three verdicts: identical stays quiet, missing-here is a hint, changed is the point. */
.past-visit-field.same { opacity: 0.7; }
.past-visit-field.absent { border-inline-start-color: var(--color-border-2); }
.past-visit-field.changed { border-inline-start-color: var(--color-primary); background: var(--primary-tint-weak); }
.past-visit-now {
    grid-column: 2; font-size: 0.75rem; color: var(--color-primary-dark); white-space: pre-wrap; word-break: break-word;
}
.timegrid-event-dept { display: block; font-size: 0.62rem; opacity: 0.75; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The appointment's own text under the patient's name; the chip clips it when space runs out. */
.timegrid-event-text { display: block; font-size: 0.66rem; opacity: 0.85; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.month-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.month-day {
    min-height: 96px; border: 1px solid var(--color-border); border-radius: var(--radius);
    background: var(--color-surface); padding: 4px 6px; cursor: pointer; overflow: hidden;
    transition: border-color .15s, box-shadow .15s;
}
.month-day:hover { border-color: var(--color-primary); box-shadow: var(--shadow-sm); }
.month-day.other-month { opacity: 0.45; }
.month-day.today { border-color: var(--color-primary); border-width: 2px; }
.month-day-num { font-size: 0.75rem; font-weight: 600; color: var(--color-text-muted); }
.month-event {
    font-size: 0.68rem; border-left: 3px solid var(--color-primary); border-radius: 3px;
    padding: 1px 4px; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    background: var(--accent-bg);
}
.month-more { font-size: 0.65rem; color: var(--color-text-muted); margin-top: 2px; }
.dept-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 4px; flex-shrink: 0; }

/* Agenda (list) view — everything on one line per appointment, nothing clipped. */
.agenda-list { display: flex; flex-direction: column; gap: 1.1rem; }
.agenda-day-header {
    display: flex; align-items: baseline; gap: .5rem; font-size: .8rem; font-weight: 600;
    padding: .3rem 0 .4rem; border-bottom: 1px solid var(--color-border); margin-bottom: .2rem;
}
.agenda-day-header.today { color: var(--color-primary); }
.agenda-day-count { font-size: .72rem; font-weight: 500; color: var(--color-text-muted); }
.agenda-row {
    display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) auto; gap: .75rem; align-items: center;
    padding: .5rem .7rem; border-bottom: 1px solid var(--color-hover); cursor: pointer;
    border-left: 3px solid transparent; border-radius: var(--radius-sm); transition: background .12s;
}
.agenda-row:hover { background: var(--primary-tint-weak); }
.agenda-row.status-completed { opacity: .6; }
.agenda-row.status-noshow { border-left-color: var(--danger); }
.agenda-row.status-arrived { border-left-color: var(--warn-fg); }
.agenda-row.status-confirmed { border-left-color: var(--success); }
.agenda-time { font-size: .8rem; font-weight: 600; color: var(--color-primary-dark); font-variant-numeric: tabular-nums; }
.agenda-who { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.agenda-name { font-size: .875rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agenda-meta { font-size: .75rem; color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agenda-empty { padding: 1.5rem; text-align: center; color: var(--color-text-muted); font-size: .875rem; }
@media (max-width: 700px) {
    .agenda-row { grid-template-columns: 5.5rem minmax(0, 1fr); row-gap: .2rem; }
    .agenda-row > .badge { grid-column: 2; justify-self: start; }
}

/* ─── Dashboard ─────────────────────────────────────────────────────────── */
/* minmax(300px, 1fr) can exceed the container when a child has wider min-content (long
   currency labels in the report KPIs), which pushed the whole grid past its parent.
   min(300px, 100%) lets a single column shrink instead of overflowing. */
.dashboard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 1rem; align-items: start; min-width: 0; }
.dashboard-grid > * { min-width: 0; }
.dash-list { display: flex; flex-direction: column; gap: 0.4rem; }
/* flex-wrap so a narrow dashboard card wraps the status dropdown to its own line rather than
   crushing the title — with min-width:0 and a fixed-width badge (Overdue/Waiting) + select both
   competing for the same row, the title used to shrink to a couple of characters before an
   ellipsis, on any card holding several badged appointments. */
.dash-list-item { display: flex; align-items: center; gap: 0.6rem; padding: 0.35rem 0; border-bottom: 1px solid var(--color-hover); flex-wrap: wrap; }
.dash-time { font-weight: 600; color: var(--color-primary); min-width: 3rem; font-size: 0.85rem; }
.dash-title { flex: 1 1 8rem; min-width: 8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Three currency figures at 1.8rem overflow a two-column report card, and the card clips.
   Wrap, and scale the figure to the space the row actually has. */
.dash-stats { display: flex; flex-wrap: wrap; gap: 0.85rem 1.5rem; container-type: inline-size; }
.dash-stat { display: flex; flex-direction: column; min-width: 0; flex: 1 1 7.5rem; }
.dash-stat-value {
    font-size: clamp(1.05rem, 6cqi, 1.8rem); font-weight: 700; color: var(--color-primary);
    font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.dash-stat-label { font-size: 0.78rem; color: var(--color-text-muted); }
.badge-low { background: var(--danger-bg); color: var(--danger-fg); }
.dash-status-select {
    font-size: 0.72rem; font-weight: 600; border: 1px solid var(--color-border-2); border-radius: 999px;
    padding: 0.15rem 0.5rem; background: var(--color-surface-alt); cursor: pointer;
}
.dash-status-select.badge-active { background: var(--success-bg); color: var(--success-fg); }
.dash-status-select.badge-inactive { background: var(--danger-bg); color: var(--danger-fg); }

/* ─── Global search dropdown ────────────────────────────────────────────── */
.search-group-title {
    font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--color-text-faint); padding: 0.5rem 0.8rem 0.2rem;
}
.search-result { display: flex; flex-direction: column; gap: 1px; }
.search-result.highlighted { background: var(--accent-bg); }
.search-result-main { font-weight: 500; }
.search-result-sub { font-size: 0.75rem; color: var(--color-text-muted); }

/* ─── Attachments ───────────────────────────────────────────────────────── */
/* Our own file picker: the native control's text is browser-language and untranslatable. */
.file-picker { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.file-input-hidden { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.file-picker-status { font-size: 0.8rem; }

.attachment-upload-row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; flex-wrap: wrap; }
.attachment-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0.9rem; }
.attachment-card {
    border: 1px solid var(--color-border-2); border-radius: var(--radius-lg); overflow: hidden;
    background: var(--color-surface); display: flex; flex-direction: column;
    transition: border-color .18s, box-shadow .18s, transform .18s;
}
.attachment-card:hover { border-color: var(--color-primary); box-shadow: var(--shadow); transform: translateY(-1px); }
.attachment-preview { height: 120px; background: var(--color-surface-alt); display: flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden; }
.attachment-preview img { width: 100%; height: 100%; object-fit: cover; }
.attachment-file-icon { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; color: var(--color-text-faint); font-size: 0.7rem; font-weight: 700; }
.attachment-meta { padding: 0.45rem 0.6rem 0.15rem; display: flex; flex-direction: column; min-width: 0; }
.attachment-name { font-size: 0.82rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attachment-sub { font-size: 0.72rem; color: var(--color-text-faint); }
/* Wraps rather than overflowing: the card clips its content, so an unwrapped row silently
   cut off the last action ("Delete") in narrow columns. */
.attachment-actions {
    display: flex; flex-wrap: wrap; gap: 0.35rem 0.6rem; padding: 0.25rem 0.6rem 0.5rem;
    align-items: center; min-width: 0;
}
.attachment-actions > * { flex: 0 0 auto; }
.btn-danger-link { color: var(--danger); }
.lightbox-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.75); z-index: 60; display: flex; align-items: center; justify-content: center; cursor: zoom-out; }

/* ─── Image viewer / before-after ────────────────────────────────────────── */
/* Each pane's viewport is a fixed box that clips its image, so zooming one pane can never
   resize the pane next to it — that reflow was what made zooming look like it hit both. */
.viewer {
    display: flex; flex-direction: column; gap: 0.5rem; cursor: default;
    background: var(--color-surface); border-radius: var(--radius-lg); padding: 0.85rem;
    max-width: 96vw; max-height: 94vh; box-shadow: var(--shadow-lg);
}
.viewer-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; }
.viewer-hint { margin-left: auto; font-size: 0.72rem; color: var(--color-text-faint); }
.viewer-panes { display: flex; gap: 0.75rem; min-height: 0; }
.viewer-pane { margin: 0; display: flex; flex-direction: column; min-width: 0; flex: 1; }
.viewer-pane-label {
    font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
    color: var(--color-text-muted); padding-bottom: 0.25rem;
}
.viewer-viewport {
    position: relative; overflow: hidden; touch-action: none; background: var(--color-surface-alt);
    border: 1px solid var(--color-border); border-radius: var(--radius);
    width: 100%; height: 72vh; display: flex; align-items: center; justify-content: center;
}
.viewer-panes-2 .viewer-viewport { height: 66vh; }
.viewer-rotor { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; transition: transform .18s; }
.viewer-viewport img { max-width: 100%; max-height: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; }
.viewer-pane-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.78rem; padding-top: 0.35rem; }
.viewer-pane-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.viewer-pane-actions { margin-left: auto; display: flex; gap: 0.5rem; flex-shrink: 0; }
@media (max-width: 800px) {
    .viewer-panes { flex-direction: column; }
    .viewer-panes-2 .viewer-viewport { height: 34vh; }
}
/* ── RTL (Arabic) ──────────────────────────────────────── */
[dir="rtl"] body { direction: rtl; }
/* No .app-layout override for RTL on purpose: dir="rtl" already reverses the grid's inline
   axis, so the base "sidebar topbar" rule puts the sidebar on the right by itself. Restating
   the columns here flipped it a second time and pushed it back to the left. */
[dir="rtl"] .topbar-user { margin-left: 0; margin-right: auto; }
[dir="rtl"] .password-eye { right: auto; left: 6px; }
[dir="rtl"] .password-field .field-input { padding-right: 12px; padding-left: 34px; }
[dir="rtl"] .search-input { padding: 7px 34px 7px 12px; }
[dir="rtl"] .search-icon { left: auto; right: 9px; }
[dir="rtl"] .search-dropdown { left: 0; right: 0; }
[dir="rtl"] .timegrid-event, [dir="rtl"] .month-event { border-left: none; border-right-style: solid; border-right-width: 3px; }
[dir="rtl"] .side-panel { right: auto; left: 0; box-shadow: var(--shadow-lg); }
[dir="rtl"] .column-menu { right: 0; left: auto; }
[dir="rtl"] .ldp-popup { left: auto; right: 0; }
[dir="rtl"] .ldp-clear { right: auto; left: 6px; }
[dir="rtl"] .ldp-input { padding-right: 30px; padding-left: 26px; }
[dir="rtl"] .ldp-icon { left: auto; right: 9px; }
[dir="rtl"] .filter-select { padding: 0 14px 0 28px; background-position: left 8px center; }
[dir="rtl"] .toast { right: auto; left: 20px; }

/* ── Responsive tables ─────────────────────────────────── */
/* Wide tables scroll inside their container instead of blowing out the page. */
.admin-table-wrap, .grid-wrap { overflow-x: auto; }
.admin-table, .patient-table, .data-table { min-width: 560px; }
/* A nested table sits inside a card that may be far narrower than 560px (the report
   breakdowns are ~360px). Let it shrink and scroll inside its own card instead of
   spilling out of it. */
.data-table.nested { min-width: 0; }
.admin-card > .data-table.nested,
.admin-card > table.data-table.nested { display: block; overflow-x: auto; }
@media (max-width: 900px) {
    /* Cards become their own horizontal scroll context on small screens. */
    .admin-card { overflow-x: auto; }
    .content { padding: 12px; }
    .page-header { flex-wrap: wrap; gap: 8px; }
    .search-wrapper { width: 100%; max-width: 280px; }
}
/* The topbar has to survive 360px. Everything in it is one row that cannot wrap, so past a point
   the only honest move is to drop what can be reached elsewhere: the profile name is a link to a
   page the sidebar already lists, and its icon keeps the target. Search shrinks rather than
   holding a fixed width, and the row is allowed to compress before anything overflows. */
@media (max-width: 640px) {
    /* The status buttons wrap internally, but as a flex ITEM the row still took its max-content
       width (four buttons side by side) and hung 90px off the right of a 360px screen, dragging
       the whole document into a sideways scroll. Giving it the full line and letting it shrink
       below that width is what actually lets its own flex-wrap do its job. */
    .page-header { align-items: flex-start; }
    .visit-status-actions { width: 100%; min-width: 0; }

    /* A section's title, its template name, its filled count and Save Section were one unwrapped
       row: the title wrapped to two lines and the button sat on top of it. The heading takes the
       line, the action takes the next, and the secondary labels clip instead of pushing. */
    .panel-header-row { flex-wrap: wrap; }
    .panel-header-row > .section-toggle { flex: 1 1 100%; }
    /* Left, not pushed right: the floating navigator button sits in the bottom-right corner on
       these widths, and a right-aligned Save Section ends up underneath it on whichever section
       happens to be at the foot of the viewport. */
    .panel-header-row > .section-toggle + * { margin-inline-start: 0; }
    .section-filled { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

    .topbar { padding: 0 10px; gap: 6px; min-width: 0; }
    .topbar-user { gap: 6px; min-width: 0; flex-shrink: 0; }
    .topbar-username { font-size: 0; }          /* icon stays, name goes */
    .topbar-username svg { margin-right: 0; }
    /* .search-wrapper is a fixed 280px, which alone is most of a 360px screen — the row then
       needed 448px and took the whole document sideways with it. Here it gives up the fixed
       width and takes whatever the buttons leave. */
    .search-wrapper { width: auto; max-width: none; flex: 1 1 0; min-width: 0; }
    .search-input { min-width: 0; }
}

@media (max-width: 700px) {
    /* Collapse the sidebar to an icon rail so content gets the width. */
    :root { --sidebar-width: 56px; }
    .nav-links li a span, .nav-links li a { font-size: 0; gap: 0; justify-content: center; }
    /* The "Setup" flyout's own items live inside .nav-links in the DOM, so the blanket rule
       above collapses their text too — same fix as the pinned rail, restored here. */
    .nav-submenu li a span, .nav-submenu li a { font-size: 0.875rem; gap: 8px; justify-content: flex-start; }
    /* Shrink the pill inset so icons fit the 56px rail. */
    .nav-links li a { margin: 2px 6px; padding: 9px 0; }
    .nav-links li a .nav-icon { width: 20px; height: 20px; }
    .nav-section { display: none; }
    .nav-group-toggle { font-size: 0; gap: 0; justify-content: center; margin: 2px 6px; padding: 9px 0; }
    .nav-group-toggle .nav-icon { width: 20px; height: 20px; }
    .nav-caret { display: none; }
    /* Same story as the pinned rail: the wordmark can't fit 56px, the mark can. */
    .sidebar-logo { display: none; }
    .sidebar-mark { display: block; height: 24px; }
    .sidebar-header { flex-direction: column; justify-content: center; gap: 6px; height: auto; padding: 10px 6px; }
    .sidebar-pin { position: static; transform: none; margin: 0 auto; }
    [dir="rtl"] .sidebar-pin { transform: scaleX(-1); }
}

.image-editor {
    background: var(--color-surface); border-radius: 10px; padding: 0.8rem; cursor: default;
    max-width: 94vw; max-height: 94vh; display: flex; flex-direction: column;
}
.image-editor-toolbar { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center; }
.image-editor-canvas-wrap {
    overflow: auto; margin-top: 0.5rem; max-height: 74vh; max-width: 92vw;
    background: var(--color-surface-alt); border: 1px solid var(--color-border); border-radius: 6px;
}
.image-editor-canvas-wrap canvas { display: block; }

.password-field { position: relative; }
.password-field .field-input { padding-right: 34px; width: 100%; }
.password-eye {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    background: none; border: none; cursor: pointer; color: var(--color-text-muted);
    display: flex; align-items: center; padding: 4px;
}
.password-eye:hover { color: var(--color-text); }
.attachment-tags { display: flex; gap: 0.25rem; flex-wrap: wrap; margin-top: 0.2rem; }
.attachment-card.compare-selected { outline: 3px solid var(--color-primary); }

/* ── Obsolete answers on a visit section ───────────────── */
/* A template version can stop rendering a field, but the answer stays on the visit. Amber rather
   than red, and using the existing --warn tokens so it follows both themes: nothing is broken and
   nothing is lost — this is a "look at this", not a failure. border-inline-start, not -left, so
   it lands on the correct side in Arabic. */
.obsolete-answers {
    border-inline-start: 4px solid var(--warn-fg);
    background: var(--warn-bg);
}
.obsolete-answers .panel-header-row strong { color: var(--warn-fg); }

/* ── Autosave state, per section ───────────────────────── */
/* Beside that section's own Save button, never as a page-level toast: with several sections
   open, "Saved" on its own cannot say *what* saved. */
.autosave-state {
    font-size: 0.75rem; margin-inline-end: 0.5rem; color: var(--color-text-muted);
}
.autosave-state.saved  { color: var(--success-fg); }
.autosave-state.failed { color: var(--danger-fg); font-weight: 600; }

/* ── Saved text snippets ───────────────────────────────── */
/* Anchored to the field it writes into, so with several textareas open it is never ambiguous
   which one an insert will land in. */
.snippet-picker { position: relative; display: inline-block; float: inline-end; }
.snippet-trigger { font-size: 0.72rem; padding: 1px 8px; }
.snippet-dropdown {
    position: absolute; inset-inline-end: 0; top: 100%; z-index: 40; width: 22rem; max-width: 80vw;
    background: var(--color-surface); border: 1px solid var(--color-border-2);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 0.5rem;
}
.snippet-list { list-style: none; margin: 0.4rem 0 0; padding: 0; max-height: 16rem; overflow-y: auto; }
.snippet-item {
    display: block; width: 100%; text-align: start; background: none; border: none; cursor: pointer;
    padding: 0.35rem 0.4rem; border-radius: var(--radius-sm);
}
.snippet-item:hover { background: var(--primary-tint-weak); }
.snippet-name { display: block; font-weight: 600; font-size: 0.82rem; }
.snippet-preview { display: block; font-size: 0.74rem; color: var(--color-text-muted); }
.snippet-save { display: flex; gap: 0.35rem; margin-top: 0.5rem; border-top: 1px solid var(--color-border-2); padding-top: 0.5rem; }

/* Fill stage: the snippet's blanks as inline inputs inside the flowing text. */
.snippet-dropdown.filling { width: 30rem; }

.snippet-fill-title { font-weight: 600; font-size: 0.85rem; margin: 0 0 0.4rem; }

.snippet-fill-body {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: 0.84rem;
    line-height: 1.9;
    max-height: 18rem;
    overflow-y: auto;
    padding: 0.5rem 0.55rem;
    background: var(--color-bg);
    border-radius: var(--radius);
}

.snippet-blank {
    display: inline-block;
    border: none;
    border-bottom: 2px solid var(--color-primary);
    border-radius: 0;
    background: var(--primary-tint-weak);
    color: var(--color-text);
    font: inherit;
    padding: 0 4px;
    margin: 0 2px;
    outline: none;
    vertical-align: baseline;
}

.snippet-blank:focus { background: var(--primary-tint); }

.snippet-fill-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.55rem;
}

.snippet-fill-actions .field-hint { flex: 1; }

/* Small helper text under an input. Sits with .field-label / .field-input as the standard
   form vocabulary — pages used to invent their own hint markup with inline styles. */
.field-hint {
    font-size: 0.75rem;
    color: var(--color-text-muted);
}
.field-hint a { color: var(--color-primary); }

/* SMS length/segment hint under an SMS body field — neutral for a single segment, warm once it
   splits so the extra cost (carriers bill per segment) is obvious before Send, not after. */
.sms-length-hint {
    display: inline-block;
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-top: 0.25rem;
}
.sms-length-hint-multi { color: var(--warn-fg); }

/* Star-per-row picker for "default department" — click a row's star to make it the default,
   instead of a plain <select> that hides which one is currently active. */
.default-org-list { display: flex; flex-direction: column; gap: 2px; }
.default-org-row {
    display: flex; align-items: center; gap: 0.5rem;
    background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
    padding: 4px 6px; font: inherit; font-size: 0.85rem; text-align: start;
    color: var(--color-text-muted); cursor: pointer; transition: background .12s;
}
.default-org-row:hover:not(:disabled) { background: var(--color-hover); }
.default-org-row:disabled { cursor: default; opacity: .6; }
.default-org-row svg { flex: none; color: var(--color-border-strong); }
.default-org-row.is-default { color: var(--color-text); font-weight: 600; }
.default-org-row.is-default svg { color: var(--warn-fg); }

/* Amber state badge — "waiting", "expired": needs attention but is not an error. */
.badge-warn { background: var(--warn-bg); color: var(--warn-fg); }

/* ---- Waiting room ---------------------------------------------------- */

.waiting-room-inbox { margin-bottom: 1rem; }

.waiting-room-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.55rem 0;
    border-top: 1px solid var(--color-border-2);
}

.waiting-room-item:first-of-type { border-top: none; }
.waiting-room-item.likely-match { background: var(--success-bg); border-radius: var(--radius-sm); padding-left: 0.5rem; padding-right: 0.5rem; margin: 0 -0.5rem; }

/* Collapsed by default and visually recessive: nothing in this inbox blocks the visit, so it sits
   at the bottom looking like a footnote until it has a likely match, at which point the whole card
   picks up the same light green the matching row uses. */
/* No accent stripe when there's nothing to say. The amber left border this used to carry was from
   when the inbox lived above the clinical sections and had to announce itself; down here it was
   just a warning colour on a card that warns about nothing. */
.waiting-room-inbox { background: var(--color-surface-2, var(--color-surface)); }
.waiting-room-inbox.has-match {
    background: var(--success-bg);
    border-color: var(--success-border);
    border-left: 3px solid var(--success);
}
.wr-inbox-head {
    display: flex; align-items: center; gap: 0.45rem; width: 100%;
    background: none; border: none; padding: 0; cursor: pointer;
    font: inherit; color: inherit; text-align: start;
}
.wr-inbox-title { font-size: 0.875rem; font-weight: 600; }
.waiting-room-inbox:not(.has-match) .wr-inbox-title { font-weight: 500; color: var(--color-text-muted); }
.wr-inbox-caret { display: inline-block; transition: transform .15s; opacity: 0.6; }
.wr-inbox-caret.open { transform: rotate(90deg); }

/* Template family cards. Reuses .wr-cards for the grid so the two "things you configure" pages
   read the same way; the only additions are the version control and the upstream tint. */
.tpl-card { display: flex; flex-direction: column; gap: 0.5rem; }
/* Someone else's: recessive, because the useful action on it is "make my own copy". */
.tpl-card.tpl-upstream { background: var(--color-surface-2, var(--color-surface)); }
.tpl-card-version { display: flex; align-items: center; gap: 0.5rem; }
.tpl-card-version .field-label { margin: 0; white-space: nowrap; font-size: 0.78rem; }
.tpl-card-version .field-input { flex: 1 1 auto; min-width: 0; }

/* One card per form: name and status at a glance, the link and its QR right on the card. */
.wr-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 1rem;
}

.wr-card {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 1.1rem 1.2rem;
    min-width: 0;
}

.wr-card-head {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}

.wr-card-title {
    font-weight: 600;
    font-size: 0.95rem;
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.wr-card-meta { font-size: 0.8rem; }

.wr-card-desc {
    font-size: 0.82rem;
    color: var(--color-text-muted);
    margin: 0;
}

.wr-linkrow {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}

.wr-linkrow .field-input {
    flex: 1;
    min-width: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.wr-linkrow .btn-sm { flex: 0 0 auto; white-space: nowrap; }

.wr-card-actions {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
    margin-top: auto;
    border-top: 1px solid var(--color-border-2);
    padding-top: 0.6rem;
}

/* Always on a white tile: a QR on a dark-theme surface can fail to scan. */
.wr-qr { text-align: center; padding: 0.3rem 0; }
.wr-qr img {
    width: 200px;
    max-width: 100%;
    background: #fff;
    padding: 10px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border-2);
}

.wr-page-note { margin-top: 1rem; }

/* ---- Waiting room: the patient-facing page --------------------------- */

/* Reached on a phone as often as a desk, by someone who has never seen the app: a wide
   readable card, big touch targets, questions grouped under their section headings. */
.wr-public { max-width: 46rem; }

/* The login shell centers vertically, which clips the top of anything taller than the
   viewport — a 50-question intake sheet very much is. */
.auth-layout:has(.wr-public) {
    align-items: flex-start;
    padding: 1.5rem 1rem 4rem;
}

.wr-section-title {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-primary);
    border-bottom: 1px solid var(--color-border-2);
    padding-bottom: 0.35rem;
    margin: 1.4rem 0 0.9rem;
}

.wr-fields {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.9rem 1rem;
}

.wr-fields .field { margin-bottom: 0; grid-column: 1 / -1; }
.wr-fields .wr-field-half { grid-column: auto / span 1; }

@media (max-width: 560px) {
    .wr-fields { grid-template-columns: 1fr; }
    .wr-fields .wr-field-half { grid-column: 1 / -1; }
}

/* Finger-sized inputs: this page is filled standing up, on a tablet at reception. */
.wr-public .field-input {
    padding: 11px 14px;
    font-size: 1rem;
}

.wr-public .field-label { font-size: 0.875rem; }

.wr-submit {
    width: 100%;
    padding: 13px;
    font-size: 1.05rem;
    margin-top: 1.4rem;
}

.wr-note {
    margin-top: 0.9rem;
    font-size: 0.8rem;
    text-align: center;
}

/* Stacked, not side-by-side: each stays a full-width, thumb-sized target on a phone. */
.wr-choice-buttons { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1rem; }
.wr-choice-buttons .wr-submit { margin-top: 0; }

.wr-done { text-align: center; padding: 1.5rem 0; }
.wr-done-mark {
    width: 64px;
    height: 64px;
    margin: 0 auto 1rem;
    border-radius: 50%;
    background: var(--success-bg);
    color: var(--success-fg);
    font-size: 2rem;
    line-height: 64px;
    text-align: center;
}

/* ---- Public booking page ----------------------------------------------- */

.bp-public { max-width: 46rem; }

.auth-layout:has(.bp-public) {
    align-items: flex-start;
    padding: 1.5rem 1rem 4rem;
}

.bp-header { display: flex; gap: 1rem; align-items: center; margin-bottom: 1rem; }
.bp-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    object-fit: cover;
    flex: 0 0 auto;
    background: var(--color-surface-2);
}

/* Days across the top, buttons underneath — a public "pick a free half-hour" picker,
   deliberately not TimeGrid: no department chips, no click-to-edit, no auth. */
.sp-days {
    display: flex;
    gap: 0.4rem;
    overflow-x: auto;
    padding-bottom: 0.3rem;
    margin: 1rem 0;
}

.sp-day {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    min-width: 52px;
    padding: 0.5rem 0.3rem;
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius);
    background: var(--color-surface);
    cursor: pointer;
}

.sp-day-active {
    border-color: var(--color-primary);
    background: var(--primary-tint);
}

.sp-day-name { font-size: 0.72rem; text-transform: uppercase; color: var(--color-text-muted); }
.sp-day-num { font-size: 1.05rem; font-weight: 600; }

.sp-slots {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
    gap: 0.5rem;
}

.sp-slot {
    padding: 0.55rem 0.4rem;
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius);
    background: var(--color-surface);
    font-size: 0.9rem;
    cursor: pointer;
}

.sp-slot-active {
    border-color: var(--color-primary);
    background: var(--color-primary);
    color: var(--color-primary-contrast);
}

/* ---- Saved text page -------------------------------------------------- */

.snippet-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
    margin-top: 1rem;
}

.snippet-card {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 1rem 1.1rem;
    min-width: 0;
}

.snippet-card-head {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}

/* The prose block itself, kept short — the card is a picker entry, not a reading pane. */
.snippet-card-body {
    font-size: 0.82rem;
    color: var(--color-text-muted);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.snippet-card-actions {
    display: flex;
    gap: 0.3rem;
    margin-top: auto;
    border-top: 1px solid var(--color-border-2);
    padding-top: 0.5rem;
}

/* ---- Guided tour ------------------------------------------------------ */

/* The shade is one element whose box-shadow floods everything around the spotlight hole,
   so the highlighted control stays fully visible and clickable-looking without cloning it. */
.tour-spotlight {
    position: fixed;
    z-index: 300;
    border-radius: 10px;
    box-shadow: 0 0 0 9999px color-mix(in srgb, #000 55%, transparent);
    pointer-events: none;
    transition: top .25s ease, left .25s ease, width .25s ease, height .25s ease;
}

/* Full-page shade for steps with no target (welcome / closing). */
.tour-shade {
    position: fixed;
    inset: 0;
    z-index: 300;
    background: color-mix(in srgb, #000 55%, transparent);
}

.tour-tip {
    position: fixed;
    z-index: 301;
    width: 320px;
    max-width: calc(100vw - 2rem);
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 1rem 1.1rem;
}

.tour-tip h3 {
    font-size: 0.95rem;
    font-weight: 700;
    margin: 0 0 0.4rem;
}

.tour-tip p {
    font-size: 0.84rem;
    color: var(--color-text-muted);
    margin: 0 0 0.8rem;
}

.tour-tip-footer {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* The ?-button chooser: two big options, general vs this page. */
.tour-choices { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 0.8rem; }
.tour-choice {
    text-align: start;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    padding: 0.6rem 0.8rem;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.tour-choice strong { font-size: 0.9rem; color: var(--color-text); }
.tour-choice span { font-size: 0.78rem; color: var(--color-text-muted); }
.tour-choice:hover { border-color: var(--color-primary); background: var(--primary-tint-weak); }

.tour-dots {
    display: flex;
    gap: 4px;
    flex: 1;
}

.tour-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--color-border-strong);
}

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

/* Round help button in the topbar, styled like its btn-sm neighbours but unmistakably "help". */
.topbar-help {
    font-weight: 700;
}

/* Honeypot: physically off-screen (display:none would tip off smarter bots). */
.hp-field {
    position: absolute;
    inset-inline-start: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Minimal-vs-detailed choice on the register page: two selectable cards, radio hidden. */
.style-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.style-card {
    position: relative;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.6rem 0.7rem;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.78rem;
    color: var(--color-text-muted);
}
.style-card strong { color: var(--color-text); font-size: 0.85rem; }
.style-card input { position: absolute; opacity: 0; pointer-events: none; }
.style-card.selected {
    border-color: var(--color-primary);
    background: var(--primary-tint-weak);
    box-shadow: 0 0 0 1px var(--color-primary);
}

/* Subscription plan picker on the register page — same selectable-card mechanics as
   .style-cards, but 2-3 plans need more room than a fixed two-column grid. */
.plan-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0.5rem; }
.plan-card .plan-price { color: var(--color-primary); font-weight: 600; font-size: 0.82rem; }
.plan-card .plan-features { font-size: 0.72rem; line-height: 1.4; display: flex; flex-direction: column; gap: 1px; margin-top: 0.25rem; }
/* One gated feature per row, ✓ when the plan includes it, — (dimmed) when it doesn't — the
   whole point is that what a plan lacks is as visible as what it has. */
.plan-feat { display: flex; align-items: baseline; gap: 0.35rem; }
.plan-feat::before { content: "✓"; color: var(--color-primary); font-weight: 700; flex-shrink: 0; }
.plan-feat.no { opacity: 0.55; }
.plan-feat.no::before { content: "—"; color: var(--color-text-muted); font-weight: 400; }
.plan-feat em { font-style: normal; color: var(--color-primary); white-space: nowrap; }
/* A caveat on the row above (e.g. "reminders" meaning email only) — too long to fit as a
   same-line <em> hint like the add-on prices above, so it gets its own wrapped line instead. */
.plan-subnote { display: block; margin: -1px 0 0 1.1rem; }
.plan-flag {
    display: inline-block;
    margin-inline-start: 0.35rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: var(--color-primary);
    color: #fff;
    font-size: 0.62rem;
    font-weight: 600;
    vertical-align: middle;
}

/* Plain checkbox rows (contact preferences, trial toggle) — unlike .style-card, the box stays
   visible since these are independent toggles, not a mutually-exclusive choice. */
.checkbox-group { display: flex; flex-wrap: wrap; gap: 0.9rem; }
.checkbox-label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    cursor: pointer;
}
.checkbox-label input[type="checkbox"] { width: auto; }

/* "New here? Create an account" under the login form. */
.auth-register-hint {
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--color-border-2);
    text-align: center;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* ---- Odontogram -------------------------------------------------------- */

/* Chart fill palette. Service.ChartColor stores the bare key; the SVG fills with
   var(--chart-<key>, <key>), so unknown keys still work as plain CSS colors and these
   tokens exist to tune the known ones per theme. */
:root {
    --chart-grey: #9ca3af;
    --chart-white: #f3f4f6;
    --chart-black: #374151;
    --chart-red: #dc2626;
    --chart-yellow: #f59e0b;
    --chart-blue: #3b82f6;
    --chart-green: #16a34a;
    --chart-orange: #ea580c;
    --chart-purple: #9333ea;
    --chart-brown: #92400e;
    --chart-pink: #ec4899;
}

[data-theme="dark"] {
    --chart-white: #e5e7eb;
    --chart-black: #6b7280;
}

.og-panel .panel-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.og-controls { display: flex; gap: 0.3rem; }

.og-procedure-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin: 0.6rem 0 0.2rem;
}

.og-procedure-row .field-label { margin: 0; }
.og-procedure-row select { max-width: 22rem; }
.og-procedure-row .field-hint { flex-basis: 100%; }

.og-swatch {
    display: inline-block;
    width: 18px;
    height: 18px;
    border-radius: 4px;
    border: 1px solid var(--color-border-strong);
    flex: 0 0 auto;
}

.og-color-row { display: flex; align-items: center; gap: 0.4rem; }

.og-filter-row { display: flex; gap: 0.3rem; flex-wrap: wrap; margin: 0.5rem 0; }

.og-chip {
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    color: var(--color-text-muted);
    border-radius: var(--radius-pill);
    padding: 3px 12px;
    font-size: 0.78rem;
    cursor: pointer;
}

.og-chip.active {
    background: var(--primary-tint);
    border-color: var(--color-primary);
    color: var(--color-primary-dark);
}

/* The chart is fixed-proportion; on a narrow screen it scrolls in its own box rather than
   squeezing the teeth into unclickable slivers. */
.og-chart-scroll { overflow-x: auto; padding: 0.4rem 0; }

.og-chart {
    display: block;
    min-width: 640px;
    max-width: 900px;
    width: 100%;
    margin: 0 auto;
}

.og-midline { stroke: var(--color-border-2); stroke-width: 1; stroke-dasharray: 4 4; }

.og-surface-region {
    fill: var(--color-bg);
    stroke: var(--color-border-strong);
    stroke-width: 1;
    cursor: pointer;
    transition: opacity .1s;
}

.og-surface-region:hover { opacity: 0.7; stroke: var(--color-primary); stroke-width: 1.5; }

/* Planned work is an outline of intent, not a fact — dashed and translucent until done. */
.og-surface-region.planned { opacity: 0.65; stroke-dasharray: 3 2; }

.og-surface-region.selected { stroke: var(--color-primary); stroke-width: 2; }

.og-whole { stroke: none; opacity: 0.4; }
.og-whole.planned { opacity: 0.25; }

.og-label {
    font-size: 12px;
    font-weight: 600;
    fill: var(--color-text);
    cursor: pointer;
}

.og-label:hover, .og-label.selected { fill: var(--color-primary); }

.og-glyphs {
    font-size: 12px;
    font-weight: 700;
    fill: var(--danger-fg);
    pointer-events: none;
}

.og-table { margin-top: 0.6rem; }
.og-table .og-status { max-width: 9.5rem; }
.og-table .og-priority { max-width: 4.5rem; }
.og-table .og-remarks .field-input { min-width: 10rem; }

/* ---- Inline field customization (the iPhone model) --------------------- */

.field-edit-banner {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    border-left: 4px solid var(--color-primary);
}
.field-edit-banner .text-muted { font-size: 0.82rem; }

/* A field being customized: dashed outline, room for its chrome, inert content. */
.field.field-editing {
    position: relative;
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius);
    padding: 20px 8px 8px;
    cursor: grab;
    background: var(--color-surface);
}
.field.field-editing:active { cursor: grabbing; }

/* The form itself is frozen while editing — clicks drag and remove, they don't type. */
.field-editing .field-frozen { pointer-events: none; opacity: 0.75; }

.field-remove {
    position: absolute;
    top: -9px;
    inset-inline-start: -9px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: none;
    background: var(--danger-fg);
    color: #fff;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: var(--shadow);
    z-index: 5;
}
.field-remove:hover { transform: scale(1.12); }

.field-edit-tools {
    position: absolute;
    top: 2px;
    inset-inline-end: 4px;
    display: flex;
    align-items: center;
    gap: 4px;
    z-index: 5;
}
.field-width-picker { display: inline-flex; border: 1px solid var(--color-border); border-radius: var(--radius-sm); overflow: hidden; }
.field-width-picker button {
    border: none;
    background: var(--color-surface);
    color: var(--color-text-muted);
    font-size: 0.68rem;
    padding: 1px 6px;
    cursor: pointer;
}
.field-width-picker button.active { background: var(--primary-tint); color: var(--color-primary-dark); font-weight: 700; }
.field-move {
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text-muted);
    border-radius: var(--radius-sm);
    font-size: 0.7rem;
    padding: 1px 5px;
    cursor: pointer;
}

/* The "add a field" tile at the end of the grid, and the buffer it opens. */
.field-add-tile {
    grid-column: span 3;
    min-height: 52px;
    border: 1px dashed var(--color-primary);
    border-radius: var(--radius);
    background: var(--primary-tint-weak);
    color: var(--color-primary-dark);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}
.field-buffer {
    margin-top: 0.6rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--color-border-2);
    border-radius: var(--radius);
    background: var(--color-bg);
}
.field-buffer > .field-input { max-width: 16rem; margin-bottom: 0.5rem; }
.field-buffer-list { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.field-buffer-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    border: 1px dashed var(--color-border-strong);
    background: var(--color-surface);
    border-radius: var(--radius-pill);
    padding: 4px 12px;
    font-size: 0.8rem;
    cursor: pointer;
}
.field-buffer-item:hover { border-color: var(--color-primary); color: var(--color-primary); }
.field-buffer-name { font-weight: 500; }
.field-buffer-section { font-size: 0.7rem; color: var(--color-text-muted); }
.field-buffer-plus { color: var(--color-primary); font-weight: 700; }

/* ---- Growth chart ------------------------------------------------------ */

.growth-panel .panel-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.growth-controls { display: flex; gap: 0.4rem; }
.growth-controls .field-input { width: auto; }

.growth-latest { font-size: 0.85rem; color: var(--color-text-muted); margin: 0.4rem 0 0.2rem; }

.growth-chart-scroll { overflow-x: auto; }
.growth-chart { display: block; min-width: 640px; width: 100%; max-width: 980px; margin: 0 auto; }

/* Reference curves are context, not data: recessive strokes, quiet grid, muted labels.
   The patient's series is the only thing in the primary color. */
.growth-grid { stroke: var(--color-border-2); stroke-width: 0.7; }
.growth-tick { font-size: 10px; fill: var(--color-text-muted); }
.growth-axis-label { font-size: 11px; fill: var(--color-text-muted); }

.growth-ref { fill: none; stroke: var(--color-border-strong); stroke-width: 1.2; }
.growth-ref.median { stroke-width: 1.8; }
.growth-ref-label { font-size: 10px; font-weight: 600; fill: var(--color-text-muted); }

.growth-series { fill: none; stroke: var(--color-primary); stroke-width: 2; }
.growth-point { fill: var(--color-primary); stroke: var(--color-surface); stroke-width: 1.5; }

/* Trends: series "a" is the primary; "b" is the paired series (diastolic, left eye). */
.trend-series { fill: none; stroke-width: 2; }
.trend-point { stroke: var(--color-surface); stroke-width: 1.5; }
.trend-series.a { stroke: var(--color-primary); }
.trend-point.a { fill: var(--color-primary); }
.trend-series.b { stroke: var(--chart-orange); }
.trend-point.b { fill: var(--chart-orange); }

/* Reference geometry: the healthy band sits behind everything; guides are quiet dashes. */
.trend-band { fill: var(--success-bg); opacity: 0.55; }
.trend-guide { stroke: var(--color-border-strong); stroke-width: 1; stroke-dasharray: 5 4; }

.trend-legend { display: flex; gap: 1rem; margin: 0.4rem 0 0; font-size: 0.8rem; color: var(--color-text-muted); }
.trend-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.trend-chip { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.trend-chip.a { background: var(--color-primary); }
.trend-chip.b { background: var(--chart-orange); }

/* ---- On-visit calculations -------------------------------------------- */

.calc-card .panel-header-row { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }

.calc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.8rem 1.2rem;
    margin-top: 0.6rem;
}

.calc-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.calc-value { font-size: 1.15rem; font-weight: 700; color: var(--color-text); }
.calc-label { font-size: 0.75rem; color: var(--color-text-muted); }
.calc-activity {
    font-size: 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text-muted);
    padding: 1px 4px;
    max-width: 100%;
}

/* ── Template builder list toolbar ──────────────────────────────────────── */
.template-list-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    flex-wrap: wrap;
}
.seg-control {
    display: inline-flex;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    overflow: hidden;
    background: var(--color-surface);
}
.seg-option {
    border: none;
    background: transparent;
    color: var(--color-text-muted);
    font-size: 0.82rem;
    padding: 0.4rem 0.85rem;
    cursor: pointer;
}
.seg-option + .seg-option { border-left: 1px solid var(--color-border); }
.seg-option.active {
    background: var(--primary-tint-weak);
    color: var(--color-primary);
    font-weight: 600;
}
.template-search { max-width: 260px; }

/* Section heading inside a column/details dropdown menu */
.column-menu-heading {
    padding: 0.45rem 0.8rem 0.15rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    border-top: 1px solid var(--color-border);
    margin-top: 0.25rem;
}

/* Customize-mode bar above each togglable visit panel */
.panel-visibility-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.35rem 0.75rem;
    margin-bottom: 0.4rem;
    border: 1px dashed var(--color-border);
    border-radius: 8px;
    background: var(--primary-tint-weak);
    font-size: 0.82rem;
    font-weight: 600;
}
.rx-field-picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 0.5rem;
    padding: 0.3rem 0.5rem;
    border: 1px dashed var(--color-border);
    border-radius: 8px;
}

/* ── Arrivals bell ──────────────────────────────────────────────────────── */
.arrivals-wrap { position: relative; display: inline-flex; }
.arrivals-bell { position: relative; display: inline-flex; align-items: center; }
.arrivals-count {
    position: absolute;
    top: -6px;
    inset-inline-end: -6px;
    background: var(--warn, #d97706);
    color: #fff;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 700;
    min-width: 15px;
    height: 15px;
    line-height: 15px;
    text-align: center;
    padding: 0 3px;
}
.arrivals-menu { min-width: 260px; }
.arrivals-row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    padding: 0.3rem 0.8rem;
    font-size: 0.85rem;
}

/* ── Notification bell ─────────────────────────────────────────────────── */
.notif-wrap { position: relative; display: inline-flex; }
.notif-bell { position: relative; display: inline-flex; align-items: center; }
.notif-count {
    position: absolute;
    top: -6px;
    inset-inline-end: -6px;
    background: var(--danger, #dc2626);
    color: #fff;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 700;
    min-width: 15px;
    height: 15px;
    line-height: 15px;
    text-align: center;
    padding: 0 3px;
}
.notif-menu { min-width: 300px; max-width: 340px; max-height: 70vh; overflow-y: auto; }
.notif-row {
    display: block;
    padding: 0.5rem 0.8rem;
    font-size: 0.85rem;
    border-bottom: 1px solid var(--color-border);
    text-decoration: none;
    color: inherit;
}
.notif-row:last-child { border-bottom: none; }
.notif-row:hover { background: var(--color-bg); cursor: pointer; }
.notif-row.unread { background: var(--primary-tint-weak); }
.notif-row-title { font-weight: 600; display: flex; align-items: center; gap: 0.4rem; }
.notif-row-dot { width: 7px; height: 7px; border-radius: 999px; background: var(--danger, #dc2626); flex: none; }
.notif-row-message { color: var(--color-text-muted); margin-top: 0.15rem; }
.notif-row-time { color: var(--color-text-muted); font-size: 0.72rem; margin-top: 0.2rem; }

/* An arrived patient's row on the dashboard — someone is physically waiting */
.dash-item-waiting {
    background: var(--primary-tint-weak);
    border-radius: 8px;
}

/* ── Visit page: floating "On this page" navigator + panel tab bar ─────────────
   Fixed at the inline-end edge so it stays in view however far the visit scrolls;
   hidden on narrow screens where it would sit on top of the content. */
.visit-nav {
    position: fixed;
    inset-inline-end: 1rem;
    top: 50%;
    transform: translateY(-50%);
    width: 200px;
    max-height: 72vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 0.55rem 0.55rem 0.65rem;
    z-index: 30; /* under drawers (41) and the toast */
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.visit-nav-head {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
    color: var(--color-text-muted);
    padding: 0.15rem 0.35rem 0.4rem;
}
.visit-nav-close {
    border: none; background: none; cursor: pointer; color: var(--color-text-muted);
    font-size: 0.75rem; line-height: 1; padding: 0.15rem 0.3rem; border-radius: 6px;
}
.visit-nav-close:hover { color: var(--color-text); background: var(--primary-tint-weak); }
.visit-nav-item {
    border: none; background: none; cursor: pointer; text-align: start;
    font-size: 0.82rem; color: var(--color-text);
    padding: 0.28rem 0.35rem; border-radius: 6px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.visit-nav-item:hover { background: var(--primary-tint-weak); color: var(--color-primary); }
.visit-nav-sub { padding-inline-start: 1rem; font-size: 0.78rem; }
.visit-nav-group {
    font-size: 0.7rem; font-weight: 600; color: var(--color-text-muted);
    padding: 0.35rem 0.35rem 0.1rem; text-transform: uppercase; letter-spacing: 0.03em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.visit-nav-sep { border-top: 1px solid var(--color-border); margin: 0.35rem 0.2rem; }

/* What the visit still needs, parked at the foot of the navigator. Sticky rather than merely last:
   .visit-nav is capped at 72vh and scrolls, so on a visit with many sections a plain bottom group
   would sit below the fold — which is exactly what moving it here was meant to stop. */
.visit-nav-warngroup {
    position: sticky;
    bottom: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin: 0.35rem -0.55rem -0.65rem;   /* bleed to the panel's edges */
    padding: 0.35rem 0.55rem 0.5rem;
    border-top: 1px solid var(--color-border);
    background: var(--color-surface);     /* opaque: rows scroll underneath it */
}
/* Both variants keep .visit-nav-item's ellipsis clipping — a long field name costs no width. */
.visit-nav-warn { background: var(--warn-bg); color: var(--warn-fg); font-weight: 600; }
.visit-nav-warn:hover:not(:disabled) { background: var(--warn-border); color: var(--warn-fg); }
.visit-nav-match { background: var(--success-bg); color: var(--success-fg); font-weight: 600; }
.visit-nav-match:hover { background: var(--success-border); color: var(--success-fg); }
/* Facts on file, not fields to fill: nothing to jump to, so nothing that looks clickable. */
.visit-nav-static { cursor: default; }
.visit-nav-warn:disabled { opacity: 0.6; cursor: not-allowed; }
.visit-nav-fab {
    position: fixed;
    inset-inline-end: 1rem;
    top: 50%;
    transform: translateY(-50%);
    width: 2.3rem; height: 2.3rem; border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    cursor: pointer; color: var(--color-text);
    z-index: 30;
}
/* The only trace of an outstanding answer once the panel is closed. Deliberately a dot and not a
   count: the number is in the panel, this just has to say "there is something". */
.visit-nav-fab-dot {
    position: absolute; top: 3px; inset-inline-end: 3px;
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--warn-fg); border: 1px solid var(--color-surface);
}
.visit-nav-fab:hover { background: var(--primary-tint-weak); color: var(--color-primary); }
/* Below this width there is no room for a reserved column, so the navigator stops being a
   persistent panel and becomes the floating button — tapped open, and closed again by picking a
   section (see ScrollToAsync). Hiding it outright, as this used to, left a phone with no way to
   move between sections at all, and no sight of what the visit still needs. */
@media (max-width: 1280px) {
    .visit-nav {
        top: auto;
        bottom: 4.5rem;                  /* clear of the button that opened it */
        transform: none;
        max-height: 60vh;
        width: min(17rem, calc(100vw - 2rem));
    }
    /* Out of the vertical middle. Centred, it floats over whatever happens to be halfway down the
       page — on a phone that was a section's own Save button, covered by a button that only opens
       a menu. The corner is where a floating action belongs and collides with nothing. */
    .visit-nav-fab { top: auto; bottom: 1rem; transform: none; }
}
/* Reserve the nav's column so it never sits on top of a card's own buttons — the fixed
   element is out of flow, so the content body cedes the space instead. */
@media (min-width: 1281px) {
    .content-body:has(.visit-nav) { padding-inline-end: 230px; }
}
.visit-panel-tabs { margin: 1rem 0 0.6rem; scroll-margin-top: 5rem; }
