/*
 * SSKH Chemotherapy Program
 * Copyright (c) 2026 Sitthichai C. <schanmaniloet@hotmail.com> All rights reserved.
 * This software is the property of Sitthichai C.
 * Unauthorized copying, modification, or redistribution is prohibited.
 */
:root {
  --bg: #f5f5f7;
  --surface: #ffffff;
  --surface-2: #fbfbfd;
  --border: #d2d2d7;
  --border-strong: #c6c6cc;
  --text: #1d1d1f;
  --text-2: #424245;
  --muted: #6e6e73;

  /* Apple system palette (light) */
  --primary: #0071e3;
  --primary-hover: #0077ed;
  --primary-active: #006edb;
  --accent: #34c759;
  --accent-hover: #30b653;
  --danger: #ff3b30;
  --warn: #ff9f0a;
  --indigo: #5e5ce6;
  --purple: #af52de;
  --pink: #ff375f;
  --orange: #ff9500;
  --yellow: #ffd60a;
  --mint: #00c7be;
  --teal: #40c8e0;
  --cyan: #64d2ff;

  /* Tint-aware text shades for AAA-ish contrast on white */
  --teal-ink: #117a8f;
  --mint-ink: #008e88;
  --green-ink: #239e44;
  --orange-ink: #b66800;
  --indigo-ink: #4a48c0;

  --shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
  --shadow-md: 0 4px 16px rgba(0,0,0,0.06);
  --shadow-lg: 0 12px 32px rgba(0,0,0,0.10);
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;

  /* ---- Theme tokens. Default = "classic". Overridden per html[data-theme]
     (see the blocks right below); the picker in shared/theme.js sets that
     attribute. Pages read only these tokens, never theme names. ---- */
  --topbar-bg: rgba(255,255,255,0.84);
  --topbar-fg: #1d1d1f;
  --topbar-muted: #6e6e73;
  --topbar-border: rgba(0,0,0,0.08);
  --topbar-accent: var(--primary);         /* 3px line along the very top */
  --topbar-blur: saturate(180%) blur(20px);
  --nav-bg: rgba(0,113,227,0.11);
  --nav-fg: #0b5cab;
  --nav-border: rgba(0,113,227,0.22);
  --nav-bg-hover: rgba(0,113,227,0.19);
  --nav-bg-active: rgba(0,113,227,0.28);
  --nav-admin-bg: rgba(175,82,222,0.12);
  --nav-admin-fg: #7a2fa3;
  --nav-admin-border: rgba(175,82,222,0.28);
  --nav-admin-bg-hover: rgba(175,82,222,0.22);
  --nav-signout-bg: rgba(255,59,48,0.10);
  --nav-signout-fg: #c0392b;
  --nav-signout-border: rgba(255,59,48,0.28);
  --nav-signout-bg-hover: rgba(255,59,48,0.19);
  --nav-divider: rgba(0,0,0,0.14);
  /* Secondary buttons: a soft fill of the theme colour, not a white pill —
     white-on-white vanished into the card. Primary buttons stay solid and
     carry a coloured glow so the one main action per card reads first. */
  --btn2-bg: rgba(0,113,227,0.11);
  --btn2-fg: #0b5cab;
  --btn2-border: rgba(0,113,227,0.20);
  --btn2-bg-hover: rgba(0,113,227,0.19);
  --btn2-bg-active: rgba(0,113,227,0.28);
  --btn-glow: rgba(0,113,227,0.30);
  --focus-ring: rgba(0,113,227,0.25);
  --focus-ring-soft: rgba(0,113,227,0.15);
  --strip-bg: rgba(255,255,255,0.88);
  --wash: rgba(0,113,227,0.055);           /* faint top wash on blue-tinted cards */
  --final-border: rgba(0,113,227,0.55);     /* the Final-dose box on the order page */
  --final-bg: rgba(0,113,227,0.045);
}

/* ---- Ocean: deep blue header, teal-blue actions ---- */
html[data-theme="ocean"] {
  --primary: #0b6fb6; --primary-hover: #0a63a2; --primary-active: #09588f;
  --bg: #eef3f7; --surface-2: #f5f8fb;
  --topbar-bg: linear-gradient(90deg, #0b3a5a 0%, #0f6a8a 100%);
  --topbar-fg: #ffffff; --topbar-muted: rgba(255,255,255,0.74);
  --topbar-border: rgba(0,0,0,0.18); --topbar-accent: #0b3a5a; --topbar-blur: none;
  --nav-bg: rgba(255,255,255,0.14); --nav-fg: #ffffff; --nav-border: rgba(255,255,255,0.42);
  --nav-bg-hover: rgba(255,255,255,0.26); --nav-bg-active: rgba(255,255,255,0.38);
  --nav-admin-bg: rgba(221,196,255,0.22); --nav-admin-fg: #ffffff; --nav-admin-border: rgba(221,196,255,0.65);
  --nav-admin-bg-hover: rgba(221,196,255,0.36);
  --nav-signout-bg: rgba(255,120,110,0.26); --nav-signout-fg: #ffffff; --nav-signout-border: rgba(255,150,140,0.7);
  --nav-signout-bg-hover: rgba(255,120,110,0.42);
  --nav-divider: rgba(255,255,255,0.32);
  --btn2-bg: rgba(11,111,182,0.11); --btn2-fg: #0a5f9a; --btn2-border: rgba(11,111,182,0.20);
  --btn2-bg-hover: rgba(11,111,182,0.19); --btn2-bg-active: rgba(11,111,182,0.28);
  --btn-glow: rgba(11,111,182,0.32);
  --focus-ring: rgba(11,111,182,0.28); --focus-ring-soft: rgba(11,111,182,0.16);
  --strip-bg: rgba(233,242,248,0.94);
  --wash: rgba(11,111,182,0.06);
  --final-border: rgba(11,111,182,0.6); --final-bg: rgba(11,111,182,0.05);
}

/* ---- Forest: green header, calm cream pages ---- */
html[data-theme="forest"] {
  --primary: #1f8a5b; --primary-hover: #1a7a50; --primary-active: #166b46;
  --accent: #2fb344; --accent-hover: #2aa33e;
  --bg: #f2f5f0; --surface-2: #f7faf5;
  --topbar-bg: linear-gradient(90deg, #14532d 0%, #1f7a4d 100%);
  --topbar-fg: #ffffff; --topbar-muted: rgba(255,255,255,0.74);
  --topbar-border: rgba(0,0,0,0.18); --topbar-accent: #14532d; --topbar-blur: none;
  --nav-bg: rgba(255,255,255,0.14); --nav-fg: #ffffff; --nav-border: rgba(255,255,255,0.42);
  --nav-bg-hover: rgba(255,255,255,0.26); --nav-bg-active: rgba(255,255,255,0.38);
  --nav-admin-bg: rgba(221,196,255,0.22); --nav-admin-fg: #ffffff; --nav-admin-border: rgba(221,196,255,0.65);
  --nav-admin-bg-hover: rgba(221,196,255,0.36);
  --nav-signout-bg: rgba(255,120,110,0.26); --nav-signout-fg: #ffffff; --nav-signout-border: rgba(255,150,140,0.7);
  --nav-signout-bg-hover: rgba(255,120,110,0.42);
  --nav-divider: rgba(255,255,255,0.32);
  --btn2-bg: rgba(31,138,91,0.12); --btn2-fg: #1b6f4a; --btn2-border: rgba(31,138,91,0.22);
  --btn2-bg-hover: rgba(31,138,91,0.20); --btn2-bg-active: rgba(31,138,91,0.30);
  --btn-glow: rgba(31,138,91,0.32);
  --focus-ring: rgba(31,138,91,0.28); --focus-ring-soft: rgba(31,138,91,0.16);
  --strip-bg: rgba(236,244,234,0.94);
  --wash: rgba(31,138,91,0.06);
  --final-border: rgba(31,138,91,0.6); --final-bg: rgba(31,138,91,0.05);
}

/* ---- Sunset: plum-to-orange header, warm pages ---- */
html[data-theme="sunset"] {
  --primary: #d9480f; --primary-hover: #c23f0b; --primary-active: #a93608;
  --bg: #faf5f0; --surface-2: #fdf9f5;
  --topbar-bg: linear-gradient(90deg, #6d2a6b 0%, #c2410c 100%);
  --topbar-fg: #ffffff; --topbar-muted: rgba(255,255,255,0.76);
  --topbar-border: rgba(0,0,0,0.18); --topbar-accent: #6d2a6b; --topbar-blur: none;
  --nav-bg: rgba(255,255,255,0.16); --nav-fg: #ffffff; --nav-border: rgba(255,255,255,0.45);
  --nav-bg-hover: rgba(255,255,255,0.28); --nav-bg-active: rgba(255,255,255,0.40);
  --nav-admin-bg: rgba(255,230,160,0.24); --nav-admin-fg: #ffffff; --nav-admin-border: rgba(255,230,160,0.7);
  --nav-admin-bg-hover: rgba(255,230,160,0.38);
  --nav-signout-bg: rgba(60,20,40,0.30); --nav-signout-fg: #ffffff; --nav-signout-border: rgba(255,200,200,0.55);
  --nav-signout-bg-hover: rgba(60,20,40,0.46);
  --nav-divider: rgba(255,255,255,0.34);
  --btn2-bg: rgba(217,72,15,0.11); --btn2-fg: #b23a0b; --btn2-border: rgba(217,72,15,0.20);
  --btn2-bg-hover: rgba(217,72,15,0.19); --btn2-bg-active: rgba(217,72,15,0.28);
  --btn-glow: rgba(217,72,15,0.32);
  --focus-ring: rgba(217,72,15,0.28); --focus-ring-soft: rgba(217,72,15,0.16);
  --strip-bg: rgba(252,243,236,0.94);
  --wash: rgba(217,72,15,0.06);
  --final-border: rgba(217,72,15,0.6); --final-bg: rgba(217,72,15,0.05);
}

/* ---- Pokémon (2026-10-08, ported from RBH): Pikachu-yellow header on a
   cream ground, Pokémon-logo blue actions, Bulbasaur green accent, Poké Ball
   red danger. Character art further down (screen only, this theme only). ---- */
html[data-theme="pokemon"] {
  --bg: #fff8dc; --surface: #ffffff; --surface-2: #fffbea;
  --border: #e6d394; --border-strong: #d6bf72;
  --text: #1d2340; --text-2: #3b4263; --muted: #646a85;
  --primary: #2a75bb; --primary-hover: #2468a8; --primary-active: #1f5a92;
  --accent: #2b7d36; --accent-hover: #256d2f; --danger: #d62828;
  --shadow-md: 0 4px 16px rgba(42,60,110,0.10); --shadow-lg: 0 12px 32px rgba(42,60,110,0.14);
  --topbar-bg: rgba(255,214,51,0.94);
  --topbar-fg: #1d2340; --topbar-muted: #3b4263;
  --topbar-border: rgba(42,117,187,0.35); --topbar-accent: #2a75bb; --topbar-blur: saturate(180%) blur(20px);
  --nav-bg: rgba(255,255,255,0.62); --nav-fg: #1f5a92; --nav-border: rgba(42,117,187,0.38);
  --nav-bg-hover: rgba(255,255,255,0.85); --nav-bg-active: #ffffff;
  --nav-admin-bg: rgba(255,255,255,0.62); --nav-admin-fg: #6d28a8; --nav-admin-border: rgba(109,40,168,0.35);
  --nav-admin-bg-hover: rgba(255,255,255,0.85);
  --nav-signout-bg: rgba(255,255,255,0.62); --nav-signout-fg: #b91c1c; --nav-signout-border: rgba(214,40,40,0.38);
  --nav-signout-bg-hover: rgba(255,255,255,0.85);
  --nav-divider: rgba(29,35,64,0.20);
  --btn2-bg: rgba(42,117,187,0.10); --btn2-fg: #1f5a92; --btn2-border: rgba(42,117,187,0.24);
  --btn2-bg-hover: rgba(42,117,187,0.18); --btn2-bg-active: rgba(42,117,187,0.27);
  --btn-glow: rgba(42,117,187,0.30);
  --focus-ring: rgba(42,117,187,0.28); --focus-ring-soft: rgba(42,117,187,0.16);
  --strip-bg: rgba(255,248,220,0.95);
  --wash: rgba(42,117,187,0.06);
  --final-border: rgba(42,117,187,0.6); --final-bg: rgba(42,117,187,0.05);
}

/* ---- Hirono (2026-10-08, ported from RBH): warm paper ground, kraft
   cardboard header, denim-blue actions, olive accent, brick-red danger. ---- */
html[data-theme="hirono"] {
  --bg: #f4efe7; --surface: #fffdf8; --surface-2: #faf6ef;
  --border: #dcd1bf; --border-strong: #c9bba3;
  --text: #2b2621; --text-2: #4b433a; --muted: #6e6559;
  --primary: #3e5a7a; --primary-hover: #344d69; --primary-active: #2b4058;
  --accent: #4d6b33; --accent-hover: #435d2c; --danger: #a3271f;
  --shadow-md: 0 4px 16px rgba(60,48,32,0.10); --shadow-lg: 0 12px 32px rgba(60,48,32,0.14);
  --topbar-bg: rgba(217,194,158,0.95);
  --topbar-fg: #2b2621; --topbar-muted: #4b433a;
  --topbar-border: rgba(62,90,122,0.30); --topbar-accent: #3e5a7a; --topbar-blur: saturate(160%) blur(16px);
  --nav-bg: rgba(255,253,248,0.55); --nav-fg: #2b4058; --nav-border: rgba(62,90,122,0.35);
  --nav-bg-hover: rgba(255,253,248,0.80); --nav-bg-active: #fffdf8;
  --nav-admin-bg: rgba(255,253,248,0.55); --nav-admin-fg: #5b3a6e; --nav-admin-border: rgba(91,58,110,0.32);
  --nav-admin-bg-hover: rgba(255,253,248,0.80);
  --nav-signout-bg: rgba(255,253,248,0.55); --nav-signout-fg: #a3271f; --nav-signout-border: rgba(163,39,31,0.35);
  --nav-signout-bg-hover: rgba(255,253,248,0.80);
  --nav-divider: rgba(43,38,33,0.20);
  --btn2-bg: rgba(62,90,122,0.10); --btn2-fg: #2b4058; --btn2-border: rgba(62,90,122,0.24);
  --btn2-bg-hover: rgba(62,90,122,0.18); --btn2-bg-active: rgba(62,90,122,0.27);
  --btn-glow: rgba(62,90,122,0.30);
  --focus-ring: rgba(62,90,122,0.28); --focus-ring-soft: rgba(62,90,122,0.16);
  --strip-bg: rgba(244,239,231,0.95);
  --wash: rgba(62,90,122,0.06);
  --final-border: rgba(62,90,122,0.6); --final-bg: rgba(62,90,122,0.05);
}

* { box-sizing: border-box; }

/* Type: IBM Plex Sans for Latin and digits, IBM Plex Sans Thai for Thai (the
   Chemo Order Redesign canvas, 2026-10-06), served from Google Fonts by
   shared/theme.js; the system stack below is what renders until they arrive
   or when the fonts cannot load, so nothing depends on them. */
:root {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans Thai", -apple-system, BlinkMacSystemFont,
               "SF Pro Text", "SF Pro Display", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  letter-spacing: -0.005em;
}

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

header.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--topbar-bg);
  color: var(--topbar-fg);
  backdrop-filter: var(--topbar-blur);
  -webkit-backdrop-filter: var(--topbar-blur);
  border-top: 3px solid var(--topbar-accent);
  border-bottom: 1px solid var(--topbar-border);
  box-shadow: 0 2px 10px rgba(0,0,0,0.07);
  padding: 10px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 20px;
}

header.topbar h1 {
  font-size: 18px;
  margin: 0;
  color: var(--topbar-fg);
  font-weight: 700;
  letter-spacing: -0.015em;
  flex-shrink: 0;
}

/* The nav div on every page is a flat run of buttons with legacy inline
   margins; flex + gap keeps the row evenly spaced at any width, and when
   it must wrap it does so as tidy right-aligned rows instead of a ragged
   inline flow. The margin override neutralizes those inline styles. */
header.topbar > div {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  align-items: center;
  justify-content: flex-end;
}
header.topbar > div > * { margin: 0 !important; }

/* Nav buttons: real, outlined pills with a 36px hit height. The old flat
   grey chips (6px tall padding, no border) were easy to miss as buttons;
   these read as controls on every theme — white-on-colour for the dark
   headers, colour-outlined-on-white for classic. Still compact enough for
   the admin's 11-item row on a desktop screen. */
header.topbar .btn,
header.topbar button {
  padding: 7px 14px;
  min-height: 36px;
  font-size: 13px;
  font-weight: 600;
  background: var(--nav-bg);
  color: var(--nav-fg);
  border: 1px solid var(--nav-border);
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}
header.topbar .btn:hover,
header.topbar button:hover { background: var(--nav-bg-hover); }
header.topbar .btn:active,
header.topbar button:active { background: var(--nav-bg-active); }
header.topbar .btn:focus-visible,
header.topbar button:focus-visible { box-shadow: 0 0 0 4px var(--focus-ring); }

header.topbar .who {
  color: var(--topbar-muted);
  font-size: 13px;
  white-space: nowrap;
}

/* Topbar nav groups — related links cluster together and consecutive
   groups are separated by a hairline divider. Color code (mirrors the
   .badge palette): purple = admin tools, blue = station pages,
   neutral gray = personal/account, red = sign out. A group that is
   shown/hidden as a whole (e.g. admin links on the doctor station)
   should be ordered second-to-last so its divider never strands. */
.topnav-group {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  align-items: center;
}
.topnav-group + .topnav-group {
  border-left: 1px solid var(--nav-divider);
  padding-left: 12px;
  margin-left: 4px;
}

/* Admin tools keep their purple identity, sign-out its red; station pages
   use the plain nav style. All token-driven so the dark headers get
   translucent white pills and classic gets colour-outlined white ones. */
.topnav-group.nav-admin .btn,
.topnav-group.nav-admin button {
  background: var(--nav-admin-bg);
  color: var(--nav-admin-fg);
  border-color: var(--nav-admin-border);
}
.topnav-group.nav-admin .btn:hover,
.topnav-group.nav-admin button:hover,
.topnav-group.nav-admin .btn:active,
.topnav-group.nav-admin button:active { background: var(--nav-admin-bg-hover); }

.topnav-group .signout {
  background: var(--nav-signout-bg);
  color: var(--nav-signout-fg);
  border-color: var(--nav-signout-border);
}
.topnav-group .signout:hover,
.topnav-group .signout:active { background: var(--nav-signout-bg-hover); }

main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 28px 24px 64px;
}

h2 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0 0 14px;
  font-weight: 600;
}

.card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 22px 24px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-md);
  border: 1px solid rgba(0,0,0,0.04);
}

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

/* Wrap wide tables so they scroll horizontally inside their card instead of
   pushing the page wider than the viewport. Used on pages with many columns
   (e.g. doctor station's appointment list) where the "All dates" view can
   produce rows whose natural width exceeds the card. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

th, td {
  text-align: left;
  padding: 10px 10px;
  vertical-align: middle;
  border-bottom: 1px solid rgba(0,0,0,0.06);
  font-size: 13px;
}
tr:last-child td { border-bottom: 0; }

th {
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: transparent;
  border-bottom: 1px solid var(--border);
}

tr.clickable { cursor: pointer; transition: background-color .12s ease; }
tr.clickable:hover { background: var(--surface-2); }

/* Appointment rows whose order has already been saved/printed get a soft
   green tint so the doctor can pick out unfinished work at a glance.
   Hover still wins so the row remains obviously clickable. */
tr.has-order { background: rgba(52, 199, 89, 0.10); }
tr.has-order:hover { background: rgba(52, 199, 89, 0.18); }

button, .btn {
  font: inherit;
  font-weight: 500;
  background: var(--primary);
  color: #fff;
  border: 0;
  padding: 9px 18px;
  border-radius: 980px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  letter-spacing: -0.005em;
  white-space: nowrap;
  /* Solid primary sits above the page: a thin contact shadow plus a glow in
     the theme colour. Secondary/ghost variants reset this below. */
  box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 3px 10px var(--btn-glow);
  transition: background-color .15s ease, transform .05s ease, box-shadow .15s ease;
}
button:hover, .btn:hover { background: var(--primary-hover); text-decoration: none; box-shadow: 0 1px 2px rgba(0,0,0,0.14), 0 5px 14px var(--btn-glow); }
button:active, .btn:active { background: var(--primary-active); transform: scale(0.98); }
button:focus-visible, .btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px var(--focus-ring);
}

/* Secondary = outlined: white face, theme-coloured text and border. The
   previous flat 5%-grey chip disappeared into the page; an outline reads
   as a button at a glance without competing with the filled primary. */
button.secondary, .btn.secondary {
  background: var(--btn2-bg);
  color: var(--btn2-fg);
  border: 1px solid var(--btn2-border);
  box-shadow: none;
}
button.secondary:hover, .btn.secondary:hover { background: var(--btn2-bg-hover); }
button.secondary:active, .btn.secondary:active { background: var(--btn2-bg-active); }

button.accent, .btn.accent { background: var(--accent); }
button.accent:hover, .btn.accent:hover { background: var(--accent-hover); }
button.danger, .btn.danger { background: var(--danger); }

button.ghost {
  background: transparent;
  color: var(--primary);
  padding: 8px 12px;
  box-shadow: none;
}
button.ghost:hover { background: rgba(0,113,227,0.08); }

/* Compact buttons used inside table rows / list cards (Edit ✎ / Delete ✕,
   ward actions, regimen icon buttons). Stays small on desktop, expands to
   a comfortable iOS-friendly tap target on phones. */
button.row-action, .btn.row-action {
  padding: 8px 12px;
  font-size: 13px;
  min-height: 34px;
}
@media screen and (max-width: 720px) {
  button.row-action, .btn.row-action {
    padding: 10px 14px;
    font-size: 14px;
    min-height: 40px;
  }
}

button.toggle-on {
  background: var(--primary);
  color: #fff;
}

/* Apple-style segmented control */
.seg {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 980px;
  overflow: hidden;
  background: var(--surface);
  margin-top: 6px;
}
.seg button {
  background: transparent;
  color: var(--text);
  box-shadow: none;
  border-radius: 0;
  padding: 6px 14px;
  font-size: 13px;
  border-right: 1px solid var(--border);
  box-shadow: none;
  transition: background-color .12s ease;
}
.seg button:last-child { border-right: 0; }
.seg button:hover { background: rgba(0,0,0,0.04); }
.seg button.active { background: var(--primary); color: #fff; }
.seg button.active:hover { background: var(--primary-hover); }

.row { display: flex; gap: 16px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 160px; }

label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 500;
}

input[type="text"], input[type="number"], input[type="date"], input[type="password"], select, textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  background: var(--surface);
  color: var(--text);
  transition: border-color .15s ease, box-shadow .15s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 4px var(--focus-ring-soft);
}

input[type="date"] { padding: 9px 12px; }

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
}
.metric {
  background: var(--surface-2);
  border: 1px solid rgba(0,0,0,0.05);
  border-radius: var(--radius-md);
  padding: 14px 16px;
}
.metric .label {
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}
.metric .value {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.metric .unit { font-size: 12px; color: var(--muted); margin-left: 4px; font-weight: 500; }

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 980px;
  font-size: 11px;
  font-weight: 500;
  background: rgba(0,113,227,0.10);
  color: var(--primary);
  white-space: nowrap;
}
.badge.warn    { background: rgba(255,159,10,0.16); color: #b87000; }
.badge.purple  { background: rgba(175,82,222,0.12); color: var(--purple); }
.badge.indigo  { background: rgba(94,92,230,0.12);  color: var(--indigo-ink); }
.badge.teal    { background: rgba(64,200,224,0.18); color: var(--teal-ink); }
.badge.mint    { background: rgba(0,199,190,0.16);  color: var(--mint-ink); }
.badge.green   { background: rgba(52,199,89,0.16);  color: var(--green-ink); }
.badge.orange  { background: rgba(255,149,0,0.18);  color: var(--orange-ink); }
.badge.pink    { background: rgba(255,55,95,0.12);  color: var(--pink); }
.badge.blue    { background: rgba(0,113,227,0.14);  color: var(--primary); }
.badge.gray    { background: rgba(142,142,147,0.18); color: #6e6e73; }

/* Card tint variants — keeps the Apple white surface, paints a 4px accent
   strip on the left and tints the H2 in the same hue. */
.card[class*="tint-"] { padding-left: 20px; border-left-width: 4px; border-left-style: solid; }
.card.tint-blue   { border-left-color: var(--primary); }
.card.tint-blue   > h2 { color: var(--primary); }
.card.tint-purple { border-left-color: var(--purple); }
.card.tint-purple > h2 { color: var(--purple); }
.card.tint-indigo { border-left-color: var(--indigo); }
.card.tint-indigo > h2 { color: var(--indigo-ink); }
.card.tint-teal   { border-left-color: var(--teal); }
.card.tint-teal   > h2 { color: var(--teal-ink); }
.card.tint-mint   { border-left-color: var(--mint); }
.card.tint-mint   > h2 { color: var(--mint-ink); }
.card.tint-green  { border-left-color: var(--accent); }
.card.tint-green  > h2 { color: var(--green-ink); }
.card.tint-orange { border-left-color: var(--orange); }
.card.tint-orange > h2 { color: var(--orange-ink); }
.card.tint-pink   { border-left-color: var(--pink); }
.card.tint-pink   > h2 { color: var(--pink); }

/* A faint wash of the tint colour across the top of the card and a dot
   before the heading: each section gets a colour identity you can scan by,
   without changing any layout. The blue tint follows the theme's primary. */
.card[class*="tint-"] > h2 { font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card[class*="tint-"] > h2::before {
  content: ''; width: 9px; height: 9px; border-radius: 50%;
  background: currentColor; flex: none; opacity: 0.9;
}
.card.tint-blue   { background: linear-gradient(180deg, var(--wash) 0, var(--surface) 72px); }
.card.tint-purple { background: linear-gradient(180deg, rgba(175,82,222,0.065) 0, var(--surface) 72px); }
.card.tint-indigo { background: linear-gradient(180deg, rgba(94,92,230,0.065) 0, var(--surface) 72px); }
.card.tint-teal   { background: linear-gradient(180deg, rgba(64,200,224,0.08) 0, var(--surface) 72px); }
.card.tint-mint   { background: linear-gradient(180deg, rgba(0,199,190,0.07) 0, var(--surface) 72px); }
.card.tint-green  { background: linear-gradient(180deg, rgba(52,199,89,0.075) 0, var(--surface) 72px); }
.card.tint-orange { background: linear-gradient(180deg, rgba(255,149,0,0.08) 0, var(--surface) 72px); }
.card.tint-pink   { background: linear-gradient(180deg, rgba(255,55,95,0.065) 0, var(--surface) 72px); }

/* Order phases (doctor/patient.html) — one clearly distinct hue per
   prescribing step, painted as a full-width header band with a step number.
   1 Assessment slate-blue · 2 Pre-chemo teal · 3 Chemo solid violet ·
   4 Post-chemo/ward amber · 5 Home meds rose · 6 Follow-up graphite. */
.card.phase { padding-top: 0; overflow: hidden; scroll-margin-top: 130px; border: 1px solid var(--ph-line); }
.card.phase > h2 {
  margin: 0 -24px 16px; padding: 11px 24px;
  background: var(--ph-fill); color: var(--ph-ink);
  border-bottom: 1px solid var(--ph-line);
  font-size: 15px; font-weight: 700; letter-spacing: 0.02em;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.card.phase > h2::before {
  content: var(--ph-num); flex: none;
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ph-solid); color: #fff; font-size: 13px; letter-spacing: 0;
}
.card.phase-1 { --ph-num: '1'; --ph-solid: #2f5d8a; --ph-fill: #e6eef6; --ph-line: #d5e1ee; --ph-ink: #1e3f5e; }
.card.phase-2 { --ph-num: '2'; --ph-solid: #0f766e; --ph-fill: #d7f0ec; --ph-line: #bfe3dd; --ph-ink: #0b4f4a; }
.card.phase-3 { --ph-num: '3'; --ph-solid: #ffffff; --ph-fill: #4c1d95; --ph-line: #4c1d95; --ph-ink: #ffffff; }
.card.phase-4 { --ph-num: '4'; --ph-solid: #b45309; --ph-fill: #fcebd3; --ph-line: #f3d3a8; --ph-ink: #7a3a06; }
.card.phase-5 { --ph-num: '5'; --ph-solid: #be185d; --ph-fill: #fbe1ec; --ph-line: #f3c4d8; --ph-ink: #831843; }
.card.phase-6 { --ph-num: '6'; --ph-solid: #4b5563; --ph-fill: #e9eaec; --ph-line: #d9dbdf; --ph-ink: #1f2937; }
.card.phase-3 { border-width: 2px; box-shadow: 0 6px 20px rgba(76,29,149,0.14); }
.card.phase-3 > h2 { font-size: 16px; }
.card.phase-3 > h2::before { color: #4c1d95; }
.card.phase-3 > h2 .muted { color: #e4dbfb !important; }
.card.phase-3 .dose-line.header { color: #4c1d95; }

/* Inside a phase card the secondary buttons take the phase's own hue, so a
   control reads as belonging to its step (the design's violet-outlined chemo
   buttons, slate for assessment, …). Primary buttons keep the theme colour:
   one filled action per card, the same everywhere in the app. Phase 3's band
   is solid violet, so its buttons use a pale lavender instead of the band. */
.card.phase { --ph-btn-bg: var(--ph-fill); --ph-btn-ink: var(--ph-ink); --ph-btn-line: var(--ph-line); }
.card.phase-3 { --ph-btn-bg: #ede9fe; --ph-btn-ink: #4c1d95; --ph-btn-line: #c4b5fd; }
.card.phase button.secondary, .card.phase .btn.secondary {
  background: var(--ph-btn-bg); color: var(--ph-btn-ink); border-color: var(--ph-btn-line);
}
.card.phase button.secondary:hover, .card.phase .btn.secondary:hover { filter: brightness(0.95); }
.card.phase button.secondary:active, .card.phase .btn.secondary:active { filter: brightness(0.90); }
/* The Final (mg) box is the chemo step's own control: violet frame on a pale
   lavender field, tabular digits — matches the band whatever the theme. */
.card.phase-3 .dose-line input[data-role="final"] {
  border-color: #4c1d95; background: #f5f3ff; color: #2e1065;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
}
.card.phase-3 .dose-line input[data-role="final"]:focus { border-color: #4c1d95; box-shadow: 0 0 0 4px rgba(76,29,149,0.18); }
.card.phase-3 .stale-chip { color: #4c1d95; background: #ede9fe; border-color: #a78bfa; }

/* Step jump-bar inside the sticky patient strip */
.phase-nav { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 6px; padding-top: 4px; }
.phase-nav a {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px 2px 3px; border-radius: 999px;
  font-size: 12px; font-weight: 600; text-decoration: none;
  background: var(--ph-fill); color: var(--ph-ink);
}
.phase-nav a::before {
  content: var(--ph-num); width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ph-solid); color: #fff; font-size: 11px;
}
.phase-nav a.phase-3::before { color: #4c1d95; }
.phase-nav a.phase-1 { --ph-num: '1'; --ph-solid: #2f5d8a; --ph-fill: #e6eef6; --ph-ink: #1e3f5e; }
.phase-nav a.phase-2 { --ph-num: '2'; --ph-solid: #0f766e; --ph-fill: #d7f0ec; --ph-ink: #0b4f4a; }
.phase-nav a.phase-3 { --ph-num: '3'; --ph-solid: #ffffff; --ph-fill: #4c1d95; --ph-ink: #ffffff; }
.phase-nav a.phase-4 { --ph-num: '4'; --ph-solid: #b45309; --ph-fill: #fcebd3; --ph-ink: #7a3a06; }
.phase-nav a.phase-5 { --ph-num: '5'; --ph-solid: #be185d; --ph-fill: #fbe1ec; --ph-ink: #831843; }
.phase-nav a.phase-6 { --ph-num: '6'; --ph-solid: #4b5563; --ph-fill: #e9eaec; --ph-ink: #1f2937; }
.phase-nav a.ph-hidden { display: none; }

/* Metric tile tint variants */
.metric[class*="tint-"] { background: var(--surface); }
.metric.tint-blue   { border-color: rgba(0,113,227,0.25);  background: rgba(0,113,227,0.05); }
.metric.tint-blue   .label { color: var(--primary); }
.metric.tint-purple { border-color: rgba(175,82,222,0.28); background: rgba(175,82,222,0.05); }
.metric.tint-purple .label { color: var(--purple); }
.metric.tint-mint   { border-color: rgba(0,199,190,0.28);  background: rgba(0,199,190,0.06); }
.metric.tint-mint   .label { color: var(--mint-ink); }
.metric.tint-teal   { border-color: rgba(64,200,224,0.28); background: rgba(64,200,224,0.06); }
.metric.tint-teal   .label { color: var(--teal-ink); }
.metric.tint-orange { border-color: rgba(255,149,0,0.28);  background: rgba(255,149,0,0.06); }
.metric.tint-orange .label { color: var(--orange-ink); }

/* Button extras — only when a section explicitly opts in. Keeps the default
   primary button blue everywhere else. */
button.indigo, .btn.indigo { background: var(--indigo); }
button.indigo:hover, .btn.indigo:hover { background: #4a48c0; }
button.purple, .btn.purple { background: var(--purple); }
button.purple:hover, .btn.purple:hover { background: #9a3cc7; }
button.teal, .btn.teal { background: var(--teal); }
button.teal:hover, .btn.teal:hover { background: #2faec7; }

.toolbar {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.toolbar .spacer { flex: 1; }
.toolbar label { margin: 0; }
.toolbar > label > input,
.toolbar > input { margin-top: 6px; }

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

/* Login screen */
.login-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background:
    radial-gradient(900px 600px at 0% 0%,    rgba(0,113,227,0.22),  transparent 55%),
    radial-gradient(900px 600px at 100% 0%,  rgba(175,82,222,0.22), transparent 55%),
    radial-gradient(900px 700px at 100% 100%, rgba(0,199,190,0.26), transparent 60%),
    radial-gradient(900px 700px at 0% 100%, rgba(255,149,0,0.18),   transparent 60%),
    linear-gradient(180deg, #fbfbfd 0%, #f5f5f7 100%);
  padding: 24px;
}
.login-card {
  background: rgba(255,255,255,0.85);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid rgba(255,255,255,0.6);
  border-radius: var(--radius-lg);
  padding: 32px;
  width: 360px;
  box-shadow: var(--shadow-lg);
}
.login-card h1 {
  margin: 0 0 6px;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.login-card p.sub { margin: 0 0 20px; color: var(--muted); font-size: 14px; }
.login-card .field { margin-bottom: 14px; }
.login-card button {
  width: 100%;
  padding: 12px;
  font-size: 15px;
  font-weight: 500;
  border-radius: var(--radius-md);
}

/* Dose grid */
.dose-line {
  display: grid;
  grid-template-columns: 1.4fr .9fr .9fr .9fr 1.1fr 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 12px 4px;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}
.dose-line:last-child { border-bottom: 0; }
.dose-line .name { font-weight: 600; letter-spacing: -0.01em; }
.dose-line .prev { color: var(--muted); font-size: 12px; }
.dose-line.header {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  padding: 8px 4px;
}
.dose-line input[type="number"] { padding: 8px 10px; font-weight: 500; }
/* Final (mg) is the one box on the sheet that matters: a 2px theme-coloured
   frame and a bigger, bolder number so it is never mistaken for the
   read-only columns beside it. */
.dose-line input[data-role="final"] {
  border: 2px solid var(--final-border);
  background: var(--final-bg);
  font-size: 15px;
  font-weight: 700;
  padding: 7px 10px;
}
.dose-line input[data-role="final"]:focus { border-color: var(--primary); }
.dose-line button.secondary {
  padding: 6px 10px;
  border-radius: 980px;
  font-size: 13px;
}

/* Password strength meter (rendered under a new-password input) */
.pwd-meter {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.4;
}
.pwd-meter-bars {
  display: flex;
  gap: 4px;
  margin-bottom: 4px;
}
.pwd-meter-bars span {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--border);
  transition: background 0.15s ease;
}
.pwd-meter-label {
  font-weight: 600;
  min-height: 1.2em;
}
.pwd-meter-hint {
  color: var(--muted);
  min-height: 1.2em;
}

/* ---------- Responsive (phones & small tablets) ---------- */

/* Tablets — tighten chrome and let the topbar's nav buttons wrap rather
   than spilling off the right edge. Desktop dose / row layouts are kept. */
@media screen and (max-width: 900px) {
  main { padding: 22px 16px 56px; }
  .card { padding: 18px 18px; }
  .card[class*="tint-"] { padding-left: 14px; }

  /* Nav flex/wrap behavior comes from the base header.topbar rules;
     here we just let the whole bar wrap and tighten its padding. */
  header.topbar { flex-wrap: wrap; gap: 8px; padding: 10px 16px; }
  header.topbar h1 { flex-shrink: 1; }

  /* The 7-column dose grid is too tight below ~1000px — give the inputs
     room and shrink the header chrome so labels still fit on one line. */
  .dose-line, .dose-line.header { gap: 8px; }
  .dose-line.header { font-size: 10px; }
  .dose-line input[type="number"] { padding: 7px 8px; }
  .dose-line button.secondary { padding: 5px 8px; font-size: 12px; }

  /* Toolbars with many controls (Doctor Station has 6+) wrap cleanly. */
  .toolbar { row-gap: 10px; }
}

/* Phones — stack the topbar, collapse .row / .toolbar grids, let
   wide tables scroll horizontally, fold the chemo dose grid into
   stacked mini-cards. Single-file responsive layer: all pages
   share this stylesheet, so no per-page markup changes are needed. */
@media screen and (max-width: 720px) {
  /* 16px on inputs prevents iOS Safari from auto-zooming on focus. */
  input[type="text"],
  input[type="number"],
  input[type="date"],
  input[type="password"],
  input[type="search"],
  select,
  textarea {
    font-size: 16px;
  }

  header.topbar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 10px 14px;
  }
  header.topbar h1 { font-size: 15px; white-space: normal; }
  header.topbar > div { justify-content: flex-start; }
  header.topbar .who { font-size: 12px; }

  /* Stacked layout: each nav group takes its own row and the divider
     turns horizontal. */
  .topnav-group { width: 100%; }
  .topnav-group + .topnav-group {
    border-left: 0;
    padding-left: 0;
    margin-left: 0;
    border-top: 1px solid rgba(0,0,0,0.08);
    padding-top: 8px;
  }

  main { padding: 14px 12px 48px; }

  .card {
    padding: 16px 14px;
    margin-bottom: 14px;
    border-radius: var(--radius-md);
  }
  .card[class*="tint-"] { padding-left: 12px; }

  /* Stack form rows; override inline fixed flex-basis values
     (e.g. flex:0 0 260px) used on individual pages. */
  .row { flex-direction: column; gap: 12px; }
  .row > * {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    max-width: 100% !important;
    width: 100%;
  }

  /* Toolbars: every control becomes a full-width row. */
  .toolbar { flex-direction: column; align-items: stretch; gap: 10px; }
  .toolbar > * {
    width: 100% !important;
    max-width: none !important;
    flex: 0 0 auto !important;
  }
  .toolbar .spacer { display: none; }

  /* Slightly larger tap targets. Segmented-control buttons stay compact. */
  button, .btn { padding: 10px 16px; }
  .seg button { padding: 8px 14px; }

  /* Tables: switch to a horizontally-scrollable block so the page
     itself doesn't widen on narrow screens. Each row stays on one
     line so columns remain visually aligned while the user swipes. */
  table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
    max-width: 100%;
  }
  th, td { padding: 10px 10px; }
  /* Pre-meds is only checkbox · drug · dose — wrap the long dose text
     instead of hiding it off-screen behind a sideways swipe. */
  #preMedTable { white-space: normal; }

  /* Chemo dose grid → labelled mini-cards stacked vertically. The shared
     column header row is meaningless once stacked, so hide it — but each
     value cell then needs its own caption, or the doctor sees an unlabelled
     stack of numbers on a dosing screen. The render adds data-label="…" to
     every value cell (Basis, Calculated dose, Final dose, Route, Previous);
     we surface it as a small caption above the value here. The drug-name
     cell and the recalc-button cell carry no data-label, so they stay clean. */
  .dose-line {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 14px;
    background: var(--surface-2);
    border: 1px solid rgba(0,0,0,0.06);
    border-radius: var(--radius-md);
    margin-bottom: 10px;
  }
  .dose-line.header { display: none; }
  .dose-line .name { font-size: 15px; }
  .dose-line > [data-label] { display: flex; flex-direction: column; gap: 3px; }
  .dose-line > [data-label]::before {
    content: attr(data-label);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    color: var(--muted);
  }
  /* The recalc button sits in a .right cell on desktop; left-align it once
     the line is a stacked card so it doesn't float alone on the right. */
  .dose-line .right { text-align: left; }

  /* Login card fills the screen but caps at the original width. */
  .login-card { width: min(360px, 100%); padding: 28px 22px; }

  /* Metric tiles: fixed two-up on phones instead of auto-fit. */
  .metrics { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .metric { padding: 12px 12px; }
  .metric .value { font-size: 20px; }
}

/* Very narrow phones (≤ 380px). */
@media screen and (max-width: 380px) {
  header.topbar h1 { font-size: 14px; }
  .metrics { grid-template-columns: 1fr; }
  button, .btn { padding: 10px 14px; font-size: 13px; }
  /* Keep the segmented control buttons visually consistent with the
     shrunk sibling buttons on tiny phones — without this they retained
     6px vertical padding while neighbouring buttons dropped to 10px. */
  .seg button { padding: 8px 12px; font-size: 13px; }
}

/* ====================================================================
   Keyboard / "mouseless" support (shared/keyboard.js)
   ==================================================================== */

/* A clearly visible focus ring on every interactive element for keyboard
   users. :focus-visible only paints when navigating by keyboard, so mouse
   clicks stay clean. */
a:focus-visible,
[tabindex]:focus-visible,
.kb-click:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Rows / cards opted into keyboard activation. The whole element reads as a
   button: pointer cursor on hover, ring on keyboard focus. */
.kb-click { cursor: pointer; }
.kb-click:hover { background: rgba(0,113,227,0.05); }
tr.kb-click:hover > td { background: rgba(0,113,227,0.05); }
.kb-click:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: -2px;
}

/* Command palette + help overlay backdrop */
.kb-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(0,0,0,0.32);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh 16px 16px;
  -webkit-backdrop-filter: saturate(120%) blur(2px);
  backdrop-filter: saturate(120%) blur(2px);
}

/* ---- Command palette ---- */
.kb-palette {
  width: 100%;
  max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 64vh;
}
.kb-palette-input {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 16px 18px;
  font-size: 16px;
  background: var(--surface);
  color: var(--text);
}
.kb-palette-input:focus { outline: none; box-shadow: none; border-color: var(--border); }
.kb-palette-list { overflow-y: auto; padding: 6px; }
.kb-palette-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.kb-palette-item.sel { background: var(--primary); color: #fff; }
.kb-palette-item.sel .kb-pi-group,
.kb-palette-item.sel .kb-pi-hint { color: rgba(255,255,255,0.82); }
.kb-pi-group {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  min-width: 56px;
}
.kb-pi-label { flex: 1; font-weight: 500; }
.kb-pi-hint { font-size: 12px; color: var(--muted); }
.kb-palette-empty { padding: 18px; text-align: center; color: var(--muted); }

/* ---- Help overlay ---- */
.kb-help {
  position: relative;
  width: 100%;
  max-width: 640px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 22px 24px 18px;
  max-height: 76vh;
  overflow-y: auto;
}
.kb-help h2 { margin: 0 0 14px; font-size: 18px; }
.kb-help-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 28px;
}
.kb-help-sec h3 {
  margin: 0 0 8px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}
.kb-help-sec dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 12px;
  align-items: baseline;
}
.kb-help-sec dt { white-space: nowrap; }
.kb-help-sec dd { margin: 0; color: var(--text-2); }
.kb-help-foot { margin: 16px 0 0; color: var(--muted); font-size: 13px; }
.kb-help-close {
  position: absolute;
  top: 12px;
  right: 12px;
  background: rgba(0,0,0,0.05);
  color: var(--text);
  padding: 6px 10px;
  min-height: 0;
}
kbd {
  display: inline-block;
  font: 600 12px/1.4 -apple-system, "SF Mono", ui-monospace, monospace;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 1px 7px;
  color: var(--text);
  min-width: 16px;
  text-align: center;
}
@media (max-width: 560px) {
  .kb-help-grid { grid-template-columns: 1fr; }
}

/* Floating "⌘K shortcuts" discovery pill */
.kb-hint {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 8000;
  background: rgba(0,0,0,0.72);
  color: #fff;
  border: 0;
  border-radius: 980px;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 500;
  box-shadow: var(--shadow-md);
  opacity: 0.55;
  transition: opacity .15s ease, background-color .15s ease;
  min-height: 0;
}
.kb-hint:hover { opacity: 1; background: rgba(0,0,0,0.85); }
.kb-hint span {
  font: 600 11px/1 "SF Mono", ui-monospace, monospace;
  background: rgba(255,255,255,0.2);
  border-radius: 4px;
  padding: 2px 5px;
  margin-right: 4px;
}
@media (max-width: 720px) {
  /* On phones the pill would cover row actions — shrink to just the chip. */
  .kb-hint { padding: 8px 10px; font-size: 0; opacity: 0.5; }
  .kb-hint span { font-size: 12px; margin: 0; }
}

/* ====================================================================
   Dialogs — shared modal chrome. Pages set only the width inline (it is
   legitimately per-dialog); the frame, the dimmed/blurred backdrop, and
   the iOS-style open animation all live here so every modal matches and
   no page has to re-declare border/radius/padding. Width is supplied via
   a `--dlg-w` custom property (preferred) or a plain inline width.
   ==================================================================== */
dialog {
  width: var(--dlg-w, min(560px, 92vw));
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  max-width: calc(100vw - 24px);
}
dialog > form { padding: 20px; }
dialog > form > h2:first-child,
dialog > h2:first-child { margin-top: 0; }
dialog::backdrop {
  background: rgba(0,0,0,0.32);
  -webkit-backdrop-filter: saturate(120%) blur(3px);
  backdrop-filter: saturate(120%) blur(3px);
}
@media (prefers-reduced-motion: no-preference) {
  dialog[open] { animation: dlg-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1); }
  dialog[open]::backdrop { animation: dlg-fade 0.22s ease; }
}
@keyframes dlg-in {
  from { opacity: 0; transform: translateY(8px) scale(0.975); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@keyframes dlg-fade { from { opacity: 0; } to { opacity: 1; } }

/* Right-aligned button row that closes most dialogs/forms. Replaces the
   repeated inline `display:flex; gap:8px; justify-content:flex-end`. */
.form-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: center;
  margin-top: 14px;
  flex-wrap: wrap;
}
.form-actions.between { justify-content: space-between; }

/* Inline form error line. Pages toggle visibility with `style.display`,
   so this class only carries the colour — it must NOT set display, or the
   JS reveal (`el.style.display = ''`) would fall back to hidden again. */
.form-error { color: var(--danger); font-size: 13px; margin: 10px 0 0; }

/* Solid (filled) badge variant — higher emphasis than the default tinted
   badge, for "here now / active" states (e.g. pharmacy "Arrived"). */
.badge.solid        { color: #fff; background: var(--primary); }
.badge.solid.mint   { background: var(--mint-ink); }
.badge.solid.green  { background: var(--green-ink); }
.badge.solid.orange { background: var(--orange-ink); }
.badge.solid.danger { background: var(--danger); }

/* Category pills — same shape as .badge, surfaced as its own class so
   audit-style category tags read distinctly from data badges. */
.pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.pill.auth     { background: rgba(0,113,227,0.12);  color: var(--primary); }
.pill.access   { background: rgba(175,82,222,0.12); color: var(--purple); }
.pill.protocol { background: rgba(0,199,190,0.14);  color: var(--mint-ink); }
.pill.data     { background: rgba(52,199,89,0.16);  color: var(--green-ink); }
.pill.fail     { background: rgba(255,59,48,0.12);  color: var(--danger); }

/* Call-out banners — tinted box with a coloured left rail, mirroring the
   card-tint language. `.danger` for destructive warnings, `.warn` for
   caution, `.info` for neutral notes. Colour differentiates intent. */
.banner {
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  border-left: 4px solid var(--border-strong);
  padding: 10px 12px;
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.5;
}
.banner.danger {
  background: rgba(255,59,48,0.06);
  border-color: rgba(255,59,48,0.20);
  border-left-color: var(--danger);
  color: #7a2a16;
}
.banner.warn {
  background: rgba(255,159,10,0.08);
  border-color: rgba(255,159,10,0.22);
  border-left-color: var(--warn);
  color: var(--orange-ink);
}
.banner.info {
  background: rgba(0,113,227,0.06);
  border-color: rgba(0,113,227,0.18);
  border-left-color: var(--primary);
  color: var(--text-2);
}
.banner.indigo {
  background: rgba(94,92,230,0.07);
  border-color: rgba(94,92,230,0.25);
  border-left-color: var(--indigo);
  color: var(--text-2);
}

/* Highlighted table rows with a coloured left rail — the "needs attention
   now" treatment (e.g. a patient who has physically arrived). Pair with a
   background tint set per page so the hue carries the meaning. */
tr.row-rail td:first-child { box-shadow: inset 3px 0 0 0 var(--rail, var(--primary)); }

/* Small monospace timestamp / status stamp used in row cells. */
.stamp { font-size: 11px; white-space: nowrap; color: var(--muted); }

/* ---- Spacing utilities — for genuinely static margins only. Do not use
   on elements whose visibility is toggled via inline `style.display`. ---- */
.mt-0  { margin-top: 0 !important; }
.mt-6  { margin-top: 6px; }
.mt-8  { margin-top: 8px; }
.mt-10 { margin-top: 10px; }
.mt-12 { margin-top: 12px; }
.mt-14 { margin-top: 14px; }
.mb-0  { margin-bottom: 0 !important; }
.mb-6  { margin-bottom: 6px; }
.mb-8  { margin-bottom: 8px; }
.mb-12 { margin-bottom: 12px; }
.mb-14 { margin-bottom: 14px; }

/* ---- Theme picker (shared/theme.js) ---- */
header.topbar .theme-btn { padding-left: 11px; padding-right: 12px; }
.theme-pop {
  position: fixed;
  z-index: 9500;
  display: none;
  min-width: 240px;
  padding: 8px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
.theme-pop.open { display: block; }
.theme-pop-title {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); padding: 4px 10px 8px;
}
.theme-opt {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text); box-shadow: none;
  font-weight: 500; justify-content: flex-start; text-align: left;
}
.theme-opt:hover { background: rgba(0,0,0,0.05); }
.theme-opt.active { background: rgba(0,0,0,0.06); font-weight: 700; }
.theme-sw { width: 36px; height: 20px; border-radius: 6px; border: 1px solid rgba(0,0,0,0.14); flex: none; }
.theme-sw.classic { background: linear-gradient(90deg, #ffffff 0 55%, #0071e3 55%); }
.theme-sw.ocean   { background: linear-gradient(90deg, #0b3a5a, #0f6a8a); }
.theme-sw.forest  { background: linear-gradient(90deg, #14532d, #1f7a4d); }
.theme-sw.sunset  { background: linear-gradient(90deg, #6d2a6b, #c2410c); }
.theme-sw.pokemon { background: linear-gradient(90deg, #ffcb05 0 55%, #2a75bb 55%); }
.theme-sw.hirono  { background: linear-gradient(90deg, #d9c29e 0 55%, #3e5a7a 55%); }
.theme-name { flex: 1; }
.theme-hint { font-size: 11px; color: var(--muted); }
.theme-check { width: 16px; text-align: right; opacity: 0; color: var(--primary); }
.theme-opt.active .theme-check { opacity: 1; }

/* Print */
@media print {
  .kb-overlay, .kb-hint, .theme-pop { display: none !important; }
  header.topbar, .toolbar, button, .btn { display: none !important; }
  body { background: #fff; }
  .card { border: 0; box-shadow: none; padding: 0; }
  /* Restore native table layout when printing on a phone — the mobile
     `display:block` rule would otherwise carry over into the printout. */
  table { display: table; white-space: normal; overflow: visible; }
}

/* ---- Pokémon / Hirono decorative art (2026-10-08, ported from RBH) ------
   Screen only, and only while that theme is on — all background images, so
   nothing is read aloud and other themes never download them. One figure
   beside every topbar title, one per order phase on doctor/patient.html,
   two on the login card.
   Pokémon: Pikachu topbar · 1 Squirtle 2 Bulbasaur 3 Charmander 4 Psyduck
   5 Igglybuff 6 Eevee · Pichu + Bellossom on login.
   Hirono: box-head boy topbar · 1 coat 2 tree 3 Little Prince 4 sleeping
   (rest after chemo) 5 suitcase (going home) 6 scarecrow (next visit) ·
   apple + red-hair boys on login. */
@media screen {
  html[data-theme="pokemon"] header.topbar h1 {
    padding-left: 40px;
    background: url("pokemon/pikachu.png") no-repeat left center / auto 36px;
  }
  html[data-theme="hirono"] header.topbar h1 {
    padding-left: 34px;
    background: url("hirono/box.png") no-repeat left center / auto 38px;
  }
  html[data-theme="pokemon"] .card.phase > h2,
  html[data-theme="hirono"] .card.phase > h2 {
    padding-right: 84px;
    background-repeat: no-repeat;
    background-position: right 18px bottom -8px;
    background-size: auto 54px;
  }
  html[data-theme="hirono"] .card.phase > h2 { background-position: right 18px bottom -6px; }
  html[data-theme="pokemon"] .card.phase-1 > h2 { background-image: url("pokemon/squirtle.png"); }
  html[data-theme="pokemon"] .card.phase-2 > h2 { background-image: url("pokemon/bulbasaur.png"); }
  html[data-theme="pokemon"] .card.phase-3 > h2 { background-image: url("pokemon/charmander.png"); }
  html[data-theme="pokemon"] .card.phase-4 > h2 { background-image: url("pokemon/psyduck.png"); }
  html[data-theme="pokemon"] .card.phase-5 > h2 { background-image: url("pokemon/igglybuff.png"); }
  html[data-theme="pokemon"] .card.phase-6 > h2 { background-image: url("pokemon/eevee.png"); }
  html[data-theme="hirono"] .card.phase-1 > h2 { background-image: url("hirono/coat.png"); }
  html[data-theme="hirono"] .card.phase-2 > h2 { background-image: url("hirono/tree.png"); }
  html[data-theme="hirono"] .card.phase-3 > h2 { background-image: url("hirono/prince.png"); }
  html[data-theme="hirono"] .card.phase-4 > h2 { background-image: url("hirono/sleep.png"); background-size: auto 44px; background-position: right 14px bottom -2px; }
  html[data-theme="hirono"] .card.phase-5 > h2 { background-image: url("hirono/suitcase.png"); }
  html[data-theme="hirono"] .card.phase-6 > h2 { background-image: url("hirono/scarecrow.png"); }

  html[data-theme="pokemon"] .login-card,
  html[data-theme="hirono"] .login-card { position: relative; overflow: visible; }
  html[data-theme="pokemon"] .login-card::before,
  html[data-theme="pokemon"] .login-card::after,
  html[data-theme="hirono"] .login-card::before,
  html[data-theme="hirono"] .login-card::after {
    content: ""; position: absolute; pointer-events: none;
    background: no-repeat center / contain;
  }
  html[data-theme="pokemon"] .login-card::before { width: 76px; height: 76px; top: -58px; right: 18px; background-image: url("pokemon/pichu.png"); }
  html[data-theme="pokemon"] .login-card::after  { width: 70px; height: 70px; bottom: -26px; left: -30px; background-image: url("pokemon/bellossom.png"); }
  html[data-theme="hirono"] .login-card::before  { width: 60px; height: 96px; top: -76px; right: 22px; background-image: url("hirono/apple.png"); }
  html[data-theme="hirono"] .login-card::after   { width: 56px; height: 90px; bottom: -34px; left: -26px; background-image: url("hirono/redhair.png"); }
}
@media screen and (max-width: 720px) {
  html[data-theme="pokemon"] .card.phase > h2,
  html[data-theme="hirono"] .card.phase > h2 { padding-right: 60px; background-size: auto 44px; }
  html[data-theme="hirono"] .card.phase-4 > h2 { padding-right: 76px; background-size: auto 36px; }
}
