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

/* ---- Kitty ("เหมียวชมพู"): pastel pink, light header with dark berry text,
   plus the Mochi cat mascot (decorations near the end of this file). Text
   and muted greys stay ≥4.5:1 on white; the alert red is not changed. ---- */
html[data-theme="kitty"] {
  --primary: #d6336c; --primary-hover: #c2255c; --primary-active: #a61e4d;
  --bg: #fff4f8; --surface-2: #fff9fb;
  --border: #f2c6d6; --border-strong: #eab2c7;
  --text: #3b2330; --text-2: #5a3a4a; --muted: #8a5f72;
  --shadow-md: 0 4px 16px rgba(214,51,108,0.08);
  --radius-lg: 22px;
  --topbar-bg: #ffd8e7;
  --topbar-fg: #6b1f45; --topbar-muted: #8a3a5f;
  --topbar-border: transparent; --topbar-accent: #f06595; --topbar-blur: none;
  --nav-bg: rgba(255,255,255,0.78); --nav-fg: #a61e4d; --nav-border: #f3a6c3;
  --nav-bg-hover: #ffffff; --nav-bg-active: #ffe3ee;
  --nav-admin-bg: #f1e7ff; --nav-admin-fg: #6a3fb3; --nav-admin-border: #cfb6f4;
  --nav-admin-bg-hover: #e6d6ff;
  --nav-signout-bg: #fff0ef; --nav-signout-fg: #c0392b; --nav-signout-border: #f4b4ad;
  --nav-signout-bg-hover: #ffe0dd;
  --nav-divider: #eba3bf;
  --btn2-bg: #ffe3ee; --btn2-fg: #a61e4d; --btn2-border: #f8c4d8;
  --btn2-bg-hover: #ffd6e5; --btn2-bg-active: #ffc6da;
  --btn-glow: rgba(214,51,108,0.32);
  --focus-ring: rgba(214,51,108,0.28); --focus-ring-soft: rgba(214,51,108,0.16);
  --strip-bg: rgba(255,240,246,0.94);
  --wash: rgba(214,51,108,0.06);
  --final-border: rgba(214,51,108,0.6); --final-bg: rgba(214,51,108,0.05);
  --cute-font: "Mali", "IBM Plex Sans Thai", var(--font-sans);
  --cute-card-border: #f8d3e1;
  --cute-dots: radial-gradient(#ffd3e3 1.8px, transparent 2.2px);
  --cute-dots-size: 24px 24px;
  --bubble-fg: #a61e4d; --bubble-border: #f3a6c3;
  --header-trim: radial-gradient(circle at 10px 0, #ffd8e7 9px, transparent 9.5px) 0 0 / 20px 10px repeat-x;
  --header-trim-h: 10px;
  --mascot-head: url("mascots/kitty-head.svg"); --mascot-head-w: 46px; --mascot-head-h: 39px;
  --mascot-peek: url("mascots/kitty-peek.svg"); --mascot-peek-w: 100px; --mascot-peek-h: 60px;
  --mascot-nap: url("mascots/kitty-sleep.svg"); --mascot-nap-w: 96px; --mascot-nap-h: 58px;
  --mascot-wave: url("mascots/kitty-wave.svg"); --mascot-wave-h: 152px;
  --mascot-hello: "สวัสดี~";
}

/* ---- Frenchie ("เฟรนชี่"): cream pages, merle-spotted header, slate-blue
   actions and tan secondary buttons, plus the Mocha French Bulldog
   mascot. ---- */
html[data-theme="frenchie"] {
  --primary: #4f6a8f; --primary-hover: #435b7c; --primary-active: #384d69;
  --bg: #fbf6ef; --surface-2: #fdfaf5;
  --border: #e3d2bd; --border-strong: #d8c3a8;
  --text: #3d3547; --text-2: #5a5163; --muted: #6e6475;
  --shadow-md: 0 4px 16px rgba(79,106,143,0.08);
  --radius-lg: 20px;
  --topbar-bg:
    radial-gradient(22px 13px at 6% 78%, #e3ddea 96%, transparent 100%),
    radial-gradient(16px 10px at 31% 22%, #e3ddea 96%, transparent 100%),
    radial-gradient(26px 14px at 57% 80%, #e5dfec 96%, transparent 100%),
    radial-gradient(18px 11px at 79% 20%, #e3ddea 96%, transparent 100%),
    radial-gradient(12px 8px at 94% 82%, #e0d9e8 96%, transparent 100%),
    #ece7f1;
  --topbar-fg: #3d3547; --topbar-muted: #5a5163;
  --topbar-border: rgba(61,53,71,0.12); --topbar-accent: #d4a373; --topbar-blur: none;
  --nav-bg: rgba(255,255,255,0.85); --nav-fg: #3f5677; --nav-border: #c3cddc;
  --nav-bg-hover: #ffffff; --nav-bg-active: #e4eaf2;
  --nav-admin-bg: #f1e7ff; --nav-admin-fg: #6a3fb3; --nav-admin-border: #cfb6f4;
  --nav-admin-bg-hover: #e6d6ff;
  --nav-signout-bg: #fff0ef; --nav-signout-fg: #c0392b; --nav-signout-border: #f4b4ad;
  --nav-signout-bg-hover: #ffe0dd;
  --nav-divider: #bdb3c9;
  --btn2-bg: #f5e6d3; --btn2-fg: #7a4a1e; --btn2-border: #e8cfae;
  --btn2-bg-hover: #f0dcc3; --btn2-bg-active: #e9d0b2;
  --btn-glow: rgba(79,106,143,0.32);
  --focus-ring: rgba(79,106,143,0.28); --focus-ring-soft: rgba(79,106,143,0.16);
  --strip-bg: rgba(250,243,234,0.94);
  --wash: rgba(79,106,143,0.06);
  --final-border: rgba(79,106,143,0.6); --final-bg: rgba(79,106,143,0.05);
  --cute-font: "Itim", "IBM Plex Sans Thai", var(--font-sans);
  --cute-card-border: #ecdcc8;
  --cute-dots: radial-gradient(#efdfca 2px, transparent 2.4px);
  --cute-dots-size: 26px 26px;
  --cute-font-weight: 400;
  --bubble-fg: #3f5677; --bubble-border: #c3cddc;
  --header-trim:
    url("mascots/frenchie-tag.svg") 64px 6px / 28px 28px no-repeat,
    linear-gradient(90deg, #e2bf98 50%, transparent 50%) 0 5px / 16px 2px repeat-x,
    linear-gradient(#4f6a8f, #4f6a8f) 0 0 / 100% 12px no-repeat;
  --header-trim-h: 34px;
  --mascot-head: url("mascots/frenchie-head.svg"); --mascot-head-w: 48px; --mascot-head-h: 40px;
  --mascot-peek: url("mascots/frenchie-peek.svg"); --mascot-peek-w: 112px; --mascot-peek-h: 67px;
  --mascot-nap: url("mascots/frenchie-sleep.svg"); --mascot-nap-w: 96px; --mascot-nap-h: 58px;
  --mascot-wave: url("mascots/frenchie-wave.svg"); --mascot-wave-h: 160px;
  --mascot-hello: "โฮ่ง ๆ สวัสดี~";
}

/* ---- Hello Kitty: red polka-dot header with a yellow top line, magenta
   actions on soft pink pages, and the user's own Hello Kitty pictures
   (assets/mascots/hellokitty-*.png, cut down from assets/hellokitty/). The
   header red is dark enough for white nav text at 4.5:1; the magenta
   primary stays clear of the alert red. ---- */
html[data-theme="hellokitty"] {
  --primary: #d6006f; --primary-hover: #bd0062; --primary-active: #a30055;
  --bg: #fff6f8; --surface-2: #fffafb;
  --border: #f6c4d3; --border-strong: #efafc3;
  --text: #2b1d24; --text-2: #4d3640; --muted: #7d5b69;
  --shadow-md: 0 4px 16px rgba(214,0,111,0.08);
  --radius-lg: 22px;
  --topbar-bg: radial-gradient(rgba(255,255,255,0.16) 2.4px, transparent 2.8px) 0 0 / 22px 22px, #c0263b;
  --topbar-fg: #ffffff; --topbar-muted: rgba(255,255,255,0.86);
  --topbar-border: transparent; --topbar-accent: #ffd400; --topbar-blur: none;
  --nav-bg: rgba(255,255,255,0.16); --nav-fg: #ffffff; --nav-border: rgba(255,255,255,0.55);
  --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.75);
  --nav-admin-bg-hover: rgba(255,230,160,0.38);
  --nav-signout-bg: rgba(60,10,20,0.28); --nav-signout-fg: #ffffff; --nav-signout-border: rgba(255,210,210,0.6);
  --nav-signout-bg-hover: rgba(60,10,20,0.44);
  --nav-divider: rgba(255,255,255,0.4);
  --btn2-bg: #ffe0ec; --btn2-fg: #a3004f; --btn2-border: #f7b9d2;
  --btn2-bg-hover: #ffd2e4; --btn2-bg-active: #ffc2da;
  --btn-glow: rgba(214,0,111,0.30);
  --focus-ring: rgba(214,0,111,0.28); --focus-ring-soft: rgba(214,0,111,0.16);
  --strip-bg: rgba(255,240,245,0.94);
  --wash: rgba(214,0,111,0.06);
  --final-border: rgba(214,0,111,0.6); --final-bg: rgba(214,0,111,0.05);
  --cute-font: "Mali", "IBM Plex Sans Thai", var(--font-sans);
  --cute-card-border: #f8d0dc;
  --cute-dots: radial-gradient(#ffc9d6 2px, transparent 2.4px);
  --cute-dots-size: 24px 24px;
  --bubble-fg: #a3004f; --bubble-border: #f7b9d2;
  --header-trim: radial-gradient(circle at 10px 0, #c0263b 9px, transparent 9.5px) 0 0 / 20px 10px repeat-x;
  --header-trim-h: 10px;
  --mascot-head: url("mascots/hellokitty-head.png"); --mascot-head-w: 50px; --mascot-head-h: 36px;
  --mascot-peek: url("mascots/hellokitty-peek.png"); --mascot-peek-w: 112px; --mascot-peek-h: 65px;
  --mascot-nap: url("mascots/hellokitty-sit.png"); --mascot-nap-w: 68px; --mascot-nap-h: 70px;
  --mascot-wave: url("mascots/hellokitty-wave.png"); --mascot-wave-h: 152px;
  --mascot-hello: "สวัสดี~";
}

/* ---- Miffy ("มิฟฟี่"): Dick Bruna primaries — sunny yellow header with a
   blue top line and a red/blue/green stripe under it, blue actions, yellow
   secondary buttons on warm white pages, and the user's own Miffy pictures
   (assets/mascots/miffy-*.png, cut down from assets/Miffy/). Red stays the
   alert colour only. ---- */
html[data-theme="miffy"] {
  --primary: #1f5fae; --primary-hover: #1a529a; --primary-active: #154585;
  --bg: #fffdf5; --surface-2: #fffcf0;
  --border: #e9dfbd; --border-strong: #dfd2a6;
  --text: #1d1d1f; --text-2: #3a3a3e; --muted: #5f5f66;
  --shadow-md: 0 4px 16px rgba(31,95,174,0.08);
  --radius-lg: 20px;
  --topbar-bg: #ffd84d;
  --topbar-fg: #1d1d1f; --topbar-muted: #4a4a4f;
  --topbar-border: transparent; --topbar-accent: #1f5fae; --topbar-blur: none;
  --nav-bg: #ffffff; --nav-fg: #1d1d1f; --nav-border: rgba(0,0,0,0.5);
  --nav-bg-hover: #fff7d6; --nav-bg-active: #ffefad;
  --nav-admin-bg: #e6eefb; --nav-admin-fg: #1f4f96; --nav-admin-border: #9db8e3;
  --nav-admin-bg-hover: #d6e3f8;
  --nav-signout-bg: #fff0ef; --nav-signout-fg: #c0392b; --nav-signout-border: #f4b4ad;
  --nav-signout-bg-hover: #ffe0dd;
  --nav-divider: rgba(0,0,0,0.25);
  --btn2-bg: #fff2b8; --btn2-fg: #5c4500; --btn2-border: #f0d97a;
  --btn2-bg-hover: #ffeb9c; --btn2-bg-active: #ffe27a;
  --btn-glow: rgba(31,95,174,0.30);
  --focus-ring: rgba(31,95,174,0.28); --focus-ring-soft: rgba(31,95,174,0.16);
  --strip-bg: rgba(255,251,234,0.94);
  --wash: rgba(31,95,174,0.06);
  --final-border: rgba(31,95,174,0.6); --final-bg: rgba(31,95,174,0.05);
  --cute-font: "Mitr", "IBM Plex Sans Thai", var(--font-sans);
  --cute-font-weight: 500;
  --cute-card-border: #efe6c8;
  --cute-dots: radial-gradient(#f3e6b0 2px, transparent 2.4px);
  --cute-dots-size: 26px 26px;
  --bubble-fg: #1f5fae; --bubble-border: #9db8e3;
  --header-trim: repeating-linear-gradient(90deg, #e2402b 0 32px, #1f5fae 32px 64px, #2f8a3e 64px 96px) 0 0 / 100% 6px no-repeat;
  --header-trim-h: 6px;
  --mascot-head: url("mascots/miffy-peek.png"); --mascot-head-w: 38px; --mascot-head-h: 42px;
  --mascot-peek: url("mascots/miffy-peek.png"); --mascot-peek-w: 70px; --mascot-peek-h: 78px;
  --mascot-nap: url("mascots/miffy-rest.png"); --mascot-nap-w: 56px; --mascot-nap-h: 84px;
  --mascot-wave: url("mascots/miffy-wave.png"); --mascot-wave-h: 160px;
  --mascot-hello: "สวัสดี~";
}

* { 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.kitty   { background: linear-gradient(90deg, #ffd8e7 0 55%, #d6336c 55%); }
.theme-sw.frenchie { background: linear-gradient(90deg, #b9b4c2 0 55%, #e2bf98 55%); }
.theme-sw.hellokitty { background: linear-gradient(90deg, #c0263b 0 45%, #ffffff 45% 80%, #ffd400 80%); }
.theme-sw.miffy   { background: linear-gradient(90deg, #ffd84d 0 40%, #1f5fae 40% 70%, #e2402b 70%); }
.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; }

/* ---- Mascot themes (kitty, frenchie, hellokitty, miffy): page pattern, rounded
   headings and the mascot pictures. shared/theme.js puts data-mascot on
   <html> for these themes; each theme block near the top supplies its
   pictures and trim as --mascot-* / --header-trim tokens, so a new mascot
   theme needs only a token block. Every mascot is a background image on a
   pseudo-element with pointer-events off: it sits only in margins (above
   the first card, below the last one, beside the page title), never over
   patient data, and is dropped from print. Clinical numbers keep IBM Plex —
   only headings take the rounded face. ---- */
html[data-mascot] body {
  background-image: var(--cute-dots);
  background-size: var(--cute-dots-size);
}
html[data-mascot] header.topbar h1 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--cute-font);
  font-weight: var(--cute-font-weight, 700);
  letter-spacing: 0;
}
html[data-theme="frenchie"] header.topbar h1 { font-size: 20px; }
html[data-mascot] header.topbar h1::before {
  content: '';
  flex: none;
  width: var(--mascot-head-w);
  height: var(--mascot-head-h);
  background: var(--mascot-head) center / contain no-repeat;
}
html[data-mascot] h2 {
  font-family: var(--cute-font);
  letter-spacing: 0.02em;
}
html[data-mascot] .card {
  border-top-color: var(--cute-card-border);
  border-right-color: var(--cute-card-border);
  border-bottom-color: var(--cute-card-border);
}

/* Header edge trim (lace, collar, scallops) hanging just below the sticky
   header. */
html[data-mascot] header.topbar::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: var(--header-trim-h);
  background: var(--header-trim);
  pointer-events: none;
}

/* The mascot peeks over the top edge of the first card and rests after the
   last one. main gets extra top room so the peek never covers content. */
html[data-mascot] main {
  position: relative;
  padding-top: 76px;
}
html[data-mascot] main::before {
  content: '';
  position: absolute;
  z-index: 1;
  top: calc(80px - var(--mascot-peek-h));
  right: 48px;
  width: var(--mascot-peek-w);
  height: var(--mascot-peek-h);
  background: var(--mascot-peek) center bottom / contain no-repeat;
  pointer-events: none;
}
html[data-mascot] main::after {
  content: '';
  display: block;
  width: var(--mascot-nap-w);
  height: var(--mascot-nap-h);
  margin: 24px auto 0;
  background: var(--mascot-nap) center / contain no-repeat;
  pointer-events: none;
}

/* Sign-in page: the mascot waves from just above the card. */
html[data-mascot] .login-shell {
  background: var(--cute-dots) 0 0 / var(--cute-dots-size), var(--bg);
}
html[data-mascot] .login-card {
  position: relative;
  margin-top: 140px;
  background: var(--surface);
  border: 1px solid var(--cute-card-border);
  border-radius: 26px;
}
html[data-mascot] .login-card h1 {
  font-family: var(--cute-font);
  font-weight: var(--cute-font-weight, 700);
  letter-spacing: 0;
}
html[data-theme="frenchie"] .login-card h1 { font-size: 25px; }
html[data-mascot] .login-card button { border-radius: 980px; }
html[data-mascot] .login-card::before {
  content: '';
  position: absolute;
  left: 50%;
  top: calc(4px - var(--mascot-wave-h));
  width: 150px;
  height: var(--mascot-wave-h);
  transform: translateX(-50%);
  background: var(--mascot-wave) center bottom / contain no-repeat;
  pointer-events: none;
}
html[data-mascot] .login-card::after {
  content: var(--mascot-hello);
  position: absolute;
  top: calc(10px - var(--mascot-wave-h));
  left: calc(50% + 62px);
  padding: 5px 12px;
  border-radius: 14px 14px 14px 4px;
  background: var(--surface);
  border: 2px solid var(--bubble-border);
  color: var(--bubble-fg);
  font-family: var(--cute-font);
  font-size: 15px;
  white-space: nowrap;
  pointer-events: none;
}

@media (max-width: 720px) {
  html[data-mascot] header.topbar h1::before {
    width: calc(var(--mascot-head-w) * 0.74);
    height: calc(var(--mascot-head-h) * 0.74);
  }
  html[data-mascot] main::before { right: 16px; }
  html[data-mascot] .login-card::after { display: none; }
}

/* Print */
@media print {
  .kb-overlay, .kb-hint, .theme-pop { display: none !important; }
  html[data-mascot] body { background-image: none !important; }
  html[data-mascot] main { padding-top: 28px !important; }
  html[data-mascot] main::before, html[data-mascot] main::after,
  html[data-mascot] header.topbar::after, html[data-mascot] header.topbar h1::before { 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; }
}
