/*
 * 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;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
               "Helvetica Neue", Helvetica, Arial, sans-serif;
  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: rgba(255,255,255,0.72);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid rgba(0,0,0,0.06);
  padding: 12px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 20px;
}

header.topbar h1 {
  font-size: 17px;
  margin: 0;
  font-weight: 600;
  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; }

/* Compact nav buttons so the admin's 11-item row fits on one line
   on a typical desktop screen. */
header.topbar .btn,
header.topbar button {
  padding: 6px 13px;
  font-size: 13px;
}

header.topbar .who {
  color: var(--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(--border);
  padding-left: 12px;
  margin-left: 4px;
}

.topnav-group.nav-admin .btn,
.topnav-group.nav-admin button {
  background: rgba(175,82,222,0.12);
  color: var(--purple);
}
.topnav-group.nav-admin .btn:hover,
.topnav-group.nav-admin button:hover { background: rgba(175,82,222,0.20); }
.topnav-group.nav-admin .btn:active,
.topnav-group.nav-admin button:active { background: rgba(175,82,222,0.26); }

.topnav-group.nav-station .btn,
.topnav-group.nav-station button {
  background: rgba(0,113,227,0.10);
  color: var(--primary);
}
.topnav-group.nav-station .btn:hover,
.topnav-group.nav-station button:hover { background: rgba(0,113,227,0.17); }
.topnav-group.nav-station .btn:active,
.topnav-group.nav-station button:active { background: rgba(0,113,227,0.24); }

.topnav-group .signout { background: rgba(255,59,48,0.10); color: var(--danger); }
.topnav-group .signout:hover  { background: rgba(255,59,48,0.17); }
.topnav-group .signout:active { background: rgba(255,59,48,0.24); }

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;
  transition: background-color .15s ease, transform .05s ease, box-shadow .15s ease;
}
button:hover, .btn:hover { background: var(--primary-hover); text-decoration: none; }
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 rgba(0,113,227,0.25);
}

button.secondary, .btn.secondary {
  background: rgba(0,0,0,0.05);
  color: var(--text);
}
button.secondary:hover, .btn.secondary:hover { background: rgba(0,0,0,0.08); }
button.secondary:active, .btn.secondary:active { background: rgba(0,0,0,0.12); }

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;
}
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);
  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 rgba(0,113,227,0.15);
}

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); }

/* 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); }

/* 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; }
.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"],
  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; }

  /* 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; }

/* Print */
@media print {
  .kb-overlay, .kb-hint { 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; }
}
