/* ── Typefaces ──────────────────────────────────────────────────────────────
   IBM Plex, self-hosted. Not linked from Google Fonts: that would add a
   third-party origin to the CSP and send a request carrying the viewer's IP
   and referrer on every page load of an authenticated clinical session. These
   ship with the app, so font-src stays 'self', they work inside the installed
   PWA, and there is no extra DNS and TLS handshake before text can paint.

   Plex was drawn for interfaces and data. That matters more here than taste:
   staff read dosages and times on a phone, often in poor light, so the numerals
   are unambiguous and 1 / l / I and 0 / O do not collapse into each other.

   font-display: swap — text paints immediately in the fallback and reflows when
   the face arrives. A blank screen while a font loads is not acceptable when
   someone is checking a medication.
   ────────────────────────────────────────────────────────────────────────── */
@font-face { font-family: 'Plex Sans'; src: url('/fonts/plex-sans-400.woff2') format('woff2');
             font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Plex Sans'; src: url('/fonts/plex-sans-500.woff2') format('woff2');
             font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Plex Sans'; src: url('/fonts/plex-sans-600.woff2') format('woff2');
             font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Plex Sans'; src: url('/fonts/plex-sans-700.woff2') format('woff2');
             font-weight: 700; font-style: normal; font-display: swap; }

/* The serif carries the one thing the brand is about. Used for the sign-in
   promise and the daily greeting only — warmth where a person is addressed,
   never in the dense clinical screens where it would cost legibility. */
@font-face { font-family: 'Plex Serif'; src: url('/fonts/plex-serif-400.woff2') format('woff2');
             font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Plex Serif'; src: url('/fonts/plex-serif-600.woff2') format('woff2');
             font-weight: 600; font-style: normal; font-display: swap; }

/* Monospace for anything read as data rather than prose: times, dosages,
   client numbers, backup codes. Fixed advance width makes a column of figures
   scannable and a transposed digit visible. */
@font-face { font-family: 'Plex Mono'; src: url('/fonts/plex-mono-400.woff2') format('woff2');
             font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Plex Mono'; src: url('/fonts/plex-mono-500.woff2') format('woff2');
             font-weight: 500; font-style: normal; font-display: swap; }

/* ═══════════════════════════════════════════════════════════════════════════
   Victory Digital Health — design system

   Built mobile-first: the base rules describe the phone layout and the
   breakpoints add structure as the viewport grows. Staff use this on a phone
   at a client's kitchen table far more often than at a desk, so the small
   screen is the primary case rather than an afterthought.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Brand — teal reads as clinical without the coldness of a corporate blue,
     and the rose accent carries the human half of the mark. */
  --brand-50:  #f0fdfa;
  --brand-100: #ccfbf1;
  --brand-200: #99f6e4;
  --brand-300: #5eead4;
  --brand-400: #2dd4bf;
  --brand-500: #14b8a6;
  --brand-600: #0d9488;
  --brand-700: #0f766e;
  --brand-800: #115e59;
  --brand-900: #134e4a;
  --brand-950: #042f2e;

  --heart-400: #fb7185;
  --heart-500: #f43f5e;

  /* Neutrals */
  --ink-950: #080f1a;
  --ink-900: #0f172a;
  --ink-800: #1e293b;
  --ink-700: #334155;
  --ink-600: #475569;
  --ink-500: #64748b;
  --ink-400: #94a3b8;
  --ink-300: #cbd5e1;
  --ink-200: #e2e8f0;
  --ink-100: #f1f5f9;
  --ink-50:  #f8fafc;

  /* Status */
  --ok-500: #10b981;   --ok-50: #ecfdf5;   --ok-700: #047857;
  --warn-500: #f59e0b; --warn-50: #fffbeb; --warn-700: #b45309;
  --risk-500: #ef4444; --risk-50: #fef2f2; --risk-700: #b91c1c;
  --info-500: #3b82f6; --info-50: #eff6ff; --info-700: #1d4ed8;

  /* Semantic surfaces */
  --bg:            #f5f7f9;
  --surface:       #ffffff;
  --surface-2:     var(--ink-50);
  --surface-sunken: var(--ink-100);
  --border:        var(--ink-200);
  --border-strong: var(--ink-300);
  --text:          var(--ink-900);
  --text-muted:    var(--ink-500);
  --text-subtle:   var(--ink-400);
  --accent:        var(--brand-600);
  --accent-text:   var(--brand-700);
  --accent-soft:   var(--brand-50);

  /* Elevation. Layered rather than single-shadow so cards read as physical
     without the muddy grey halo a single large blur produces. */
  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.07), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.07), 0 2px 4px rgba(15, 23, 42, 0.04);
  --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.11), 0 4px 8px rgba(15, 23, 42, 0.05);
  --shadow-xl: 0 24px 64px rgba(15, 23, 42, 0.18), 0 8px 16px rgba(15, 23, 42, 0.06);

  --radius-sm: 8px;
  --radius:    12px;
  --radius-lg: 16px;
  --radius-xl: 22px;
  --radius-pill: 999px;

  /* Type. Fluid sizes so the same stylesheet reads well on a 360px phone and
     a 1600px desk monitor without a stack of breakpoint overrides. */
  --font: 'Plex Sans', ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI',
          Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-serif: 'Plex Serif', ui-serif, Georgia, 'Times New Roman', serif;
  --font-mono: 'Plex Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  --text-xs:   0.76rem;
  --text-sm:   0.83rem;
  --text-base: 0.955rem;
  --text-md:   1.02rem;
  --text-lg:   clamp(1.05rem, 0.98rem + 0.35vw, 1.25rem);
  --text-xl:   clamp(1.3rem, 1.15rem + 0.7vw, 1.75rem);
  --text-2xl:  clamp(1.7rem, 1.35rem + 1.6vw, 2.6rem);
  --text-3xl:  clamp(2.1rem, 1.5rem + 2.6vw, 3.4rem);

  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
  --space-12: 48px; --space-16: 64px;

  /* The smallest comfortable touch target. Anything interactive meets it. */
  --tap: 44px;

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --sidebar-w: 248px;
  --bottom-nav-h: 62px;

  color-scheme: light dark;
}

/* Dark theme. Follows the device setting: night-shift staff work in dim rooms
   and a full-brightness white screen at 3am is a genuine usability problem. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg:            #0a1017;
    --surface:       #121a24;
    --surface-2:     #18222e;
    --surface-sunken: #0d141c;
    --border:        #24303e;
    --border-strong: #33414f;
    --text:          #e8eef4;
    --text-muted:    #93a3b5;
    --text-subtle:   #6b7c8f;
    --accent:        var(--brand-400);
    --accent-text:   var(--brand-300);
    --accent-soft:   rgba(20, 184, 166, 0.12);

    --ok-50:   rgba(16, 185, 129, 0.13);
    --warn-50: rgba(245, 158, 11, 0.13);
    --risk-50: rgba(239, 68, 68, 0.13);
    --info-50: rgba(59, 130, 246, 0.13);
    --ok-700:  #34d399;
    --warn-700:#fbbf24;
    --risk-700:#f87171;
    --info-700:#60a5fa;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.45);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
    --shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.6);
  }
}

/* ── Reset ────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;   /* stop iOS enlarging text in landscape */
  scroll-behavior: smooth;
}

body {
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: 1.58;
  /* Lining figures at a consistent width, so a column of dosages or times
     lines up and an unexpected digit stands out. */
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Stops the pull-to-refresh gesture firing while scrolling a long MAR. */
  overscroll-behavior-y: none;
}

a { text-decoration: none; color: var(--accent-text); }
img, svg { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
.hidden { display: none !important; }

/* Every focusable element gets a visible ring. Staff work through these forms
   by keyboard at speed, and it is an accessibility requirement besides. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

::selection { background: var(--brand-200); color: var(--brand-950); }

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

/* ═══ Sign-in ══════════════════════════════════════════════════════════════ */

.login-body {
  min-height: 100svh;         /* svh, not vh: excludes mobile browser chrome */
  display: grid;
  grid-template-columns: 1fr;
  background: var(--bg);
}

/* The brand panel. On a phone it is a compact banner above the form; from
   1024px it becomes a full-height column beside it. */
.auth-hero {
  position: relative;
  overflow: hidden;
  padding: clamp(var(--space-8), 6vw, var(--space-16)) clamp(var(--space-5), 5vw, var(--space-12));
  padding-top: calc(clamp(var(--space-8), 6vw, var(--space-16)) + env(safe-area-inset-top));
  background:
    radial-gradient(1100px 700px at 12% -10%, rgba(45, 212, 191, 0.30), transparent 62%),
    radial-gradient(900px 700px at 105% 108%, rgba(244, 63, 94, 0.20), transparent 58%),
    linear-gradient(155deg, var(--brand-950) 0%, var(--brand-800) 48%, #0b3f45 100%);
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-5);
}

/* A soft grid, barely visible, to keep the large gradient from reading flat. */
.auth-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(70% 60% at 30% 25%, #000 25%, transparent 78%);
  pointer-events: none;
}

.auth-hero > * { position: relative; z-index: 1; }

.brand-lockup { display: flex; align-items: center; gap: var(--space-3); }
.brand-icon { width: 46px; height: 46px; border-radius: 13px; box-shadow: var(--shadow-lg); flex-shrink: 0; }
.brand-name {
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.brand-name small {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-300);
  margin-top: 3px;
}

/* The promise. This is the first thing anyone sees, so it is set as the
   largest element on the page rather than tucked under the form. */
.auth-promise {
  font-family: var(--font-serif);
  font-size: var(--text-2xl);
  font-weight: 600;
  /* The serif is already wide and open; the tight tracking that suited the
     system sans would close it up and cost the warmth it is here for. */
  letter-spacing: -0.012em;
  line-height: 1.2;
  max-width: 21ch;
  text-wrap: balance;
}
/* The emphasised word carries the rose from the mark. It ran teal-to-rose
   before, which put the first half of the word in the same hue as the panel
   behind it and lost the emphasis entirely. */
.auth-promise em {
  font-style: normal;
  background: linear-gradient(100deg, var(--heart-400), #fda4af 55%, var(--brand-300) 145%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.auth-promise-sub {
  font-size: var(--text-md);
  color: rgba(255, 255, 255, 0.76);
  max-width: 46ch;
  line-height: 1.6;
}

.auth-values { display: grid; gap: var(--space-3); margin-top: var(--space-2); }
.auth-value { display: flex; align-items: flex-start; gap: var(--space-3); font-size: var(--text-sm); color: rgba(255, 255, 255, 0.8); }
.auth-value-icon {
  flex-shrink: 0;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.11);
  border: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 0.8rem;
}
.auth-value strong { display: block; color: #fff; font-weight: 600; margin-bottom: 1px; }

/* Form column */
.auth-shell {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(var(--space-6), 5vw, var(--space-12)) var(--space-5);
  padding-bottom: calc(clamp(var(--space-6), 5vw, var(--space-12)) + env(safe-area-inset-bottom));
}

.auth-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: clamp(var(--space-6), 4vw, var(--space-8));
  box-shadow: var(--shadow-md);
}

.auth-logo { display: none; }   /* the hero carries the mark instead */
.auth-title {
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.008em;
  text-wrap: balance;
}
.auth-sub { font-size: var(--text-sm); color: var(--text-muted); margin: var(--space-2) 0 var(--space-6); }

.login-form { display: grid; gap: var(--space-4); }
.login-step { display: grid; gap: var(--space-2); }

.step-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--accent-text);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.step-hint { font-size: var(--text-xs); color: var(--text-muted); line-height: 1.5; }
.step-hint a { font-weight: 600; }

.login-form input,
.form-input,
.filter-row input, .filter-row select,
.section-toolbar input, .section-toolbar select,
.modal-form input, .modal-form select, .modal-form textarea,
.ai-input, .ai-select, .ai-textarea {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-3) var(--space-4);
  /* 16px on mobile: iOS Safari zooms the viewport when a focused field is any
     smaller, which throws the user out of the layout mid-entry. */
  font-size: max(16px, var(--text-base));
  color: var(--text);
  background: var(--surface);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
  -webkit-appearance: none;
  appearance: none;
}

.login-form input::placeholder,
.form-input::placeholder,
textarea::placeholder { color: var(--text-subtle); }

.login-form input:focus,
.form-input:focus,
.filter-row input:focus, .filter-row select:focus,
.section-toolbar input:focus, .section-toolbar select:focus,
.modal-form input:focus, .modal-form select:focus, .modal-form textarea:focus,
.ai-input:focus, .ai-select:focus, .ai-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}

select, .ai-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%2364748b' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  padding-right: var(--space-10);
}

.otp-row { display: flex; gap: var(--space-2); }
.otp-row input { flex: 1; }
.otp-btn { flex-shrink: 0; white-space: nowrap; }

.otp-display {
  font-size: var(--text-md);
  font-weight: 700;
  font-family: var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--info-700);
  background: var(--info-50);
  border: 1px solid color-mix(in srgb, var(--info-500) 25%, transparent);
  padding: var(--space-3);
  border-radius: var(--radius);
  text-align: center;
}

.redirect-notice {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--warn-50);
  color: var(--warn-700);
  font-size: var(--text-sm);
  font-weight: 500;
  border: 1px solid color-mix(in srgb, var(--warn-500) 32%, transparent);
  margin-bottom: var(--space-5);
}

.hipaa-notice {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  line-height: 1.6;
  color: var(--text-muted);
}

.error-text { color: var(--risk-500); font-size: var(--text-sm); font-weight: 500; min-height: 1.2em; }

/* Two-factor enrollment */
.enroll-qr {
  margin: var(--space-4) auto;
  background: #fff;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.enroll-secret {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.09em;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  word-break: break-all;
  user-select: all;
}

.backup-codes {
  background: var(--warn-50);
  border: 1px solid color-mix(in srgb, var(--warn-500) 32%, transparent);
  border-radius: var(--radius);
  padding: var(--space-4);
  margin: var(--space-4) 0;
  color: var(--warn-700);
}
.backup-codes ul {
  list-style: none;
  margin-top: var(--space-3);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-1) var(--space-4);
}
.backup-codes li { font-family: var(--font-mono); font-size: var(--text-sm); letter-spacing: 0.05em; user-select: all; }

/* ═══ Buttons ══════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap);
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: -0.005em;
  border: 1.5px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.12s var(--ease), box-shadow 0.18s var(--ease),
              background-color 0.15s var(--ease), border-color 0.15s var(--ease);
  /* Suppresses the grey flash iOS paints over a tapped control. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.btn:active:not(:disabled) { transform: translateY(1px) scale(0.995); }
.btn:disabled, .btn.disabled { opacity: 0.5; cursor: not-allowed; }

.btn-primary {
  background: linear-gradient(160deg, var(--brand-500), var(--brand-700));
  color: #fff;
  box-shadow: 0 1px 2px rgba(15, 118, 110, 0.3), 0 4px 14px rgba(13, 148, 136, 0.28);
}
.btn-primary:hover:not(:disabled) {
  box-shadow: 0 2px 4px rgba(15, 118, 110, 0.32), 0 8px 22px rgba(13, 148, 136, 0.35);
}

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); border-color: var(--accent); color: var(--accent-text); }

.btn-full { width: 100%; }
.btn-sm { min-height: 34px; padding: var(--space-1) var(--space-3); font-size: var(--text-xs); border-radius: var(--radius-sm); }

.btn-signout {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-2);
  background: rgba(239, 68, 68, 0.1);
  color: #fca5a5;
  border: 1px solid rgba(239, 68, 68, 0.28);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s var(--ease);
}
.btn-signout:hover { background: rgba(239, 68, 68, 0.2); }

/* ═══ Portal shell ═════════════════════════════════════════════════════════ */

.portal-body { background: var(--bg); height: 100svh; overflow: hidden; }
.app-layout { display: flex; height: 100svh; overflow: hidden; }

/* ── Sidebar ──────────────────────────────────────────────────────────────
   Below 1024px it leaves the flow and becomes an off-canvas drawer. */
.sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background: linear-gradient(185deg, var(--brand-950) 0%, #0a1520 62%, var(--ink-950) 100%);
  color: var(--ink-200);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  border-right: 1px solid rgba(255, 255, 255, 0.06);
}

.sidebar-brand {
  padding: var(--space-6) var(--space-5) var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-base);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  color: #fff;
}
.sidebar-brand img { width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0; }
.brand-mark { font-size: 1.5rem; }
.sidebar-brand small {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-300);
  margin-top: 2px;
}

.sidebar-nav { flex: 1; padding: var(--space-3) var(--space-3); display: grid; gap: 2px; align-content: start; }

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink-400);
  cursor: pointer;
  border-radius: var(--radius-sm);
  position: relative;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.nav-item:hover { background: rgba(255, 255, 255, 0.06); color: var(--ink-100); }
.nav-item.active { background: rgba(20, 184, 166, 0.15); color: var(--brand-300); font-weight: 600; }
.nav-item.active::before {
  content: '';
  position: absolute;
  left: calc(var(--space-3) * -1 + 2px);
  top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 22px;
  border-radius: var(--radius-pill);
  background: var(--brand-400);
}

.sidebar-footer { padding: var(--space-4) var(--space-4); border-top: 1px solid rgba(255, 255, 255, 0.07); }
.sidebar-user-info { font-size: var(--text-xs); color: var(--ink-400); margin-bottom: var(--space-2); word-break: break-word; line-height: 1.45; }

/* ── Main column ─────────────────────────────────────────────────────────── */
.main-wrapper { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; }

.topbar {
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
  padding: 0 var(--space-5);
  padding-top: env(safe-area-inset-top);
  min-height: calc(58px + env(safe-area-inset-top));
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  z-index: 20;
}
.topbar h2 { font-size: var(--text-lg); font-weight: 600; letter-spacing: -0.015em; flex: 1; min-width: 0; }

/* Drawer toggle — only meaningful once the sidebar is off-canvas. */
.nav-toggle {
  display: none;
  width: var(--tap); height: var(--tap);
  margin-left: calc(var(--space-2) * -1);
  align-items: center; justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
  -webkit-tap-highlight-color: transparent;
}
.nav-toggle:hover { background: var(--surface-sunken); }
.nav-toggle span { display: block; width: 19px; height: 2px; background: currentColor; border-radius: 2px; position: relative; }
.nav-toggle span::before, .nav-toggle span::after {
  content: ''; position: absolute; left: 0; width: 19px; height: 2px;
  background: currentColor; border-radius: 2px;
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after { top: 6px; }

.role-badge {
  background: var(--accent-soft);
  color: var(--accent-text);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.content-area {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding: var(--space-5);
  padding-bottom: calc(var(--space-10) + env(safe-area-inset-bottom));
}

.session-warning {
  margin: var(--space-4) var(--space-5) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--warn-50);
  border: 1px solid color-mix(in srgb, var(--warn-500) 34%, transparent);
  border-radius: var(--radius);
  color: var(--warn-700);
  font-size: var(--text-sm);
  font-weight: 500;
}

.content-section { animation: sectionIn 0.24s var(--ease-out); }
@keyframes sectionIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── Dashboard ───────────────────────────────────────────────────────────── */
.dash-greeting {
  background: linear-gradient(140deg, var(--brand-800), var(--brand-950) 78%);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: clamp(var(--space-5), 4vw, var(--space-8));
  margin-bottom: var(--space-5);
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
.dash-greeting::after {
  content: '';
  position: absolute;
  right: -60px; top: -70px;
  width: 260px; height: 260px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(45, 212, 191, 0.30), transparent 68%);
  pointer-events: none;
}
.dash-greeting h3 {
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.008em;
  position: relative;
}
.dash-greeting p { font-size: var(--text-sm); color: rgba(255, 255, 255, 0.76); margin-top: var(--space-2); max-width: 60ch; position: relative; line-height: 1.6; }

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
  transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
/* A colour rail rather than a coloured card: the number stays the loudest
   thing in the tile. */
.stat-card::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--stat-colour, var(--brand-500));
}
.stat-card.blue   { --stat-colour: var(--info-500); }
.stat-card.green  { --stat-colour: var(--ok-500); }
.stat-card.orange { --stat-colour: var(--warn-500); }
.stat-card.purple { --stat-colour: #8b5cf6; }
.stat-card.blue .stat-val   { color: var(--info-700); }
.stat-card.green .stat-val  { color: var(--ok-700); }
.stat-card.orange .stat-val { color: var(--warn-700); }
.stat-card.purple .stat-val { color: #a78bfa; }

.stat-val {
  /* A count is data, not prose. Mono keeps the figures at a fixed advance so
     the four tiles align down the page as the numbers change. */
  font-family: var(--font-mono);
  font-size: clamp(1.75rem, 1.4rem + 1.3vw, 2.3rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stat-lbl { font-size: var(--text-xs); color: var(--text-muted); margin-top: var(--space-2); font-weight: 500; }

.mini-list { display: grid; gap: 0; }
.mini-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--text-sm);
}
.mini-row:last-child { border-bottom: none; }

/* ── Panels & tables ─────────────────────────────────────────────────────── */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
}
.panel h3 { font-size: var(--text-md); font-weight: 600; letter-spacing: -0.012em; margin-bottom: var(--space-4); }

.section-toolbar {
  display: flex; align-items: center; gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.filter-row { display: flex; gap: var(--space-3); flex: 1; flex-wrap: wrap; min-width: 0; }
.filter-row input, .filter-row select { flex: 1 1 170px; min-width: 0; }
.section-toolbar > .btn { flex-shrink: 0; }

/* Wide clinical tables scroll inside their own container rather than pushing
   the page sideways — a MAR has 31 day columns and will never fit a phone. */
.data-list {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.data-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface-2);
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  /* Dates, times, dosages and client numbers all sit in these cells; tabular
     figures keep them aligned so a transposed digit is visible at a glance. */
  font-variant-numeric: lining-nums tabular-nums;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr { transition: background 0.12s var(--ease); }
.data-table tbody tr:hover { background: var(--surface-2); }

.empty-msg, .empty-state {
  padding: var(--space-10) var(--space-5);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* ── Badges ──────────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  background: var(--surface-sunken);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.badge-active, .badge-given, .badge-green, .badge-completed, .badge-approved, .badge-resolved {
  background: var(--ok-50); color: var(--ok-700); border-color: color-mix(in srgb, var(--ok-500) 28%, transparent);
}
.badge-pending, .badge-orange, .badge-in-progress, .badge-moderate, .badge-variance, .badge-review {
  background: var(--warn-50); color: var(--warn-700); border-color: color-mix(in srgb, var(--warn-500) 28%, transparent);
}
.badge-open, .badge-red, .badge-high, .badge-severe, .badge-refused, .badge-missed, .badge-critical {
  background: var(--risk-50); color: var(--risk-700); border-color: color-mix(in srgb, var(--risk-500) 28%, transparent);
}
.badge-blue, .badge-scheduled, .badge-low, .badge-mild {
  background: var(--info-50); color: var(--info-700); border-color: color-mix(in srgb, var(--info-500) 28%, transparent);
}

/* ── Modals ──────────────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(8, 15, 26, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
  animation: fadeIn 0.18s var(--ease);
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.modal-box {
  background: var(--surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  width: 100%;
  max-width: 640px;
  max-height: min(88svh, 860px);
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: modalIn 0.26s var(--ease-out);
}
@keyframes modalIn { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: none; } }

.modal-header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.modal-header h3 { font-size: var(--text-md); font-weight: 700; letter-spacing: -0.015em; }
.modal-close-btn {
  width: var(--tap); height: var(--tap);
  display: grid; place-items: center;
  background: transparent; border: none;
  border-radius: var(--radius-sm);
  font-size: 1.35rem; line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
}
.modal-close-btn:hover { background: var(--surface-sunken); color: var(--text); }

.modal-body { padding: var(--space-5); overflow-y: auto; -webkit-overflow-scrolling: touch; }

.modal-form { display: grid; gap: var(--space-4); }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--space-4); }
.form-grid label, .modal-form label {
  display: grid; gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.form-actions { display: flex; gap: var(--space-3); justify-content: flex-end; flex-wrap: wrap; padding-top: var(--space-2); }
.form-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-5); }

/* ── AI assistant ────────────────────────────────────────────────────────── */
.ai-fab {
  position: fixed;
  right: var(--space-5);
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex; align-items: center; gap: var(--space-2);
  min-height: 52px;
  padding: var(--space-3) var(--space-5);
  background: linear-gradient(150deg, var(--brand-500), var(--brand-700));
  color: #fff;
  border: none;
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(255, 255, 255, 0.08) inset;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.ai-fab:hover { transform: translateY(-2px); box-shadow: var(--shadow-xl); }
.ai-icon { font-size: 1.05rem; }

.ai-drawer {
  position: fixed; inset: 0; z-index: 110;
  background: var(--surface);
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-xl);
  animation: sheetUp 0.3s var(--ease-out);
}
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
@keyframes slideInRight { from { transform: translateX(100%); } to { transform: none; } }

.ai-drawer-header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5);
  padding-top: calc(var(--space-5) + env(safe-area-inset-top));
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.ai-drawer-title { font-size: var(--text-md); font-weight: 700; }
.ai-drawer-close {
  width: var(--tap); height: var(--tap);
  display: grid; place-items: center;
  background: transparent; border: none; border-radius: var(--radius-sm);
  font-size: 1.35rem; color: var(--text-muted); cursor: pointer;
}
.ai-drawer-close:hover { background: var(--surface-sunken); }
.ai-drawer-body {
  padding: var(--space-5);
  padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom));
  overflow-y: auto;
  display: grid;
  gap: var(--space-4);
  align-content: start;
}
.ai-field-group { display: grid; gap: var(--space-2); }
.ai-label { font-size: var(--text-xs); font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.ai-textarea { min-height: 140px; resize: vertical; line-height: 1.6; }
.ai-hint { font-size: var(--text-xs); color: var(--text-subtle); line-height: 1.5; }
.ai-result-section { display: grid; gap: var(--space-2); }
.ai-result-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.ai-result-label { font-size: var(--text-xs); font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.ai-result-text {
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  font-size: var(--text-sm);
  line-height: 1.65;
  white-space: pre-wrap;
  max-height: 46svh;
  overflow-y: auto;
}
.ai-notice { font-size: var(--text-xs); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); }
.ai-notice-info { background: var(--info-50); color: var(--info-700); }
.ai-notice-error { background: var(--risk-50); color: var(--risk-700); }
.btn-ai { background: linear-gradient(150deg, var(--brand-500), var(--brand-700)); color: #fff; }

/* ── Toasts ──────────────────────────────────────────────────────────────── */
.toast-container {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-6) + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 200;
  display: grid;
  gap: var(--space-2);
  width: min(420px, calc(100vw - var(--space-8)));
  pointer-events: none;
}
.toast {
  background: var(--ink-900);
  color: #fff;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.24s var(--ease), transform 0.24s var(--ease-out);
}
.toast.toast-show { opacity: 1; transform: none; }

/* ── Spinner ─────────────────────────────────────────────────────────────── */
.spinner-wrap { display: grid; place-items: center; padding: var(--space-10); }
.spinner {
  width: 30px; height: 30px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Mobile bottom navigation ────────────────────────────────────────────── */
/* The five routes staff reach for during a shift. Thumb-reachable, unlike a
   drawer that has to be opened first. */
.bottom-nav {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 70;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.bottom-nav-inner { display: grid; grid-template-columns: repeat(5, 1fr); }
.bottom-nav-item {
  display: grid;
  place-items: center;
  gap: 3px;
  padding: var(--space-2) var(--space-1);
  min-height: var(--bottom-nav-h);
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--text-subtle);
  cursor: pointer;
  border: none;
  background: transparent;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.15s var(--ease);
}
.bottom-nav-item .bn-icon { font-size: 1.2rem; line-height: 1; }
.bottom-nav-item.active { color: var(--accent-text); }

.nav-scrim {
  display: none;
  position: fixed; inset: 0; z-index: 79;
  background: rgba(8, 15, 26, 0.5);
  backdrop-filter: blur(2px);
  animation: fadeIn 0.2s var(--ease);
}

/* ═══ Breakpoints ══════════════════════════════════════════════════════════ */

/* Tablet and below: sidebar becomes a drawer, bottom nav appears. */
@media (max-width: 1023px) {
  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 80;
    transform: translateX(-100%);
    transition: transform 0.28s var(--ease-out);
    box-shadow: var(--shadow-xl);
    width: min(84vw, 300px);
  }
  .sidebar.open { transform: none; }
  .nav-scrim.open { display: block; }
  .nav-toggle { display: flex; }
  .bottom-nav { display: block; }

  .content-area { padding-bottom: calc(var(--bottom-nav-h) + var(--space-8) + env(safe-area-inset-bottom)); }
  .ai-fab { bottom: calc(var(--bottom-nav-h) + var(--space-4) + env(safe-area-inset-bottom)); }
  .toast-container { bottom: calc(var(--bottom-nav-h) + var(--space-4) + env(safe-area-inset-bottom)); }
}

/* Phones. */
@media (max-width: 640px) {
  .content-area { padding: var(--space-4); padding-bottom: calc(var(--bottom-nav-h) + var(--space-8) + env(safe-area-inset-bottom)); }
  .topbar { padding: 0 var(--space-4); }
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
  .stat-card { padding: var(--space-4); }
  .panel { padding: var(--space-4); border-radius: var(--radius); }
  .section-toolbar > .btn { width: 100%; }
  .filter-row { flex-direction: column; }
  .filter-row input, .filter-row select { flex: 1 1 auto; width: 100%; }

  /* Modals become bottom sheets: reachable by thumb and matching the platform
     convention users already expect. */
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal-box {
    max-width: 100%;
    max-height: 92svh;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    animation: sheetUp 0.3s var(--ease-out);
  }
  .modal-body { padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom)); }
  .form-grid { grid-template-columns: 1fr; }
  .form-actions { flex-direction: column-reverse; }
  .form-actions .btn { width: 100%; }

  .ai-fab { padding: 0; width: 56px; height: 56px; justify-content: center; }
  .ai-fab-label { display: none; }

  .data-table thead th, .data-table td { padding: var(--space-3); }
}

/* Desktop: the hero and the form sit side by side. */
@media (min-width: 1024px) {
  .login-body { grid-template-columns: 1.15fr 1fr; }
  .auth-hero { padding: var(--space-16) var(--space-12); }
}

/* Very wide screens: cap the reading measure rather than stretching tables
   across a 32-inch monitor. */
@media (min-width: 1600px) {
  .content-area > .content-section { max-width: 1500px; margin-inline: auto; }
}

/* Landscape phones have almost no vertical room; drop the hero. */
@media (max-width: 1023px) and (max-height: 520px) and (orientation: landscape) {
  .auth-hero { display: none; }
}

/* ═══ Print ════════════════════════════════════════════════════════════════ */
@media print {
  .sidebar, .topbar, .bottom-nav, .ai-fab, .nav-scrim, .toast-container, .no-print { display: none !important; }
  .app-layout, .portal-body { height: auto; overflow: visible; }
  .content-area { overflow: visible; padding: 0; }
  .panel, .data-list, .stat-card { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
  body { background: #fff; color: #000; }
}
