/* ==========================================================================
   Soft-TechBd DoctorDesk — core design system
   --------------------------------------------------------------------------
   One file owns the tokens, the shell and every shared component. Its four
   sibling stylesheets (prescription, print, calendar, queue, tv, auth) refine
   specific screens and inherit these tokens, so a colour or radius change
   lands everywhere at once.

   Direction : ink rail + paper canvas. The navigation is a deep, quiet slab
               of colour; the working surface is white paper. On a phone the
               rail becomes a bottom bar the thumb can reach.
   Accent    : clinical viridian. Carmine is reserved for the Rx mark alone.
   Themes    : light (default) and dark, both driven by the same token names.
               `data-theme="dark"` on <html> switches every value, so no
               component needs a dark variant.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS — LIGHT
   ========================================================================== */

/* Self-hosted Bengali webfont (no CDN): phones without a Bengali system
   font render every Bengali string through these two files. display=swap
   keeps Latin text painting instantly while they load. */
@font-face {
    font-family: "Noto Sans Bengali";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/noto-sans-bengali-400.woff2") format("woff2");
}
@font-face {
    font-family: "Noto Sans Bengali";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/noto-sans-bengali-700.woff2") format("woff2");
}

:root {
    color-scheme: light;

    /* --- Brand: clinical viridian -------------------------------------- */
    --brand:          #0e6b5b;
    --brand-dark:     #0a5648;
    --brand-darker:   #073f35;
    --brand-soft:     #e1f1ec;
    --brand-softer:   #f1f8f5;
    --brand-line:     #bfdfd5;
    --brand-ring:     rgba(14, 107, 91, .22);

    /* Text colour that sits ON each filled colour. In the light theme every
       fill is dark enough for white; in the dark theme the fills are bright
       tints, so white would land at about 2.8:1 — these flip to near-black
       and reach 6.6:1 or better. */
    --brand-contrast:   #ffffff;
    --danger-contrast:  #ffffff;
    --success-contrast: #ffffff;
    --warning-contrast: #ffffff;

    /* --- Rx accent: carmine, for the prescription mark only ------------ */
    --rx:             #b1272f;
    --rx-soft:        #fbeceb;

    /* --- Surfaces ------------------------------------------------------ */
    --paper:          #ffffff;
    --canvas:         #f2f5f6;
    --canvas-deep:    #e7edee;
    --surface-muted:  #f7f9fa;
    --surface-sunken: #edf1f3;
    --surface-hover:  #f1f5f6;
    --surface-glass:  rgba(255, 255, 255, .84);

    /* --- Ink ----------------------------------------------------------- */
    --ink:            #0b1a1f;
    --body:           #364a52;
    --muted:          #63797f;
    --faint:          #8ba0a6;

    /* --- Lines --------------------------------------------------------- */
    --line:           #e0e8ea;
    --line-soft:      #edf2f3;
    --line-strong:    #c9d6d9;

    /* --- Semantic ------------------------------------------------------ */
    --success:        #127a46;
    --success-bg:     #e4f4ea;
    --success-border: #bee3cd;
    --success-ink:    #0b5230;

    --warning:        #96600a;
    --warning-bg:     #fcf2df;
    --warning-border: #eed7a8;
    --warning-ink:    #68420a;

    --danger:         #b3261e;
    --danger-bg:      #fcecea;
    --danger-border:  #f2c9c4;
    --danger-ink:     #7e1b15;

    --info:           #1b5fa8;
    --info-bg:        #e7f0fa;
    --info-border:    #c2d9f0;
    --info-ink:       #124070;

    --slate:          #546773;
    --slate-bg:       #edf1f4;
    --slate-border:   #d3dce1;

    /* --- The rail (sidebar) has its own palette so its component rules
           never have to know that they live on a dark surface. ----------- */
    --rail:            #0c1d23;
    --rail-deep:       #0a171c;

    /* --- Radii --------------------------------------------------------- */
    --radius-xs: 6px;
    --radius-sm: 8px;
    --radius:    10px;
    --radius-md: 12px;
    --radius-lg: 14px;
    --radius-xl: 18px;

    /* --- Elevation (low spread, layered, never dramatic) --------------- */
    --shadow-xs:  0 1px 1px rgba(11, 26, 31, .04);
    --shadow-sm:  0 1px 2px rgba(11, 26, 31, .05), 0 1px 1px rgba(11, 26, 31, .04);
    --shadow-md:  0 1px 2px rgba(11, 26, 31, .05), 0 4px 12px rgba(11, 26, 31, .06);
    --shadow-lg:  0 6px 24px rgba(11, 26, 31, .13);
    --shadow-pop: 0 2px 6px rgba(11, 26, 31, .08), 0 16px 40px rgba(11, 26, 31, .14);

    /* --- Type ---------------------------------------------------------- */
    --font-ui: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system,
               "Nirmala UI", "Hind Siliguri", "Noto Sans Bengali", Arial, sans-serif;
    --font-display: "Sitka Text", "Palatino Linotype", "Book Antiqua", Georgia,
                    Cambria, "Noto Sans Bengali", "Nirmala UI", serif;
    --font-mono: "Cascadia Mono", "Consolas", "SF Mono", ui-monospace, monospace;
    /* Bengali first, so the pad and the printed sheet read cleanly. Latin
       falls through to the UI stack. Swap this one value to self-host a
       Bengali webfont later — nothing else has to change. */
    --font-bn: "Noto Sans Bengali", "Nirmala UI", "Hind Siliguri", "Vrinda",
               "Shonar Bangla", "Kalpurush", var(--font-ui);

    --fs-xs:   11.5px;
    --fs-sm:   13px;
    --fs-base: 14px;
    --fs-md:   15px;
    --fs-lg:   18px;
    --fs-xl:   22px;
    --fs-2xl:  27px;
    --fs-3xl:  34px;

    /* --- Layout -------------------------------------------------------- */
    --sidebar-w: 175px;
    /* Icon-only rail width. Wide enough for a 17px icon plus its own padding,
       narrow enough to hand the extra width back to the content column. */
    --sidebar-w-collapsed: 58px;
    --topbar-h:  38px;
    --gutter:    18px;
    --tabbar-h:  0px;

    /* --- Motion -------------------------------------------------------- */
    --ease: cubic-bezier(.22, .61, .36, 1);
    --dur:  .18s;
}

/* ==========================================================================
   1b. TOKENS — DARK
   --------------------------------------------------------------------------
   Same names, re-pointed. Nothing below this block ever tests for the theme.
   Values are chosen for contrast on a near-black canvas, not by inverting
   the light palette (which would crush every tint to a muddy grey).
   ========================================================================== */

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

    --brand:          #35c39f;
    --brand-dark:     #2aa989;
    --brand-darker:   #7fe3c8;
    --brand-soft:     rgba(53, 195, 159, .15);
    --brand-softer:   rgba(53, 195, 159, .07);
    --brand-line:     rgba(53, 195, 159, .34);
    --brand-ring:     rgba(53, 195, 159, .28);
    --brand-contrast:   #04120e;
    --danger-contrast:  #170605;
    --success-contrast: #04170d;
    --warning-contrast: #170f01;

    --rx:             #f0706a;
    --rx-soft:        rgba(240, 112, 106, .14);

    --paper:          #111b21;
    --canvas:         #080e12;
    --canvas-deep:    #05090c;
    --surface-muted:  #151f26;
    --surface-sunken: #1a262d;
    --surface-hover:  #1a262d;
    --surface-glass:  rgba(17, 27, 33, .86);

    --ink:            #e8f0f2;
    --body:           #b3c4ca;
    --muted:          #8b9da4;
    --faint:          #6d818a;

    --line:           #24343c;
    --line-soft:      #1b2830;
    --line-strong:    #33454e;

    --success:        #43c97f;
    --success-bg:     rgba(67, 201, 127, .14);
    --success-border: rgba(67, 201, 127, .32);
    --success-ink:    #93e6b6;

    --warning:        #dda64a;
    --warning-bg:     rgba(221, 166, 74, .14);
    --warning-border: rgba(221, 166, 74, .32);
    --warning-ink:    #f0cf92;

    --danger:         #ef6159;
    --danger-bg:      rgba(239, 97, 89, .14);
    --danger-border:  rgba(239, 97, 89, .32);
    --danger-ink:     #f7a8a2;

    --info:           #5aa3e6;
    --info-bg:        rgba(90, 163, 230, .14);
    --info-border:    rgba(90, 163, 230, .32);
    --info-ink:       #a6cdf2;

    --slate:          #9aacb4;
    --slate-bg:       rgba(154, 172, 180, .13);
    --slate-border:   rgba(154, 172, 180, .26);

    --rail:           #070d10;
    --rail-deep:      #050a0c;

    --shadow-xs:  0 1px 1px rgba(0, 0, 0, .30);
    --shadow-sm:  0 1px 2px rgba(0, 0, 0, .34);
    --shadow-md:  0 1px 2px rgba(0, 0, 0, .34), 0 4px 14px rgba(0, 0, 0, .36);
    --shadow-lg:  0 8px 30px rgba(0, 0, 0, .55);
    --shadow-pop: 0 2px 6px rgba(0, 0, 0, .40), 0 18px 44px rgba(0, 0, 0, .55);
}

/* ==========================================================================
   2. RESET & BASE
   ========================================================================== */

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

/* Author display values (flex/grid) beat the UA [hidden] rule, so every
   JS-driven toggle needs this one global guard. */
[hidden] { display: none !important; }

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    -webkit-tap-highlight-color: transparent;
}

body {
    margin: 0;
    font-family: var(--font-ui);
    font-size: var(--fs-base);
    line-height: 1.5;
    color: var(--body);
    background: var(--canvas);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-variant-numeric: tabular-nums;
    /* Deliberately no overflow-x guard: every component is sized to fit its
       container and scrollable regions scroll on their own. Hiding page
       overflow would only mask a real layout bug. */
}

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 .3em;
    font-family: var(--font-display);
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -.008em;
    line-height: 1.24;
}

h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--brand);
    text-decoration: none;
    transition: color var(--dur) var(--ease);
}
a:hover { color: var(--brand-dark); text-decoration: underline; }

img, svg { max-width: 100%; vertical-align: middle; }

/* Visible keyboard focus everywhere, without disturbing mouse users. */
:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
}

::selection { background: var(--brand-soft); color: var(--ink); }

/* ==========================================================================
   3. TYPE UTILITIES
   ========================================================================== */

/* Bengali is a clustering script: letter-spacing pulls conjuncts and vowel
   signs apart and makes words visibly harder to read. When the interface is
   Bengali the tracked-out label treatment is switched off entirely and each
   label uses the natural spacing of the font. */
html[lang="bn"] :is(
    .nav-group__title,
    .stat__label,
    .field__label,
    .label-quiet,
    .detail__key,
    .table th,
    .badge,
    .tab,
    .card__title,
    .dropdown__head,
    .week-day__name,
    /* DEAD CODE 2026-10-08: .cal-day__name is only used by the removed calendar.php */
    /* .cal-day__name, */
    .tv-now__label,
    .tv-next__label,
    .tv-tail__label,
    .tv-foot,
    .auth-brand__sub,
    .sidebar__sub,
    .tabbar__label
) {
    letter-spacing: 0;
    text-transform: none;
}

.display   { font-family: var(--font-display); }
.num       { font-variant-numeric: tabular-nums; }
.muted     { color: var(--muted); }
.faint     { color: var(--faint); }
.strong    { font-weight: 600; color: var(--ink); }
.tiny      { font-size: var(--fs-xs); }
.small     { font-size: var(--fs-sm); }
.truncate  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.mono      { font-family: var(--font-mono); font-size: .92em; }

.label-quiet {
    display: block;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    line-height: 1.35;
    margin-bottom: 4px;
}

/* ==========================================================================
   4. APP SHELL
   ========================================================================== */

.app-shell {
    display: flex;
    min-height: 100vh;
    min-height: 100dvh;
}

/* --- The rail ---------------------------------------------------------
   A dark slab of navigation against the paper canvas. Its component rules
   below reuse --ink/--body/--line, so this block re-points those tokens for
   everything inside it and no child needs a special case.
   --------------------------------------------------------------------- */

.sidebar {
    --paper:          transparent;
    --surface-hover:  rgba(255, 255, 255, .075);
    --surface-sunken: rgba(255, 255, 255, .06);
    --ink:            #eaf3f4;
    --body:           #a9bcc1;
    --muted:          #81959c;
    --faint:          #6c8087;
    --line:           rgba(255, 255, 255, .10);
    --line-soft:      rgba(255, 255, 255, .065);
    --line-strong:    rgba(255, 255, 255, .16);
    --brand:          #4fd0ae;
    --brand-dark:     #7fe3c8;
    --brand-darker:   #b6f0df;
    /* The rail is dark in both themes, so a mint-filled pill inside it needs
       dark text — not the light theme's white. */
    --brand-contrast: #04120e;
    --brand-soft:     rgba(79, 208, 174, .16);
    --brand-softer:   rgba(79, 208, 174, .08);

    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: linear-gradient(180deg, var(--rail) 0%, var(--rail-deep) 100%);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    z-index: 40;
}

.sidebar__brand {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 5px 12px;
    border-bottom: 1px solid var(--line-soft);
    min-height: var(--topbar-h);
    flex: 0 0 auto;
}

.sidebar__mark {
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    border-radius: var(--radius);
    background: var(--rx);
    color: #fff;
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -.02em;
    box-shadow: 0 4px 12px rgba(177, 39, 47, .35);
}
.sidebar__logo {
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    border-radius: var(--radius);
    object-fit: contain;
    background: #fff;
    padding: 3px;
    box-shadow: var(--shadow-xs);
}

.sidebar__titles { min-width: 0; flex: 1 1 auto; }

.sidebar__close {
    display: none;
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    place-items: center;
    border: 1px solid var(--line);
    background: transparent;
    border-radius: var(--radius-sm);
    color: #a9bcc1;
    cursor: pointer;
}
.sidebar__close:hover { background: var(--surface-hover); color: #ffffff; }

.sidebar__name {
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    color: #f2f8f9;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar__sub {
    font-size: 10.5px;
    color: #7d9199;
    letter-spacing: .04em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar__nav {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 10px 8px 14px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .16) transparent;
}
.sidebar__nav::-webkit-scrollbar { width: 8px; }
.sidebar__nav::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, .14);
    border-radius: 99px;
}

.nav-group { margin-bottom: 9px; }

.nav-group__title {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #5d7078;
    padding: 8px 9px 5px;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 8px;
    border-radius: var(--radius);
    color: var(--body);
    font-size: 13.5px;
    font-weight: 500;
    position: relative;
    margin-bottom: 1px;
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.nav-link:hover {
    background: var(--surface-hover);
    color: #eaf3f4;
    text-decoration: none;
}
.nav-link .icon { color: #718790; flex: 0 0 auto; transition: color var(--dur) var(--ease); }
.nav-link:hover .icon { color: var(--brand); }

.nav-link.is-active {
    background: var(--brand-soft);
    color: #eafbf5;
    font-weight: 600;
}
.nav-link.is-active .icon { color: var(--brand); }
.nav-link.is-active::before {
    content: "";
    position: absolute;
    left: -8px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 20px;
    border-radius: 0 3px 3px 0;
    background: var(--brand);
}

.nav-link__count {
    margin-left: auto;
    font-size: 11px;
    font-weight: 700;
    background: var(--brand);
    color: var(--brand-contrast);
    border-radius: 99px;
    padding: 1px 7px;
    min-width: 20px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* --- Rail collapse (desktop only) -------------------------------------
   The state lives on <html> as .is-sidebar-collapsed so the CSS can shrink
   the rail without waiting for JS, and so the same class can be set before
   first paint by app.js to avoid a flash of the wide rail.

   The button sits in the topbar, not in the sidebar: inside the rail it stole
   width from the brand text and pushed the app name into an ellipsis.

   Labels, group titles and the brand text are hidden rather than the icons,
   so every destination stays reachable and the active item stays obvious.
   The mobile drawer is untouched - it already slides out of the way. */
.topbar__collapse {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    margin-right: 2px;
    border-radius: var(--radius);
    background: transparent;
    border: 0;
    color: var(--body);
    cursor: pointer;
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.topbar__collapse:hover { background: var(--surface-hover); color: var(--ink); }

/* Two chevrons ship in the markup; the first is the collapse direction and the
   second the expand direction, so exactly one is ever visible. */
.topbar__collapse-icon { display: grid; place-items: center; }
.topbar__collapse-icon + .topbar__collapse-icon { display: none; }
.is-sidebar-collapsed .topbar__collapse-icon { display: none; }
.is-sidebar-collapsed .topbar__collapse-icon + .topbar__collapse-icon { display: grid; }

.is-sidebar-collapsed .sidebar {
    width: var(--sidebar-w-collapsed);
    flex-basis: var(--sidebar-w-collapsed);
}
.is-sidebar-collapsed .sidebar__titles,
.is-sidebar-collapsed .sidebar__foot,
.is-sidebar-collapsed .nav-group__title,
.is-sidebar-collapsed .nav-link__label {
    display: none;
}
.is-sidebar-collapsed .sidebar__brand { padding-left: 12px; padding-right: 12px; }
.is-sidebar-collapsed .sidebar__nav { padding-left: 8px; padding-right: 8px; }
/* Centre the icon in the row once the label is gone. */
.is-sidebar-collapsed .nav-link {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}
.is-sidebar-collapsed .nav-link__count {
    /* A badge on an icon-only row would sit on top of the icon, so it becomes
       a small dot - enough to know a count exists without reading it. The span
       is only rendered when the count is above zero, so there is no empty
       case to hide. */
    position: absolute;
    top: 3px;
    right: 3px;
    min-width: 0;
    width: 7px;
    height: 7px;
    padding: 0;
    margin-left: 0;
    font-size: 0;
    border-radius: 99px;
}

.sidebar__foot {
    flex: 0 0 auto;
    border-top: 1px solid var(--line-soft);
    padding: 10px 8px;
    font-size: var(--fs-xs);
    color: #6c8087;
}

/* --- Main column ------------------------------------------------------ */

.main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* --- Topbar: a utility strip, not a second title block ---------------- */

.topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    min-height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 3px var(--gutter);
    /* Same dark rail as the sidebar (both themes) — text vars below keep
       everything inside readable on it. Flat rail-top color, not the
       sidebar's full-height gradient (squeezed into 40px it would render
       darker and the seam would show). */
    background: var(--rail);
    border-bottom: 1px solid var(--line);
    --paper:          transparent;
    --surface-hover:  rgba(255, 255, 255, .075);
    --surface-sunken: rgba(255, 255, 255, .06);
    --ink:            #eaf3f4;
    --body:           #a9bcc1;
    --muted:          #81959c;
    --faint:          #6c8087;
    --line:           rgba(255, 255, 255, .10);
    --line-soft:      rgba(255, 255, 255, .065);
    --line-strong:    rgba(255, 255, 255, .16);
    --brand:          #4fd0ae;
    --brand-dark:     #7fe3c8;
    --brand-darker:   #b6f0df;
    --brand-contrast: #04120e;
    --brand-soft:     rgba(79, 208, 174, .16);
    --brand-softer:   rgba(79, 208, 174, .08);
}

/* Compact controls inside the topbar only — global .btn/.input stay full-size. */
.topbar .input { padding: 5px 11px; }
.topbar .btn { padding: 5px 12px; }

/* Content surfaces on the dark rail. --paper is transparent here (same as
   the sidebar), so floating panels need a solid dark surface, and the
   search field needs a dark sunken fill to keep light text readable. */
.topbar .dropdown__menu,
.topbar .ac__list {
    background: var(--rail-deep);
    border-color: rgba(255, 255, 255, .14);
}
.topbar .topbar__search .input {
    background: rgba(255, 255, 255, .08);
    border-color: transparent;
    color: var(--ink);
}
.topbar .topbar__search .input::placeholder { color: var(--muted); }
.topbar .user-chip { background: rgba(255, 255, 255, .06); }

/* Bright content on the dark rail — near-white text and icons so every
   control stays legible at a glance. */
.topbar .topbar__title { color: #ffffff; }
.topbar .topbar__crumb { color: var(--body); }
.topbar .btn--ghost,
.topbar .topbar__collapse,
.topbar .topbar__toggle,
.topbar .user-chip { color: #eaf3f4; }
.topbar .dropdown__head { color: var(--body); }

.topbar__toggle {
    display: none;
    width: 30px;
    height: 30px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    background: var(--paper);
    border-radius: var(--radius);
    color: var(--body);
    cursor: pointer;
    flex: 0 0 auto;
}
.topbar__toggle:hover { background: var(--surface-hover); color: var(--ink); }

.topbar__heading { min-width: 0; }

.topbar__title {
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 600;
    color: var(--ink);
    margin: 0;
    line-height: 1.2;
}

.topbar__crumb {
    font-size: var(--fs-xs);
    color: var(--muted);
    line-height: 1.35;
}

.topbar__spacer { flex: 1 1 auto; }

.topbar__actions {
    display: flex;
    align-items: center;
    gap: 7px;
    /* Shrinkable: with `flex: 0 0 auto` this group refuses to give up any
       width and pushes the whole topbar past the viewport on a phone. */
    flex: 0 1 auto;
    min-width: 0;
}

/* The global patient lookup. It gets a sensible width on a desktop and is
   allowed to shrink all the way down on a phone — the topbar must never be
   the thing that makes the page scroll sideways. */
.topbar__search {
    flex: 1 1 210px;
    min-width: 0;
    max-width: 340px;
}

.topbar__search .input {
    width: 100%;
    min-width: 0;
    border-radius: 99px;
    background: var(--surface-muted);
}

/* --- Page body -------------------------------------------------------- */

.page {
    padding: var(--gutter);
    flex: 1 1 auto;
    min-width: 0;
}

.page--flush { padding: 0; }

.page-head {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}
.page-head__text { min-width: 0; flex: 1 1 260px; }
.page-head__title {
    margin: 0 0 3px;
    font-size: var(--fs-xl);
}
.page-head__desc {
    margin: 0;
    color: var(--muted);
    font-size: var(--fs-sm);
}
.page-head__actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

/* ==========================================================================
   5. CARD
   ========================================================================== */

.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xs);
    margin-bottom: 14px;
    overflow: hidden;
}
.card:last-child { margin-bottom: 0; }

/* A suggestion dropdown must escape its card while open — otherwise the
   card's rounded edge clips the results. Older browsers without :has()
   simply keep the previous clipping behaviour. */
.card:has(.ac__list:not([hidden])) { overflow: visible; }
/* A row action menu must escape its card while open — same treatment as
   the autocomplete dropdown above. Older browsers without :has() simply
   keep the previous clipping behaviour. */
.card:has(.dropdown__menu:not([hidden])) { overflow: visible; }

.card__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--line-soft);
}

.card__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--fs-md);
    font-weight: 600;
    color: var(--ink);
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.card__title .icon { color: var(--brand); flex: 0 0 auto; }

.card__tools { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.card__body { padding: 16px; }
.card__foot {
    padding: 11px 16px;
    border-top: 1px solid var(--line-soft);
    background: var(--surface-muted);
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* ==========================================================================
   6. KPI TILES
   --------------------------------------------------------------------------
   Label, value, one line of context. The tinted icon is the only decoration:
   it identifies the metric at a glance and nothing more.
   ========================================================================== */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
    gap: 12px;
    margin-bottom: 14px;
}

.stat {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 12px 14px;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    box-shadow: var(--shadow-xs);
    min-width: 0;
}

.stat__body { min-width: 0; flex: 1 1 auto; }

.stat__label {
    display: block;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 6px;
    line-height: 1.35;
}

.stat__value {
    font-family: var(--font-display);
    font-size: var(--fs-2xl);
    font-weight: 700;
    line-height: 1.05;
    color: var(--ink);
    letter-spacing: -.02em;
}

.stat__meta {
    margin-top: 5px;
    font-size: var(--fs-xs);
    color: var(--muted);
}

/* Token-style values (queue tokens like A-003) must never wrap mid-token. */
.stat__value--token {
    white-space: nowrap;
}

.stat__icon {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: var(--radius-sm);
    display: grid;
    place-items: center;
    background: var(--slate-bg);
    color: var(--slate);
}

.stat--brand .stat__icon { background: var(--brand-soft);   color: var(--brand); }
.stat--amber .stat__icon { background: var(--warning-bg);   color: var(--warning); }
.stat--green .stat__icon { background: var(--success-bg);   color: var(--success); }
.stat--red   .stat__icon { background: var(--danger-bg);    color: var(--danger); }
.stat--info  .stat__icon { background: var(--info-bg);      color: var(--info); }
.stat--slate .stat__icon { background: var(--slate-bg);     color: var(--slate); }
.stat--teal  .stat__icon { background: var(--brand-soft);   color: var(--brand); }

/* The old design drew a coloured rule across the top of every tile and a
   bare icon inside the label. Both are gone; a tile that needs to draw
   attention is marked with data-state instead of a fourth colour. */
.stat[data-state="alert"] { border-color: var(--warning-border); }
.stat[data-state="alert"] .stat__value { color: var(--warning-ink, var(--warning)); }

/* ==========================================================================
   7. BUTTONS
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 8px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--paper);
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    min-width: 0;
    transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
                color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.btn:hover { background: var(--surface-hover); text-decoration: none; color: var(--ink); }
.btn:active { transform: translateY(.5px); }
.btn .icon { flex: 0 0 auto; }

.btn--primary {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--brand-contrast);
    box-shadow: var(--shadow-sm);
}
.btn--primary:hover {
    background: var(--brand-dark);
    border-color: var(--brand-dark);
    color: var(--brand-contrast);
}

.btn--danger { background: var(--danger); border-color: var(--danger); color: var(--danger-contrast); }
.btn--danger:hover { background: var(--danger); border-color: var(--danger); color: var(--danger-contrast); filter: brightness(.94); }

.btn--success { background: var(--success); border-color: var(--success); color: var(--success-contrast); }
.btn--success:hover { background: var(--success); border-color: var(--success); color: var(--success-contrast); filter: brightness(.94); }

.btn--warning { background: var(--warning); border-color: var(--warning); color: var(--warning-contrast); }
.btn--warning:hover { background: var(--warning); border-color: var(--warning); color: var(--warning-contrast); filter: brightness(.94); }

.btn--ghost { background: transparent; border-color: transparent; color: var(--body); }
.btn--ghost:hover { background: var(--surface-hover); }
.btn--danger-ghost { background: transparent; border-color: transparent; color: var(--danger); }
.btn--danger-ghost:hover { background: var(--danger-soft, #fde8e8); }

.btn--soft {
    background: var(--brand-soft);
    border-color: transparent;
    color: var(--brand-darker);
}
.btn--soft:hover { background: var(--brand-soft); color: var(--brand-darker); filter: brightness(.96); }
/* A set priority flag. Amber rather than the brand tint so it reads as
   "already flagged" at a glance in the queue row. */
.btn--priority-on {
    background: #fff4e0;
    border-color: transparent;
    color: #d97706;
}
.btn--priority-on:hover { background: #fde9c4; color: #b5740a; filter: none; }

.btn--sm { padding: 5px 10px; font-size: var(--fs-sm); gap: 5px; border-radius: var(--radius-sm); }
.btn--lg { padding: 11px 20px; font-size: var(--fs-md); }
.btn--block { width: 100%; }
.btn--icon { padding: 7px; width: 36px; height: 36px; }
.btn--icon.btn--sm { width: 30px; height: 30px; padding: 4px; }

.btn:disabled,
.btn.is-disabled {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}

/* A quiet icon-only control — used for destructive row actions. */
.btn-quiet {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--faint);
    cursor: pointer;
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn-quiet:hover { background: var(--surface-sunken); color: var(--body); }
.btn-quiet--danger:hover { background: var(--danger-bg); color: var(--danger); }

/* Text-only action: no border, no background. */
.link-action {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: var(--brand);
    cursor: pointer;
}
.link-action:hover { text-decoration: underline; }
.link-action--danger { color: var(--danger); }

.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.btn-group {
    display: inline-flex;
    border-radius: var(--radius-sm);
    overflow: hidden;
    border: 1px solid var(--line);
}
.btn-group .btn { border: 0; border-radius: 0; }

/* ==========================================================================
   8. BADGES, PILLS, CHIPS
   ========================================================================== */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 99px;
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1.7;
    border: 1px solid transparent;
    white-space: nowrap;
}

.badge--slate   { background: var(--slate-bg);   color: var(--slate);   border-color: var(--slate-border); }
.badge--blue, .badge--info { background: var(--info-bg); color: var(--info-ink); border-color: var(--info-border); }
.badge--amber, .badge--warning { background: var(--warning-bg); color: var(--warning-ink); border-color: var(--warning-border); }
.badge--green, .badge--success { background: var(--success-bg); color: var(--success-ink); border-color: var(--success-border); }
.badge--red, .badge--danger { background: var(--danger-bg); color: var(--danger-ink); border-color: var(--danger-border); }
.badge--teal, .badge--brand { background: var(--brand-soft); color: var(--brand-darker); border-color: var(--brand-line); }
.badge--violet { background: #efe9fb; color: #5b3fa8; border-color: #d9cdf3; }

.badge--dot::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

/* Token / serial pill — the number itself is the information. */
.token-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 56px;
    padding: 3px 9px;
    border-radius: var(--radius-sm);
    background: var(--surface-sunken);
    border: 1px solid var(--line);
    color: var(--ink);
    font-weight: 700;
    font-size: var(--fs-sm);
    letter-spacing: .02em;
    white-space: nowrap;
}
.token-pill--current {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--brand-contrast);
}
.token-pill--done {
    background: var(--success-bg);
    border-color: var(--success-border);
    color: var(--success-ink);
}
.token-pill--report {
    background: var(--info-bg);
    border-color: var(--info-border);
    color: var(--info-ink);
}
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px 3px 10px;
    border-radius: 99px;
    background: var(--brand-soft);
    color: var(--brand-darker);
    font-size: var(--fs-sm);
    font-weight: 600;
    border: 1px solid var(--brand-line);
}
/* A short result or note shown inside a chip, kept quiet so the chip's own
   label stays the loudest thing in it. */
.chip__note {
    font-weight: 500;
    font-size: var(--fs-xs);
    color: var(--muted);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 34ch;
}

.chip-add {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 99px;
    border: 1px dashed var(--line-strong);
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
}
.chip-add:hover { border-color: var(--brand); color: var(--brand); background: var(--brand-softer); }

/* Simple removable chips for the pre-check / instant-visit investigation
   box (no prescription.css dependency — plain spans + hidden inputs). */
.inv-list { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.inv-list:empty { margin-bottom: 0; }
.inv-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 10px;
    border-radius: 99px;
    background: var(--brand-soft);
    color: var(--brand-darker);
    font-size: var(--fs-sm);
    font-weight: 600;
    border: 1px solid var(--brand-line);
}
.inv-chip__x {
    border: 0;
    background: none;
    color: inherit;
    font-size: 15px;
    line-height: 1;
    padding: 4px 6px;
    border-radius: 50%;
    cursor: pointer;
}
.inv-chip__x:hover { background: rgba(0, 0, 0, .08); }
.inv-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 6px;
    width: 100%;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    background: var(--brand-soft);
    border: 1px solid var(--brand-line);
}
.inv-row .input { min-width: 0; grid-column: 1 / -1; }
.inv-row__head {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
}
/* Instant Visit sections read as grouped blocks: the bare margin between
   them looked like a stray white band, so each section gets the same
   subtle divider the appointment comment describes ("one divider each"). */
.instant-page .appt-sec + .appt-sec {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}
/* Section titles double as collapse toggles (Vitals / Investigations start
   hidden). The chevron points down when closed, up when open. */
.sec-toggle {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    text-align: left;
}
.sec-toggle .icon { transition: transform .15s ease; color: var(--muted); }
.sec-toggle[aria-expanded="true"] .icon { transform: rotate(180deg); }

/* Section headings must read as headings on EVERY screen. This rule used to
   live only in responsive.css inside @media (max-width: 767px), so on a
   desktop the Instant Visit / check-in section titles fell back to the UA's
   plain h3 — no brand colour, no uppercase, no accent — and "Vitals" and
   "Investigations" did not stand out the way the form's other headings do.
   Base rule here (all viewports); the mobile block only trims the margin. */
.appt-sec__title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    padding-left: 10px;
    border-left: 3px solid var(--brand);
    font-size: 14px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--brand-darker);
    line-height: 1.3;
}
/* Bengali has no uppercase; the extra tracking just smears the letters. */
html[lang="bn"] .appt-sec__title { letter-spacing: 0; text-transform: none; }
/* The toggle IS the heading here, so it must not flatten the weight it
   inherits (font:inherit does keep it, but the UA button style can fight
   it on some engines). */
.appt-sec__title .sec-toggle {
    font: inherit;
    font-weight: inherit;
    color: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    font-size: inherit;
}
/* The bracketed hint next to a title is guidance, not part of the heading. */
.appt-sec__title .faint { font-weight: 600; text-transform: none; letter-spacing: 0; }
.appt-sec__title .sec-toggle .icon { color: var(--brand); }
/* Vitals / Investigations are the two collapsible clinical blocks on the
   Instant Visit form; red ink sets them apart from the plain Patient / Type /
   Billing / Referral sections above. Weight is already 800 from
   .appt-sec__title, so only the ink and the accent bar change — and the
   chevron follows, because this rule lands after the --brand one above. The
   doubled class is deliberate: responsive.css re-inks .appt-sec__title for
   phones and is loaded later, so a single class would lose there. */
.appt-sec__title.appt-sec__title--accent { color: var(--danger); border-left-color: var(--danger); }
.appt-sec__title.appt-sec__title--accent .sec-toggle .icon { color: var(--danger); }

/* Unit hint sitting next to a field label ("BP mmHg"). Was only styled inside
   the check-in modal's phone block, so the same markup elsewhere rendered as
   plain body text. Kept light: it is a unit, not a second label. */
.ci-unit {
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--muted);
    font-size: .92em;
}

/* PC checkbox (Instant Visit + the appointments form).
   The native box already ticks, but at 17px on a phone that tick is easy to
   miss, so the LABEL carries the confirmation too: tick the box and the word
   itself becomes "✓ PC" in the brand colour. CSS only — no JS to keep in
   sync, and the checked state survives a form re-render. */
.appt-pccheck .check { align-items: center; }
.appt-pccheck .check input[type="checkbox"] { width: 19px; height: 19px; }
.appt-pccheck .check span {
    font-weight: 700;
    transition: color .12s ease;
}
.appt-pccheck .check input:checked + span { color: var(--brand-darker); }
.appt-pccheck .check input:checked + span::before {
    content: "\2713\00a0"; /* ✓ + nbsp, so the tick sits off the text */
    font-weight: 800;
}

/* ==========================================================================
   INVESTIGATIONS (shared with investigations/order.php — its inline copy
   was moved here so the instant form and check-in modal reuse the same
   picker, rows and history blocks; .inv- prefix, page-agnostic).
   ========================================================================== */

.inv-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.inv-head__title { font-size: 24px; margin: 0; }
.inv-head__sub { color: var(--muted, #45606e); font-size: 14px; margin-top: 4px; }
.inv-idbadge {
    display: inline-block; font-size: 13px; font-weight: 600;
    border: 1px solid var(--line, #d9e2e8); border-radius: 8px;
    background: var(--surface-soft, #f4f7f9); padding: 2px 10px; margin-top: 6px;
}
.inv-card {
    background: #fff; border: 1px solid var(--line-soft, #e5ebef);
    border-radius: 14px; padding: 16px 18px; margin-bottom: 16px;
}
.inv-card__title { font-size: 17px; margin: 0 0 4px; display: flex; align-items: center; gap: 8px; }
.inv-card__sub { color: var(--muted, #45606e); font-size: 13px; margin: 0 0 12px; }
.inv-pgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 560px) {
    .inv-head { margin-bottom: 12px; }
    .inv-head__title { font-size: 20px; }
    .inv-card { padding: 12px 13px; margin-bottom: 12px; border-radius: 12px; }
    .inv-card__title { font-size: 15.5px; }
    .inv-card__sub { margin-bottom: 10px; }
    .inv-pgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; }
    .inv-pgrid__val { font-size: 14px; }
    .inv-req { margin-bottom: 10px; }
    .inv-result { min-height: 42px; }
}
.inv-pgrid__key { font-size: 12px; color: var(--muted, #45606e); }
.inv-pgrid__val { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.inv-requested { background: #f2f8f7; border-color: #d7e9e4; }
.inv-req { display: grid; gap: 2px 12px; margin-bottom: 12px; }
.inv-req:last-child { margin-bottom: 0; }
.inv-result { border-radius: 9px; min-height: 46px; }
.inv-result:focus { border-color: var(--brand, #0e6b5b); box-shadow: 0 0 0 3px rgba(14,107,91,.12); outline: none; }
.inv-req__field { min-width: 0; }
.inv-prev {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
    margin-top: 5px; font-size: 12.5px; line-height: 1.5; color: var(--muted, #45606e);
}
.inv-prev__tag {
    font-size: 11.5px; font-weight: 700; color: var(--brand-darker, #0e6b5b);
    background: #e3f0ed; border-radius: 999px; padding: 1px 9px; white-space: nowrap;
}
.inv-prev__text { color: var(--ink, #16232b); overflow-wrap: anywhere; }
.inv-prev__file { font-size: 12.5px; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.inv-submitted { display: grid; gap: 10px; }
.inv-submitted__row {
    border-left: 3px solid var(--brand, #0e6b5b);
    background: var(--surface-soft, #f4f7f9);
    border-radius: 0 9px 9px 0; padding: 9px 12px;
}
.inv-submitted__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; }
.inv-submitted__name { font-weight: 600; font-size: 14.5px; overflow-wrap: anywhere; }
.inv-submitted__head .btn { margin-left: auto; }
.inv-submitted__text {
    margin-top: 4px; font-size: 13.5px; line-height: 1.55;
    color: var(--ink, #16232b); overflow-wrap: anywhere;
}
@media (min-width: 561px) {
    .inv-req { grid-template-columns: minmax(200px, 5fr) 7fr; align-items: center; }
}
@media (max-width: 820px) {
    .inv-pgrid { grid-template-columns: repeat(2, 1fr); }
    .inv-head__title { font-size: 22px; }
}
@media (max-width: 560px) {
    .inv-pgrid { grid-template-columns: 1fr; }
    .inv-actions .btn { flex: 1 1 100%; }
}
.inv-modal[hidden] { display: none; }
/* Above .modal-backdrop (800): the picker is also launched from inside the
   check-in modal, where it must sit on top rather than hide behind it. */
.inv-modal { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 16px; }
.inv-modal__scrim { position: absolute; inset: 0; background: rgba(16,35,45,.45); }
.inv-modal__dialog {
    position: relative; background: #fff; border-radius: 16px; width: 100%; max-width: 560px;
    max-height: 70vh; display: flex; flex-direction: column; overflow: hidden;
}
.inv-modal__head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 8px; }
.inv-modal__title { font-size: 17px; margin: 0; }
.inv-modal__search { padding: 0 16px 8px; }
.inv-modal__list { overflow: auto; padding: 0 8px; flex: 1 1 auto; min-height: 0; }
.inv-modal__list .check { display: flex; min-height: 48px; align-items: center; font-size: 15px; border-bottom: 1px solid var(--line-soft, #eef2f5); }
.inv-modal__foot {
    display: flex; align-items: center; gap: 8px; padding: 12px 16px;
    border-top: 1px solid var(--line-soft, #eef2f5); background: #fff;
    position: sticky; bottom: 0;
}
.inv-countbadge {
    display: inline-block; font-size: 13px; font-weight: 700; color: var(--brand-darker, #0e6b5b);
    background: #e3f0ed; border-radius: 999px; padding: 3px 12px; margin-left: 8px; vertical-align: middle;
}
@media (max-width: 560px) {
    .inv-modal { align-items: flex-end; padding: 0 0 calc(var(--tabbar-h, 0px) + env(safe-area-inset-bottom, 0px)); }
    .inv-modal__dialog { border-radius: 16px 16px 0 0; max-width: none; max-height: 85vh; }
}
.inv-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.inv-workflow { border-style: dashed; }
/* Checkbox-picker trigger row inside forms reusing the picker. */
.inv-pickrow { margin-bottom: 8px; }
.inv-pickrow:empty { margin-bottom: 0; }
.inv-row__name {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--brand-darker);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.iv-lastvisit {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-sunken);
    padding: 10px 12px;
}
.iv-lastvisit__head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.iv-lastvisit__grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 12px;
    font-size: var(--fs-sm);
}
.iv-lastvisit__grid > span:nth-child(odd) { color: var(--muted); }
.iv-lastvisit__sec { margin-top: 8px; font-size: var(--fs-sm); }
.iv-lastvisit__sec ul { margin: 4px 0 0; padding-left: 18px; }

/* ==========================================================================
   9. TABLES
   ========================================================================== */

.table-wrap { overflow-x: auto; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

.table th {
    text-align: left;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--surface-muted);
    padding: 9px 12px;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 1;
}

.table td {
    padding: 9px 12px;
    border-bottom: 1px solid var(--line-soft);
    vertical-align: middle;
    color: var(--body);
}

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

/* Patient list address column (desktop table only — phones render .pt-list).
   Long village names ellipsize instead of stretching the table. */
.pt-table td.col-address { max-width: 220px; }
.pt-table td.col-address .truncate { display: inline-block; max-width: 100%; vertical-align: bottom; }
.table tbody tr:hover { background: var(--surface-hover); }

.table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.table td.center, .table th.center { text-align: center; }
.table .cell-strong { font-weight: 600; color: var(--ink); }
/* Where a cell carries a name plus a code, stack them: the code is a second
   line of information, not a word in the sentence. Keeping them inline made
   the code break across lines mid-token ("P-" / "000011"). */
.table td.cell-title > .cell-strong { display: block; }
.table td.cell-title > .faint {
    display: block;
    font-size: var(--fs-xs);
    white-space: nowrap;
    line-height: 1.4;
}
.table .cell-actions { text-align: right; white-space: nowrap; }
.table .cell-tight { width: 1%; white-space: nowrap; }

/* --- Compact appointment board (appointments/index.php, desktop) --------
   Tighter cells so a day's list reads as rows, not padded blocks. The
   patient cell still carries two lines (name + code · age · gender). */
.appt-table th { padding: 8px 10px; }
.appt-table td { padding: 6px 10px; }

/* Doctor-created bookings: a calm teal tint plus an accent bar on the
   first cell, so the desk sees at a glance who booked it. Never dark. */
.appt-table tr.is-doctor { background: #f5f1fd; }
.appt-table tr.is-doctor > td:first-child { box-shadow: inset 3px 0 0 #7c5cd6; }
.doc-badge { font-size: 10px; padding: 1px 6px; margin-left: 6px; vertical-align: 1px; white-space: nowrap; }

/* Today's Collection hooks: desktop shows the full type label and plain
   amounts; the short badge and inline labels are phone-only (see the 767px
   block in responsive.css). */
.collect-table .ctype-short,
.collect-table .ccol-label,
.collect-table .cdisc-label { display: none; }

/* Billing hooks: desktop shows the plain table; the due label is phone-only
   (see the 767px block in responsive.css). */
.bill-table .bdue-label { display: none; }
.appt-table .cell-actions .btn,
.appt-table .cell-actions .btn-quiet { vertical-align: middle; }

/* Compact two-line rows: tighter cells, token + checkbox on one line. */
.appt-page .appt-table th { padding: 5px 10px; }
.appt-page .appt-table td { padding: 3px 10px; }
.appt-page .appt-table .cell-title > .cell-strong { font-size: 13px; font-weight: 700; line-height: 1.3; }
.appt-page .appt-table td.cell-title > .faint { font-size: 11px; line-height: 1.35; margin-top: 0; }
.appt-page .appt-table .token-pill { min-width: 48px; padding: 2px 6px; font-size: 12px; }
.appt-page .appt-table .cell-token .rep-check { margin-right: 4px; }
.appt-page .appt-table .badge { padding: 1px 8px; }
.appt-page .appt-table .cell-act-top,
.appt-page .appt-table .cell-act-bottom {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    vertical-align: middle;
}
/* Status/type badges: calm neutrals; only now + next carry a subtle teal.
   Same size and shape throughout. */
.appt-page .appt-table .badge { font-size: 11.5px; }
.appt-page .appt-table .badge--slate,
.appt-page .appt-table .badge--amber,
.appt-page .appt-table .badge--blue,
.appt-page .appt-table .badge--green,
.appt-page .appt-table .badge--red {
    background: var(--surface-sunken);
    color: var(--body);
    border-color: var(--line);
}
/* Doctor-added marker: subtle teal tint. */
.appt-page .appt-table .badge--violet {
    background: var(--brand-soft);
    color: var(--brand-dark);
    border-color: var(--brand-line);
}
.appt-page .appt-table .badge--teal {
    background: var(--brand-soft);
    color: var(--brand-dark);
    border-color: var(--brand-line);
}
.appt-page .appt-table .token-pill--done,
.appt-page .appt-table .token-pill--report {
    background: var(--surface-sunken);
    border-color: var(--line);
    color: var(--body);
}
/* Doctor-added rows: very subtle teal wash + teal edge bar, so the desk
   sees at a glance who booked it. */
.appt-page .appt-table tr.is-doctor { background: var(--brand-softer); }
.appt-page .appt-table tr.is-doctor > td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
/* Selected / active row: white, with a small teal accent on its left edge. */
.appt-page .appt-table tbody tr.is-current > td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
.appt-page .appt-table tbody tr.is-highlight > td:first-child { box-shadow: inset 3px 0 0 var(--brand-line); }
/* Row icon buttons: neutral light-gray, dark icon. */
.appt-page .appt-table .btn--soft {
    background: var(--surface-sunken);
    border-color: transparent;
    color: var(--body);
}
/* Toolbar secondary action: white with a thin border. */
.appt-panel__tools .btn--soft {
    background: var(--paper);
    border-color: var(--line-strong);
    color: var(--body);
}

/* DEAD CODE 2026-10-08: .pc-table is not used by any live markup
   (the pre-check board was retired). Commented out, not deleted.
--- Compact pre-check board (precheck/index.php, desktop) --------------
.pc-table th { padding: 8px 10px; }
.pc-table td { padding: 6px 10px; }
.pc-table .cell-actions .btn,
.pc-table .cell-actions .btn-quiet { vertical-align: middle; }
*/

/* --- Compact patient board (patients/index.php, desktop) ---------------- */
.pt-table th { padding: 8px 10px; }
.pt-table td { padding: 6px 10px; }
.pt-table .cell-actions .btn,
.pt-table .cell-actions .btn-quiet { vertical-align: middle; }

/* Visit-type tally strip between the filters and the list. Plain text
   with tabular numerals — a segmented control would promise filtering
   that is not there. */
.appt-types {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    padding: 9px 18px;
    border-bottom: 1px solid var(--line-soft);
    font-size: 12.5px;
    color: var(--muted);
}
.appt-types__item { display: inline-flex; align-items: baseline; gap: 5px; white-space: nowrap; }
.appt-types__label { text-transform: uppercase; font-size: 11px; font-weight: 700; letter-spacing: .05em; }
html[lang="bn"] .appt-types__label { letter-spacing: 0; }
.appt-types__num { font-size: 13px; font-weight: 800; color: var(--brand-dark); font-variant-numeric: tabular-nums; }
/* Mobile-only phone line in waiting rows (rendered on small screens). */
.cell-phone-mob { display: none; }

/* --- Compact visit board (visits/index.php, desktop) ------------------- */
.visit-table th { padding: 8px 10px; }
.visit-table td { padding: 6px 10px; }
.visit-table .cell-actions .btn,
.visit-table .cell-actions .btn-quiet { vertical-align: middle; }

/* Phone-only lists (see responsive.css): desktop never renders them. */
.appt-list { display: none; }
.pc-list { display: none; }
.pv-list { display: none; }
.rx-list { display: none; }
.rx-vitals-m { display: none; }

/* The waiting board's phone card list. Desktop keeps the table above, so this
   is hidden here and switched on at <=640px in responsive.css. */
.appt-cards { display: none; }
.vs-list { display: none; }

/* Shared print-chooser / fee modals on the appointment board. */
.modal--sm { width: min(400px, 100%); }
.modal__title { margin: 0; font-size: var(--fs-md); }
.modal__head .btn-quiet { margin-left: auto; }
.modal__patient { margin: 0 0 12px; font-weight: 600; color: var(--ink); }
.modal__choices { display: grid; gap: 8px; }
.modal__choices .btn { justify-content: center; }
.fee-current {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 12px;
    margin-bottom: 12px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--surface-muted);
    font-size: 13.5px;
}
.fee-current__label { color: var(--muted); }
.fee-current__val { font-size: var(--fs-md); font-variant-numeric: tabular-nums; }

.table--rows tr.is-highlight { background: var(--brand-softer); }
.table--rows tr.is-current { background: var(--brand-soft); box-shadow: inset 3px 0 0 var(--brand); }

/* ==========================================================================
   10. FORMS
   ========================================================================== */

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px 16px;
}
.form-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.field { min-width: 0; }
.field--full { grid-column: 1 / -1; }
.field--narrow { flex: 0 1 110px; }

/* --- Repeater rows (allergies, medical history, template medicines) ----- */

.repeater__rows { display: grid; gap: 10px; }

.repeater__row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-end;
    padding: 10px 12px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--surface-muted);
}
.repeater__row .field { flex: 1 1 160px; min-width: 0; }
.repeater__row .field--narrow { flex: 0 1 110px; }
.repeater__row .repeater__remove { margin-left: auto; flex: 0 0 auto; margin-bottom: 3px; }

.field__label {
    display: block;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    line-height: 1.35;
    margin-bottom: 4px;
}
.field__label .req { color: var(--danger); margin-left: 2px; }

.field__hint {
    margin-top: 3px;
    font-size: var(--fs-xs);
    line-height: 1.4;
    color: var(--faint);
}

.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea { border-color: var(--danger); background: var(--danger-bg); }

.input,
.select,
.textarea {
    width: 100%;
    min-width: 0;
    padding: 9px 11px;
    font-family: inherit;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--ink);
    background: var(--paper);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
    -webkit-appearance: none;
    appearance: none;
}

.input::placeholder, .textarea::placeholder { color: var(--faint); }

.input:hover, .select:hover, .textarea:hover { border-color: var(--faint); }

.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-ring);
}

.input:disabled, .select:disabled, .textarea:disabled,
.input[readonly] {
    background: var(--surface-sunken);
    color: var(--muted);
    cursor: not-allowed;
}

/* A control that needs the operator's attention before it can be submitted. */
.input.is-invalid {
    border-color: var(--danger);
    background: var(--danger-bg);
    box-shadow: 0 0 0 3px var(--danger-bg);
}

.select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b8590' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 32px;
}
html[data-theme="dark"] .select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b9da4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

.textarea { min-height: 76px; resize: vertical; line-height: 1.6; }
.textarea--one-line { min-height: 40px; }

.input--sm { padding: 5px 9px; font-size: var(--fs-sm); }

.input-group { display: flex; gap: 8px; align-items: stretch; }
.input-group .input { flex: 1 1 auto; min-width: 0; }
.input-group .btn { flex: 0 0 auto; }

/* Checkbox & radio */
.check {
    display: inline-flex;
    align-items: flex-start;
    gap: 8px;
    cursor: pointer;
    font-size: 13.5px;
    color: var(--body);
    user-select: none;
}
.check input[type="checkbox"],
.check input[type="radio"] {
    width: 17px;
    height: 17px;
    margin: 2px 0 0;
    flex: 0 0 auto;
    accent-color: var(--brand);
    cursor: pointer;
}

.switch {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    cursor: pointer;
    font-size: 13.5px;
}
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
    width: 40px;
    height: 23px;
    border-radius: 99px;
    background: var(--line-strong);
    position: relative;
    transition: background var(--dur) var(--ease);
    flex: 0 0 auto;
}
.switch__track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: #fff;
    box-shadow: var(--shadow-sm);
    transition: transform var(--dur) var(--ease);
}
.switch input:checked + .switch__track { background: var(--brand); }
.switch input:checked + .switch__track::after { transform: translateX(17px); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Filter bar */
.filters {
    display: flex;
    gap: 9px;
    align-items: flex-end;
    flex-wrap: wrap;
    padding: 11px 16px;
    border-bottom: 1px solid var(--line-soft);
    background: var(--surface-muted);
}
.filters .field { flex: 1 1 150px; max-width: 260px; }
.filters .field__label { margin-bottom: 3px; }
.filters .field--wide { flex: 1 1 260px; max-width: 420px; }
.filters__actions { display: flex; gap: 8px; margin-left: auto; }

/* Appointment list filters are only two short fields, so the default filter
   bar is taller than the content it holds. Trim the vertical padding to about
   62px. Responsive.css applies the same trim at phone widths - these rules
   are the desktop half of that pair, so the bar does not jump size between
   breakpoints. */
.appt-page .filters { padding: 7px 14px; gap: 8px; }
.appt-page .filters .field__label { margin-bottom: 2px; font-size: 10.5px; line-height: 1.2; }
.appt-page .filters .input,
.appt-page .filters .select { padding: 6px 10px; }
.appt-page .filters__actions .btn { padding: 6px 12px; }

/* ==========================================================================
   11. TABS / SEGMENTED
   ========================================================================== */

.tabs {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

/* Settings home cards (Digital Rx style simple navigation). */
.settings-home-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}
.settings-home-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--card, #fff);
    color: inherit;
    text-decoration: none;
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.settings-home-card:active { transform: scale(.98); }
.settings-home-card:hover { border-color: var(--primary, #0d6e7a); box-shadow: 0 4px 14px rgba(13, 110, 122, .12); }
.settings-home-ico {
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: var(--primary-soft, #e6f4f1);
    color: var(--primary-deep, #0d6e7a);
}
.settings-home-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.settings-home-body b { font-size: 14px; }
.settings-home-body small { font-size: 12px; color: var(--muted); }
.settings-home-go { color: var(--muted); flex-shrink: 0; font-size: 22px; line-height: 1; font-weight: 700; }

/* Preset Data template hub (Digital Rx style search + list). */
.tpl-hub__bar { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
.tpl-hub__bar .search-box { position: relative; display: flex; align-items: center; }
.tpl-hub__bar .search-ico { position: absolute; left: 10px; color: var(--muted); display: grid; place-items: center; pointer-events: none; }
.tpl-hub__bar .input[type="search"] { padding-left: 34px; width: 100%; }
.tpl-hub .list-end { display: flex; gap: 6px; align-items: center; }

/* Preset Data hub (Digital Rx style: left categories + scored list). */
.preset-layout { display: flex; gap: 0; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--card, #fff); }
.preset-nav { width: 210px; flex-shrink: 0; border-right: 1px solid var(--line); padding: 8px; display: flex; flex-direction: column; gap: 2px; background: var(--surface, #f8faf9); }
.preset-nav__item { display: block; padding: 8px 10px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--body); text-decoration: none; }
.preset-nav__item:hover { background: var(--surface-hover, #eef3f1); }
.preset-nav__item.is-active { background: #d7e9f5; color: #0b4a5a; }
.preset-main { flex: 1; min-width: 0; padding: 14px 16px; overflow: hidden; }
.preset-main__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.preset-main__head .btn { flex-shrink: 0; }
.preset-main__title { font-size: 17px; font-weight: 700; margin: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; min-width: 0; }
.preset-search { position: relative; display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.preset-search .search-ico { position: absolute; left: 10px; color: var(--muted); display: grid; place-items: center; pointer-events: none; }
.preset-search .input[type="search"] { padding-left: 34px; flex: 1; min-width: 0; }
.preset-search .btn { flex-shrink: 0; }
/* Preset rows: Digital Rx style — text left, Edit/Hide right, hairline between. */
.preset-list { border-top: 1px solid var(--line); }
.preset-list .list-item.preset-row { display: flex; align-items: center; gap: 12px; padding: 9px 2px; border-bottom: 1px solid var(--line); }
.preset-list .list-body { flex: 1; min-width: 0; }
.preset-list .list-body .name { font-size: 14px; font-weight: 600; overflow-wrap: break-word; }
.preset-list .list-body .sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.preset-row.is-hidden { opacity: .55; }
.preset-actions { display: flex; gap: 10px; align-items: center; flex-shrink: 0; }
.preset-act { font-size: 12px; font-weight: 700; color: #b7791f; text-decoration: none; background: none; border: none; cursor: pointer; padding: 2px 0; white-space: nowrap; }
.preset-act:hover { text-decoration: underline; }
.preset-act--danger { color: #c0392b; }
.preset-add { display: flex; gap: 8px; margin-bottom: 12px; }
.preset-add .input { flex: 1; }
@media (max-width: 720px) {
    .preset-layout { flex-direction: column; }
    .preset-nav { width: auto; border-right: none; border-bottom: 1px solid var(--line); flex-direction: row; overflow-x: auto; }
    .preset-nav__item { white-space: nowrap; }
}

.tab {
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    flex: 0 0 auto;
    transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.is-active { color: var(--brand); border-bottom-color: var(--brand); }

/* Status-filter tabs on the Appointment Summary: label + live count chip. */
.tab__count {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface-sunken);
    font-size: 11px;
    font-weight: 700;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
.tab.is-active .tab__count {
    background: var(--brand-soft);
    border-color: var(--brand-line);
    color: var(--brand);
}
.appt-tabs {
    gap: 10px;
    padding: 2px 0 6px;
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow-x: auto;
}
.appt-tabs .tab {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 8px 14px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--body);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 7px;
    white-space: nowrap;
}
.appt-tabs .tab:hover {
    border-color: var(--brand-line);
    color: var(--brand-dark);
}
.appt-tabs .tab:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}
.appt-tabs .tab__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    margin: 0;
    padding: 0 7px;
    border: 0;
    border-radius: 999px;
    background: var(--surface-sunken);
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1;
    color: var(--body);
    font-variant-numeric: tabular-nums;
}
/* Active tab — the only tinted tab: very subtle teal wash, bold dark-teal
   text, solid dark-teal count badge, clean 2px bottom accent. */
.appt-tabs .tab.is-active {
    background: var(--brand-softer);
    border-color: var(--brand-line);
    color: var(--brand-dark);
    font-weight: 700;
    box-shadow: inset 0 -2px 0 var(--brand);
}
.appt-tabs .tab.is-active .tab__count {
    background: var(--brand-dark);
    border: 0;
    color: #ffffff;
}
.appt-panel { min-height: 120px; }
.appt-panel.is-loading { opacity: .55; pointer-events: none; }
.appt-panel__tools {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    padding: 12px 18px 0;
}

.segmented {
    display: inline-flex;
    padding: 3px;
    background: var(--surface-sunken);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    gap: 2px;
}
.segmented a, .segmented button {
    padding: 5px 12px;
    border: 0;
    background: transparent;
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
}
.segmented a:hover, .segmented button:hover { color: var(--ink); text-decoration: none; }
.segmented .is-active {
    background: var(--paper);
    color: var(--ink);
    box-shadow: var(--shadow-xs);
}

/* ==========================================================================
   12. ALERTS / FLASH / TOAST
   ========================================================================== */

.alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 11px 13px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface-muted);
    font-size: 13.5px;
    margin-bottom: 10px;
}
.alert .icon { flex: 0 0 auto; margin-top: 1px; }
.alert__body { flex: 1 1 auto; min-width: 0; }
.alert__title { font-weight: 700; margin-bottom: 2px; }
.alert--success { background: var(--success-bg); border-color: var(--success-border); color: var(--success-ink); }
.alert--success .icon { color: var(--success); }
.alert--error { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-ink); }
.alert--error .icon { color: var(--danger); }
.alert--warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-ink); }
.alert--warning .icon { color: var(--warning); }
.alert--info { background: var(--info-bg); border-color: var(--info-border); color: var(--info-ink); }
.alert--info .icon { color: var(--info); }

.alert ul { margin: 4px 0 0; padding-left: 18px; }

.flash-stack { margin-bottom: 12px; }
.flash-stack .alert:last-child { margin-bottom: 0; }

/* Flash-message wrapper (includes/topbar.php). It deliberately is NOT .page:
   .page is flex:1 1 auto, and as a sibling of the content <main class="page">
   inside the flex-column .main it would absorb free viewport height and park
   a ~140px empty gap under the alert. This wrapper keeps its own height;
   the gap to the card below is the stack margin (6px) plus the content
   page's own top padding (gutter, 18px) = 24px. */
.flash-wrap { flex: 0 0 auto; padding: var(--gutter) var(--gutter) 0; }
.flash-wrap > .flash-stack { margin-bottom: 6px; }
.flash-wrap > .alert { margin-bottom: 6px; }

.toast-host {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 900;
    left: auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: min(360px, calc(100vw - 36px));
    pointer-events: none;
}
.toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 12px 13px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-left: 3px solid var(--brand);
    border-radius: var(--radius);
    box-shadow: var(--shadow-pop);
    font-size: 13.5px;
    color: var(--ink);
    animation: toast-in .22s var(--ease);
}
.toast--success { border-left-color: var(--success); }
.toast--success .icon { color: var(--success); }
.toast--error { border-left-color: var(--danger); }
.toast--error .icon { color: var(--danger); }
.toast--info { border-left-color: var(--info); }
.toast--info .icon { color: var(--info); }
.toast.is-leaving { animation: toast-out .18s var(--ease) forwards; }

@keyframes toast-in  { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-out { to   { opacity: 0; transform: translateY(6px); } }

/* ==========================================================================
   13. MODAL / BOTTOM SHEET
   ========================================================================== */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(6, 16, 20, .52);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    z-index: 800;
    display: grid;
    place-items: center;
    padding: 20px;
    overscroll-behavior: contain;
    animation: fade-in .16s var(--ease);
}
/* display:grid above beats the UA [hidden] rule, so JS-driven modals
   would stay visible forever without this (project [hidden] convention). */
.modal-backdrop[hidden] { display: none; }
@keyframes fade-in { from { opacity: 0; } }

.modal {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-pop);
    width: min(560px, 100%);
    max-height: calc(100dvh - 40px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: modal-in .2s var(--ease);
}
.modal--wide { width: min(840px, 100%); }
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.99); } }

.modal__head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--line-soft);
    flex: 0 0 auto;
}
.modal__title { margin: 0; font-size: var(--fs-md); }
.modal__body { padding: 16px; overflow-y: auto; overscroll-behavior: contain; }
.modal__foot {
    padding: 11px 16px;
    border-top: 1px solid var(--line-soft);
    background: var(--surface-muted);
    display: flex;
    gap: 9px;
    justify-content: flex-end;
    flex-wrap: wrap;
    flex: 0 0 auto;
}

/* Check-in dialog (all viewports): the form must be a flex column with
   min-height:0, otherwise .modal__body never becomes the scroll container —
   a long investigation list grows the plain block form past .modal's
   max-height and the footer (Check In button) is clipped below the fold.
   Phones additionally compact the dialog (see responsive.css ≤820px). */
#checkinModal #checkinForm {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}
#checkinModal .modal__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}
#checkinModal .modal__foot { flex: 0 0 auto; }
/* Above five rows JS adds .inv-list--scroll: cap the list itself so the
   footer stays on screen; the body scrolls whatever still overflows. */
#checkinModal .inv-list--scroll {
    max-height: 190px;
    overflow-y: auto;
    overscroll-behavior: contain;
}
#checkinModal .inv-list--scroll.ci-fade {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
}

/* ==========================================================================
   14. AUTOCOMPLETE
   ========================================================================== */

.ac { position: relative; }

.ac__list {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 60;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-pop);
    max-height: 300px;
    overflow-y: auto;
    overscroll-behavior: contain;
    margin: 0;
    padding: 5px;
    list-style: none;
}
.ac__list[hidden] { display: none; }

.ac__item {
    padding: 7px 9px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13.5px;
    line-height: 1.35;
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.ac__item:hover, .ac__item.is-active { background: var(--brand-soft); }
.ac__name { font-weight: 600; color: var(--ink); min-width: 0; }
.ac__meta {
    font-size: var(--fs-xs);
    color: var(--muted);
    margin-left: auto;
    white-space: nowrap;
    flex: 0 0 auto;
}
.ac__empty { padding: 10px; font-size: var(--fs-sm); color: var(--muted); }

/* Two-line suggestion rows: name, then generic · detail (never truncated away) */
.ac__item--stacked { display: block; }
.ac__item--stacked .ac__line2 {
    display: flex;
    gap: 6px;
    align-items: baseline;
    font-size: var(--fs-xs);
    color: var(--muted);
    margin-top: 2px;
    flex-wrap: wrap;
}
.ac__line2 .dot::before { content: "·"; margin-right: 6px; }

/* ==========================================================================
   15. PAGINATION / EMPTY STATE
   ========================================================================== */

.pagination {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    border-top: 1px solid var(--line-soft);
    font-size: var(--fs-sm);
    color: var(--muted);
    flex-wrap: wrap;
}
.pagination__pages { margin-left: auto; display: flex; gap: 4px; align-items: center; }

.page-link {
    min-width: 32px;
    height: 32px;
    display: inline-grid;
    place-items: center;
    padding: 0 8px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--paper);
    color: var(--body);
    font-size: var(--fs-sm);
    font-weight: 600;
}
.page-link:hover { background: var(--surface-hover); text-decoration: none; color: var(--ink); }
.page-link.is-active { background: var(--brand); border-color: var(--brand); color: var(--brand-contrast); }
.page-link.is-disabled { opacity: .4; pointer-events: none; }

.empty-state {
    padding: 30px 20px;
    text-align: center;
    color: var(--muted);
}
.empty-state__icon {
    display: inline-grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: var(--radius-lg);
    background: var(--surface-sunken);
    color: var(--faint);
    margin-bottom: 13px;
}
.empty-state__title {
    font-size: var(--fs-md);
    color: var(--ink);
    margin-bottom: 4px;
}
.empty-state__text {
    font-size: var(--fs-sm);
    max-width: 40ch;
    margin: 0 auto 16px;
}
.empty-state--denied .empty-state__icon { background: var(--danger-bg); color: var(--danger); }

/* ==========================================================================
   16. MISC COMPONENTS
   ========================================================================== */

/* --- 7-day trend bars (real counts, no chart library) ------------------ */

.trend {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    min-height: 132px;
    padding-top: 6px;
}
.trend__col {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 132px;
    gap: 5px;
}
.trend__value {
    font-size: var(--fs-xs);
    font-weight: 700;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.trend__bar {
    width: 100%;
    max-width: 46px;
    background: var(--brand-soft);
    border-radius: var(--radius-sm) var(--radius-sm) 3px 3px;
    border: 1px solid var(--brand-line);
    border-bottom: 0;
    min-height: 4px;
    transition: background var(--dur) var(--ease);
}
.trend__col:hover .trend__bar { background: var(--brand); border-color: var(--brand); }
.trend__label {
    font-size: 10.5px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* --- Quick action grid ------------------------------------------------- */

.quick-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 9px;
}
.quick-action {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--paper);
    color: var(--body);
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1.35;
    min-width: 0;
    transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.quick-action:hover {
    border-color: var(--brand-line);
    background: var(--brand-softer);
    color: var(--ink);
    text-decoration: none;
}
.quick-action .icon {
    color: var(--brand);
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    padding: 8px;
    border-radius: var(--radius-sm);
    background: var(--brand-soft);
    box-sizing: border-box;
}

/* --- Week grid (chamber schedule at a glance) --------------------------- */

.week-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: 10px;
}

.week-day {
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 10px 12px;
    background: var(--paper);
}
.week-day.is-closed { background: var(--surface-muted); }

.week-day__name {
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 6px;
    padding-bottom: 5px;
    border-bottom: 1px solid var(--line-soft);
}
.week-day.is-closed .week-day__name { color: var(--faint); }

.week-day__session {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 4px 0;
    font-size: var(--fs-sm);
}
.week-day__session .strong { font-size: 13px; }

.week-day__closed {
    font-size: var(--fs-sm);
    color: var(--faint);
    padding: 4px 0;
}

.avatar {
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    border-radius: 50%;
    background: var(--brand-soft);
    color: var(--brand-darker);
    display: grid;
    place-items: center;
    font-size: var(--fs-sm);
    font-weight: 700;
    text-transform: uppercase;
    overflow: hidden;
}
.avatar--lg { width: 54px; height: 54px; flex-basis: 54px; font-size: var(--fs-lg); }
.avatar--sm { width: 26px; height: 26px; flex-basis: 26px; font-size: var(--fs-xs); }
.avatar img { width: 100%; height: 100%; object-fit: cover; }

.user-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 8px 3px 3px;
    border-radius: 99px;
    border: 1px solid var(--line);
    background: var(--paper);
    color: var(--body);
    cursor: pointer;
    max-width: 100%;
}
.user-chip:hover { background: var(--surface-hover); color: var(--ink); }

.dropdown { position: relative; }
.dropdown__menu {
    position: absolute;
    right: 0;
    top: calc(100% + 7px);
    min-width: 200px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-pop);
    padding: 5px;
    z-index: 70;
    margin: 0;
    list-style: none;
}
.dropdown__menu[hidden] { display: none; }
.dropdown__menu.is-up { top: auto; bottom: calc(100% + 7px); }
.dropdown__item {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 9px 10px;
    border: 0;
    background: none;
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: 13.5px;
    color: var(--body);
    cursor: pointer;
    text-align: left;
}
.dropdown__item:hover { background: var(--surface-hover); color: var(--ink); text-decoration: none; }
.dropdown__item .icon { color: var(--muted); flex: 0 0 auto; }
/* A row action menu sometimes wraps a POST form around the item button —
   the form itself must not add height between menu items. */
.dropdown__menu form { margin: 0; }
.dropdown__sep { height: 1px; background: var(--line-soft); margin: 5px 0; }
.dropdown__head { padding: 8px 10px 6px; font-size: var(--fs-xs); color: var(--muted); }

/* --- Theme switch (topbar) -------------------------------------------- */

.theme-toggle .icon-sun { display: block; }
.theme-toggle .icon-moon { display: none; }
html[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
html[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

/* The language switch has two homes: its own topbar control on a wide screen,
   and a section of the account menu on a phone (see responsive.css). */
.topbar__lang-inline { display: none; }

.def-list { margin: 0; }
.def-list__row {
    display: flex;
    gap: 14px;
    padding: 7px 0;
    border-bottom: 1px dashed var(--line-soft);
    font-size: 13.5px;
}
.def-list__row:last-child { border-bottom: 0; }
.def-list__key {
    flex: 0 0 42%;
    max-width: 42%;
    color: var(--muted);
    font-size: var(--fs-sm);
}
.def-list__val { flex: 1 1 auto; min-width: 0; color: var(--ink); font-weight: 500; }

.detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 12px 18px;
}
.detail { min-width: 0; }
.detail__key {
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    line-height: 1.35;
    margin-bottom: 2px;
}
.detail__val { color: var(--ink); font-weight: 500; word-break: break-word; }

.section-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-size: var(--fs-md);
    font-weight: 600;
    color: var(--ink);
    margin: 0 0 8px;
}
.section-title .icon { color: var(--brand); }

.hr { height: 1px; background: var(--line-soft); border: 0; margin: 13px 0; }

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    padding: 10px 16px;
    background: var(--brand);
    color: var(--brand-contrast);
    border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }

/* Visually hidden but available to assistive tech. */
.sr-only {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* A d-inline wrapper so a row-action form does not break the line. */
.d-inline { display: inline; }

/* Development-only meter: queries, time and peak memory for this page.
   Rendered by footer.php only while APP_DEBUG is on. */
.dev-meter {
    position: fixed;
    /* Clear of the rail: the badge is a tool, and the rail's footer text is
       not part of it. */
    left: calc(var(--sidebar-w) + 10px);
    bottom: 8px;
    z-index: 700;
    padding: 3px 9px;
    border-radius: 99px;
    background: rgba(6, 16, 20, .82);
    color: #cfe3e8;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    letter-spacing: .01em;
    pointer-events: none;
}

/* Mobile drawer backdrop */
.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(6, 16, 20, .5);
    z-index: 39;
    animation: fade-in .16s var(--ease);
}

/* ==========================================================================
   17. MOBILE TAB BAR
   --------------------------------------------------------------------------
   The primary destinations, inside thumb reach. The rail itself stays
   available behind the "More" item, which is the same control that opens the
   drawer on a tablet.
   ========================================================================== */

.tabbar {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    background: var(--surface-glass);
    backdrop-filter: saturate(160%) blur(12px);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
    border-top: 1px solid var(--line);
    padding: 5px 4px calc(5px + env(safe-area-inset-bottom, 0px));
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
}

.tabbar__item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 6px 2px;
    min-height: 48px;
    border: 0;
    background: none;
    border-radius: var(--radius-md);
    color: var(--muted);
    font: inherit;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1.15;
    cursor: pointer;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}
.tabbar__item:hover { color: var(--ink); text-decoration: none; }
.tabbar__item.is-active { color: var(--brand); }
.tabbar__item.is-active .icon { color: var(--brand); }
.tabbar__item .icon { color: inherit; flex: 0 0 auto; }

.tabbar__label {
    letter-spacing: .01em;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tabbar__count {
    position: absolute;
    top: 2px;
    left: 50%;
    transform: translateX(2px);
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 99px;
    background: var(--danger);
    color: var(--danger-contrast);
    font-size: 10px;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   18. UTILITIES
   ========================================================================== */

.grid { display: grid; gap: 14px; }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--sidebar { grid-template-columns: minmax(0, 1fr) 336px; align-items: start; }

.flex { display: flex; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.justify-center { justify-content: center; }
.flex-wrap { flex-wrap: wrap; }
.flex-1 { flex: 1 1 auto; min-width: 0; }
.gap-1 { gap: 4px; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.gap-4 { gap: 18px; }

.mt-1 { margin-top: 6px; }
.mt-2 { margin-top: 12px; }
.mt-3 { margin-top: 18px; }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 6px; }
.mb-2 { margin-bottom: 12px; }
.mb-3 { margin-bottom: 18px; }
.ml-auto { margin-left: auto; }
.hidden { display: none !important; }
.text-right { text-align: right; }
.text-danger { color: var(--danger); }
.text-warning { color: var(--warning); }

.amount { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink); white-space: nowrap; }
.amount--due { color: var(--danger); }
.amount--paid { color: var(--success); }

.box {
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 12px;
    background: var(--surface-muted);
}

/* ==========================================================================
   19. PRINT BASE (module print styles extend this)
   ========================================================================== */

@media print {
    body { background: #fff; }
    .sidebar, .topbar, .sidebar-backdrop, .tabbar, .no-print, .toast-host { display: none !important; }
    .main { display: block; }
    .page { padding: 0; }
    .card { border: 0; box-shadow: none; margin: 0; }
}

/* ==========================================================================
   20. REDUCED MOTION
   ========================================================================== */

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

/* ==========================================================================
   21. PATIENT TIMELINE  (patients/view.php?tab=timeline)
   ========================================================================== */

.timeline {
    list-style: none;
    margin: 0;
    padding: 0 0 0 24px;
    position: relative;
}

.timeline::before {
    content: "";
    position: absolute;
    left: 5px;
    top: 6px;
    bottom: 6px;
    width: 2px;
    background: var(--line);
}

.timeline__item { position: relative; padding-bottom: 11px; }
.timeline__item:last-child { padding-bottom: 0; }

.timeline__dot {
    position: absolute;
    left: -24px;
    top: 10px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--brand);
    box-shadow: 0 0 0 3px var(--paper);
}

.timeline__body {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 11px 13px;
}

.timeline__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
}

.timeline__date { font-weight: 700; color: var(--ink); }

.timeline__row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 6px;
    font-size: var(--fs-sm);
}

.timeline__key {
    flex: 0 0 auto;
    min-width: 96px;
    color: var(--muted);
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .05em;
}

html[lang="bn"] .timeline__key { letter-spacing: 0; text-transform: none; }

.timeline__chips { display: flex; flex-wrap: wrap; gap: 6px; }

/* ==========================================================================
   22. PAPER DOCUMENTS
   --------------------------------------------------------------------------
   A prescription pad, a receipt and a token slip are sheets of paper. They
   keep the light palette in either theme so that what is on screen is what
   comes out of the printer.

   Rather than writing dark-mode overrides for every rule inside them, this
   block re-points the tokens for the document scope. Everything the module
   stylesheets already express in tokens therefore stays correct in dark mode
   with no second code path — and the surrounding chrome switches back to the
   dark palette the moment the document ends.
   ========================================================================== */

:is(.pad, .a4, .a5, .ds-sheet, .rc-sheet, .token-sheet, .token-slip,
    .rx-sheet, .rx-print-body, .print-toolbar) {
    color-scheme: light;

    --paper:          #ffffff;
    --canvas:         #f4f6f7;
    --canvas-deep:    #eceff1;
    --surface-muted:  #f7f9fa;
    --surface-sunken: #edf1f3;
    --surface-hover:  #f1f5f6;

    --ink:            #0b1a1f;
    --body:           #364a52;
    --muted:          #63797f;
    --faint:          #8ba0a6;

    --line:           #e0e8ea;
    --line-soft:      #edf2f3;
    --line-strong:    #c9d6d9;

    --brand:          #0e6b5b;
    --brand-dark:     #0a5648;
    --brand-darker:   #073f35;
    --brand-soft:     #e1f1ec;
    --brand-softer:   #f1f8f5;
    --brand-line:     #bfdfd5;
    --brand-ring:     rgba(14, 107, 91, .22);
    --brand-contrast: #ffffff;

    --rx:             #b1272f;
    --rx-soft:        #fbeceb;

    --success:        #127a46;
    --success-bg:     #e4f4ea;
    --success-border: #bee3cd;
    --success-ink:    #0b5230;

    --warning:        #96600a;
    --warning-bg:     #fcf2df;
    --warning-border: #eed7a8;
    --warning-ink:    #68420a;

    --danger:         #b3261e;
    --danger-bg:      #fcecea;
    --danger-border:  #f2c9c4;
    --danger-ink:     #7e1b15;

    --info:           #1b5fa8;
    --info-bg:        #e7f0fa;
    --info-border:    #c2d9f0;
    --info-ink:       #124070;

    --slate:          #546773;
    --slate-bg:       #edf1f4;
    --slate-border:   #d3dce1;

    /* A sheet of paper casts a light shadow. Left on the dark theme's values
       it would look like the page was printed on black card. */
    --shadow-xs:  0 1px 1px rgba(11, 26, 31, .04);
    --shadow-sm:  0 1px 2px rgba(11, 26, 31, .05);
    --shadow-md:  0 1px 3px rgba(11, 26, 31, .07), 0 6px 16px rgba(11, 26, 31, .06);
    --shadow-lg:  0 8px 28px rgba(11, 26, 31, .13);
    --shadow-pop: 0 2px 6px rgba(11, 26, 31, .08), 0 16px 40px rgba(11, 26, 31, .12);
}

/* PWA update banner: one quiet bar above the mobile tab bar, only while a
   newer service worker waits. Created by assets/js/pwa.js. */
.pwa-banner {
    position: fixed;
    left: 50%;
    bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    z-index: 1200;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: min(92vw, 560px);
    background: var(--surface, #ffffff);
    color: var(--ink, #0A2E29);
    border: 1px solid var(--line, #d9e2e8);
    border-radius: 14px;
    box-shadow: var(--shadow-lg);
    padding: 10px 12px 10px 16px;
}
.pwa-banner__text {
    flex: 1 1 auto;
    font-size: 14px;
}
@media (max-width: 640px) {
    .pwa-banner {
        bottom: calc(76px + env(safe-area-inset-bottom, 0px));
    }
}
