/* ============================================================================
   BelIQ.Rantevou — design system (single global stylesheet; no component CSS)
   ========================================================================== */
:root {
    /* ── Brand: the "R" identity — plum #3E2C55, amber #F0A23C, paper #FBFAFC ──────────
       --brand carries every primary action, link and active state. --accent is the amber
       from the mark's lower half and is used sparingly (active nav rail, brand marks,
       focus ring) so it never competes with --amber, which still means "warning". */
    /* The mark's #3E2C55 is the deep end of the family, not the working colour: at full
       strength across a UI it reads heavy. Everything on screen uses the lighter --brand,
       which still clears 8:1 on white, and the surfaces are tinted rather than grey. */
    --brand: #55427F;            /* links, primary actions, active states */
    --brand-deep: #3E2C55;       /* the logo colour — gradient end + pressed states */
    --brand-soft: #8B7BB0;       /* muted plum — secondary icons on light surfaces */
    --brand-bg: #F3EFFB;         /* plum tint — chips, badges, selected cells */
    --accent: #F0A23C;
    --accent-deep: #B9761A;      /* clears 4.5:1 on white — amber for text/icons */
    --accent-bg: #FEF5E8;
    --paper: #FBFAFC;

    --navy: #4A3E63;             /* neutral dark, kept for .b-navy badges */
    --ink: #322A42;
    --muted: #7A7391;
    --surface: #ffffff;
    --surface2: #FAF9FD;
    --surface3: #F2F0F8;
    --border: #E8E4F1;
    --green: #2e9e5b;
    --green-bg: #e4f5ea;
    --amber: #d98a13;            /* status "warning" — deliberately darker than --accent */
    --amber-bg: #fbf0dc;
    --red: #d6453d;
    --red-bg: #fbe5e4;
    --navy-bg: #E8E5EE;
    /* No shadows on cards, drawers or auth cards: separation is a 1px --border hairline or a
       background change (docs/DESIGN.md). Kept as a token so existing call sites resolve to nothing. */
    --shadow: none;
    /* Only things that float above content (menus, popovers, dialogs) carry this one. */
    --shadow-float: 0 4px 14px rgba(24,20,32,.10);
    --radius: 6px;
    --radius-card: 10px;         /* public and auth cards only */
    /* Amber focus ring: with the wordmark, the only place the accent appears, so keyboard
       focus is unmistakable. */
    --focus-ring: 0 0 0 3px rgba(240,162,60,.55);
    --scrim: rgba(24,20,32,.32);

    /* Appointment status colours — the scheduler line + legend + timeline share these.
       These are semantic, not brand: they stay put so learned colour meanings survive. */
    --st-sched: #2074BF;        /* Scheduled — steel blue */
    --st-confirmed: #2e9e5b;    /* Confirmed — green */
    --st-completed: #5a6b7b;    /* Completed — slate */
    --st-cancelled: #d6453d;    /* Cancelled — red */
    --st-noshow: #d98a13;       /* No-show — amber */
    --st-resched: #7a5cc0;      /* Rescheduled — purple */
    --st-arrived: #c2419e;      /* Arrived/waiting (1.15) — magenta, distinct from every other status */
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    /* Commissioner is Greek-designed and ships Greek glyphs, so Latin and Greek set in one face.
       The previous face had no Greek, and every Greek string fell back to Segoe UI mid-row. */
    font-family: 'Commissioner', 'Segoe UI', system-ui, -apple-system, Roboto, 'Noto Sans', sans-serif;
    color: var(--ink);
    background: var(--surface2);
    font-size: 15px;
    line-height: 1.45;
}
/* Never let a transient horizontal overflow (e.g. the fixed drawer mid slide-in when the circuit
   stalls) scroll the viewport sideways and paint the drawer's right edge off-screen (F-4). Wide
   tables keep their own inner scroll (.g-card-body / .tbl-wrap / .sched), so this only clips the
   stray overflow, not real content.

   On <html> ONLY, never on <body>. `overflow-x: hidden` forces the computed `overflow-y` to `auto`,
   which turns the element into a scroll container. On <body> that container never actually scrolls
   (the viewport does), so `position: sticky` inside it resolves against a scrollport that stays
   still — the plum rail scrolled away and left the page white below it. */
html { overflow-x: hidden; }

/* Headings differ from body by weight and size only: same family, no tracking. */
h1, h2, h3, h4 { font-family: inherit; font-weight: 600; letter-spacing: 0; line-height: 1.25; }
h1 { font-size: 1.5rem; margin: 0; }
/* Every time, price, quantity and figure sets in tabular numerals so columns line up. */
.num, .cal-time, .kpi-value, .pb-price, .pb-hours, .pb-service-meta, .pb-time, .h-meta, .rec-meta, .detail-meta, .fig-val { font-variant-numeric: tabular-nums; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- Layout shell ---------------------------------------------------------- */
.app-shell { display: flex; min-height: 100vh; }
.sidebar {
    width: 232px; flex: 0 0 232px;
    /* Light rail: chrome is neutral, colour appears only where it means something. */
    background: var(--surface);
    border-right: 1px solid var(--border);
    color: var(--ink);
    display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh;
}
/* The wordmark is 3:1, so its height drives the whole brand box. */
.sidebar-brand { display: flex; align-items: center; gap: .6rem; padding: .6rem 1rem .5rem; }
.sidebar-brand .brand-word { height: 44px; width: auto; }
.sidebar-brand .brand-mark { height: 36px; width: 36px; display: none; }
.sheet-close { display: none; }

.nav-scroll { flex: 1 1 auto; overflow-y: auto; padding-bottom: .4rem; }
.nav-scroll::-webkit-scrollbar { width: 6px; }
.nav-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.nav-items { display: flex; flex-direction: column; padding: .25rem .6rem; gap: 1px; }
.nav-link-item { display: flex; align-items: center; gap: .65rem; padding: .45rem .65rem; border-radius: var(--radius); color: var(--ink); font-weight: 500; }
.nav-link-item:hover { background: var(--surface2); text-decoration: none; color: var(--ink); }
.nav-link-item.active { background: var(--brand-bg); color: var(--brand); font-weight: 600; }
.nav-link-item i { width: 18px; text-align: center; color: var(--muted); }
.nav-link-item.active i { color: var(--brand); }

/* Collapsible group — a hidden checkbox drives it, so it works with no Blazor circuit
   (MainLayout is statically rendered) and keeps working while the circuit reconnects.
   Items stay in the DOM whatever the state, so the icon rail and the phone sheet can force
   every group open in CSS without a second copy of the menu. */
.nav-group { padding-top: .1rem; }
/* A lone destination between groups (Reports): spaced like a group, no header to collapse. */
.nav-solo { padding-top: .5rem; }
/* Visually hidden but still focusable + keyboard-toggleable (Space), and clipped so the
   1px box can never swallow a tap meant for the control it sits behind. */
.nav-group-toggle, .nav-sheet-toggle { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; clip-path: inset(50%); }
.nav-group-head {
    display: flex; align-items: center; gap: .4rem; width: 100%; cursor: pointer;
    padding: .75rem 1.25rem .25rem; font-size: .82rem; font-weight: 500; color: var(--muted);
}
.nav-group-head:hover { color: var(--ink); }
.nav-group-head.static { cursor: default; }
.nav-group-head i { margin-left: auto; font-size: .68rem; transition: transform .15s ease; }
.nav-group-toggle:not(:checked) ~ .nav-group-head i { transform: rotate(-90deg); }
.nav-group-toggle:not(:checked) ~ .nav-items { display: none; }
.nav-group-toggle:focus-visible ~ .nav-group-head { color: var(--ink); border-radius: var(--radius); box-shadow: var(--focus-ring); }
@media (prefers-reduced-motion: reduce) { .nav-group-head i { transition: none; } }

.sidebar-foot { margin-top: auto; padding: .35rem .6rem .55rem; border-top: 1px solid var(--border); font-size: .9rem; }
.nav-signout { width: 100%; background: none; border: 0; font: inherit; font-weight: 500; text-align: left; cursor: pointer; }
/* Phone-only "More" sheet plumbing — inert (and out of the tab order) above 768px. */
.nav-sheet-toggle, .nav-more, .nav-scrim { display: none; }

.main { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.topbar { display: flex; align-items: center; gap: 1rem; padding: .6rem 1.4rem; background: var(--surface); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 20; }
.breadcrumbs { color: var(--muted); font-size: .9rem; }
.breadcrumbs a { color: var(--muted); }
.topbar-spacer { flex: 1 1 auto; }
/* Plain text: which clinic, who is signed in. Not controls, so no border or pill. */
.clinic-chip, .user-chip { display: inline-block; font-size: .9rem; font-weight: 600; color: var(--ink); white-space: nowrap; }
.user-chip { font-weight: 500; color: var(--muted); }
/* Global search: the one pill in the app, so it reads as a search field at a glance. */
.topbar-search { position: relative; flex: 0 1 320px; min-width: 170px; }
.topbar-search i { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: .85rem; pointer-events: none; }
.topbar-search input { width: 100%; padding: .35rem .8rem .35rem 2rem; border: 1px solid var(--border); border-radius: 20px; background: var(--surface2); font: inherit; font-size: .85rem; }
.topbar-search input::placeholder { color: var(--muted); }
.topbar-search input:focus { background: var(--surface); border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px rgba(85,66,127,.22); }
.content { padding: 1.4rem; flex: 1 1 auto; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.1rem; }
.page-head .subtitle { color: var(--muted); margin: .2rem 0 0; font-size: .92rem; }
/* A page head or toolbar never wraps a button's label onto two lines; the row wraps instead. */
.page-head .btn-g, .toolbar .btn-g, .toolbar .seg button { white-space: nowrap; }

/* ---- Cards ----------------------------------------------------------------- */
.g-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }
.g-card-head { padding: .85rem 1.1rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: .75rem; }
.g-card-head h2 { font-size: 1.05rem; font-weight: 600; margin: 0; }
.g-card-body { padding: 1.1rem; }
.g-card-tools { margin-left: auto; display: flex; gap: .5rem; align-items: center; }

/* ---- KPI stat cards -------------------------------------------------------- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1rem; margin-bottom: 1.3rem; }
.kpi-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.1rem; box-shadow: var(--shadow); }
.kpi-card.alert { border-color: var(--red); background: var(--red-bg); }
.kpi-label { color: var(--muted); font-size: .85rem; font-weight: 500; }
.kpi-value { font-size: 1.75rem; font-weight: 600; line-height: 1.1; margin: .25rem 0 .1rem; font-variant-numeric: tabular-nums; }
.kpi-sub { color: var(--muted); font-size: .82rem; }
.kpi-trend { font-size: .8rem; font-weight: 600; }

/* ---- Figure row: a line of plain figures under a heading (Reports), not a row of tiles ---- */
.fig-row { display: flex; flex-wrap: wrap; gap: 1rem 2.75rem; margin: 0 0 1.5rem; padding: 0 0 1.25rem; border-bottom: 1px solid var(--border); }
.fig { min-width: 0; }
.fig-label { color: var(--muted); font-size: .85rem; }
.fig-val { font-size: 1.5rem; font-weight: 600; line-height: 1.25; margin-top: .1rem; }
.fig-val .kpi-trend { font-size: .8rem; margin-left: .3rem; vertical-align: middle; }
.fig-sub { color: var(--muted); font-size: .8rem; }
.fig.alert .fig-val { color: var(--red); }

/* ---- Monthly SMS quota meter (dashboard widget) ---------------------------- */
.sms-meter { height: 8px; background: var(--surface2); border: 1px solid var(--border); border-radius: 3px; overflow: hidden; }
.sms-meter-fill { height: 100%; transition: width .3s ease; }
.sms-meter-fill.ok { background: var(--green); }
.sms-meter-fill.warn { background: var(--amber); }
.sms-meter-fill.alert { background: var(--red); }
.sms-meter-legend { display: flex; justify-content: space-between; gap: .5rem; margin-top: .5rem; font-size: .9rem; color: var(--muted); }
.sms-meter-legend .num { font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .sms-meter-fill { transition: none; } }

/* ---- Patient Overview tab — compact, scannable (scoped to .ov-stack) ------- */
.ov-stack { display: flex; flex-direction: column; gap: 1rem; }
.ov-stack .kpi-grid { margin-bottom: 0; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); }
/* A record's figures as one line of text: "Completed visits 4 · Upcoming 1 · No-shows 0 · Files 2". */
.facts-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .55rem; margin: 0; font-size: .95rem; color: var(--muted); }
.facts-row strong { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; margin-left: .15rem; }
.facts-row .red-text strong { color: var(--red); }
.facts-row .sep { opacity: .55; }
/* An empty section: its one line of text and its action on the same row. */
.empty-row { display: flex; align-items: center; justify-content: space-between; gap: .5rem .75rem; flex-wrap: wrap; color: var(--muted); font-size: .92rem; }
.ov-stack .kpi-card { display: flex; align-items: center; gap: .7rem; padding: .7rem .8rem; }
.ov-stack .kpi-value { font-size: 1.65rem; margin: .05rem 0 0; }
.ov-stack .kpi-label { font-size: .8rem; }
.ov-stack .kpi-sub { font-size: .76rem; line-height: 1.25; }
.kpi-ico { width: 36px; height: 36px; border-radius: var(--radius); background: var(--brand-bg); color: var(--brand); display: flex; align-items: center; justify-content: center; font-size: 1.05rem; flex: 0 0 auto; }
.kpi-card.alert .kpi-ico { background: var(--red-bg); color: var(--red); }
.kpi-body { min-width: 0; }
.ov-stack .g-card-head { padding: .7rem 1rem; }
.ov-stack .g-card-head h2 { font-size: 1.02rem; display: flex; align-items: center; gap: .5rem; }
.ov-stack .g-card-head h2 .bi { color: var(--brand); font-size: .95em; }
.ov-stack .g-card-body { padding: .85rem 1rem; }
.ov-stack .kv { grid-template-columns: 150px 1fr; gap: .35rem 1rem; font-size: .92rem; }
.kpi-trend.up { color: var(--green); }
.kpi-trend.down { color: var(--red); }

/* ---- Tables ---------------------------------------------------------------- */
.g-table { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.g-table thead th { text-align: left; padding: .55rem .8rem; color: var(--muted); font-weight: 600; border-bottom: 1px solid var(--border); white-space: nowrap; font-size: 13px; }
.g-table tbody td { padding: .65rem .8rem; border-bottom: 1px solid var(--surface3); }
.g-table tbody tr:hover { background: var(--surface2); }
.g-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.g-table a.primary-link { font-weight: 600; }
/* Row actions are always visible (not hover-only) for discoverability (QA P3). */
.row-actions { display: inline-flex; gap: .25rem; opacity: .8; transition: opacity .12s; }
.g-table tbody tr:hover .row-actions { opacity: 1; }
.icon-btn { border: none; background: transparent; color: var(--muted); cursor: pointer; padding: .25rem .4rem; border-radius: var(--radius); }
.icon-btn:hover { background: var(--surface3); color: var(--ink); }
.icon-btn.danger:hover { color: var(--red); }
.amber-text { color: var(--amber); font-weight: 600; }
.red-text { color: var(--red); font-weight: 600; }
.g-table tr.row-muted td { opacity: .6; }

/* ---- Badges ---------------------------------------------------------------- */
.badge-pill { display: inline-block; padding: .15rem .45rem; border-radius: 4px; font-size: .78rem; font-weight: 600; white-space: nowrap; }
/* Plain status text with a 6px colour dot: what StatusBadge renders. The dot carries the colour,
   the text stays ink, so a column of statuses reads as text, not as a row of stickers. */
.status { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }
.dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.dot.b-navy { background: var(--navy); } .dot.b-green { background: var(--green); } .dot.b-amber { background: var(--amber); }
.dot.b-red { background: var(--red); } .dot.b-teal { background: var(--brand); } .dot.b-pink { background: var(--st-arrived); }
.dot.s-sched { background: var(--st-sched); } .dot.s-confirmed { background: var(--st-confirmed); } .dot.s-completed { background: var(--st-completed); }
.dot.s-cancelled { background: var(--st-cancelled); } .dot.s-noshow { background: var(--st-noshow); } .dot.s-resched { background: var(--st-resched); }
.dot.s-arrived { background: var(--st-arrived); }
.b-navy { background: var(--navy-bg); color: var(--navy); }
.b-green { background: var(--green-bg); color: var(--green); }
.b-amber { background: var(--amber-bg); color: var(--amber); }
.b-red { background: var(--red-bg); color: var(--red); }
.b-teal { background: var(--brand-bg); color: var(--brand); }
.b-pink { background: #fbeaf5; color: var(--st-arrived); }

/* ---- Buttons --------------------------------------------------------------- */
.btn-g { display: inline-flex; align-items: center; gap: .4rem; padding: .45rem .85rem; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); color: var(--ink); font-weight: 600; font-size: .88rem; line-height: 1.3; cursor: pointer; }
.btn-g:hover { background: var(--surface2); text-decoration: none; }
.btn-g.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-g.primary:hover { background: var(--brand-deep); border-color: var(--brand-deep); }
.btn-g.danger { background: var(--red); border-color: var(--red); color: #fff; }
.btn-g.danger:hover { background: #b93a33; border-color: #b93a33; }
.btn-g:disabled { opacity: .55; cursor: not-allowed; }
.btn-sm { padding: .3rem .6rem; font-size: .82rem; }
.btn-spinner { width: 14px; height: 14px; border: 2px solid rgba(255,255,255,.5); border-top-color: #fff; border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- Forms ----------------------------------------------------------------- */
.field { margin-bottom: 1rem; }
.field label { display: block; font-weight: 600; font-size: .85rem; margin-bottom: .3rem; }
.field .required { color: var(--red); }
.field input, .field select, .field textarea { width: 100%; padding: .5rem .65rem; border: 1px solid var(--border); border-radius: var(--radius); font: inherit; background: var(--surface); }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible, .btn-g:focus-visible, .nav-link-item:focus-visible, a:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.field .err { color: var(--red); font-size: .8rem; margin-top: .25rem; }
/* Blazor's <ValidationMessage>/<ValidationSummary> splat AdditionalAttributes and THEN set their
   own class, so an author-supplied class="err" never reaches the DOM — the rendered elements are
   always .validation-message / .validation-errors. Style those directly, unscoped, or validation
   errors render as unstyled black bullet text everywhere outside .auth-body. */
.validation-errors { list-style: none; margin: 0 0 .9rem; padding: 0; }
.validation-message { color: var(--red); font-size: .82rem; margin-top: .25rem; }
.field input.field-invalid, .field select.field-invalid, .field textarea.field-invalid { border-color: var(--red); background: var(--red-bg); }
.field input.invalid, .field select.invalid, .field textarea.invalid { border-color: var(--red); }
.field-hint { color: var(--muted); font-size: .8rem; margin-top: .25rem; }
.field-hint.wh-warn { color: var(--red); font-weight: 600; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
.color-field { display: flex; gap: .5rem; align-items: center; }
.color-field input[type=color] { width: 46px; height: 38px; padding: 2px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); cursor: pointer; flex: 0 0 auto; }
.color-field .color-hex { flex: 1 1 auto; font-variant-numeric: tabular-nums; }
.type-swatch { display: inline-block; width: 16px; height: 16px; border-radius: 4px; border: 1px solid var(--border); vertical-align: middle; }
.row-click { cursor: pointer; }
.row-click:hover { background: var(--surface2); }
.locked-field { padding: .5rem .65rem; background: var(--surface2); border: 1px dashed var(--border); border-radius: var(--radius); color: var(--muted); }
/* Inline checkbox + label (compact admin/onboarding toggles). */
.chk { display: inline-flex; align-items: center; gap: .5rem; font-weight: 600; font-size: .85rem; margin: .4rem 0; cursor: pointer; }
.chk input[type=checkbox] { width: auto; }
/* One-time credential panel (operator onboarding + user add/reset). */
.cred-panel { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface2); padding: 1rem; }
.cred-head { display: flex; align-items: center; gap: .45rem; font-weight: 700; color: var(--brand); margin-bottom: .4rem; }
.cred-head i { color: var(--green); }
.cred-row { display: flex; align-items: center; gap: .6rem; padding: .35rem 0; border-top: 1px solid var(--border); }
.cred-row span { width: 110px; color: var(--muted); font-size: .82rem; }
.cred-row code { font-size: .95rem; font-weight: 600; user-select: all; }

/* ---- Type-to-search combobox (autocomplete) -------------------------------- */
.combo { position: relative; }
.combo-list { position: absolute; left: 0; right: 0; top: 100%; margin-top: 3px; z-index: 30; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-float); max-height: 260px; overflow-y: auto; list-style: none; padding: .25rem; }
.combo-list li { padding: .45rem .55rem; border-radius: 6px; cursor: pointer; display: flex; align-items: baseline; gap: .5rem; }
.combo-list li:hover { background: var(--surface2); }
.combo-list .combo-sub { color: var(--muted); font-size: .8rem; }
.combo-list .combo-empty { color: var(--muted); cursor: default; }
.combo-list .combo-empty:hover { background: transparent; }

/* ---- Drawer ---------------------------------------------------------------- */
.drawer-overlay { position: fixed; inset: 0; background: var(--scrim); z-index: 1000; animation: fade .15s; }
@keyframes fade { from { opacity: 0; } }
.drawer { position: fixed; top: 0; right: 0; height: 100vh; background: var(--surface); border-left: 1px solid var(--border); z-index: 1001; display: flex; flex-direction: column; animation: slidein .2s ease; max-width: 96vw; }
@keyframes slidein { from { transform: translateX(100%); } }
.drawer-head { padding: 1rem 1.2rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: .75rem; }
.drawer-head h3 { margin: 0; font-size: 1.1rem; }
.drawer-body { padding: 1.2rem; overflow-y: auto; flex: 1 1 auto; }
.drawer-foot { padding: .85rem 1.2rem; border-top: 1px solid var(--border); display: flex; gap: .6rem; justify-content: flex-end; }

/* ---- Modal (confirm) ------------------------------------------------------- */
.modal-overlay { position: fixed; inset: 0; background: var(--scrim); z-index: 1100; display: flex; align-items: center; justify-content: center; animation: fade .15s; }
.modal-box { background: var(--surface); border-radius: var(--radius); width: 440px; max-width: 92vw; box-shadow: var(--shadow-float); }
.modal-box .mh { padding: 1.1rem 1.2rem .25rem; font-size: 1.1rem; font-weight: 600; }
.modal-box .mb { padding: .25rem 1.2rem 1rem; color: var(--ink); }
.modal-box .mf { padding: .85rem 1.2rem; display: flex; gap: .6rem; justify-content: flex-end; border-top: 1px solid var(--border); }

/* ---- Empty / skeleton ------------------------------------------------------ */
.empty-state { text-align: center; padding: 1.6rem 1rem; }
.empty-state-title { font-size: .95rem; font-weight: 600; margin: 0 0 .2rem; }
.empty-state-body { color: var(--muted); font-size: .9rem; max-width: 420px; margin: 0 auto .75rem; }
.empty-state > .btn-g, .empty-state > a.btn-g { margin-top: .35rem; }
.skeleton-row { height: 44px; background: linear-gradient(90deg, var(--surface2) 25%, #F0EDF8 50%, var(--surface2) 75%); background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: 4px; margin-bottom: 4px; }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton-row, .btn-spinner { animation: none; } }

/* ---- Toasts + banners ------------------------------------------------------ */
.toast-host { position: fixed; top: 1rem; right: 1rem; z-index: 1200; display: flex; flex-direction: column; gap: .5rem; }
.toast { min-width: 280px; max-width: 380px; padding: .7rem .9rem; border-radius: var(--radius); color: #fff; box-shadow: var(--shadow-float); font-size: .9rem; animation: slidein .2s; }
.toast.success { background: var(--green); }
.toast.error { background: var(--red); }
.toast.warning { background: var(--amber); }
.toast.info { background: var(--brand); }
.banner { padding: .65rem .9rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: .9rem; display: flex; align-items: center; gap: .55rem; }
.banner.warn { background: var(--amber-bg); color: #8a5a0c; border: 1px solid #f0d9b0; }
.banner.danger { background: var(--red-bg); color: #9c2b25; border: 1px solid #f0c0bd; }
.banner.info { background: var(--brand-bg); color: var(--brand); border: 1px solid #E0D8F2; }
.banner.ok { background: var(--green-bg); color: #1c6b3c; border: 1px solid #bfe3cb; }
.alert-error { background: var(--red-bg); color: #9c2b25; padding: .7rem .9rem; border-radius: var(--radius); border: 1px solid #f0c0bd; margin-bottom: 1rem; }

/* Blazor circuit error UI. MUST default to display:none — the framework toggles it to
   display:block (inline style) only on an actual unhandled circuit error. Without this rule
   the banner is permanently visible at the foot of every page (looks like a constant crash). */
#blazor-error-ui {
    display: none;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 2000;
    background: var(--red-bg); color: #9c2b25; border-top: 1px solid #f0c0bd;
    padding: .7rem 1.25rem; font-size: .9rem;
}
#blazor-error-ui .reload { color: #9c2b25; font-weight: 600; text-decoration: underline; margin-left: .4rem; }
#blazor-error-ui .dismiss { cursor: pointer; float: right; padding-left: 1rem; }

/* ---- Search + toolbar ------------------------------------------------------ */
.toolbar { display: flex; gap: .6rem; align-items: center; margin-bottom: 1rem; flex-wrap: wrap; }
.search-box { position: relative; flex: 0 0 280px; }
.search-box i { position: absolute; left: .65rem; top: 50%; transform: translateY(-50%); color: var(--muted); }
.search-box input { width: 100%; padding: .5rem .65rem .5rem 2rem; border: 1px solid var(--border); border-radius: var(--radius); font: inherit; }
.pager { display: flex; align-items: center; gap: .5rem; justify-content: space-between; margin-top: .8rem; color: var(--muted); font-size: .85rem; }
.pager .pages { display: flex; gap: .25rem; }
.chips { display: flex; gap: .4rem; flex-wrap: wrap; }
.chip { background: var(--brand-bg); color: var(--brand); padding: .15rem .5rem; border-radius: 4px; font-size: .8rem; display: inline-flex; gap: .3rem; align-items: center; }
/* A chip that removes the filter it names. */
.chip-btn { border: 0; font: inherit; font-size: .82rem; font-weight: 600; padding: .3rem .55rem; cursor: pointer; white-space: nowrap; }
.chip-btn:hover { background: #E8E1F6; }
.chip-btn i { font-size: .7rem; }

/* ---- Menu button (tertiary actions, view options) ------------------------------ */
.menu { position: relative; display: inline-flex; }
.menu-chev { font-size: .68rem; color: var(--muted); margin-left: .1rem; }
.menu-backdrop { display: none; position: fixed; inset: 0; z-index: 40; }
.menu-pop { display: none; position: absolute; top: calc(100% + 4px); left: 0; z-index: 41; min-width: 190px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-float); padding: .3rem; }
.menu-pop.right { left: auto; right: 0; }
.menu.open .menu-backdrop, .menu.open .menu-pop { display: block; }
.menu-item { display: flex; align-items: center; gap: .55rem; width: 100%; padding: .45rem .6rem; border: 0; background: none; border-radius: 4px; font: inherit; font-size: .9rem; color: var(--ink); text-align: left; cursor: pointer; white-space: nowrap; }
.menu-item:hover, .menu-item:focus-visible { background: var(--surface2); color: var(--ink); text-decoration: none; outline: none; }
.menu-item > i { width: 16px; flex: 0 0 16px; text-align: center; color: var(--muted); }
.menu-item > i.bi-check2 { color: var(--brand); }
.menu-sep { height: 1px; background: var(--border); margin: .3rem .2rem; }

/* ---- Diary head + toolbar: one primary, nothing wraps at 1280px and up ------------- */
.diary-head { align-items: center; }
.head-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.diary-toolbar { gap: .5rem .75rem; margin-bottom: .8rem; }
.tb-date, .tb-view { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.tb-view { flex: 1 1 auto; }
.tb-date input[type=date] { padding: .3rem .45rem; border: 1px solid var(--border); border-radius: var(--radius); font: inherit; font-size: .88rem; background: var(--surface); }
.diary-toolbar .seg { flex-wrap: nowrap; }

/* ---- Detail header --------------------------------------------------------- */
.detail-meta { color: var(--muted); font-size: .9rem; display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.detail-meta .sep { opacity: .5; }
.kv { display: grid; grid-template-columns: 180px 1fr; gap: .5rem 1rem; }
.kv dt { color: var(--muted); font-weight: 600; }
.kv dd { margin: 0; }

/* ---- Responsive ------------------------------------------------------------ */
/* Tablet: collapse the sidebar to an icon rail. Groups are forced open here — a
   collapsed group would be unreachable once its header is hidden. */
@media (max-width: 1100px) and (min-width: 769px) {
    .sidebar { width: 68px; flex-basis: 68px; }
    .nav-link-item span, .nav-group-head, .nav-group-toggle { display: none; }
    .sidebar-brand { justify-content: center; padding: .95rem .4rem; }
    .sidebar-brand .brand-word { display: none; }
    .sidebar-brand .brand-mark { display: block; }
    .nav-link-item { justify-content: center; padding: .55rem 0; }
    .nav-link-item i { width: auto; font-size: 1.05rem; }
    .nav-group-toggle:not(:checked) ~ .nav-items { display: flex; }
    .nav-group { margin-top: .35rem; padding-top: .35rem; border-top: 1px solid var(--border); }
    .sidebar-foot { padding: .35rem .3rem .5rem; }
}

/* Mobile: the sidebar becomes a five-slot bottom tab bar — the four everyday
   destinations plus "More", which expands the same nav into a full-height sheet. Content
   goes single-column and wide tables scroll inside their cards. */
@media (max-width: 768px) {
    html, body { overflow-x: hidden; }
    .app-shell { flex-direction: column; }

    .sidebar {
        position: fixed; top: auto; bottom: 0; left: 0; right: 0;
        width: 100%; height: auto; flex: none;
        flex-direction: row; align-items: stretch;
        padding-bottom: env(safe-area-inset-bottom);
        z-index: 1000; border-right: 0; border-top: 1px solid var(--border);
    }
    .sidebar-brand, .sidebar-foot { display: none; }
    .nav-scroll { display: flex; flex: 1 1 auto; overflow: visible; padding: 0; }
    /* `display: contents` dissolves the groups so the four `.nav-tab` links become direct flex
       items of the bar wherever they sit in the desktop tree — the phone bar and the desktop
       grouping stay independent without a second copy of the menu. */
    .nav-group, .nav-items { display: contents; }
    /* Must out-specify the desktop collapse rule (.nav-group-toggle:not(:checked) ~ .nav-items),
       or a tab living inside a collapsed group — Diary, Requests — never reaches the bar. */
    .nav-group .nav-group-toggle:not(:checked) ~ .nav-items { display: contents; }
    .nav-group-head, .nav-group-toggle { display: none; }
    .nav-link-item { display: none; }
    .nav-link-item.nav-tab { display: flex; }
    .nav-tab.o1 { order: 1; } .nav-tab.o2 { order: 2; } .nav-tab.o3 { order: 3; } .nav-tab.o4 { order: 4; }
    /* Tab: icon over a short label. Labels earn their pixels on a phone — an unlabelled
       icon row is the single biggest source of "where do I find X" on mobile. */
    .nav-link-item {
        flex: 1 1 0; min-width: 0; flex-direction: column; justify-content: center; gap: 2px;
        padding: .45rem .15rem .5rem; min-height: 56px; border-left-width: 0; border-radius: 0;
        font-size: .66rem; font-weight: 600; line-height: 1.1; text-align: center;
    }
    .nav-link-item span { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .nav-link-item i { font-size: 1.2rem; width: auto; opacity: 1; }
    .nav-link-item.active { background: transparent; color: var(--brand); box-shadow: inset 0 2px 0 var(--brand); }

    .nav-more {
        display: flex; flex: 1 1 0; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
        min-height: 56px; padding: .45rem .15rem .5rem;
        color: var(--ink); font-size: .66rem; font-weight: 600; cursor: pointer;
    }
    .nav-more i { font-size: 1.2rem; color: var(--muted); }
    /* The checkbox is the real control behind the "More" label — hidden, but focusable. */
    .nav-sheet-toggle { display: block; }
    .nav-sheet-toggle:focus-visible ~ .sidebar .nav-more { color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent); }

    /* "More" opens the same markup as a bottom sheet — nothing is duplicated. It stops short
       of the top so the scrim behind it stays tappable, which is how a phone user expects to
       dismiss it; the X in the sheet header does the same for anyone who reaches for it. */
    .nav-sheet-toggle:checked ~ .sidebar {
        top: auto; bottom: 0; height: auto; max-height: 86dvh; flex-direction: column;
        border-radius: var(--radius-card) var(--radius-card) 0 0;
    }
    .nav-sheet-toggle:checked ~ .sidebar .sidebar-brand { display: flex; flex: 0 0 auto; }
    .nav-sheet-toggle:checked ~ .sidebar .sheet-close { display: inline-flex; margin-left: auto; padding: .3rem .45rem; color: var(--ink); font-size: 1.05rem; cursor: pointer; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-scroll { flex: 1 1 auto; min-height: 0; flex-direction: column; overflow-y: auto; }
    .nav-sheet-toggle:checked ~ .sidebar .sidebar-foot { flex: 0 0 auto; }
    /* In the sheet the groups reassemble: `display: contents` is undone, every link comes back,
       and the tab-bar ordering is reset so each group lists in its authored order. */
    .nav-sheet-toggle:checked ~ .sidebar .nav-group { display: block; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-group-head { display: flex; }
    /* The sheet exists to show what the tab bar cannot — every group opens. */
    .nav-sheet-toggle:checked ~ .sidebar .nav-items,
    .nav-sheet-toggle:checked ~ .sidebar .nav-group-toggle:not(:checked) ~ .nav-items { display: flex; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-group-toggle ~ .nav-group-head i { display: none; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-items { flex-direction: column; padding: .3rem .6rem; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-link-item {
        display: flex; order: 0;
        flex: 0 0 auto; flex-direction: row; justify-content: flex-start; gap: .7rem; text-align: left;
        min-height: 44px; padding: .6rem .7rem; border-radius: var(--radius); font-size: .95rem; font-weight: 500;
    }
    .nav-sheet-toggle:checked ~ .sidebar .nav-link-item i { font-size: 1rem; width: 18px; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-link-item.active { box-shadow: none; background: var(--brand-bg); }
    .nav-sheet-toggle:checked ~ .sidebar .sidebar-foot { display: block; }
    .nav-sheet-toggle:checked ~ .sidebar .nav-more { display: none; }
    .nav-sheet-toggle:checked ~ .nav-scrim { display: block; position: fixed; inset: 0; background: var(--scrim); z-index: 999; }

    .main { padding-bottom: calc(62px + env(safe-area-inset-bottom)); min-width: 0; }
    .content { padding: .9rem .8rem calc(74px + env(safe-area-inset-bottom)); }

    .topbar { padding: .5rem .8rem; gap: .4rem; flex-wrap: wrap; }
    .clinic-chip, .user-chip { font-size: .82rem; max-width: 46vw; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
    /* Search drops to its own full-width row rather than squeezing the two chips off-screen. */
    .topbar-search { order: 3; flex: 1 1 100%; min-width: 0; }
    .topbar-spacer { order: 2; }

    h1 { font-size: 1.35rem; }
    .page-head { flex-direction: column; align-items: stretch; gap: .7rem; }
    /* The Diary's head stays one row: title, then its two buttons. */
    .page-head.diary-head { flex-direction: row; align-items: center; justify-content: space-between; margin-bottom: .8rem; }
    /* Toolbar: the date row, then the view row. Never more than two rows before the grid. */
    .diary-toolbar .tb-date { flex: 1 1 100%; }
    .diary-toolbar .tb-date input[type=date] { flex: 1 1 auto; min-width: 0; }
    .diary-toolbar .tb-view { flex: 1 1 100%; }
    .sched { max-height: max(320px, calc(100dvh - 360px)); }
    .page-head .g-card-tools, .page-head > div:last-child { display: flex; flex-wrap: wrap; gap: .5rem; }

    .form-grid, .kv { grid-template-columns: 1fr; }
    .kv { gap: .15rem .5rem; margin-bottom: .4rem; }
    .drawer { width: 100vw !important; }

    .toolbar { gap: .5rem; }
    .search-box { flex: 1 1 100%; }

    /* Wide tables scroll horizontally within the card, not the whole viewport. */
    .g-card-body { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .g-table { white-space: nowrap; }
    .kpi-grid { gap: .7rem; }
}

/* ---- Print ----------------------------------------------------------------- */
@media print { .sidebar, .nav-scrim, .topbar, .no-print, .row-actions { display: none !important; } .content { padding: 0; } .g-card { box-shadow: none; } }

.skip-link { position: absolute; left: -999px; }
.skip-link:focus { left: 1rem; top: .5rem; z-index: 2000; background: #fff; padding: .5rem; border-radius: 6px; }

/* ---- Auth pages (branded login/register, no app shell) ---------------------- */
.auth-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1.5rem 16px; background: var(--surface2); }
.auth-card { width: 100%; max-width: 400px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); padding: 1.6rem 1.6rem 1.3rem; }
.auth-brand { display: flex; align-items: center; gap: .6rem; font-weight: 700; font-size: 1.3rem; color: var(--brand); margin: .1rem 0 1.3rem; }
.auth-brand .auth-logo { height: 48px; width: auto; margin-left: -4px; }
/* 1.20 — "Powered by Rantevou" mark on patient-facing public pages (Single plan only). */
.powered-by { text-align: center; margin-top: 1.3rem; padding-top: .9rem; border-top: 1px solid var(--border); font-size: .78rem; color: var(--muted); }
.powered-by strong { color: var(--brand); }
.confirm-list { list-style: none; margin: 0 0 1.1rem; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.confirm-list li { display: flex; align-items: center; gap: .7rem; padding: .6rem .8rem; border-bottom: 1px solid var(--border); font-size: .95rem; }
.confirm-list li:last-child { border-bottom: none; }
.confirm-list .confirm-time { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--navy); min-width: 48px; }
/* Deposit-to-confirm on /c/{token}: the ask, the one-sentence terms ABOVE the button, the button. */
.card-hold-box { border: 1px solid var(--border); border-radius: var(--radius); padding: .9rem .95rem; margin: 0 0 .9rem; background: var(--surface); }
.card-hold-ask { margin: 0 0 .6rem; font-size: .95rem; display: flex; gap: .5rem; align-items: flex-start; }
.card-hold-ask i { color: var(--brand); margin-top: .15rem; }
.card-hold-terms { margin: 0 0 .75rem; font-size: .82rem; line-height: 1.45; color: var(--muted); }
.card-hold-btn { width: 100%; justify-content: center; }
.card-hold-alt { margin: .6rem 0 0; font-size: .82rem; color: var(--muted); text-align: center; }
.card-hold-note { font-size: .85rem; color: var(--muted); margin: 0 0 1rem; }
.card-hold-done { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .4rem; margin-bottom: .4rem; }
.card-hold-done > i { font-size: 2rem; color: var(--green); }
.card-hold-done ~ .auth-sub, .card-hold-done ~ .card-hold-note { text-align: center; }
.card-hold-waiting { text-align: center; padding: .6rem 0 .4rem; }
.card-hold-waiting .btn-spinner { display: inline-block; width: 1.4rem; height: 1.4rem; margin-bottom: .6rem; border-color: var(--navy-bg); border-top-color: var(--brand); }
.auth-title { font-size: 1.35rem; margin: 0; }
/* Blazor enhanced navigation programmatically focuses the page's h1 (tabindex="-1") on every
   load so screen readers announce it — not reachable via Tab, so no visible ring is needed. */
.auth-title:focus { outline: none; }
.auth-sub { color: var(--muted); margin: .15rem 0 1.2rem; font-size: .92rem; }
.auth-body .field input { width: 100%; }
.auth-check { display: flex; align-items: center; gap: .45rem; font-size: .88rem; font-weight: 500; margin: .2rem 0 1.1rem; cursor: pointer; }
.auth-check input { width: auto; }
.auth-submit { width: 100%; justify-content: center; padding: .6rem; font-size: .95rem; }
.auth-links { margin-top: 1rem; text-align: center; font-size: .88rem; }
.auth-foot { margin-top: 1.4rem; padding-top: 1rem; border-top: 1px solid var(--surface3); text-align: center; color: var(--muted); font-size: .78rem; }
.auth-body .validation-message, .auth-body .text-danger { color: var(--red); font-size: .82rem; }

/* ---- Brand override for Bootstrap-scaffolded Identity (auth) pages (QA P3) ---- */
.btn-primary { background-color: var(--brand); border-color: var(--brand); }
.btn-primary:hover, .btn-primary:focus, .btn-primary:active { background-color: var(--brand-deep); border-color: var(--brand-deep); }
.btn-link { color: var(--brand); }
a { color: var(--brand); }

/* ---- Account management (Identity "Manage" area) — match the app shell ------ */
.acct-manage { max-width: 940px; }

/* Content card */
.acct-manage .manage-body { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.2rem 1.3rem; }
.acct-manage .manage-body h3 { font-size: 1.25rem; font-weight: 700; margin: 0 0 1rem; }

/* ---- Account area — design-system markup ------------------------------------
   The Bootstrap shim that used to sit here (.nav-pills, .form-control, .form-floating,
   .alert-*, .btn-danger overrides) was deleted with the markup it targeted — every one of
   those selectors had zero remaining references once the scaffold pages were converted.
   This area lives INSIDE the app shell,
   so nothing here may widen the page: the nav is a rail on desktop and a scrolling
   strip on a phone, and wide content scrolls inside its own box. */
.acct-grid { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 1.1rem; align-items: start; }

/* Left rail — same vocabulary as the app's other selected states (plum tint, no pill). */
.acct-nav { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.acct-nav-link {
    display: block; padding: .5rem .75rem; border-radius: var(--radius); border: 1px solid transparent;
    color: var(--ink); font-weight: 600; font-size: .9rem; line-height: 1.3;
}
.acct-nav-link:hover { background: var(--surface2); text-decoration: none; }
.acct-nav-link.active { background: var(--brand-bg); color: var(--brand); border-color: var(--border); }

/* The scaffold pages head their sections with h3/h4 and plain paragraphs. */
.acct-manage .manage-body h4 { font-size: 1.05rem; font-weight: 700; margin: 1.4rem 0 .5rem; }
.acct-manage .manage-body p { margin: 0 0 .8rem; }
.acct-section { border-top: 1px solid var(--border); margin-top: 1.2rem; padding-top: 1rem; }
.acct-section:first-child { border-top: 0; margin-top: 0; padding-top: 0; }

/* A form in a full-width card still wants a readable measure. */
.acct-form { max-width: 460px; }
.acct-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .9rem; }
/* Identity posts each button from its own <form>; they still have to read as one row. */
.acct-actions form { display: inline-flex; margin: 0; }
.acct-note { color: var(--muted); font-size: .88rem; }
.acct-providers { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }

/* Recovery codes tile and wrap — a single long row would push the card sideways. */
.acct-codes { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: .4rem; margin-top: .9rem; }
.acct-code {
    display: block; padding: .4rem .55rem; border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface2); color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .92rem; font-weight: 600; letter-spacing: .5px; text-align: center;
    -webkit-user-select: all; user-select: all; overflow-wrap: anywhere;
}

/* Wide content (the external-logins table) scrolls in its own box, never the body. */
.acct-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.acct-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.acct-table th, .acct-table td { padding: .55rem .6rem; text-align: left; border-bottom: 1px solid var(--border); }
.acct-table th { font-size: 13px; color: var(--muted); font-weight: 600; }
.acct-table tbody tr:last-child td { border-bottom: 0; }

/* .banner is a single centred row; multi-paragraph copy needs one block child so the
   paragraphs stack instead of lining up beside each other as flex items. */
.banner-body { min-width: 0; }
.banner-body > :first-child { margin-top: 0; }
.banner-body > :last-child { margin-bottom: 0; }
.banner-body p { margin: .25rem 0 0; }

@media (max-width: 768px) {
    .acct-grid { grid-template-columns: minmax(0, 1fr); gap: .8rem; }
    /* Six links will not fit across a phone, so the rail becomes a strip that scrolls
       itself. minmax(0, 1fr) on the grid track is what lets it shrink rather than
       stretch the page — without it `overflow-x` here would never engage. */
    .acct-nav {
        flex-direction: row; gap: .25rem; overflow-x: auto; -webkit-overflow-scrolling: touch;
        padding-bottom: .35rem; border-bottom: 1px solid var(--border);
    }
    .acct-nav-link { flex: 0 0 auto; white-space: nowrap; padding: .4rem .65rem; font-size: .85rem; }
    .acct-manage .manage-body { padding: .9rem 1rem; }
    .acct-form { max-width: none; }
    .acct-codes { grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr)); }
    .acct-table { white-space: nowrap; }
}

/* ---- Sortable + filterable table headers (QA P3) ---------------------------- */
.g-table th.sortable .th-sort { cursor: pointer; user-select: none; display: inline-flex; align-items: center; }
.g-table th.sortable .th-sort:hover { color: var(--ink); }
.g-table th.sortable .sort-ind { opacity: .5; font-size: .7rem; margin-left: .2rem; }
.g-table th.sortable.sorted .sort-ind { opacity: 1; color: var(--brand); }
.g-table th .th-filter { display: block; width: 100%; margin-top: .35rem; padding: .25rem .4rem; border: 1px solid var(--border); border-radius: 6px; font: inherit; font-size: .8rem; font-weight: 400; text-transform: none; letter-spacing: 0; }

/* ---- Excel-style column filter (FilterHeader) ------------------------------- */
.g-table th.sortable { position: relative; }
.th-wrap { display: inline-flex; align-items: center; gap: .25rem; }
.th-wrap .th-label { cursor: pointer; user-select: none; display: inline-flex; align-items: center; }
.th-wrap .th-label:hover { color: var(--ink); }
.th-funnel { border: none; background: none; cursor: pointer; color: var(--muted); padding: .1rem .2rem; border-radius: 4px; line-height: 1; font-size: .82rem; }
.th-funnel:hover { background: var(--surface3); color: var(--ink); }
.th-funnel.active { color: var(--brand); }
.cf-backdrop { position: fixed; inset: 0; z-index: 1150; background: transparent; }
.cf-pop { position: absolute; top: 100%; left: 0; margin-top: 4px; z-index: 1160; width: 250px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-float); padding: .5rem; text-transform: none; letter-spacing: 0; font-weight: 400; font-size: .85rem; color: var(--ink); }
.cf-sort { display: flex; gap: .35rem; margin-bottom: .45rem; }
.cf-sort button { flex: 1; border: 1px solid var(--border); background: var(--surface); border-radius: 6px; padding: .3rem .35rem; cursor: pointer; font-size: .78rem; display: inline-flex; align-items: center; justify-content: center; gap: .25rem; color: var(--ink); }
.cf-sort button:hover { background: var(--surface2); }
.cf-search { width: 100%; padding: .35rem .5rem; border: 1px solid var(--border); border-radius: 6px; font: inherit; font-size: .82rem; margin-bottom: .4rem; }
.cf-list { max-height: 220px; overflow-y: auto; border: 1px solid var(--border); border-radius: 6px; padding: .25rem; margin-bottom: .45rem; }
.cf-item { display: flex; align-items: center; gap: .45rem; padding: .25rem .35rem; border-radius: 4px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cf-item:hover { background: var(--surface2); }
.cf-item input { flex: 0 0 auto; }
.cf-item span { overflow: hidden; text-overflow: ellipsis; }
.cf-all { border-bottom: 1px solid var(--border); border-radius: 0; margin-bottom: .2rem; padding-bottom: .35rem; }
.cf-empty { color: var(--muted); font-size: .8rem; padding: .4rem; text-align: center; }
.cf-actions { display: flex; gap: .4rem; justify-content: flex-end; }

/* ---- Time-grid scheduler (day = chairs, week = days) (QA P2-4) --------------- */
.cal-time { font-weight: 700; font-variant-numeric: tabular-nums; }
.sched-range { color: var(--muted); font-weight: 600; font-size: .85rem; margin-left: .3rem; }
/* The grid scrolls inside its own box, so the page head, toolbar and attention line stay on
   screen while the day scrolls under the sticky column headers. */
.sched { overflow: auto; max-height: max(360px, calc(100vh - 275px)); border: 1px solid var(--border); border-radius: var(--radius); }
.sched-grid { display: grid; user-select: none; min-width: 640px; }
.sched-corner, .sched-dayhead { position: sticky; top: 0; background: var(--surface2); border-bottom: 1px solid var(--border); padding: .45rem; font-size: .85rem; font-weight: 600; color: var(--ink); z-index: 7; }
/* The corner and the time gutter stay pinned while wide days scroll sideways (phones). */
.sched-corner { left: 0; z-index: 8; }
.sched-dayhead { text-align: center; border-left: 1px solid var(--border); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 1.13 — Week-view occupancy heatmap: relative to this week's own busiest day, so an empty
   day/afternoon stands out at a glance without reading a single number. Heat-N owns the
   background; "today" gets its own cue via an inset border so the two never fight over
   the same property regardless of which one is declared later in the cascade. */
.sched-dayhead.today { color: var(--brand); box-shadow: inset 0 -2px 0 var(--brand); }
.sched-dayhead.heat-0 { background: var(--surface2); }
.sched-dayhead.heat-1 { background: #F7F4FC; }
.sched-dayhead.heat-2 { background: #EFE9F8; }
.sched-dayhead.heat-3 { background: #E4DBF4; }
.sched-dayhead.heat-4 { background: #D6C9EE; }
.sched-dayhead .heat-count { display: block; font-size: .95rem; font-weight: 700; letter-spacing: 0; text-transform: none; margin-top: .1rem; }
.sched-time { position: sticky; left: 0; z-index: 6; background: var(--surface); padding: .15rem .45rem; font-size: .75rem; color: var(--muted); border-bottom: 1px solid var(--surface3); text-align: right; font-variant-numeric: tabular-nums; height: 44px; }
.sched-cell { position: relative; height: 44px; border-bottom: 1px solid var(--surface3); border-left: 1px solid var(--surface3); padding: 2px; cursor: cell; }
/* Quarter-hour rule half-way down each 30-minute row. */
.sched-cell::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px dotted var(--surface3); pointer-events: none; }
/* The current time: one hairline across every column showing today, starting in the time gutter. */
.now-line { position: absolute; left: 0; right: 0; height: 0; border-top: 2px solid var(--red); z-index: 4; pointer-events: none; }
.now-line.in-gutter { left: auto; width: 10px; right: 0; }
.now-line.in-gutter::before { content: ""; position: absolute; right: 2px; top: -5px; width: 8px; height: 8px; border-radius: 50%; background: var(--red); }
/* Outside the practitioner's (Day) / clinic's (Week) working hours — hatched to read as
   "not on shift", but still fully bookable. Diagonal lines instead of a flat grey fill. */
.sched-cell.closed { background-color: rgba(42,35,56,.03); background-image: repeating-linear-gradient(45deg, rgba(42,35,56,.07) 0, rgba(42,35,56,.07) 1px, transparent 1px, transparent 7px); }

/* Dashboard "today at a glance" — appointments beside registers. */
.glance-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 1.1rem; margin-top: 1.1rem; align-items: start; }
/* The side column stacks its short widgets rather than each claiming a grid row of its own —
   otherwise the tall card next to them leaves a column-height hole underneath. */
.glance-side { display: flex; flex-direction: column; gap: 1.1rem; min-width: 0; }
@media (max-width: 900px) { .glance-grid { grid-template-columns: 1fr; } }

/* Cash-up: open register beside its transaction list (fills the right-side space). */
.cashup-grid { display: grid; grid-template-columns: minmax(0, 520px) minmax(0, 1fr); gap: 1.1rem; align-items: start; }
.cashup-grid .txn-opening { background: var(--surface2); font-weight: 600; }
@media (max-width: 900px) { .cashup-grid { grid-template-columns: minmax(0, 1fr); } }

/* Multi-block practitioner schedule editor (Administration › Team, practitioner drawer). */
.sched-edit-list { display: flex; flex-direction: column; }
.sched-day-row { display: flex; align-items: flex-start; gap: .75rem; padding: .45rem 0; border-bottom: 1px solid var(--surface3); }
.sched-day-name { width: 42px; font-weight: 600; padding-top: .35rem; }
.sched-day-work { min-width: 96px; padding-top: .3rem; }
.sched-day-blocks { display: flex; flex-direction: column; gap: .35rem; flex: 1; }
.sched-block { display: flex; align-items: center; gap: .4rem; }
.sched-block input[type=time] { padding: .35rem .5rem; }
.sched-cell.droppable { background-color: rgba(85,66,127,.035); }
.sched-cell.droppable:hover { background: var(--brand-bg); outline: 1px dashed var(--brand); outline-offset: -2px; }
.sched-cell.sel { background: var(--brand-bg); box-shadow: inset 0 0 0 1px var(--brand); }
/* The scheduler "line" is coloured by STATUS (border + tint) and is positioned
   absolutely so it spans its real duration (09:00 + 120 min ends at 11:00). */
.sched-appt { position: absolute; z-index: 5; box-sizing: border-box; background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--st-sched); border-radius: 4px; padding: 3px 6px; font-size: .78rem; line-height: 1.3; color: var(--ink); cursor: grab; overflow: hidden; }
.sched-appt:hover { background: var(--surface2); z-index: 6; }
.sched-appt:active { cursor: grabbing; }
.appt-l1 { display: flex; align-items: center; gap: 4px; min-width: 0; white-space: nowrap; }
.appt-l1 .cal-time { font-weight: 500; color: var(--muted); flex: 0 0 auto; }
.appt-name { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.appt-l2 { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.appt-glyph { font-size: .8rem; flex: 0 0 auto; }
.appt-glyph.s-noshow, .lg-glyph.s-noshow { color: var(--st-noshow); }
.appt-glyph.s-cancelled, .lg-glyph.s-cancelled { color: var(--st-cancelled); }
.lg-glyph.s-arrived { color: var(--st-arrived); }
.sched-appt.s-sched     { border-left-color: var(--st-sched); }
.sched-appt.s-confirmed { border-left-color: var(--st-confirmed); }
.sched-appt.s-completed { border-left-color: var(--st-completed); }
.sched-appt.s-completed .appt-name { font-weight: 500; }
.sched-appt.s-cancelled { border-left-color: var(--st-cancelled); background: var(--surface2); }
.sched-appt.s-cancelled .appt-name, .sched-appt.s-noshow .appt-name { text-decoration: line-through; color: var(--muted); }
.sched-appt.s-noshow    { border-left-color: var(--st-noshow); }
.sched-appt.s-resched   { border-left-color: var(--st-resched); }
.sched-appt.s-arrived   { border-left-color: var(--st-arrived); }

/* Status legend under the toolbar. */
.sched-legend { display: flex; gap: 1.1rem; flex-wrap: wrap; margin: 0 0 .8rem; font-size: .82rem; color: var(--ink); }
.sched-legend .lg { display: inline-flex; align-items: center; gap: .35rem; }
.lg-sw { width: 3px; height: 13px; border-radius: 1px; display: inline-block; }
.lg-sw.s-sched { background: var(--st-sched); }
.lg-sw.s-confirmed { background: var(--st-confirmed); }
.lg-sw.s-completed { background: var(--st-completed); }
.lg-sw.s-cancelled { background: var(--st-cancelled); }
.lg-sw.s-noshow { background: var(--st-noshow); }
.lg-sw.s-resched { background: var(--st-resched); }
.lg-sw.s-arrived { background: var(--st-arrived); }

/* Google-sync badge on a scheduler card (green = synced, amber = out of sync). */
.appt-g { font-size: .6rem; font-weight: 700; line-height: 1; padding: 2px 3px; border-radius: 3px; background: var(--st-confirmed); color: #fff; flex: 0 0 auto; }
.appt-g.dirty { background: var(--st-noshow); }

/* Sync status pill (drawer + sync page). */
.sync-badge { display: inline-flex; align-items: center; gap: .3rem; padding: .15rem .45rem; border-radius: 4px; font-size: .76rem; font-weight: 600; }
.sync-badge.s-ok { background: var(--green-bg); color: var(--green); }
.sync-badge.s-dirty { background: var(--amber-bg); color: var(--amber); }
.sync-badge.s-none { background: var(--surface3); color: var(--muted); }

/* ---- Clinical records: notes + file lists (appointment + patient) ----------- */
.rec-section { margin-top: 1.3rem; border-top: 1px solid var(--border); padding-top: 1rem; }
.rec-head { font-size: .95rem; font-weight: 600; display: flex; align-items: center; gap: .4rem; margin-bottom: .5rem; }
.rec-head i { color: var(--brand); }
.rec-section textarea, .drawer-body textarea, .g-card-body textarea { width: 100%; box-sizing: border-box; resize: vertical; }
.rec-add-row { display: flex; gap: .5rem; align-items: center; margin: .5rem 0 .25rem; }
.rec-add-row select { width: auto; flex: 0 0 auto; }
.rec-empty { color: var(--muted); font-size: .85rem; margin: .5rem 0 0; }
.rec-list { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .55rem; }
.rec-list li { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: .55rem .7rem; }
.rec-meta { font-size: .78rem; color: var(--muted); display: flex; gap: .4rem; align-items: center; margin-bottom: .25rem; }
.rec-body { font-size: .9rem; white-space: pre-wrap; }

.file-drop { display: block; border: 1px dashed var(--border); border-radius: var(--radius); padding: .7rem .8rem; background: var(--surface2); cursor: pointer; font-size: .85rem; color: var(--muted); }
.file-drop:hover { border-color: var(--brand); color: var(--ink); }
.file-drop input { display: block; margin-bottom: .35rem; font-size: .82rem; }
.file-list { list-style: none; margin: .7rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.file-list li { display: flex; align-items: center; gap: .5rem; padding: .35rem .5rem; border-radius: var(--radius); }
.file-list li:hover { background: var(--surface2); }
.file-list a { font-weight: 600; display: inline-flex; align-items: center; gap: .35rem; }
.file-size { color: var(--muted); font-size: .78rem; margin-left: auto; }
.file-chip { display: inline-flex; align-items: center; gap: .3rem; background: var(--brand-bg); color: var(--brand); padding: .15rem .45rem; border-radius: 4px; font-size: .8rem; font-weight: 600; }
.file-chip:hover { text-decoration: none; filter: brightness(.97); }

/* Patient files — richer rows with uploader + source-appointment metadata. */
.file-list li.pf-item { flex-direction: column; align-items: stretch; gap: .2rem; padding: .5rem .55rem; }
.file-list li.pf-item:hover { background: var(--surface2); }
.pf-main { display: flex; align-items: center; gap: .5rem; }
.pf-meta { display: flex; flex-wrap: wrap; gap: .15rem .8rem; align-items: center; font-size: .78rem; color: var(--muted); }
.pf-meta .bi { color: var(--brand); }
.pf-src { display: inline-flex; align-items: center; gap: .3rem; }

/* ---- Patient visit timeline ------------------------------------------------- */
.timeline { list-style: none; margin: 0; padding: 0 0 0 .5rem; }
.tl-item { position: relative; padding: 0 0 1.2rem 1.5rem; border-left: 2px solid var(--border); }
.tl-item:last-child { border-left-color: transparent; padding-bottom: 0; }
.tl-dot { position: absolute; left: -8px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--brand); border: 3px solid var(--surface); box-shadow: 0 0 0 1px var(--border); }
.tl-dot.s-sched { background: var(--st-sched); }
.tl-dot.s-confirmed { background: var(--st-confirmed); }
.tl-dot.s-completed { background: var(--st-completed); }
.tl-dot.s-cancelled { background: var(--st-cancelled); }
.tl-dot.s-noshow { background: var(--st-noshow); }
.tl-dot.s-resched { background: var(--st-resched); }
.tl-dot.s-arrived { background: var(--st-arrived); }
.tl-item.future .tl-card { border-style: dashed; }
.tl-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: .65rem .85rem; }
.tl-when { font-size: .78rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.tl-title { display: flex; align-items: center; gap: .5rem; font-size: 1rem; font-weight: 600; margin: .1rem 0; }
.tl-sub { color: var(--muted); font-size: .85rem; margin-bottom: .25rem; }
.tl-note { font-size: .85rem; margin: .3rem 0; display: flex; gap: .35rem; align-items: baseline; flex-wrap: wrap; }
.tl-by { color: var(--muted); font-size: .78rem; }
.tl-files { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .45rem; }

/* ---- Tab strip (drawer + detail pages) ------------------------------------- */
.tabs { display: flex; gap: .1rem; border-bottom: 1px solid var(--border); margin-bottom: 1.1rem; overflow-x: auto; }
.tabs button { border: none; background: transparent; padding: .55rem .85rem; font: inherit; font-weight: 600; font-size: .9rem; color: var(--muted); cursor: pointer; border-bottom: 2px solid transparent; white-space: nowrap; display: inline-flex; align-items: center; gap: .35rem; }
.tabs button:hover { color: var(--ink); }
.tabs button.active { color: var(--brand); border-bottom-color: var(--brand); }
.tabs .tab-count { background: var(--surface3); color: var(--muted); border-radius: 4px; padding: 0 .4rem; font-size: .72rem; font-weight: 700; }
.tabs button.active .tab-count { background: var(--brand-bg); color: var(--brand); }

/* ---- Appointment history (audit log) --------------------------------------- */
.hist { list-style: none; margin: 0; padding: 0; }
.hist li { position: relative; padding: .15rem 0 .9rem 1.4rem; border-left: 2px solid var(--border); margin-left: .45rem; }
.hist li:last-child { border-left-color: transparent; padding-bottom: 0; }
.hist .h-dot { position: absolute; left: -8px; top: .25rem; width: 13px; height: 13px; border-radius: 50%; background: var(--st-sched); border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--border); }
.hist .h-dot.s-sched { background: var(--st-sched); }
.hist .h-dot.s-confirmed { background: var(--st-confirmed); }
.hist .h-dot.s-completed { background: var(--st-completed); }
.hist .h-dot.s-cancelled { background: var(--st-cancelled); }
.hist .h-dot.s-noshow { background: var(--st-noshow); }
.hist .h-dot.s-resched { background: var(--st-resched); }
.hist .h-dot.s-arrived { background: var(--st-arrived); }
.hist .h-main { font-size: .92rem; font-weight: 600; }
.hist .h-meta { font-size: .78rem; color: var(--muted); margin-top: .05rem; }
.hist .h-reason { font-size: .85rem; margin-top: .25rem; color: var(--ink); background: var(--surface2); border-left: 2px solid var(--border); padding: .25rem .5rem; border-radius: 0 6px 6px 0; }

/* ---- Profile header (patient / detail pages) ------------------------------- */
.profile-head { display: flex; align-items: center; gap: 1rem; }
.avatar { width: 52px; height: 52px; border-radius: 50%; background: var(--brand-bg); color: var(--brand); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 1.15rem; flex: 0 0 auto; box-shadow: var(--shadow); }

/* ---- Patient invoicing & accounts (mobile-first) --------------------------- */
.num { font-variant-numeric: tabular-nums; }
.acct-head-actions { margin-left: auto; display: flex; gap: .4rem; flex-wrap: wrap; }
.acct-summary { display: flex; flex-wrap: wrap; gap: 1rem 1.6rem; padding-bottom: .9rem; border-bottom: 1px solid var(--border); margin-bottom: .9rem; }
.acct-metric { display: flex; flex-direction: column; gap: .1rem; }
.acct-label { font-size: .8rem; color: var(--muted); }
.acct-val { font-size: 1.15rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.acct-sub { font-size: .76rem; color: var(--muted); }
.acct-bal { font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.acct-bal.owe { color: var(--red); }
.acct-bal.credit { color: var(--green); }
.acct-bal.zero { color: var(--muted); }
.acct-h { font-size: .92rem; font-weight: 600; color: var(--ink); margin: 1rem 0 .4rem; }
.acct-list { list-style: none; margin: 0; padding: 0; }
.acct-item { display: flex; align-items: center; flex-wrap: wrap; gap: .15rem .6rem; padding: .55rem 0; border-bottom: 1px solid var(--border); }
.acct-item:last-child { border-bottom: 0; }
.acct-item-main { display: flex; align-items: center; gap: .5rem; flex: 1 1 60%; min-width: 0; }
.acct-item-title { font-weight: 600; }
.acct-item-meta { flex: 1 1 100%; order: 3; font-size: .78rem; color: var(--muted); display: flex; gap: .35rem; flex-wrap: wrap; }
.acct-item-amt { font-weight: 600; font-variant-numeric: tabular-nums; margin-left: auto; }
.acct-due { color: var(--red); }

/* Invoice line editor — collapses to a single column on narrow screens */
.line-editor { display: flex; flex-direction: column; gap: .6rem; }
.line-row { display: grid; grid-template-columns: 1fr; gap: .4rem; padding: .6rem; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); }
.line-row .field { margin: 0; }
.line-pick { margin-bottom: .35rem; }
.line-total { font-weight: 600; font-variant-numeric: tabular-nums; align-self: center; }
.invoice-totals { margin: 1rem 0; border-top: 1px solid var(--border); padding-top: .6rem; }
.invoice-totals > div { display: flex; justify-content: space-between; padding: .15rem 0; color: var(--muted); }
.invoice-totals .grand { font-size: 1.05rem; font-weight: 700; color: var(--ink); border-top: 1px solid var(--border); margin-top: .25rem; padding-top: .4rem; }

/* From ~620px the line editor lays out horizontally */
@media (min-width: 620px) {
    .line-row { grid-template-columns: minmax(0,2.4fr) .7fr .9fr 1.1fr auto auto; align-items: end; }
    .line-desc { grid-column: 1; }
}

/* ---- Daily cash-up --------------------------------------------------------- */
/* minmax(0, 1fr), not 1fr: a bare 1fr track grows to its widest content and pushed the till card
   off a phone screen. */
.cashup-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.1rem; }
@media (min-width: 820px) { .cashup-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.takings-row { display: flex; justify-content: space-between; padding: .5rem 0; border-bottom: 1px solid var(--border); }
.takings-row:last-child { border-bottom: 0; }
.takings-row .num { font-weight: 600; }
.takings-total { font-size: 1.1rem; font-weight: 700; border-top: 2px solid var(--border); margin-top: .25rem; padding-top: .5rem; }
.variance-ok { color: var(--green); font-weight: 600; }
.variance-bad { color: var(--red); font-weight: 600; }
.cashup-locked { display: flex; align-items: center; gap: .4rem; font-size: .82rem; color: var(--muted); background: var(--surface2); border: 1px dashed var(--border); border-radius: var(--radius); padding: .5rem .65rem; margin-top: 1rem; }
.cashup-locked i { color: var(--green); }

/* ---- Closed till-session card (per-shift cash-up, N-5) --------------------- */
.closed-shift { border: 1px solid var(--border); border-radius: var(--radius); padding: .65rem .8rem; margin-bottom: .7rem; background: var(--surface2); }
.closed-shift-head { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; margin-bottom: .4rem; }
.closed-shift .kv { margin: 0; }

/* ---- HelpTip (hover on desktop, tap/focus on mobile) ----------------------- */
.helptip { position: relative; display: inline-flex; align-items: center; color: var(--muted); cursor: help; vertical-align: middle; margin-left: .25rem; }
.helptip:focus { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 50%; }
.helptip > i { font-size: .9rem; line-height: 1; }
.helptip .helptip-bubble {
    position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px);
    width: max-content; max-width: 240px; background: var(--ink); color: #fff; font-size: .78rem; line-height: 1.35;
    font-weight: 400; text-align: left; padding: .45rem .6rem; border-radius: var(--radius); opacity: 0; visibility: hidden; transition: opacity .12s ease, transform .12s ease;
    z-index: 60; pointer-events: none; white-space: normal;
}
.helptip.wide .helptip-bubble { max-width: 320px; }
.helptip .helptip-bubble::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 6px solid transparent; border-top-color: var(--ink); }
.helptip:hover .helptip-bubble, .helptip:focus .helptip-bubble, .helptip:focus-within .helptip-bubble { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }

/* ---- Sub-tabs (Billing) reuse .tabs; segmented filter pills --------------- */
.seg { display: inline-flex; flex-wrap: wrap; gap: .2rem; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: .2rem; }
.seg button { border: 0; background: transparent; color: var(--muted); font: inherit; font-size: .82rem; font-weight: 600; padding: .3rem .7rem; border-radius: 4px; cursor: pointer; white-space: nowrap; }
.seg button.active { background: var(--surface); color: var(--ink); box-shadow: 0 0 0 1px var(--border); }
.filter-row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-bottom: .9rem; }
.filter-row .search { flex: 1 1 220px; min-width: 0; }

/* ---- Data table (clinic invoice list, AR aging) — scrolls on mobile ------- */
.tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.data { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
table.data th, table.data td { padding: .55rem .6rem; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
table.data th { font-size: 13px; color: var(--muted); font-weight: 600; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tbody tr:hover { background: var(--surface2); }
table.data a.inv-link { font-weight: 600; }
.ar-bucket-bad { color: var(--red); font-weight: 600; }

/* ---- Patient account statement (chronological ledger view) ----------------- */
.acct-statement-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.acct-statement-head .acct-h { margin: 0; }
table.stmt td { vertical-align: top; }
table.stmt td.stmt-detail-cell { white-space: normal; }
.stmt-date { color: var(--muted); }
.stmt-detail { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.stmt-ref { font-size: .76rem; color: var(--muted); margin-top: .15rem; }
.stmt-charge { color: var(--ink); font-weight: 600; }
.stmt-credit { color: var(--green); font-weight: 600; }
.stmt-bal { color: var(--ink); font-variant-numeric: tabular-nums; }
.stmt-actions { text-align: right; white-space: nowrap; }
.stmt-controls { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.stmt-period { display: inline-flex; align-items: center; gap: .6rem; font-size: .82rem; color: var(--muted); flex-wrap: wrap; }
.stmt-period label { display: inline-flex; align-items: center; gap: .35rem; }
.stmt-period input[type="date"] { padding: .25rem .4rem; font-size: .82rem; }
.stmt-balances { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; align-items: baseline; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: .5rem .7rem; margin: .6rem 0; font-size: .88rem; }
.stmt-balances .owe { color: var(--ink); } .stmt-balances .credit { color: var(--green); } .stmt-balances .zero { color: var(--muted); }
.pager { display: flex; align-items: center; justify-content: center; gap: .8rem; margin-top: .8rem; }
.pager-info { font-size: .85rem; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---- Print-only formal account statement ---------------------------------- */
.stmt-print { display: none; }
.stmt-print .sp-head { display: flex; justify-content: space-between; gap: 1rem; border-bottom: 2px solid #222; padding-bottom: .5rem; margin-bottom: .8rem; }
.stmt-print .sp-name { font-size: 1.15rem; font-weight: 700; }
.stmt-print .sp-title { text-align: right; font-size: .85rem; }
.stmt-print .sp-title h1 { font-size: 1.2rem; margin: 0; }
.stmt-print .sp-meta { display: grid; grid-template-columns: 1fr 1fr; gap: .2rem 1rem; margin-bottom: .8rem; font-size: .9rem; }
.stmt-print .sp-lbl { display: inline-block; min-width: 130px; color: #555; }
.stmt-print .sp-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.stmt-print .sp-table th, .stmt-print .sp-table td { padding: .35rem .5rem; border-bottom: 1px solid #ccc; text-align: left; vertical-align: top; }
.stmt-print .sp-table th.num, .stmt-print .sp-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.stmt-print .sp-bf td, .stmt-print .sp-cf td { font-weight: 700; background: #f3f3f3; }
.stmt-print .sp-foot { margin-top: .8rem; font-size: .85rem; color: #333; }

@media print {
    .stmt-screen, .page-head, .tabs, .kpi-grid { display: none !important; }
    .stmt-print { display: block !important; color: #000; }
    @page { margin: 14mm; }
}

.inv-link { color: var(--brand); text-decoration: none; }
.inv-link:hover { text-decoration: underline; }

/* ---- Owes badge (day sheet / appointment) --------------------------------- */
.appt-owes { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; background: var(--red); color: #fff; font-size: .6rem; font-weight: 700; flex: 0 0 auto; }
/* 1.15 — waiting-room chip: tap to mark Arrived, tap again to undo. */
.appt-arrive { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; margin-left: auto; flex: 0 0 auto; color: var(--muted); background: transparent; font-size: .72rem; cursor: pointer; }
.appt-arrive:hover { background: rgba(42,35,56,.16); }
.appt-arrive.active { background: var(--st-arrived); color: #fff; }
/* Deposit-to-confirm — card-hold chip on a Diary block. Text + icon, never colour alone; the full
   label and amount ride in the title. Uses the .b-* badge colours so it reads like every other pill. */
.appt-card { display: inline-flex; align-items: center; gap: 2px; padding: 0 4px; border-radius: 3px; font-size: .6rem; font-weight: 700; line-height: 1.45; white-space: nowrap; flex: 0 0 auto; }
.appt-card .bi { font-size: .62rem; }
/* The hold panel in the appointment drawer / full page. */
.hold-line { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; margin: .35rem 0 .5rem; }
.hold-amt { font-weight: 700; font-variant-numeric: tabular-nums; }
.hold-ref { font-size: .72rem; color: var(--muted); word-break: break-all; }
.hold-capture-by { font-weight: 700; color: var(--red); }
.hold-decide { border: 1px solid var(--amber); background: var(--amber-bg); border-radius: var(--radius); padding: .6rem .7rem; margin: .5rem 0; }
.hold-decide .hd-q { font-weight: 700; margin-bottom: .35rem; }
/* Reminders → card-hold worklists. */
.hold-lists { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; }
.hold-list h3 { font-size: .9rem; margin: 0 0 .4rem; display: flex; align-items: center; gap: .4rem; }
.hold-list .g-table td { vertical-align: middle; }
.owes-badge { display: inline-flex; align-items: center; gap: .25rem; font-size: .76rem; font-weight: 600; padding: .1rem .4rem; border-radius: 4px; background: rgba(214,69,61,.12); color: var(--red); }
.owes-badge.credit { background: rgba(46,158,91,.12); color: var(--green); }
.owes-badge.settled { background: var(--surface2); color: var(--muted); }

/* ---- Appointment billing card --------------------------------------------- */
.appt-bill-summary { display: flex; flex-wrap: wrap; gap: .5rem 1.4rem; align-items: baseline; }
.appt-bill-summary .acct-bal { font-size: 1.1rem; }

/* ---- Appointment preview drawer — compact, readable (scoped) --------------- */
.appt-preview .appt-pv-head { margin-bottom: .7rem; padding-bottom: .55rem; border-bottom: 1px solid var(--border); }
.appt-preview .tabs { margin-bottom: .85rem; }
.appt-preview .kv { grid-template-columns: 110px 1fr; gap: .3rem .8rem; font-size: .9rem; align-items: baseline; }
.appt-preview .kv dd { line-height: 1.35; }
.appt-preview .rec-section { margin-top: .9rem; padding-top: .8rem; }
.appt-preview .rec-head { font-size: 1rem; margin-bottom: .45rem; }
.appt-preview .appt-bill-summary { gap: .4rem 1.2rem; margin: .35rem 0 .55rem; }
.appt-preview .takings-row { padding: .4rem 0; font-size: .9rem; }

/* ---- Invoice document (view / print) -------------------------------------- */
.doc-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
.invoice-doc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.6rem; max-width: 820px; }
.invoice-doc .doc-top { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem; border-bottom: 2px solid var(--border); padding-bottom: 1rem; margin-bottom: 1rem; }
.invoice-doc .doc-supplier h2 { margin: 0 0 .2rem; font-size: 1.2rem; }
.invoice-doc .doc-supplier .muted, .invoice-doc .doc-party .muted { color: var(--muted); font-size: .85rem; line-height: 1.5; }
.invoice-doc .doc-title { text-align: right; }
.invoice-doc .doc-title h1 { margin: 0; font-size: 1.5rem; }
.invoice-doc .doc-title .doc-no { font-variant-numeric: tabular-nums; font-weight: 600; }
.invoice-doc .doc-parties { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-bottom: 1.2rem; }
.invoice-doc .doc-party { flex: 1 1 220px; }
.invoice-doc .doc-party .lbl { font-size: .8rem; font-weight: 600; color: var(--muted); margin-bottom: .25rem; }
.invoice-doc table.doc-lines { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.invoice-doc table.doc-lines th, .invoice-doc table.doc-lines td { padding: .5rem .55rem; border-bottom: 1px solid var(--border); font-size: .9rem; }
.invoice-doc table.doc-lines th { font-size: 13px; font-weight: 600; color: var(--muted); text-align: left; }
.invoice-doc table.doc-lines td.num, .invoice-doc table.doc-lines th.num { text-align: right; font-variant-numeric: tabular-nums; }
.invoice-doc .doc-foot { display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: space-between; }
.invoice-doc .doc-vat { flex: 1 1 240px; }
.invoice-doc .doc-vat table { width: 100%; border-collapse: collapse; font-size: .82rem; }
.invoice-doc .doc-vat th, .invoice-doc .doc-vat td { padding: .3rem .4rem; border-bottom: 1px solid var(--border); color: var(--muted); }
.invoice-doc .doc-vat td.num { text-align: right; font-variant-numeric: tabular-nums; }
.invoice-doc .doc-totals { flex: 1 1 240px; max-width: 320px; margin-left: auto; }
.invoice-doc .doc-totals > div { display: flex; justify-content: space-between; padding: .25rem 0; }
.invoice-doc .doc-totals .grand { font-size: 1.15rem; font-weight: 700; border-top: 2px solid var(--border); margin-top: .3rem; padding-top: .5rem; }
.invoice-doc .doc-totals .due { color: var(--red); font-weight: 700; }
.invoice-doc .doc-totals .paid-off { color: var(--green); font-weight: 700; }
.invoice-doc .doc-notes { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid var(--border); color: var(--muted); font-size: .85rem; }
.invoice-doc .doc-payments { margin-top: 1rem; font-size: .85rem; }
.invoice-doc .doc-payments .pmt { display: flex; justify-content: space-between; padding: .2rem 0; color: var(--muted); }
.doc-watermark { font-size: 1.1rem; font-weight: 700; }
.doc-watermark.void { color: var(--red); }

@media print {
    .sidebar, .nav-scrim, .topbar, .nav-items, .doc-actions, .toast-host, .breadcrumbs { display: none !important; }
    body, .app-main, .content, main { background: #fff !important; margin: 0 !important; padding: 0 !important; }
    .invoice-doc { box-shadow: none; border: 0; max-width: none; padding: 0; }
    .no-break { break-inside: avoid; page-break-inside: avoid; }
    @page { margin: 16mm; }
}

/* ---- Public booking page (/b/{slug}, 2.9) — mobile-first page, static SSR -------- */
/* A page, not a floating card: the clinic's band across the top, one 560px column below it,
   16px side gutters on a phone. --pb-accent is the clinic's own colour (falls back to plum). */
.pb-shell { min-height: 100vh; background: var(--surface); }
.pb-page { --pb-accent: var(--brand); min-height: 100vh; display: flex; flex-direction: column; }
.pb-band { background: color-mix(in srgb, var(--pb-accent) 9%, #fff); border-bottom: 1px solid color-mix(in srgb, var(--pb-accent) 24%, #fff); }
.pb-band-inner, .pb-main, .pb-foot { width: 100%; max-width: 560px; margin: 0 auto; padding-left: 16px; padding-right: 16px; }
.pb-band-inner { display: flex; align-items: center; gap: .8rem; padding-top: .95rem; padding-bottom: .95rem; }
.pb-logo { width: 48px; height: 48px; border-radius: 8px; object-fit: cover; flex: 0 0 auto; background: #fff; }
.pb-initial { width: 46px; height: 46px; border-radius: 50%; background: var(--pb-accent); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.3rem; font-weight: 700; flex: 0 0 auto; }
.pb-band-text { min-width: 0; flex: 1 1 auto; }
.pb-name { font-size: 1.3rem; font-weight: 700; margin: 0; line-height: 1.2; }
/* Blazor focuses this h1 after navigation (for screen readers); it is not a Tab stop, so no ring. */
.pb-name:focus { outline: none; }
.pb-tag { color: var(--muted); font-size: .88rem; margin: .1rem 0 0; }
.pb-lang { align-self: flex-start; font-size: .82rem; font-weight: 600; color: var(--ink); text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; padding: .15rem 0; }
.pb-main { flex: 1 1 auto; padding-top: 1.1rem; padding-bottom: 1.6rem; }
.pb-foot { padding-top: .9rem; padding-bottom: 1.2rem; border-top: 1px solid var(--border); font-size: .78rem; color: var(--muted); text-align: center; }
.pb-h2 { font-size: 1.05rem; font-weight: 600; margin: 0 0 .7rem; }
.pb-h2-hours { margin-top: 1.2rem; }
.pb-muted { color: var(--muted); font-size: .92rem; }
.pb-after { margin: .6rem 0 0; font-size: .88rem; }
.pb-section { margin-bottom: 1.4rem; }

/* Services: one row each, name on the left, duration and price on the right. */
.pb-services { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: var(--radius-card); overflow: hidden; }
.pb-services li + li { border-top: 1px solid var(--border); }
.pb-service { display: flex; align-items: center; gap: .75rem; padding: .8rem .9rem; color: var(--ink); text-decoration: none; min-height: 56px; }
.pb-service:hover, .pb-service:focus-visible { background: var(--surface2); text-decoration: none; }
.pb-service-name { font-weight: 600; flex: 1 1 auto; min-width: 0; }
.pb-service-meta { display: flex; align-items: baseline; gap: .6rem; color: var(--muted); font-size: .88rem; white-space: nowrap; }
.pb-price { color: var(--ink); font-weight: 600; }
.pb-chev { color: var(--muted); font-size: .8rem; }

.pb-info p { margin: .35rem 0; font-size: .92rem; display: flex; gap: .5rem; align-items: baseline; }
.pb-info i { color: var(--muted); }
.pb-info a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.pb-hours { width: 100%; border-collapse: collapse; font-size: .9rem; }
.pb-hours td { padding: .32rem 0; border-bottom: 1px solid var(--surface3); }
.pb-hours td:last-child { text-align: right; color: var(--muted); }
.pb-hours .pb-today td { font-weight: 600; color: var(--ink); }

.pb-crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; font-size: .85rem; color: var(--muted); margin-bottom: .9rem; }
.pb-crumbs a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.pb-crumbs i { font-size: .7rem; }

/* Day and time on one screen: a strip of days (links), the chosen day's times beneath. */
.pb-days { display: flex; gap: .4rem; overflow-x: auto; padding-bottom: .35rem; margin: 0 0 1rem; scrollbar-width: thin; }
.pb-day { flex: 0 0 auto; width: 56px; display: flex; flex-direction: column; align-items: center; padding: .4rem 0 .45rem; border: 1px solid var(--border); border-radius: var(--radius); color: var(--ink); text-decoration: none; }
.pb-day:hover, .pb-day:focus-visible { border-color: var(--pb-accent); text-decoration: none; }
.pb-day-name, .pb-day-month { font-size: .74rem; color: var(--muted); }
.pb-day-num { font-size: 1.15rem; font-weight: 700; line-height: 1.25; font-variant-numeric: tabular-nums; }
.pb-day.on { background: var(--pb-accent); border-color: var(--pb-accent); color: #fff; }
.pb-day.on .pb-day-name, .pb-day.on .pb-day-month { color: #fff; }
.pb-dayline { font-size: .95rem; font-weight: 600; margin: 0 0 .6rem; }
.pb-times { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.pb-time { display: flex; align-items: center; justify-content: center; min-height: 46px; border: 1px solid var(--border); border-radius: var(--radius); color: var(--ink); font-weight: 600; text-decoration: none; font-variant-numeric: tabular-nums; }
.pb-time:hover, .pb-time:focus-visible { border-color: var(--pb-accent); background: color-mix(in srgb, var(--pb-accent) 8%, #fff); text-decoration: none; }

.pb-summary { display: flex; flex-direction: column; gap: .15rem; padding: .75rem .9rem; border: 1px solid var(--border); border-left: 3px solid var(--pb-accent); border-radius: var(--radius); margin-bottom: 1.1rem; font-size: .92rem; }
.pb-summary a { align-self: flex-start; margin-top: .15rem; font-size: .85rem; color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.pb-name-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 .75rem; }
.field .pb-consent { display: flex; gap: .55rem; align-items: flex-start; font-size: .88rem; font-weight: 400; cursor: pointer; }
.pb-consent input { width: auto; margin-top: .2rem; }
/* The patient-facing primary action carries the clinic's own colour, like the chosen day. */
.btn-g.primary.pb-submit { width: 100%; justify-content: center; padding: .75rem; font-size: 1rem; margin-top: .3rem; background: var(--pb-accent); border-color: var(--pb-accent); }
.btn-g.primary.pb-submit:hover { background: var(--pb-accent); border-color: var(--pb-accent); filter: brightness(.92); }
.pb-done { text-align: center; padding: 1.4rem 0; }
.pb-done > i { font-size: 2.2rem; color: var(--green); }
.pb-done h2 { font-size: 1.25rem; margin: .5rem 0 .4rem; }
.pb-done p { color: var(--muted); margin: 0 auto 1.1rem; max-width: 380px; }
/* Honeypot: visually gone, still in the DOM for bots. Never display:none (some bots skip those). */
.pb-hp { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 380px) { .pb-times { grid-template-columns: repeat(3, 1fr); } }

/* ---- QR desk/window card (/doors/card, 2.11) — A6 print target ------------- */
.door-card { width: 105mm; min-height: 148mm; margin: 1rem auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); padding: 10mm 8mm; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4mm; --pb-accent: var(--brand); }
.door-card-icon { font-size: 2.2rem; color: var(--pb-accent); }
.door-card-name { font-size: 1.4rem; font-weight: 700; line-height: 1.15; }
.door-card-headline { font-size: 1.15rem; font-weight: 600; color: var(--pb-accent); line-height: 1.25; }
.door-card-headline span { font-size: .9rem; color: var(--muted); font-weight: 500; }
.door-card-qr { width: 58mm; height: 58mm; image-rendering: pixelated; }
.door-card-url { font-weight: 700; font-size: 1rem; word-break: break-all; }
.door-card-hint { font-size: .72rem; color: var(--muted); }

/* ---- Booking-request detail: call recording + transcript ------------------- */
.row-clickable { cursor: pointer; }
.detail-head { font-size: 1rem; font-weight: 600; margin: 1.4rem 0 .6rem; display: flex; align-items: center; gap: .4rem; }
.detail-head i { color: var(--brand); }
.call-audio { width: 100%; height: 40px; }

.transcript { display: flex; flex-direction: column; gap: .5rem; max-height: 22rem; overflow-y: auto; padding-right: .25rem; }
.turn { display: grid; grid-template-columns: 3.2rem 1fr; gap: .5rem; align-items: start; }
.turn p { margin: 0; padding: .45rem .7rem; border-radius: var(--radius); line-height: 1.4; font-size: .9rem; }
/* Speaker is carried non-visually by the .visually-hidden label in the markup — that is the
   authoritative signal. Visually it is the BORDER accent that separates the two: --brand-bg and
   --navy-bg sit ~1.07:1 apart, which is indistinguishable at a glance and invisible to anyone with
   a colour-vision deficiency, so fill alone cannot carry it. */
.turn.them p { background: var(--brand-bg); border-left: 3px solid var(--brand); }
.turn.us p { background: var(--surface2); border-left: 3px solid var(--border); }
.turn-seek { font-variant-numeric: tabular-nums; font-size: .75rem; color: var(--brand); background: none; border: 0; padding: .45rem 0 0; text-align: right; cursor: pointer; }
.turn-seek:hover { text-decoration: underline; }
.turn-seek.muted { color: var(--muted); cursor: default; }

/* ── Products, stock & prepaid packages ─────────────────────────────────────── */
.pkg-list { display: flex; flex-direction: column; gap: .75rem; }
.pkg { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem .85rem; background: var(--surface2); }
.pkg.pkg-warn { border-color: var(--amber); background: var(--amber-bg); }
.pkg-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: .5rem; }
.pkg-exp { color: var(--amber); font-weight: 600; }
.pkg-sub { font-size: .9rem; font-weight: 700; margin: 1rem 0 .4rem; }
.pkg-past { margin-top: .85rem; }
.pkg-past > summary { cursor: pointer; font-size: .85rem; color: var(--muted); padding: .25rem 0; }
.pkg-past > summary:hover { color: var(--brand); }
.pkg-purchases { margin-top: 1rem; }

/* The punch-card: filled dots are sessions already taken. Reads at a glance the way a
   paper loyalty card does, which is the whole point of selling a package. */
.punch { display: flex; gap: .3rem; flex-wrap: wrap; margin-bottom: .5rem; }
.punch-dot { width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--brand); background: transparent; }
.punch-dot.used { background: var(--brand); }
/* One treatment per line: name, its dots, what is left. Without this the three parts stacked
   into three separate lines and a two-treatment card read as six unrelated rows. */
.punch-row {
    display: grid; grid-template-columns: minmax(6rem, 11rem) 1fr auto;
    gap: .5rem; align-items: center; margin-bottom: .3rem;
}
.punch-row .punch { margin-bottom: 0; }
.punch-name { font-size: .85rem; font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.punch-count { font-size: .8rem; color: var(--muted); white-space: nowrap; }
@media (max-width: 560px) {
    .punch-row { grid-template-columns: 1fr auto; }
    .punch-row .punch { grid-column: 1 / -1; }
}

.row-void td { opacity: .55; text-decoration: line-through; }

/* Inventory */
.stock-ok { color: var(--green); font-weight: 600; }
.stock-low { color: var(--amber); font-weight: 700; }
.stock-out { color: var(--red); font-weight: 700; }
.mv-in { color: var(--green); font-weight: 600; }
.mv-out { color: var(--red); font-weight: 600; }
.inv-tabs { margin-bottom: 1rem; }

/* Statement line detail — what was actually on each document, under its row. */
.stmt-lines { list-style: none; margin: .3rem 0 0; padding: 0 0 0 .9rem; border-left: 2px solid var(--border); }
.stmt-lines li { display: flex; align-items: center; gap: .4rem; font-size: .82rem; color: var(--muted); padding: .12rem 0; }
.stmt-line-name { color: var(--text); }
.stmt-line-qty { font-variant-numeric: tabular-nums; }
.stmt-line-total { margin-left: auto; font-variant-numeric: tabular-nums; }
.badge-pill.b-hidden { display: none; }
.sp-lines { font-size: .8rem; color: #555; padding-left: .8rem; }

/* "Everything bought" filter on the customer card. */
.buy-seg { margin-bottom: .6rem; }

/* Stock-history filters + paging. */
.mv-filters { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; margin-bottom: .8rem; }
.mv-filters .field { margin: 0; min-width: 180px; }
.mv-filters .mv-clear { margin-bottom: .1rem; }
.mv-more { display: flex; justify-content: center; padding-top: .8rem; }

/* ── Sales & stock report ───────────────────────────────────────────────────── */
.rep-range .g-card-body { display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap; }
.rep-dates { display: flex; gap: .75rem; }
.rep-dates .field { margin: 0; }

/* ---- Reports section (/reports/*) ------------------------------------------- */
.rep-actions { display: flex; gap: .5rem; margin-left: auto; flex-wrap: wrap; }
/* Facts that only earn their ink on paper — each report prints its range under the title,
   because the on-screen range bar is no-print. */
.print-only { display: none; }
@media print { .print-only { display: block; } }

/* Report hub — one card per report, grouped under small headings. */
.rep-hub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.rep-hub-card { display: block; text-decoration: none; color: inherit; }
.rep-hub-card .g-card { height: 100%; transition: border-color .12s ease; }
.rep-hub-card:hover .g-card { border-color: var(--brand-soft); }
.rep-hub-card h3 { font-size: 1.05rem; margin: 0 0 .25rem; display: flex; align-items: center; gap: .5rem; }
.rep-hub-card h3 i { color: var(--brand); }
.rep-hub-card p { margin: 0; font-size: .85rem; color: var(--muted, #6b6b76); }

/* Busiest-hours heatmap — a plain table whose cells carry an inline alpha of the brand colour. */
.rep-heat { border-collapse: collapse; width: 100%; }
.rep-heat th, .rep-heat td { border: 1px solid var(--line, #e7e3ef); padding: .3rem .45rem; text-align: center; font-size: .8rem; }
.rep-heat th { background: var(--paper, #faf8fd); font-weight: 600; }
.rep-heat td { min-width: 2.2rem; }
@media print { .rep-heat td { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }
.rep-sub { font-size: .9rem; font-weight: 700; margin: 1.25rem 0 .3rem; }
.rep-note { margin-top: .7rem; display: flex; gap: .4rem; align-items: flex-start; line-height: 1.45; }
.rep-table tfoot th { border-top: 2px solid var(--border); font-weight: 700; }
.rep-returned { display: block; font-size: .78rem; }
.margin-ok { color: var(--green); font-weight: 600; }
/* Selling under cost is the one number on this page that must not be missed. */
.margin-bad { color: var(--red); font-weight: 700; }

/* Item-kind badges — same colours the customer card uses, so a "product" reads the
   same whichever page you meet it on. */
.badge-pill.item-service { background: var(--brand-bg); color: var(--brand); }
.badge-pill.item-product { background: var(--amber-bg); color: #8a5a00; }
.badge-pill.item-package { background: #ede7ff; color: #5b3fbf; }
.badge-pill.item-freetext { background: var(--surface2); color: var(--muted); }

/* Package liability: four figures and how far through the sold sessions the clinic is. */
.pkg-liab { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: .8rem; }
.pkg-liab-fig { display: flex; flex-direction: column; gap: .15rem; }
.pkg-liab-fig .lbl { font-size: .82rem; color: var(--muted); }
.pkg-liab-fig .val { font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.pkg-liab-fig .val small { font-size: .85rem; font-weight: 500; color: var(--muted); }
.pkg-liab-fig.owed .val { color: var(--amber); }
.pkg-bar { height: 8px; border-radius: 3px; background: var(--surface2); border: 1px solid var(--border); overflow: hidden; }
.pkg-bar span { display: block; height: 100%; background: var(--brand); }

/* ── Day list (/day) — one date, sorted into coming / cancelled / no-show ────── */
.day-head { display: flex; align-items: center; gap: .6rem; margin: .2rem 0 .8rem; }
.day-title { font-size: 1.25rem; font-weight: 700; margin: 0; }
.badge-pill.b-brand { background: var(--brand-bg); color: var(--brand); }

/* Readable from a step away — this strip is the whole page in one line. */
.day-counts { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.1rem; }
.day-count { flex: 1 1 92px; min-width: 92px; background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--border); border-radius: var(--radius); padding: .5rem .7rem; }
.day-count .n { display: block; font-size: 1.5rem; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.day-count .l { display: block; font-size: .8rem; color: var(--muted); }
.day-count.ok { border-left-color: var(--green); } .day-count.ok .n { color: var(--green); }
.day-count.warn { border-left-color: var(--amber); } .day-count.warn .n { color: var(--amber); }
.day-count.in { border-left-color: var(--st-arrived); } .day-count.in .n { color: var(--st-arrived); }
.day-count.done { border-left-color: var(--st-completed); } .day-count.done .n { color: var(--st-completed); }
.day-count.bad { border-left-color: var(--red); } .day-count.bad .n { color: var(--red); }

.day-block { margin-bottom: 1.1rem; }
.day-block .g-card-head h2 { display: flex; align-items: center; gap: .45rem; }
.day-block .g-card-head h2 .bi { color: var(--brand); }
/* Someone is in the waiting room right now — the one row that should catch the eye. */
.g-table tbody tr.row-here { background: #fbeaf5; }
.g-table tbody tr.row-here:hover { background: #f7dcee; }

/* ── Reminders day view — each planned send under its patient ────────────────── */
.rem-table td { vertical-align: top; }
.rem-jobs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.rem-jobs li { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.rem-when { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.rem-offset { color: var(--muted); font-size: .82rem; white-space: nowrap; }

/* ── Package line editor — one treatment per row, quantity on the end ────────── */
.pkg-lines { display: flex; flex-direction: column; gap: .5rem; }
.pkg-line {
    display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.2fr) 5.5rem auto;
    gap: .5rem; align-items: end;
    padding: .55rem; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius);
}
.pkg-line .field { margin: 0; min-width: 0; }
.pkg-line .field label { font-size: .8rem; color: var(--muted); }
.pkg-line-del { align-self: center; margin-bottom: .1rem; }
.pkg-line-del:disabled { opacity: .35; cursor: not-allowed; }
/* Below ~520px (the drawer is full-width on a phone) the row folds to two columns. */
@media (max-width: 560px) {
    .pkg-line { grid-template-columns: 1fr 4.5rem; }
    .pkg-line .field:first-child { grid-column: 1 / -1; }
}

/* ── Package status on the customer card ────────────────────────────────────── */
.pkg-order { margin: 0 0 .6rem; }
/* A card that cannot be drawn on reads as inert — but stays legible, because the reason
   printed on it is the whole point of still showing it. */
.pkg.pkg-locked { border-style: dashed; border-color: var(--red); background: var(--red-bg); }
.pkg.pkg-next { border-color: var(--green); box-shadow: inset 3px 0 0 var(--green); }
.pkg-blocked {
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    font-size: .84rem; color: #9c2b25; margin-bottom: .5rem;
}
.pkg-blocked a { color: #9c2b25; text-decoration: underline; }

/* ── Dashboard "Needs attention" — one ranked list, not nine stacked banners ──── */
.attn-line { margin: 0 0 .8rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.attn-line > summary { display: flex; align-items: center; gap: .5rem; padding: .45rem .75rem; cursor: pointer; list-style: none; font-size: .9rem; font-weight: 600; }
.attn-line > summary::-webkit-details-marker { display: none; }
.attn-line > summary:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius); }
.attn-chev { font-size: .72rem; color: var(--muted); transition: transform .15s ease; }
.attn-line[open] .attn-chev { transform: rotate(180deg); }
.attn-line .attn-list { padding: 0 .75rem .35rem; border-top: 1px solid var(--border); }
@media (prefers-reduced-motion: reduce) { .attn-chev { transition: none; } }
.attn-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.attn-item {
    display: grid; grid-template-columns: 1.1rem 1fr auto; gap: .6rem; align-items: baseline;
    padding: .55rem .2rem; font-size: .9rem; border-top: 1px solid var(--border);
}
.attn-item:first-child { border-top: 0; }
.attn-item > i { font-size: .95rem; }
.attn-item.bad > i { color: var(--red); }
.attn-item.warn > i { color: var(--amber); }
.attn-item.info > i { color: var(--brand); }
.attn-text { min-width: 0; }
.attn-item.bad .attn-text strong { color: var(--red); }
.attn-action { white-space: nowrap; font-weight: 600; font-size: .85rem; }

/* A table row that behaves like a link. Used wherever clicking a line opens its detail. */
.day-row, .rem-row { cursor: pointer; }
.day-row:hover, .rem-row:hover { background: var(--brand-bg); }
.day-row:hover .day-name, .rem-row:hover .rem-name { color: var(--brand); }
.day-name, .rem-name { font-weight: 600; }

/* ── Reminders board — a column per scheduled reminder ─────────────────────────── */
.rem-col { min-width: 11rem; }
/* Stamp and outcome on one line, the reason (when there is one) wrapping under it — three stacked
   lines per cell made every row three times taller than the fact it carries. */
.rem-cell { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .4rem; }
.rem-cell .field-hint { flex-basis: 100%; }
/* "10:30 Check-up · 14:00 Hygiene" — each visit's time and treatment stay together, so the column
   still scans by time down the left edge without splitting the pairing across two columns. */
.rem-visits-cell { min-width: 12rem; font-variant-numeric: tabular-nums; }
.rem-table-foot { margin: .6rem 0 0; }
.rem-visits { list-style: none; margin: .3rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.rem-visits li { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }

/* ── Appointment lifecycle — where the visit is and what unblocks the next step ─ */
.lifecycle {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    padding: .85rem 1rem; margin-bottom: 1.1rem;
}
.lc-steps {
    list-style: none; display: flex; align-items: flex-start; margin: 0; padding: 0;
    /* Never let five steps push the drawer sideways on a phone — the rail scrolls itself. */
    overflow-x: auto; gap: 0;
}
.lc-step {
    flex: 1 1 0; min-width: 4.2rem; position: relative;
    display: flex; flex-direction: column; align-items: center; gap: .35rem;
    font-size: .76rem; color: var(--muted); text-align: center;
}
/* The connecting line lives on the step, drawn leftwards, so it never overhangs the ends. */
.lc-step::before {
    content: ""; position: absolute; top: 9px; right: 50%; left: -50%;
    height: 2px; background: var(--border);
}
.lc-step:first-child::before { display: none; }
.lc-step.done::before, .lc-step.now::before, .lc-step.stopped::before { background: var(--brand-soft); }
.lc-dot {
    width: 20px; height: 20px; border-radius: 50%; background: var(--surface);
    border: 2px solid var(--border); position: relative; z-index: 1;
    display: flex; align-items: center; justify-content: center; font-size: .62rem; color: #fff;
}
.lc-step.done .lc-dot { background: var(--brand); border-color: var(--brand); }
.lc-step.now .lc-dot { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-bg); }
.lc-step.stopped .lc-dot { background: var(--red); border-color: var(--red); }
.lc-step.done .lc-label, .lc-step.now .lc-label { color: var(--ink); font-weight: 600; }
.lc-step.stopped .lc-label { color: var(--red); font-weight: 600; }
.lc-next { display: flex; align-items: flex-start; gap: .45rem; margin: .8rem 0 0; font-size: .88rem; }
.lc-next i { color: var(--brand); margin-top: .12rem; }
.lc-stopped .lc-next i { color: var(--red); }
.lc-blockers { list-style: none; margin: .5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.lc-blockers li {
    display: flex; align-items: center; gap: .4rem; font-size: .84rem;
    color: #8a5a0c; background: var(--amber-bg); border: 1px solid #f0d9b0;
    border-radius: var(--radius); padding: .35rem .55rem;
}

/* ── Reminders on one appointment ───────────────────────────────────────────── */
.rem-block .rec-head { display: flex; align-items: center; gap: .5rem; }
.rem-mode {
    margin-left: auto; display: inline-flex; align-items: center; gap: .3rem;
    font-size: .75rem; font-weight: 600; padding: .15rem .45rem; border-radius: 4px;
}
.rem-mode.on { background: var(--green-bg); color: #1c6b3c; }
.rem-mode.off { background: var(--amber-bg); color: #8a5a0c; }
.rem-summary { margin: .45rem 0 .55rem; font-size: .88rem; }
.rem-log { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.rem-log-item {
    display: grid; grid-template-columns: 1rem 9.5rem auto 1fr; gap: .5rem; align-items: center;
    font-size: .84rem; padding: .3rem .45rem; border-radius: var(--radius); background: var(--surface2);
}
.rem-log-item.done { background: var(--green-bg); }
.rem-log-item.done > i { color: #1c6b3c; }
.rem-log-item.planned > i { color: var(--brand); }
.rem-log-item.moot { color: var(--muted); }
.rem-log-item.moot > i { color: var(--muted); }
.rem-log-when { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.rem-log-what { min-width: 0; }
.rem-foot { margin: .5rem 0 0; }
.rem-explainer { align-items: flex-start; }
.rem-explainer i { margin-top: .15rem; }
/* In a 480px drawer the four-column log row folds: time on one line, the rest under it. */
@media (max-width: 620px) {
    .rem-log-item { grid-template-columns: 1rem auto 1fr; }
    .rem-log-item .rem-log-what { grid-column: 2 / -1; }
}

/* 6.4 — Fill a quiet day (/promos): the two-week strip, the review list, and the Diary shortcut. */
.promo-days { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: .5rem; }
.promo-day { border: 1px solid var(--border); border-radius: var(--radius); padding: .55rem .5rem .6rem; text-align: center; display: flex; flex-direction: column; gap: .2rem; align-items: center; }
.promo-day-name { font-size: .8rem; font-weight: 600; color: var(--muted); }
.promo-day-date { font-weight: 700; }
.promo-day-count { font-size: .85rem; margin-bottom: .2rem; }
.promo-day-count small { color: var(--muted); }
.promo-day.closed { opacity: .55; }
.promo-day.heat-0 { background: var(--surface2); }
.promo-day.heat-1 { background: #F7F4FC; }
.promo-day.heat-2 { background: #EFE9F8; }
.promo-day.heat-3 { background: #E4DBF4; }
.promo-day.heat-4 { background: #D6C9EE; }
.sched-dayhead .heat-promo { display: inline-block; margin-left: .35rem; font-size: .8rem; color: inherit; opacity: .65; text-decoration: none; }
.sched-dayhead .heat-promo:hover, .sched-dayhead .heat-promo:focus-visible { opacity: 1; }
.sms-preview { white-space: pre-wrap; word-break: break-word; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: .6rem .75rem; font: inherit; font-size: .9rem; margin: .25rem 0 .5rem; }
.promo-recipients { max-height: 320px; overflow: auto; border: 1px solid var(--border); border-radius: var(--radius); }
.promo-recipient { display: flex; justify-content: space-between; align-items: center; gap: .5rem; padding: .35rem .6rem; border-bottom: 1px solid var(--border); font-size: .88rem; }
.promo-recipient:last-child { border-bottom: 0; }
.promo-recipient small { margin-left: .4rem; color: var(--muted); }
.promo-recipient.off { opacity: .45; text-decoration: line-through; }

/* ---- Settings area ---- */
/* /administration/* (docs/ADMIN-REDESIGN-BRIEF-2026-09-25.md §5). A bounded frame: the section nav,
   then one content column of at most 880px. Density comes from grouping and from inputs sized to
   what they hold (.w-xs to .w-lg), never from stretching a field across the card. */
.settings { display: grid; grid-template-columns: 220px minmax(0, 880px); gap: 2rem; align-items: start; }
.settings-main { min-width: 0; }
.settings .muted { color: var(--muted); }
/* Muted text after a name in a cell ("MAIN", "(you)"): Razor trims the space after an @if block. */
.settings .after { margin-left: .35rem; }

/* Section nav: text only, 36px rows. Labels wrap to a second line and are never truncated, since
   Greek labels run long (P24). Sticky under the topbar so it stays in reach on a long page. */
.settings-nav { position: sticky; top: 4.5rem; }
.settings-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.settings-nav a { display: flex; align-items: center; min-height: 36px; padding: .4rem .75rem; border-radius: var(--radius); color: var(--ink); font-weight: 500; line-height: 1.25; }
.settings-nav a:hover { background: var(--surface3); text-decoration: none; }
.settings-nav a.active { background: var(--brand-bg); color: var(--brand); font-weight: 600; }
/* The phone's way back to the Overview; the nav itself is hidden there. */
.settings-back { display: none; }

/* A group: heading and one sentence, then a card of fields. Space separates groups, no hairline.
   scroll-margin keeps an anchored group's heading clear of the sticky topbar. */
.set-group { display: grid; grid-template-columns: minmax(0, 1fr); gap: .6rem; margin-bottom: 1.5rem; scroll-margin-top: 4.5rem; }
.set-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: .75rem; align-items: start; }
.set-head h2 { grid-column: 1; font-size: 1.05rem; font-weight: 600; margin: 0; }
.set-desc { grid-column: 1; color: var(--muted); font-size: .9rem; margin: .2rem 0 0; }
.set-tools { grid-column: 2; grid-row: 1 / span 2; display: flex; flex-wrap: wrap; gap: .5rem; justify-content: flex-end; }
.set-tools .btn-g { white-space: nowrap; }
.set-group .g-card-body { overflow-x: auto; }
/* The card body contains its absolutely positioned bits (a visually hidden column name), so a wide
   table's last header cannot escape the card's own scroll and widen the page on a phone. */
.settings .g-card-body { position: relative; }
/* An EL/EN pair: each half may shrink below its input's width class instead of pushing past the card. */
.settings .form-grid, .drawer .form-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.set-group .g-card-body > :last-child { margin-bottom: 0; }
.set-bare { min-width: 0; }
@media (min-width: 1100px) {
    .set-group { grid-template-columns: 240px minmax(0, 1fr); gap: 1.5rem; }
    .set-head { display: block; }
    .set-tools { justify-content: flex-start; margin-top: .75rem; }
}
/* A report group inside Administration: its table needs the whole column, so the heading stays on top. */
@media (min-width: 1100px) {
    .set-group.wide { grid-template-columns: minmax(0, 1fr); gap: .6rem; }
    .set-group.wide .set-head { display: grid; }
    .set-group.wide .set-tools { justify-content: flex-end; margin-top: 0; }
}

/* Width classes: a field is as wide as what it holds (P7). Out-specify `.field input { width: 100% }`. */
.w-xs, .field :is(input, select, textarea).w-xs { width: 6rem; max-width: 100%; }
.w-sm, .field :is(input, select, textarea).w-sm { width: 12rem; max-width: 100%; }
.w-md, .field :is(input, select, textarea).w-md { width: 20rem; max-width: 100%; }
.w-lg, .field :is(input, select, textarea).w-lg { width: 28rem; max-width: 100%; }
.set-group .field textarea { max-width: 40rem; }
/* A field with a button beside it ("Suggest name"): the pair wraps rather than squeezing the field. */
.field-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.field-row .btn-g { white-space: nowrap; }
.set-group .field-hint { margin-top: .3rem; max-width: 40rem; }
.set-group .chk { display: flex; align-items: flex-start; min-height: 24px; margin: 0; }
.set-group .chk input[type=checkbox] { margin-top: .2rem; flex: 0 0 auto; }
/* A "go there" link sits on its own line under the field, never inside a hint (P13). */
.set-go { display: inline-block; margin-top: .3rem; font-size: .85rem; font-weight: 600; }

/* Read-only values, for a role that can view but not edit, and for the Profile facts (P18). */
.set-facts { display: grid; grid-template-columns: minmax(8rem, 16rem) minmax(0, 1fr); gap: .45rem 1rem; margin: 0; }
.set-facts dt { color: var(--muted); font-weight: 600; font-size: .9rem; }
.set-facts dd { margin: 0; overflow-wrap: anywhere; }
.set-note { color: var(--muted); font-size: .88rem; margin: .8rem 0 0; }
/* A fact with its action beside it (Business type · Change business type). */
.set-fact-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; padding: .55rem 0; border-bottom: 1px solid var(--surface3); }
.set-fact-row:first-child { padding-top: 0; }
.set-fact-row .btn-g { white-space: nowrap; }
.set-fact-label { color: var(--muted); font-weight: 600; font-size: .9rem; display: block; }
.set-starter { margin: .9rem 0 0; }
.set-live { margin-top: .4rem; padding-top: .55rem; border-top: 1px solid var(--surface3); border-bottom: 0; }
.set-live a { font-weight: 600; overflow-wrap: anywhere; }
/* Reminder schedule (read-only): the schedule's name, then one line per send. */
.rem-sched + .rem-sched { margin-top: 1rem; }
.rem-sched-name { font-weight: 600; margin: 0 0 .3rem; }
.rem-sched-list { margin: 0; padding-left: 1.1rem; }
.rem-sched-list li { padding: .1rem 0; }
/* Doors: the brand glyph sits on the row, never in a heading; instructions wrap even on a phone. */
.doors-table .door-name { white-space: nowrap; font-weight: 600; }
.doors-table .door-name .bi { color: var(--muted); margin-right: .25rem; }
.doors-table td { vertical-align: top; }
.doors-table .btn-g { white-space: nowrap; }
.doors-table td:nth-child(2) { white-space: normal; min-width: 14rem; }
.set-dialog-text { margin: .1rem 0 0; font-size: .92rem; }

/* Radio groups: a fieldset with a legend, one short line under each option (P8, P10). The reset
   undoes Bootstrap's reboot, which floats the legend and sets it at heading size. */
.set-radios { border: 0; margin: 0 0 1.1rem; padding: 0; min-width: 0; }
.set-radios legend, .drawer-fieldset legend { float: none; width: auto; padding: 0; font-weight: 600; line-height: 1.3; }
.set-radios legend { font-size: .85rem; margin: 0 0 .35rem; }
.set-radio { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: .55rem; align-items: start; padding: .3rem 0; min-height: 24px; cursor: pointer; font-weight: 600; font-size: .9rem; }
.set-radio input { margin-top: .25rem; }
.set-radio-desc { grid-column: 2; color: var(--muted); font-weight: 400; font-size: .85rem; }
/* Drawer sub-sections are fieldsets too, so a screen reader hears which part of the form it is in. */
.drawer-fieldset { border: 0; margin: 1.2rem 0 0; padding: 0; min-width: 0; }
.drawer-fieldset.first { margin-top: 0; }
.drawer-fieldset legend { font-size: 1rem; margin: 0 0 .5rem; }
/* A checkbox group inside a drawer section: its legend reads as a field label. */
.drawer-subset { border: 0; margin: 0 0 1rem; padding: 0; min-width: 0; }
.drawer-subset legend { float: none; width: auto; padding: 0; font-weight: 600; font-size: .85rem; margin: 0 0 .3rem; line-height: 1.3; }
.chk-list { display: flex; flex-wrap: wrap; gap: .4rem 1rem; }
.chk-list .chk { font-weight: 500; margin: 0; }
.sched-hint { margin: 0 0 .4rem; }
.sched-day-blocks > .btn-g { align-self: flex-start; }
/* A field whose value was refused carries the red edge as well as the message under it (P14). */
.settings [aria-invalid="true"], .drawer [aria-invalid="true"] { border-color: var(--red); }
.gcal-line { margin: 0 0 .5rem; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.set-pools { margin-top: .6rem; }
/* One hint under an EL/EN pair, attached to both inputs. */
.pair-hint { margin: -.6rem 0 1rem; }
/* Templates panel. */
.tpl-note { margin: 0 0 .8rem; }
/* Billing: the Price list pointer is one plain line after the groups, not a card. */
.set-page-note { margin: 0 0 1.5rem; }
.vat-hint { color: var(--muted); cursor: help; margin-left: .3rem; }
/* Card holds: amounts line up on the right like every other figure. */
.num-input { text-align: right; font-variant-numeric: tabular-nums; }
/* Inputs and selects that sit in a table row (hold amounts, sharing pools) look like every other field. */
.settings .g-table :is(input:not([type=checkbox]):not([type=radio]), select) { padding: .35rem .5rem; border: 1px solid var(--border); border-radius: var(--radius); font: inherit; background: var(--surface); color: var(--ink); }
.tpl-starter { margin-left: .4rem; }
.field .field-label { display: block; font-weight: 600; font-size: .85rem; margin-bottom: .3rem; }

/* One "Advanced" disclosure per page, never nested (P17). */
.set-advanced { margin-top: .4rem; }
.set-advanced > summary, .set-done > summary { cursor: pointer; font-weight: 600; font-size: .9rem; padding: .3rem 0; width: fit-content; border-radius: var(--radius); }
.set-advanced[open] > summary { margin-bottom: .6rem; }
.set-done > summary { color: var(--ink); }
.set-done[open] > summary { margin-bottom: .6rem; }

/* Setup progress (Overview). The next step is set in 600 so it is obvious (P20). */
.set-badge { margin-left: .5rem; vertical-align: middle; }
.setup-table td:first-child { width: 2rem; }
.setup-table tr.row-next td { font-weight: 600; }
.setup-done { color: var(--green); }
.setup-todo { color: var(--muted); }
/* Section list and finder results on the Overview. */
.set-links { list-style: none; margin: 0; padding: 0; }
.set-links li { padding: .55rem 0; border-bottom: 1px solid var(--surface3); }
.set-links li:first-child { padding-top: 0; }
.set-links li:last-child { border-bottom: 0; padding-bottom: 0; }
.set-links a { font-weight: 600; }
.set-links .muted { display: block; font-size: .88rem; }
.find-field { margin-bottom: 1.5rem; }
.find-results { margin-top: .6rem; }

/* The save bar: present only while the page is dirty, stuck to the bottom of the content column. */
.save-bar { position: sticky; bottom: 0; z-index: 30; display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: .5rem; padding: .75rem 1rem; background: var(--surface); border-top: 1px solid var(--border); }
.save-bar-text { margin-right: auto; font-weight: 600; }
.save-bar .btn-g { white-space: nowrap; }

/* A button that reads as a link: a table row's name, "Clear filters". Keyboard-reachable, unlike a
   clickable row, and never a javascript: href. */
.link-btn { border: 0; background: none; padding: 0; font: inherit; color: var(--brand); cursor: pointer; text-align: left; }
.link-btn:hover { text-decoration: underline; }
.g-table .link-btn { font-weight: 600; color: var(--ink); }
.g-table tr.row-click:hover .link-btn { color: var(--brand); }
/* A toggle button that is on (the Filters toggle). */
.btn-g[aria-pressed="true"] { background: var(--brand-bg); border-color: #D9CFF0; color: var(--brand); }

/* Targets and focus (P22). Checkboxes and radios take the plum accent rather than the OS colour. */
.icon-btn { min-width: 24px; min-height: 24px; }
.settings :is(input[type=checkbox], input[type=radio]), .drawer :is(input[type=checkbox], input[type=radio]) { accent-color: var(--brand); }
.settings :is(select, textarea, summary, button, .link-btn):focus-visible,
.settings input:not([type=checkbox]):not([type=radio]):focus-visible,
.drawer :is(summary, .link-btn):focus-visible,
.icon-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.settings :is(input[type=checkbox], input[type=radio]):focus-visible,
.drawer :is(input[type=checkbox], input[type=radio]):focus-visible { outline: 3px solid rgba(240,162,60,.7); outline-offset: 2px; }

@media (max-width: 1100px) and (min-width: 769px) {
    .settings { grid-template-columns: 180px minmax(0, 880px); gap: 1.5rem; }
}
@media (max-width: 768px) {
    .settings { display: block; }
    .settings-nav { display: none; }
    .settings-back { display: inline-flex; align-items: center; gap: .3rem; min-height: 32px; margin-bottom: .35rem; font-weight: 600; font-size: .92rem; }
    .set-facts { grid-template-columns: minmax(0, 1fr); gap: .05rem; }
    .settings .form-grid, .drawer .form-grid { grid-template-columns: minmax(0, 1fr); }
    /* Door names wrap on a phone so the instructions keep the width; the actions scroll in the card. */
    .doors-table .door-name { white-space: normal; min-width: 6.5rem; }
    .doors-table td:nth-child(2) { min-width: 12rem; }
    .set-facts dd { margin-bottom: .5rem; }
    /* The phone's tab bar is fixed at the bottom; the bar sits above it. */
    .save-bar { bottom: calc(62px + env(safe-area-inset-bottom)); padding: .6rem .8rem; }
}

/* ---- AI receptionist: Administration › AI receptionist, operator call statements ---- */
/* Month stepper: ‹ September 2026 › reads as one control; the label keeps its width so the arrows do not jump. */
.month-step { display: inline-flex; align-items: center; gap: .35rem; }
.month-step-label { min-width: 9.5rem; text-align: center; font-weight: 600; white-space: nowrap; }
.page-head .month-step, .doc-actions .month-step { margin-right: .25rem; }
.voice-plan { margin-bottom: .9rem; }
.voice-charges tfoot td, .voice-list tfoot td { font-weight: 700; padding: .65rem .8rem; border-top: 2px solid var(--border); }
/* Relative: the visually hidden column name is absolutely positioned and would otherwise escape the box and widen the page. */
.voice-statement .doc-scroll { position: relative; overflow-x: auto; margin-bottom: 1rem; }
.voice-statement .doc-scroll table.doc-lines { margin-bottom: 0; }
.voice-note { margin: .7rem 0 0; }
.voice-calls td.nowrap, .doc-calls td.nowrap { white-space: nowrap; }
.voice-calls .dot { margin-right: .4rem; vertical-align: middle; }
/* The statement is the invoice document, plus a figure row above the lines and the month's calls below the total. */
.voice-statement .doc-figs { margin: 0 0 1.1rem; padding-bottom: 1rem; }
.voice-statement .doc-sub { font-size: 1rem; font-weight: 600; margin: 1.5rem 0 .5rem; }
.voice-statement table.doc-calls td { font-size: .85rem; padding: .35rem .5rem; }
.voice-statement .doc-calls .row-actions { text-align: right; width: 1%; white-space: nowrap; }

@media print {
    /* An Administration page prints as its content alone: no section nav or back link, one column. */
    .settings { display: block; }
    .settings-nav, .settings-back { display: none !important; }
    .set-group { display: block; margin-bottom: 1.2rem; }
    .set-head { margin-bottom: .4rem; break-after: avoid; }
    .set-tools { display: none; }
    .set-group .g-card { border: 0; }
    .set-group .g-card-body { padding: 0; overflow: visible; }
    .fig-row { break-inside: avoid; }
    .voice-calls tr, .doc-calls tr { break-inside: avoid; }
    .voice-statement .doc-scroll { overflow: visible; }
}
