/* ══════════════════════════════════════════════════════════════════════════
   Hospital AI Knowledge Platform — design system
   Enterprise SaaS: white ground, soft blue/purple gradients, glass cards,
   24px radii, generous spacing. Light and dark.
   ══════════════════════════════════════════════════════════════════════════ */

/* Self-hosted so an on-prem hospital box with no internet still renders the
   intended typeface. 5 weights, latin subset, ~121 KB total.
   swap = text paints immediately in the fallback, then upgrades. */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/inter-latin-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('fonts/inter-latin-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fonts/inter-latin-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('fonts/inter-latin-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 800; font-display: swap;
  src: url('fonts/inter-latin-800.woff2') format('woff2');
}

:root {
  /* Brand */
  --primary: #2563eb;
  --primary-600: #1d4ed8;
  --primary-050: #eff6ff;
  --secondary: #4f46e5;   /* indigo */
  --accent: #06b6d4;      /* cyan */
  --accent-purple: #7c3aed;
  --success: #22c55e;
  --warning: #f59e0b;
  --danger: #ef4444;

  /* Surfaces */
  --bg: #f8fafc;
  --bg-elevated: #ffffff;
  --card: #ffffff;
  --card-glass: rgba(255, 255, 255, 0.72);
  --sidebar: rgba(255, 255, 255, 0.86);
  --border: #e2e8f0;
  --border-strong: #cbd5e1;

  /* Text
     --text-faint is one step darker than the palette's #94A3B8. At #94A3B8 the
     contrast on white is 2.56:1, which fails WCAG AA (4.5:1) — and this token
     carries real content: field labels, timestamps, page counts, upload hints.
     #64748b measures 4.76:1 and is visually near-identical. #94A3B8 is kept as
     --muted-decorative for non-text use (rules, inactive dots, placeholder bars),
     where no contrast minimum applies. */
  --text: #0f172a;
  --text-muted: #475569;
  --text-faint: #64748b;
  --muted-decorative: #94a3b8;
  --on-primary: #ffffff;

  /* Status colours come in two forms: the palette hex for fills (where white sits
     on top and passes) and a darker variant for coloured text/icons on a light
     surface, since #22C55E is 2.28:1 and #EF4444 is 3.76:1 as foreground. */
  --success-text: #15803d;
  --danger-text: #dc2626;

  /* Radii */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-pill: 999px;

  /* Shadows — layered, low-alpha, blue-tinted */
  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-sm: 0 2px 8px rgba(15, 23, 42, 0.05), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-md: 0 8px 24px rgba(15, 23, 42, 0.07), 0 2px 6px rgba(15, 23, 42, 0.04);
  --shadow-lg: 0 18px 48px rgba(15, 23, 42, 0.10), 0 4px 12px rgba(15, 23, 42, 0.05);
  --shadow-xl: 0 32px 72px rgba(15, 23, 42, 0.13), 0 8px 20px rgba(15, 23, 42, 0.06);
  --shadow-primary: 0 12px 28px rgba(37, 99, 235, 0.28);

  /* Layout */
  --sidebar-w: 268px;
  --navbar-h: 72px;
  --maxw: 1320px;

  /* The four named gradients of the design system */
  --grad-primary: linear-gradient(135deg, #2563eb, #4f46e5);
  --grad-hero:    linear-gradient(135deg, #2563eb, #06b6d4);
  --grad-purple:  linear-gradient(135deg, #7c3aed, #2563eb);
  --grad-card-hover: linear-gradient(135deg, rgba(37, 99, 235, .08), rgba(124, 58, 237, .08));

  /* --grad-brand stays as the alias used across components; it is the primary
     gradient with a cyan tail so large fills (orb, icon tiles) do not read flat. */
  --grad-brand: linear-gradient(135deg, #2563eb 0%, #4f46e5 55%, #06b6d4 100%);
  --grad-text: linear-gradient(100deg, #2563eb 0%, #4f46e5 52%, #06b6d4 100%);
  --grad-soft: linear-gradient(180deg, rgba(37, 99, 235, 0.06), rgba(79, 70, 229, 0.02));

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* Design-system motion: 300ms for interaction feedback, 600ms for entrances */
  --t-fast: 180ms;
  --t-base: 300ms;
  --t-slow: 600ms;
}

:root[data-theme='dark'] {
  --bg: #070b16;
  --bg-elevated: #0d1424;
  --card: #101a2e;
  --card-glass: rgba(18, 27, 46, 0.72);
  --sidebar: rgba(12, 19, 34, 0.9);
  --border: #1e2b45;
  --border-strong: #2b3c5c;

  --text: #eef3fb;
  --text-muted: #9dabc4;
  --text-faint: #6d7c96;
  --primary-050: rgba(37, 99, 235, 0.14);

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.5);
  --shadow-xl: 0 32px 72px rgba(0, 0, 0, 0.6);
  --grad-soft: linear-gradient(180deg, rgba(37, 99, 235, 0.14), rgba(79, 70, 229, 0.03));
  /* Dark surfaces swallow an 8% tint, so the card-hover wash is roughly doubled
     to stay perceptible at the same apparent strength as in light mode. */
  --grad-card-hover: linear-gradient(135deg, rgba(59, 130, 246, .16), rgba(139, 92, 246, .14));
  /* On dark surfaces the light-mode text variants invert: the bright palette hues
     already exceed 4.5:1 against #101a2e, while the darkened ones would not. */
  --success-text: #4ade80;
  --danger-text: #f87171;
  --muted-decorative: #55647f;
}

* { box-sizing: border-box; }

/* The `hidden` attribute must actually hide. The browser implements it as
   `display: none` in its own stylesheet, which any author rule setting `display`
   silently beats — so `<button class="nav-item" hidden>` stayed visible because
   `.nav-item` sets `display: flex`, and the same was true of `.nav-item__badge`
   (`display: grid`) on the patient counter. One line, so the attribute means what it
   says everywhere and no future `hidden` fails the same quiet way. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--navbar-h) + 16px); }

body {
  margin: 0;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Inter stylistic sets: cv02/03/04 give the single-storey shapes and ss01 the
     disambiguated 1/l/I that keep UHIDs and dosages readable at small sizes. */
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'ss01';
  font-variant-numeric: lining-nums;
}

/* Display type is tighter than body: at 42px+ the default tracking reads loose. */
h1, h2, h3, h4 { margin: 0; line-height: 1.12; letter-spacing: -0.03em; font-weight: 700; }
h3, h4 { letter-spacing: -0.02em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, select, textarea { font: inherit; color: inherit; }
img { max-width: 100%; display: block; }
ul { margin: 0; padding: 0; list-style: none; }

::selection { background: rgba(37, 99, 235, 0.2); }

/* Scrollbars */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 99px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: content-box; }

.gradient-text {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Navbar ─────────────────────────────────────────────────────────────── */

/* Sticky glass header. The hairline is a gradient rather than a flat border so it
   fades toward the edges instead of stopping dead against the viewport. */
.navbar {
  position: fixed; inset: 0 0 auto 0; height: var(--navbar-h); z-index: 100;
  display: flex; align-items: center; gap: 20px; padding: 0 28px;
  background: var(--card-glass);
  backdrop-filter: saturate(180%) blur(24px);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--border) 18%, var(--border) 82%, transparent) 1;
  transition: box-shadow var(--t-base) var(--ease), background var(--t-base);
  animation: navbar-in var(--t-slow) var(--ease) both;
}
/* Elevation appears only once the page has scrolled, so the header sits flat on
   the hero and lifts off the content below it. */
.navbar.is-scrolled {
  box-shadow: 0 6px 24px rgba(15, 23, 42, 0.07);
  background: rgba(255, 255, 255, 0.86);
}
:root[data-theme='dark'] .navbar.is-scrolled { background: rgba(12, 19, 34, 0.88); }

@keyframes navbar-in { from { opacity: 0; transform: translateY(-100%); } }

/* min-height matches the icon buttons opposite it, so the whole navbar row shares
   one hit-target height and the logo is not a 30px sliver to tap. */
.brand { display: flex; align-items: center; gap: 13px; min-width: 0; min-height: 40px; }

/* Alphanso wordmark. Height-constrained with width:auto so the 663x150 source
   keeps its ratio; the width/height attributes on the tag reserve the right box
   before the image decodes, so the header does not reflow on load. */
.brand__logo {
  height: 30px; width: auto; flex: 0 0 auto; display: block;
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.brand:hover .brand__logo { transform: translateY(-1px); opacity: .88; }

/* One polarity per theme — never both. */
.brand__logo--dark { display: none; }
:root[data-theme='dark'] .brand__logo--light { display: none; }
:root[data-theme='dark'] .brand__logo--dark { display: block; }

/* Hospital name, centred on the header itself — not in the space left over beside
   the brand. The brand and the action cluster are different widths, so a flex
   `margin: 0 auto` would have parked the title off-centre by half that
   difference. Absolute positioning puts it on the header's true midpoint whatever
   sits either side, and pointer-events:none keeps its invisible box from
   swallowing clicks aimed at the controls behind it. */
.navbar__title {
  position: absolute; left: 50%; transform: translateX(-50%);
  /* Because it is centred, the title grows symmetrically — so the cap has to
     reserve room on BOTH sides, not just cap the text, or a hospital with a long
     name runs under the logo. 240px per side: the brand and action clusters
     measure 161px and 186px, and below 1024px the hamburger joins the left one,
     which is what made a narrower reservation collide at ~820px. */
  max-width: min(460px, calc(100vw - 480px));
  font-size: 15px; font-weight: 700; letter-spacing: -0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-align: center; pointer-events: none;
}

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

/* ── Views ──────────────────────────────────────────────────────────────── */

/* Only one view is in the document flow at a time. The fade-and-rise is what
   makes a view switch read as a page transition rather than a flicker. */
.view { display: none; }
.view.is-active { display: block; animation: view-in .32s var(--ease) both; }
@keyframes view-in { from { opacity: 0; transform: translateY(10px); } }

/* ── Patients list page ─────────────────────────────────────────────────────
   Deliberately plain: one white card holding one table. No toolbar, no badges,
   no avatars. Rounded via overflow:hidden on the wrapper so the first and last
   rows clip to the corner radius without per-cell radii. */

.ptable-wrap {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  /* hidden clips the first and last rows to the corner radius; overflow-x then
     reopens the horizontal axis. Both are needed: with plain `hidden` any table
     wider than its wrapper was silently cut off with no way to reach the rest —
     between 900px and 1024px that severed the Action column, so the View button
     was on screen but unreachable. Scrolling is always available now, and the
     axis only actually scrolls when the columns genuinely do not fit. */
  overflow: hidden;
  overflow-x: auto;
  /* Keeps the scroll gesture on this box instead of chaining to the page. */
  overscroll-behavior-x: contain;
}

.ptable { width: 100%; border-collapse: collapse; }

.ptable th {
  padding: 15px 20px; text-align: left; white-space: nowrap;
  font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-faint);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.ptable td {
  padding: 16px 20px; text-align: left;
  font-size: 14px; color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  /* Rows are read across, so every cell in one starts on the same baseline even
     when a neighbour wraps to four lines. Centring made a one-line UHID float in
     the middle of a wrapped patient name. */
  vertical-align: top;
  /* OCR'd values include unbroken tokens (accession numbers, hyphen-free IDs)
     with no space to wrap at; without this they push the column wider than the
     screen instead of breaking. */
  overflow-wrap: anywhere;
}
.ptable tbody tr:last-child td { border-bottom: 0; }

.ptable tbody tr {
  cursor: pointer;
  transition: background var(--t-base);
}
.ptable tbody tr:hover { background: var(--primary-050); }
.ptable tbody tr:focus-visible {
  outline: none; background: var(--primary-050);
  box-shadow: inset 0 0 0 2px rgba(37, 99, 235, .38);
}

.ptable__name { font-weight: 600; color: var(--text); }
/* No nowrap: a provisional UHID can run to 30+ characters, and forcing it onto
   one line was what pushed the table past its wrapper and cut the Action column
   off. It breaks only when it has to. */
.ptable__uhid { font-weight: 600; color: var(--primary); overflow-wrap: anywhere; }
.ptable__num { text-align: right; font-variant-numeric: tabular-nums; }
.ptable__act { text-align: right; white-space: nowrap; }
/* Dates never wrap mid-value, and tabular figures keep a column of them aligned
   even in a proportional font. */
.ptable__date { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* The Medicines table has no row action — nothing to open, since medicines are
   extracted values rather than documents. Without this it would still offer a
   pointer cursor and a hover highlight, promising a click that does nothing. */
.ptable--plain tbody tr { cursor: default; }
.ptable--plain tbody tr:hover { background: transparent; }

/* Below the scroll breakpoint a table needs a floor width, otherwise the columns
   compress into unreadable slivers instead of scrolling. The floor is per table
   rather than global: the patients list carries seven columns and genuinely needs
   one, while the record tabs carry four or five and fit a phone once their cells
   are allowed to wrap — giving those the same 720px floor made them scroll for
   no reason. */
@media (max-width: 900px) {
  .ptable { min-width: 640px; }
  .ws-panel .ptable { min-width: 0; }
  /* Tighter gutters buy back ~90px across a five-column row, which is the
     difference between fitting a 390px screen and not. */
  .ptable th, .ptable td { padding-left: 14px; padding-right: 14px; }
  .ws-panel .ptable th, .ws-panel .ptable td { padding: 13px 12px; }
}

/* ── Patient workspace ──────────────────────────────────────────────────── */

/* Explicit grid rather than a wrapping flex row. As flex, the badge row carried
   margin-left:auto and justify-content:flex-end, so once it wrapped it sat
   right-aligned on its own line while the name above it was left-aligned — a
   ragged edge that got worse the more badges a patient had, and on a phone left
   each badge stranded against the right margin. The areas below pin identity to
   the left, actions to the right, and badges to a full-width row that starts on
   the same left edge as the name. */
.ws__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "avatar identity actions"
    "badges badges   badges";
  align-items: center;
  column-gap: 16px; row-gap: 14px;
  padding: 24px; margin-bottom: 18px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.ws__avatar {
  grid-area: avatar;
  width: 54px; height: 54px; border-radius: 16px; display: grid; place-items: center;
  background: var(--grad-primary); color: #fff; font-size: 18px; font-weight: 700;
  box-shadow: var(--shadow-primary);
}
.ws__identity { grid-area: identity; min-width: 0; }
.ws__name { font-size: 21px; }
.ws__uhid { font-size: 12.5px; font-weight: 700; color: var(--primary); letter-spacing: .05em; overflow-wrap: anywhere; }
.ws__badges { grid-area: badges; margin-left: 0; justify-content: flex-start; }

/* Export and Delete act on the whole record rather than on one document, so they
   belong to the header and not to any of the four tabs. */
.ws__actions { grid-area: actions; display: flex; gap: 8px; }

/* Tab bar scrolls sideways rather than wrapping: on a narrow screen the tabs
   would otherwise reflow into two rows and shift the panels down. */
.ws__tabs {
  display: flex; gap: 6px; margin-bottom: 20px; padding-bottom: 4px;
  overflow-x: auto; scrollbar-width: none;
}
.ws__tabs::-webkit-scrollbar { display: none; }

.ws-tab {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto;
  height: 40px; padding: 0 16px; border-radius: var(--r-pill);
  font-size: 13.5px; font-weight: 600; color: var(--text-muted);
  border: 1px solid var(--border); background: var(--card);
  transition: color var(--t-base), background var(--t-base), border-color var(--t-base),
              box-shadow var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.ws-tab svg { width: 16px; height: 16px; }
.ws-tab:hover { color: var(--primary); border-color: rgba(37, 99, 235, .35); transform: translateY(-1px); }
.ws-tab.is-active {
  color: #fff; background: var(--grad-primary); border-color: transparent;
  box-shadow: var(--shadow-primary);
}

/* Only the active panel is in flow. The fade-in is what makes switching read as
   a transition rather than a jump. */
.ws-panel { display: none; }
.ws-panel.is-active { display: block; animation: ws-fade .28s var(--ease) both; }
@keyframes ws-fade { from { opacity: 0; transform: translateY(6px); } }

.panel-stack { display: grid; gap: 18px; }

/* Prescriptions */
.rx-sub { font-size: 12.5px; color: var(--text-faint); margin: -4px 0 14px; }
.rx-lines { display: grid; gap: 8px; }
.rx-line {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding: 10px 14px; border-radius: var(--r-md);
  background: var(--bg); border: 1px solid var(--border);
}
.rx-line__name { font-size: 14px; font-weight: 600; }
.rx-line__meta { display: flex; gap: 10px; flex-wrap: wrap; font-size: 12px; color: var(--text-muted); }

/* AI extraction checklist */
.xtract { display: grid; gap: 2px; }
.xtract__row {
  display: grid; grid-template-columns: 22px minmax(0, 150px) minmax(0, 1fr);
  gap: 12px; align-items: center; padding: 9px 2px;
  border-bottom: 1px solid var(--border);
}
.xtract__row:last-child { border-bottom: 0; }
.xtract__icon { width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center; }
.xtract__icon svg { width: 13px; height: 13px; }
.xtract__icon--ok { background: rgba(34, 197, 94, .12); color: var(--success-text); }
.xtract__icon--miss { background: rgba(148, 163, 184, .16); color: var(--text-faint); }
.xtract__label { font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.xtract__value { font-size: 13.5px; min-width: 0; overflow-wrap: anywhere; }

/* ── Footer ─────────────────────────────────────────────────────────────── */

.site-footer {
  padding: 30px 40px 34px; text-align: center;
  border-top: 1px solid var(--border);
}
.site-footer p { font-size: 13px; color: var(--text-faint); }

.icon-btn {
  width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center;
  color: var(--text-muted); border: 1px solid transparent; position: relative;
  transition: background .18s, color .18s, border-color .18s, transform .18s;
}
.icon-btn svg { width: 19px; height: 19px; }
.icon-btn:hover { background: var(--primary-050); color: var(--primary); border-color: var(--border); }
.icon-btn:active { transform: scale(0.94); }
.icon-btn__dot {
  position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger); border: 2px solid var(--card);
}

.ai-status {
  display: flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px;
  border-radius: var(--r-pill); border: 1px solid var(--border);
  background: var(--bg-elevated); font-size: 12px; font-weight: 600; color: var(--text-muted);
  white-space: nowrap;
}
.ai-status__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint); flex: 0 0 auto; }
.ai-status--online .ai-status__dot { background: var(--success); box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18); animation: pulse-dot 2.4s var(--ease) infinite; }
.ai-status--offline .ai-status__dot { background: var(--danger); box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.18); }

@keyframes pulse-dot {
  0%, 100% { box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18); }
  50% { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0.05); }
}

.avatar {
  width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  background: var(--grad-brand); color: #fff; font-weight: 700; font-size: 13px;
  box-shadow: var(--shadow-sm); cursor: pointer; flex: 0 0 auto;
}

.nav-toggle { display: none; }

/* ── Sidebar ────────────────────────────────────────────────────────────── */

.sidebar {
  position: fixed; top: var(--navbar-h); bottom: 0; left: 0; width: var(--sidebar-w);
  z-index: 90; padding: 22px 16px; overflow-y: auto;
  display: flex; flex-direction: column;
  background: var(--sidebar);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-right: 1px solid var(--border);
  transition: transform .3s var(--ease);
}

/* Fills the sidebar's height so the footer's margin-top:auto has room to push
   against; min-height:0 keeps the nav scrollable if the list ever outgrows it. */
.sidebar > nav { display: flex; flex-direction: column; flex: 1; min-height: 0; }

.sidebar__label {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-faint); padding: 0 12px; margin: 22px 0 8px;
}
.sidebar__label:first-child { margin-top: 0; }

.nav-item {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 10px 12px; margin-bottom: 2px; border-radius: var(--r-sm);
  font-size: 14px; font-weight: 500; color: var(--text-muted); text-align: left;
  position: relative; transition: background .16s, color .16s;
}
.nav-item svg { width: 18px; height: 18px; flex: 0 0 auto; }
.nav-item:hover { background: var(--primary-050); color: var(--text); }
.nav-item.is-active { background: var(--primary-050); color: var(--primary); font-weight: 600; }
.nav-item.is-active::before {
  content: ''; position: absolute; left: -16px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 22px; border-radius: 0 3px 3px 0; background: var(--primary);
}
.nav-item__badge {
  margin-left: auto; min-width: 22px; height: 20px; padding: 0 6px; border-radius: var(--r-pill);
  background: var(--primary); color: #fff; font-size: 11px; font-weight: 700;
  display: grid; place-items: center;
}
.nav-item--danger:hover { background: rgba(239, 68, 68, 0.08); color: var(--danger); }

/* auto margin pins this to the bottom of the sidebar regardless of how many nav
   items sit above it. */
.sidebar__footer { margin-top: auto; padding-top: 18px; border-top: 1px solid var(--border); }

/* Clear All Data sits in the footer, visually separated from navigation so it is
   never mistaken for a destination. Full width to match the nav items above. */
.sidebar__footer .nav-item { width: 100%; justify-content: flex-start; }
.nav-item--danger { color: var(--danger-text); }
.nav-item--danger:disabled { opacity: .6; cursor: not-allowed; }
.nav-item--danger .spinner { margin-right: 2px; }

/* ── Shell ──────────────────────────────────────────────────────────────── */

.main { margin-left: var(--sidebar-w); padding-top: var(--navbar-h); min-width: 0; }

.section { padding: 92px 40px; position: relative; }
.section__inner { max-width: var(--maxw); margin: 0 auto; }
.section--tint { background: var(--grad-soft); }

.section-head { max-width: 720px; margin-bottom: 44px; }
.section-head--center { margin-left: auto; margin-right: auto; text-align: center; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 16px;
  padding: 6px 14px; border-radius: var(--r-pill);
  background: var(--primary-050); border: 1px solid rgba(37, 99, 235, 0.16);
  font-size: 12px; font-weight: 600; color: var(--primary); letter-spacing: -0.005em;
}
.eyebrow svg { width: 14px; height: 14px; }

.section-title { font-size: clamp(30px, 3.6vw, 42px); margin-bottom: 16px; }
.section-sub { font-size: 17px; color: var(--text-muted); line-height: 1.7; }

/* ── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  position: relative; isolation: isolate; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 48px; padding: 0 24px; border-radius: var(--r-pill);
  font-size: 15px; font-weight: 600; letter-spacing: -0.006em; white-space: nowrap;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease),
              background var(--t-base), border-color var(--t-base), opacity var(--t-fast), color var(--t-base);
}
.btn svg { width: 17px; height: 17px; flex: 0 0 auto; }
.btn:active { transform: translateY(1px) scale(0.99); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.28); }

.btn--primary { background: var(--grad-primary); color: #fff; box-shadow: var(--shadow-primary); }
/* Hover brightens via an overlay rather than a second gradient, so the lift and
   the glow animate together instead of the fill snapping. */
.btn--primary::after {
  content: ''; position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: linear-gradient(135deg, #3b82f6, #6366f1);
  transition: opacity var(--t-base) var(--ease);
}
.btn--primary:hover:not(:disabled) {
  transform: translateY(-3px);
  box-shadow: 0 20px 40px rgba(37, 99, 235, 0.36), 0 0 0 1px rgba(37, 99, 235, 0.1);
}
.btn--primary:hover:not(:disabled)::after { opacity: 1; }

.btn--secondary { background: var(--bg-elevated); color: var(--primary); border: 1px solid var(--border); box-shadow: var(--shadow-sm); }
.btn--secondary:hover:not(:disabled) {
  transform: translateY(-3px); box-shadow: var(--shadow-md);
  border-color: rgba(37, 99, 235, 0.4); background: var(--primary-050);
}

.btn--ghost { color: var(--text-muted); }
.btn--ghost:hover:not(:disabled) { background: var(--primary-050); color: var(--primary); }

.btn--danger { background: rgba(239, 68, 68, 0.1); color: var(--danger-text); border: 1px solid rgba(239, 68, 68, 0.22); }
.btn--danger:hover:not(:disabled) { background: var(--danger); color: #fff; }

.btn--sm { height: 36px; padding: 0 15px; font-size: 13px; border-radius: var(--r-sm); }
.btn--sm svg { width: 15px; height: 15px; }
.btn--block { width: 100%; }

/* ── Cards ──────────────────────────────────────────────────────────────── */

.card {
  position: relative; isolation: isolate;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease),
              border-color var(--t-base);
}
/* The card-hover gradient wash lives on a pseudo-element so it can cross-fade
   under the content without repainting the card's own background. */
.card::before {
  content: ''; position: absolute; inset: 0; z-index: -1; opacity: 0;
  border-radius: inherit; background: var(--grad-card-hover);
  transition: opacity var(--t-base) var(--ease);
}
.card--pad { padding: 28px; }
.card--hover:hover {
  transform: translateY(-6px) scale(1.012);
  box-shadow: var(--shadow-lg); border-color: rgba(37, 99, 235, 0.28);
}
.card--hover:hover::before { opacity: 1; }

.glass {
  background: var(--card-glass);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}
:root[data-theme='dark'] .glass { border-color: rgba(255, 255, 255, 0.08); }

/* ── Badges & pills ─────────────────────────────────────────────────────── */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 12px; border-radius: var(--r-pill);
  background: var(--bg-elevated); border: 1px solid var(--border);
  font-size: 12px; font-weight: 600; color: var(--text-muted); white-space: nowrap;
}
.badge svg { width: 13px; height: 13px; }
.badge--primary { background: var(--primary-050); border-color: rgba(37, 99, 235, 0.2); color: var(--primary); }
.badge--success { background: rgba(34, 197, 94, 0.1); border-color: rgba(34, 197, 94, 0.24); color: #15803d; }
.badge--warning { background: rgba(245, 158, 11, 0.1); border-color: rgba(245, 158, 11, 0.26); color: #b45309; }
.badge--danger  { background: rgba(239, 68, 68, 0.1); border-color: rgba(239, 68, 68, 0.24); color: #b91c1c; }
.badge--accent  { background: rgba(14, 165, 233, 0.1); border-color: rgba(14, 165, 233, 0.24); color: #0369a1; }
:root[data-theme='dark'] .badge--success { color: #4ade80; }
:root[data-theme='dark'] .badge--warning { color: #fbbf24; }
:root[data-theme='dark'] .badge--danger  { color: #f87171; }
:root[data-theme='dark'] .badge--accent  { color: #38bdf8; }

.badge-row { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 14px;
  border-radius: var(--r-pill); background: var(--bg-elevated); border: 1px solid var(--border);
  font-size: 13px; font-weight: 500; color: var(--text-muted);
  transition: all .16s;
}
.chip:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-050); }
.chip svg { width: 13px; height: 13px; color: var(--success-text); }

/* ══ SECTION 1 — HERO ═══════════════════════════════════════════════════ */

.hero {
  position: relative; overflow: hidden;
  padding: 84px 40px 100px;
}

.hero__grid {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    linear-gradient(to right, rgba(37, 99, 235, 0.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(37, 99, 235, 0.055) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(ellipse 90% 68% at 50% 0%, #000 38%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 90% 68% at 50% 0%, #000 38%, transparent 100%);
}

.hero__glow {
  position: absolute; border-radius: 50%; pointer-events: none; z-index: 0;
  filter: blur(76px); opacity: .5;
}
/* Blue → indigo → cyan, matching the primary/hero/purple gradient trio. */
.hero__glow--1 { width: 520px; height: 520px; top: -180px; left: -120px; background: radial-gradient(circle, rgba(37, 99, 235, 0.40), transparent 66%); animation: drift 22s var(--ease) infinite; }
.hero__glow--2 { width: 440px; height: 440px; top: 90px; right: -110px; background: radial-gradient(circle, rgba(124, 58, 237, 0.30), transparent 66%); animation: drift 26s var(--ease) infinite reverse; }
.hero__glow--3 { width: 360px; height: 360px; bottom: -140px; left: 42%; background: radial-gradient(circle, rgba(6, 182, 212, 0.28), transparent 66%); animation: drift 30s var(--ease) infinite; }

@keyframes drift {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(34px, -26px) scale(1.07); }
  66% { transform: translate(-24px, 22px) scale(0.95); }
}

/* ── Floating particles ─────────────────────────────────────────────────────
   Purely decorative motes that drift up through the hero. Kept in CSS (no canvas,
   no rAF loop) so they cost nothing on the main thread — each is one composited
   element animating transform and opacity only. aria-hidden in the markup. */
.particles { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.particles i {
  position: absolute; bottom: -12px;
  width: var(--s, 6px); height: var(--s, 6px); border-radius: 50%;
  background: var(--c, rgba(37, 99, 235, .5));
  animation: particle-rise var(--d, 18s) linear var(--delay, 0s) infinite;
  opacity: 0;
}
@keyframes particle-rise {
  0%   { transform: translateY(0) translateX(0) scale(.6); opacity: 0; }
  12%  { opacity: .75; }
  70%  { opacity: .5; }
  100% { transform: translateY(-88vh) translateX(var(--x, 30px)) scale(1.1); opacity: 0; }
}

.hero__inner {
  position: relative; z-index: 1; max-width: var(--maxw); margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr);
  gap: 52px; align-items: center;
}

/* Upload block inside the hero. z-index keeps it above the hero glows/grid, which
   are absolutely positioned siblings and would otherwise swallow pointer events
   on the dropzone. */
.hero__upload {
  position: relative; z-index: 1; max-width: var(--maxw);
  margin: 88px auto 0; padding-top: 56px;
  border-top: 1px solid var(--border);
}

/* Tops out at the 72px display size, but the coefficient is tuned to the *column*
   rather than the viewport: the sidebar takes 268px and the visual takes the rest,
   so 5vw hit 72px at 1440px where the column is only ~600px wide and the title
   broke to six lines. 4.1vw reaches 72px near 1760px, where there is room. */
.hero__title {
  font-size: clamp(38px, 4.1vw, 72px); line-height: 1.05; letter-spacing: -0.04em;
  font-weight: 800; margin-bottom: 24px;
}
.hero__title span { display: block; }

.hero__sub {
  font-size: 18px; line-height: 1.7; color: var(--text-muted);
  max-width: 580px; margin-bottom: 36px;
}

.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 40px; }

/* Staggered entrance for the hero column: each element slides up 0.6s after the
   one before it, which reads as the page assembling rather than snapping in. */
.hero__inner > div > .eyebrow,
.hero__title, .hero__sub, .hero__cta, .hero__formats {
  animation: hero-rise var(--t-slow) var(--ease) both;
}
.hero__title   { animation-delay: .06s; }
.hero__sub     { animation-delay: .12s; }
.hero__cta     { animation-delay: .18s; }

@keyframes hero-rise { from { opacity: 0; transform: translateY(20px); } }

.format-pill {
  display: inline-flex; align-items: center; height: 28px; padding: 0 11px;
  border-radius: 8px; background: var(--bg-elevated); border: 1px solid var(--border);
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.02em; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  transition: all .16s;
}
.format-pill:hover { border-color: var(--primary); color: var(--primary); transform: translateY(-1px); }

/* Hero right — illustration + floating glass cards */

.hero__visual { position: relative; min-height: 560px; }

.hero__orb {
  position: absolute; inset: 8% 10%; border-radius: 50%;
  background: var(--grad-brand); opacity: .1; filter: blur(8px);
  animation: breathe 8s var(--ease) infinite;
}
@keyframes breathe {
  0%, 100% { transform: scale(1); opacity: .1; }
  50% { transform: scale(1.06); opacity: .16; }
}

.hero__ring {
  position: absolute; border-radius: 50%; border: 1.5px dashed rgba(37, 99, 235, 0.2);
  top: 50%; left: 50%; transform: translate(-50%, -50%);
}
.hero__ring--1 { width: 340px; height: 340px; animation: spin 40s linear infinite; }
.hero__ring--2 { width: 460px; height: 460px; border-style: solid; border-color: rgba(99, 102, 241, 0.13); animation: spin 60s linear infinite reverse; }
.hero__ring--3 { width: 580px; height: 580px; border-color: rgba(14, 165, 233, 0.09); animation: spin 90s linear infinite; }
@keyframes spin { to { transform: translate(-50%, -50%) rotate(360deg); } }

.hero__illus {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 250px; height: 250px; display: grid; place-items: center;
  border-radius: var(--r-xl); background: var(--grad-brand);
  box-shadow: 0 30px 70px rgba(37, 99, 235, 0.36);
  color: #fff; animation: float-y 6s var(--ease) infinite;
}
.hero__illus svg { width: 116px; height: 116px; }

@keyframes float-y {
  0%, 100% { transform: translate(-50%, -50%) translateY(0); }
  50% { transform: translate(-50%, -50%) translateY(-14px); }
}

.float-card {
  position: absolute; z-index: 2; min-width: 168px;
  padding: 15px 17px; border-radius: var(--r-md);
  background: var(--card-glass);
  backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.66);
  box-shadow: var(--shadow-lg);
  animation: float-card 7s var(--ease) infinite;
  transition: transform .24s var(--ease), box-shadow .24s;
}
:root[data-theme='dark'] .float-card { border-color: rgba(255, 255, 255, 0.09); }
.float-card:hover { transform: translateY(-6px) scale(1.03); box-shadow: var(--shadow-xl); z-index: 3; }

@keyframes float-card {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-11px); }
}

.float-card__top { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.float-card__icon { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; color: #fff; flex: 0 0 auto; }
.float-card__icon svg { width: 15px; height: 15px; }
.float-card__label { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-faint); }
.float-card__value { font-size: 25px; font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.float-card__meta { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; font-weight: 500; }

/* Positions are laid out on two staggered columns that never overlap vertically.
   Right-hand offsets stay at 0 or positive: .hero has overflow:hidden, so a
   negative right offset clipped the card against the viewport edge. */
.float-card--1 { top: 0%;    left: -7%;  animation-delay: 0s; }
.float-card--2 { top: 11%;   right: 0;   animation-delay: .9s; }
.float-card--3 { top: 39%;   left: -11%; animation-delay: 1.8s; }
.float-card--4 { top: 41%;   right: 5%;  animation-delay: 2.7s; }
.float-card--5 { bottom: 3%; left: -2%;  animation-delay: 3.6s; }
.float-card--6 { bottom: 8%; right: 1%;  animation-delay: 4.5s; }

.spark { display: flex; align-items: flex-end; gap: 3px; height: 26px; margin-top: 8px; }
.spark i { flex: 1; border-radius: 2px 2px 0 0; background: var(--grad-brand); opacity: .82; animation: spark-grow 1.4s var(--ease) backwards; }
@keyframes spark-grow { from { height: 0 !important; opacity: 0; } }

.risk-meter { height: 6px; border-radius: 99px; background: var(--border); overflow: hidden; margin-top: 10px; }
.risk-meter i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--success), var(--warning), var(--danger)); }

/* ══ SECTION 2 — UPLOAD ═════════════════════════════════════════════════ */

.upload-layout { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 28px; align-items: start; }

.dropzone {
  position: relative; isolation: isolate;
  padding: 56px 40px; text-align: center;
  border: 2px dashed var(--border-strong); border-radius: var(--r-lg);
  background: var(--card);
  transition: border-color var(--t-base), background var(--t-base),
              transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
  cursor: pointer;
  /* Idle pulse-glow: a slow breathing ring that marks this as the primary action
     without the noise of a looping animation on the box itself. */
  animation: dropzone-pulse 3.6s var(--ease) infinite;
}
.dropzone:hover {
  border-color: var(--primary); background: var(--primary-050);
  transform: translateY(-2px); animation-play-state: paused;
}
.dropzone.is-dragover {
  border-color: var(--primary); background: var(--primary-050);
  transform: scale(1.012); box-shadow: var(--shadow-lg), 0 0 0 6px rgba(37, 99, 235, 0.12);
  animation-play-state: paused;
}
@keyframes dropzone-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0.10); }
  50%      { box-shadow: 0 0 0 10px rgba(37, 99, 235, 0.045); }
}

.dropzone__icon {
  width: 88px; height: 88px; margin: 0 auto 22px; border-radius: 26px;
  background: var(--grad-primary); display: grid; place-items: center; color: #fff;
  box-shadow: var(--shadow-primary); animation: float-y-simple 5s var(--ease) infinite;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.dropzone:hover .dropzone__icon {
  transform: scale(1.06); box-shadow: 0 18px 38px rgba(37, 99, 235, 0.38);
}
.dropzone__icon svg { width: 38px; height: 38px; }
@keyframes float-y-simple { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }

.dropzone__title { font-size: 24px; margin-bottom: 10px; }
.dropzone__hint { font-size: 15px; color: var(--text-muted); margin-bottom: 26px; }
.dropzone__actions { display: flex; flex-wrap: wrap; gap: 11px; justify-content: center; }

/* Accepted formats, inside the drop box */
.dropzone__formats { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
.dropzone__formats-label {
  display: block; margin-bottom: 12px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-faint);
}
.dropzone__formats .badge-row { justify-content: center; }
.dropzone__formats .formats-note { margin: 14px 0 0; text-align: center; }

.validation-title { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 16px; }
.formats-note { font-size: 14px; color: var(--text-muted); }
.formats-note b { color: var(--primary); font-weight: 700; }

/* Upload queue */

.queue { display: grid; gap: 12px; }

/* Panel variant: the queue sits in the right column and scrolls inside its own
   box. Without the cap, uploading a folder pushed the page down far enough that
   the dropzone left the viewport while files were still being added. */
.queue--panel {
  max-height: min(56vh, 520px); overflow-y: auto;
  /* Room for the scrollbar so rows do not sit flush against it. */
  margin-right: -6px; padding-right: 6px;
}
.queue--panel:empty { display: none; }

/* Placeholder disappears the moment a row exists — no JS needed. */
.queue:not(:empty) ~ .queue-empty { display: none; }
.queue-empty { text-align: center; padding: 26px 8px 12px; }
.queue-empty__icon {
  width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 16px;
  display: grid; place-items: center;
  background: var(--primary-050); color: var(--primary);
}
.queue-empty__icon svg { width: 24px; height: 24px; }
.queue-empty__title { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.queue-empty__text { font-size: 13.5px; color: var(--text-muted); line-height: 1.6; }

.queue-panel { align-self: start; position: sticky; top: calc(var(--navbar-h) + 24px); }

.queue-item {
  display: grid; grid-template-columns: 42px minmax(0, 1fr) auto; gap: 14px; align-items: center;
  padding: 15px 18px; border-radius: var(--r-md);
  background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow-xs);
  animation: slide-up .34s var(--ease) backwards;
}
@keyframes slide-up { from { opacity: 0; transform: translateY(12px); } }

.queue-item__icon { width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; background: var(--primary-050); color: var(--primary); flex: 0 0 auto; }
.queue-item__icon svg { width: 19px; height: 19px; }
.queue-item__name { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.queue-item__meta { font-size: 12px; color: var(--text-faint); margin-top: 2px; display: flex; gap: 10px; flex-wrap: wrap; font-variant-numeric: tabular-nums; }
.queue-item__actions { display: flex; gap: 6px; }

/* In the side panel the row is much narrower than it was full-width, so the
   actions drop to a line of their own rather than squeezing the filename down to
   a few characters. DOM order is icon → body → actions, so this needs no markup
   change. */
.queue--panel .queue-item { grid-template-columns: 42px minmax(0, 1fr); }
.queue--panel .queue-item__actions { grid-column: 2 / -1; justify-content: flex-end; flex-wrap: wrap; }
.queue-item--error { border-color: rgba(239, 68, 68, 0.32); background: rgba(239, 68, 68, 0.03); }
.queue-item--error .queue-item__icon { background: rgba(239, 68, 68, 0.1); color: var(--danger-text); }
.queue-item--done .queue-item__icon { background: rgba(34, 197, 94, 0.1); color: var(--success-text); }

.progress { height: 6px; border-radius: 99px; background: var(--border); overflow: hidden; margin-top: 9px; }
.progress__bar {
  height: 100%; border-radius: 99px; background: var(--grad-brand); width: 0;
  transition: width .4s var(--ease); position: relative; overflow: hidden;
}
.progress__bar::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.42), transparent);
  animation: shimmer 1.5s linear infinite;
}
@keyframes shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

.pipe-step.is-active { background: var(--primary-050); }
.pipe-step.is-active .pipe-step__dot {
  border-color: var(--primary); color: var(--primary);
  box-shadow: 0 0 0 5px rgba(37, 99, 235, 0.12);
}
.pipe-step.is-active .pipe-step__dot::after {
  content: ''; position: absolute; inset: -2px; border-radius: 50%;
  border: 2px solid transparent; border-top-color: var(--primary);
  animation: spin-fast .8s linear infinite;
}
@keyframes spin-fast { to { transform: rotate(360deg); } }
.pipe-step.is-active .pipe-step__label { color: var(--primary); font-weight: 700; }

.doc-card { overflow: hidden; display: flex; flex-direction: column; }
.doc-card__actions { display: flex; gap: 8px; margin-top: auto; }
.search-examples .chip { cursor: pointer; }
.search-examples .chip svg { color: var(--primary); }

.filters { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 26px; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 168px; }
.field__label { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); padding-left: 2px; }
.field select, .field input {
  height: 42px; padding: 0 13px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--card); font-size: 13.5px;
  transition: border-color .18s, box-shadow .18s;
}
.field select:focus, .field input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); }

.answer-card { margin-top: 32px; padding: 26px; border-left: 3px solid var(--primary); }
.answer-card__head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.answer-card__head svg { width: 18px; height: 18px; color: var(--primary); }
.answer-card__title { font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--primary); }
.answer-card__text { font-size: 15.5px; line-height: 1.75; white-space: pre-wrap; }
.answer-card__foot { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 12px; color: var(--text-faint); display: flex; gap: 14px; flex-wrap: wrap; }

.hit-list { margin-top: 22px; display: grid; gap: 12px; }
.hit {
  padding: 18px 20px; border-radius: var(--r-md); background: var(--card);
  border: 1px solid var(--border); box-shadow: var(--shadow-xs); cursor: pointer;
  transition: transform .2s var(--ease), box-shadow .2s, border-color .2s;
}
.hit:hover { transform: translateX(3px); box-shadow: var(--shadow-md); border-color: var(--primary); }
.hit__top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 9px; }
.hit__index { width: 22px; height: 22px; border-radius: 6px; background: var(--primary); color: #fff; font-size: 11px; font-weight: 700; display: grid; place-items: center; flex: 0 0 auto; }
.hit__patient { font-size: 13.5px; font-weight: 700; }
.hit__snippet { font-size: 13.5px; line-height: 1.65; color: var(--text-muted); }
.hit__snippet mark { background: rgba(245, 158, 11, 0.28); color: inherit; border-radius: 3px; padding: 0 2px; }

/* ══ SECTION 6 — UHID LOOKUP + PROFILE ══════════════════════════════════ */

.uhid-card { max-width: 620px; margin: 0 auto; padding: 38px; text-align: center; }
.uhid-card__icon { width: 62px; height: 62px; margin: 0 auto 20px; border-radius: 19px; background: var(--grad-brand); display: grid; place-items: center; color: #fff; box-shadow: var(--shadow-primary); }
.uhid-card__icon svg { width: 28px; height: 28px; }
/* Centred as a pair rather than stretched across the card: a UHID is ~12 characters,
   so an input that filled the full 620px card read as a search bar for prose. The
   field sizes to its content and the button sits beside it, both centred together. */
.uhid-form { display: flex; gap: 11px; margin-top: 24px; justify-content: center; }
.uhid-form input {
  flex: 0 1 auto; width: 260px; min-width: 0; max-width: 100%;
  height: 52px; padding: 0 20px; border-radius: var(--r-md);
  border: 1px solid var(--border-strong); background: var(--bg-elevated);
  font-size: 17px; font-weight: 600; letter-spacing: 0.04em; text-align: center;
  text-transform: uppercase; font-variant-numeric: tabular-nums;
  transition: border-color .18s, box-shadow .18s;
}
/* Invalid state, driven by the required-field check on submit. Only the border and
   ring change, so nothing moves and the layout cannot shift. */
.uhid-form input.is-invalid {
  border-color: var(--danger-text, #b91c1c);
  box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.12);
}
.uhid-form__error {
  margin-top: 10px; font-size: 13.5px; font-weight: 600;
  color: var(--danger-text, #b91c1c); min-height: 1em;
}
.uhid-form input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12); }
.uhid-form .btn { height: 52px; }

.profile { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 26px; align-items: start; }

.profile-card { padding: 30px; text-align: center; position: sticky; top: calc(var(--navbar-h) + 24px); }
.profile-photo {
  width: 96px; height: 96px; margin: 0 auto 18px; border-radius: 50%;
  background: var(--grad-brand); display: grid; place-items: center;
  color: #fff; font-size: 32px; font-weight: 700; letter-spacing: -0.03em;
  box-shadow: var(--shadow-primary);
}
.profile-name { font-size: 22px; margin-bottom: 5px; }
.profile-uhid { font-size: 13px; font-weight: 700; color: var(--primary); letter-spacing: 0.06em; font-variant-numeric: tabular-nums; margin-bottom: 18px; }

.profile-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 22px 0; text-align: left; }
.profile-field { padding: 12px 14px; border-radius: var(--r-sm); background: var(--bg); }
.profile-field__label { font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-faint); }
.profile-field__value { font-size: 14px; font-weight: 600; margin-top: 3px; word-break: break-word; }
.profile-field--wide { grid-column: 1 / -1; }

.profile-actions { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin-top: 22px; }
.profile-actions .btn--block { grid-column: 1 / -1; }

.detail-stack { display: grid; gap: 26px; min-width: 0; }

.panel { padding: 28px; }
.panel__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 22px; }
.panel__title { font-size: 19px; display: flex; align-items: center; gap: 11px; }
.panel__title svg { width: 20px; height: 20px; color: var(--primary); }
.panel__count { font-size: 12px; font-weight: 700; color: var(--text-faint); }

/* ══ SECTION 7 — TIMELINE ═══════════════════════════════════════════════ */

.timeline { position: relative; padding-left: 34px; }
.timeline::before {
  content: ''; position: absolute; left: 11px; top: 6px; bottom: 6px; width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--primary), var(--secondary) 40%, var(--accent) 70%, var(--success));
}

.tl-item { position: relative; padding-bottom: 26px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item__dot {
  position: absolute; left: -34px; top: 3px; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center; color: #fff; box-shadow: 0 0 0 4px var(--card);
  z-index: 1;
}
.tl-item__dot svg { width: 12px; height: 12px; }
.tl-item__head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 5px; }
.tl-item__title { font-size: 15px; font-weight: 700; }
.tl-item__date { font-size: 12px; font-weight: 600; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.tl-item__detail { font-size: 13.5px; color: var(--text-muted); line-height: 1.65; }
.tl-item__meta { font-size: 11.5px; color: var(--text-faint); margin-top: 6px; display: flex; gap: 12px; flex-wrap: wrap; }

/* Event colours */
.ev-admission    { background: var(--primary); }
.ev-diagnosis    { background: var(--secondary); }
.ev-consultation { background: var(--accent); }
.ev-lab          { background: #14b8a6; }
.ev-radiology    { background: #8b5cf6; }
.ev-operation    { background: var(--danger); }
.ev-prescription { background: var(--warning); }
.ev-discharge    { background: var(--success); }
.ev-other        { background: var(--text-faint); }

/* ══ SECTION 8 — LAB REPORTS ════════════════════════════════════════════ */

.lab-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(292px, 1fr)); gap: 18px; }

.lab-card { padding: 22px; display: flex; flex-direction: column; }
.lab-card__head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.lab-card__icon { width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center; color: #fff; font-size: 12px; font-weight: 700; flex: 0 0 auto; letter-spacing: -0.01em; }
.lab-card__name { font-size: 15px; font-weight: 700; }
.lab-card__date { font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; margin-top: 2px; }

.lab-values { display: grid; gap: 7px; margin-bottom: 16px; }
.lab-value { display: flex; align-items: baseline; gap: 10px; font-size: 13px; padding-bottom: 7px; border-bottom: 1px dashed var(--border); }
.lab-value:last-child { border-bottom: none; padding-bottom: 0; }
.lab-value__name { color: var(--text-muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lab-value__num { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lab-value__ref { font-size: 11px; color: var(--text-faint); white-space: nowrap; }
.flag { font-size: 10px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; padding: 1px 6px; border-radius: 5px; }
.flag--high { background: rgba(239, 68, 68, 0.12); color: #b91c1c; }
.flag--low { background: rgba(245, 158, 11, 0.14); color: #b45309; }
.flag--normal { background: rgba(34, 197, 94, 0.12); color: #15803d; }
.flag--critical { background: var(--danger); color: #fff; }
:root[data-theme='dark'] .flag--high { color: #f87171; }
:root[data-theme='dark'] .flag--low { color: #fbbf24; }
:root[data-theme='dark'] .flag--normal { color: #4ade80; }

.lab-findings { font-size: 12.5px; color: var(--text-muted); line-height: 1.6; margin-bottom: 14px; padding: 12px; border-radius: var(--r-sm); background: var(--bg); }
.lab-card__actions { display: flex; gap: 7px; margin-top: auto; }

/* Panel colours */
.panel-CBC     { background: linear-gradient(135deg, #ef4444, #f87171); }
.panel-LFT     { background: linear-gradient(135deg, #f59e0b, #fbbf24); }
.panel-KFT     { background: linear-gradient(135deg, #0ea5e9, #38bdf8); }
.panel-Urine   { background: linear-gradient(135deg, #eab308, #facc15); }
.panel-Sugar   { background: linear-gradient(135deg, #8b5cf6, #a78bfa); }
.panel-Thyroid { background: linear-gradient(135deg, #14b8a6, #2dd4bf); }
.panel-Vitamin { background: linear-gradient(135deg, #22c55e, #4ade80); }
.panel-Lipid   { background: linear-gradient(135deg, #6366f1, #818cf8); }
.panel-other   { background: linear-gradient(135deg, #64748b, #94a3b8); }

/* ══ SECTION 9 — MEDICINES ══════════════════════════════════════════════ */

.med-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px; }

.med-card { padding: 22px; }
.med-card__head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.med-card__pill {
  width: 40px; height: 40px; border-radius: 12px; flex: 0 0 auto;
  background: linear-gradient(135deg, var(--secondary), var(--primary));
  display: grid; place-items: center; color: #fff;
}
.med-card__pill svg { width: 19px; height: 19px; }
.med-card__name { font-size: 15.5px; font-weight: 700; line-height: 1.3; }
.med-card__dose { font-size: 12.5px; color: var(--primary); font-weight: 700; margin-top: 2px; }

.dose-timing { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.dose-slot {
  padding: 11px 8px; border-radius: var(--r-sm); text-align: center;
  background: var(--bg); border: 1px solid var(--border);
  transition: all .18s;
}
.dose-slot__icon { font-size: 15px; line-height: 1; margin-bottom: 5px; }
.dose-slot__label { font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-faint); }
.dose-slot.is-on { background: var(--primary-050); border-color: var(--primary); }
.dose-slot.is-on .dose-slot__label { color: var(--primary); }
.dose-slot.is-off { opacity: .38; }

.med-meta { display: grid; gap: 7px; font-size: 12.5px; }
.med-meta__row { display: flex; gap: 10px; }
.med-meta__key { color: var(--text-faint); min-width: 66px; font-weight: 600; }
.med-meta__val { color: var(--text-muted); min-width: 0; }

.med-warning {
  margin-top: 14px; padding: 11px 13px; border-radius: var(--r-sm);
  background: rgba(245, 158, 11, 0.08); border: 1px solid rgba(245, 158, 11, 0.24);
  font-size: 12.5px; color: #92400e; line-height: 1.55;
  display: flex; gap: 9px;
}
.med-warning svg { width: 15px; height: 15px; flex: 0 0 auto; margin-top: 2px; color: var(--warning); }
:root[data-theme='dark'] .med-warning { color: #fcd34d; }

/* ══ SECTION 10 — AI SUMMARY ════════════════════════════════════════════ */

.summary-hero {
  padding: 34px; border-radius: var(--r-lg); margin-bottom: 26px;
  background: var(--grad-brand); color: #fff; box-shadow: var(--shadow-primary);
  position: relative; overflow: hidden;
}
.summary-hero::after {
  content: ''; position: absolute; top: -60%; right: -14%; width: 380px; height: 380px;
  border-radius: 50%; background: rgba(255, 255, 255, 0.09);
}
.summary-hero__top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; position: relative; }
.summary-hero__badge {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 13px;
  border-radius: var(--r-pill); background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.28); font-size: 12px; font-weight: 700;
}
.summary-hero__badge svg { width: 14px; height: 14px; }
.summary-hero__text { font-size: 16.5px; line-height: 1.75; position: relative; white-space: pre-wrap; }

.confidence { display: flex; align-items: center; gap: 14px; margin-top: 24px; position: relative; flex-wrap: wrap; }
.confidence__track { flex: 1; min-width: 160px; height: 8px; border-radius: 99px; background: rgba(255, 255, 255, 0.24); overflow: hidden; }
.confidence__bar { height: 100%; border-radius: 99px; background: #fff; width: 0; transition: width .9s var(--ease); }
.confidence__value { font-size: 21px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }
.confidence__label { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; opacity: .8; }

.summary-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(292px, 1fr)); gap: 18px; }

.sum-card { padding: 22px; }
.sum-card__head { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.sum-card__icon { width: 34px; height: 34px; border-radius: 11px; display: grid; place-items: center; color: #fff; flex: 0 0 auto; }
.sum-card__icon svg { width: 16px; height: 16px; }
.sum-card__title { font-size: 14px; font-weight: 700; }
.sum-list { display: grid; gap: 9px; }
.sum-list li { display: flex; gap: 10px; font-size: 13.5px; line-height: 1.6; color: var(--text-muted); }
.sum-list li::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--primary); flex: 0 0 auto; margin-top: 8px; }

.sources { margin-top: 26px; padding: 22px; }
.sources__title { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 13px; }
.sources__list { display: flex; flex-wrap: wrap; gap: 8px; }

/* ── Empty / loading / toast ─────────────────────────────────────────────── */

.empty { padding: 62px 30px; text-align: center; }
.empty__icon {
  width: 68px; height: 68px; margin: 0 auto 20px; border-radius: 21px;
  background: var(--primary-050); display: grid; place-items: center; color: var(--primary);
}
.empty__icon svg { width: 30px; height: 30px; }
.empty__title { font-size: 18px; margin-bottom: 8px; }
.empty__text { font-size: 14px; color: var(--text-muted); max-width: 440px; margin: 0 auto 22px; line-height: 1.65; }

.spinner {
  width: 20px; height: 20px; border-radius: 50%; flex: 0 0 auto;
  border: 2.5px solid var(--border); border-top-color: var(--primary);
  animation: spin-fast .7s linear infinite;
}
.loading-row { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 44px; color: var(--text-muted); font-size: 14px; }
@keyframes skeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } }

.toast-wrap { position: fixed; bottom: 26px; right: 26px; z-index: 300; display: grid; gap: 10px; max-width: 400px; }
.toast {
  display: flex; align-items: flex-start; gap: 12px; padding: 15px 18px;
  border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border);
  box-shadow: var(--shadow-xl); font-size: 13.5px; font-weight: 500;
  animation: toast-in .34s var(--ease) backwards;
}
@keyframes toast-in { from { opacity: 0; transform: translateX(28px) scale(0.96); } }
.toast--out { animation: toast-out .26s var(--ease) forwards; }
@keyframes toast-out { to { opacity: 0; transform: translateX(28px) scale(0.96); } }
.toast__icon { width: 20px; height: 20px; flex: 0 0 auto; margin-top: 1px; }
.toast--success .toast__icon { color: var(--success-text); }
.toast--error .toast__icon { color: var(--danger-text); }
.toast--info .toast__icon { color: var(--primary); }
.toast--warning .toast__icon { color: var(--warning); }
.toast__body { min-width: 0; }
.toast__title { font-weight: 700; margin-bottom: 2px; }
.toast__text { color: var(--text-muted); font-size: 12.5px; line-height: 1.5; }

/* ── Modal ──────────────────────────────────────────────────────────────── */

.modal-backdrop {
  position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: 24px;
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: fade-in .2s var(--ease);
}
@keyframes fade-in { from { opacity: 0; } }
.modal {
  width: 100%; max-width: 860px; max-height: 86vh; overflow: auto;
  background: var(--card); border-radius: var(--r-lg); box-shadow: var(--shadow-xl);
  animation: modal-in .3s var(--ease) backwards;
}
@keyframes modal-in { from { opacity: 0; transform: translateY(18px) scale(0.97); } }
.modal__head {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: 16px; padding: 22px 26px;
  border-bottom: 1px solid var(--border); background: var(--card);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.modal__title { font-size: 18px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal__close { margin-left: auto; }
.modal__body { padding: 26px; }

.doc-text {
  padding: 20px; border-radius: var(--r-md); background: var(--bg);
  border: 1px solid var(--border);
  font-family: 'SF Mono', ui-monospace, 'Cascadia Code', Menlo, Consolas, monospace;
  font-size: 12.5px; line-height: 1.75; white-space: pre-wrap; word-break: break-word;
  max-height: 460px; overflow: auto;
}

.kv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; margin-bottom: 22px; }

/* ── Reveal on scroll ───────────────────────────────────────────────────── */

.reveal { opacity: 0; transform: translateY(22px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.reveal.is-visible { opacity: 1; transform: none; }

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1180px) {
  .hero__inner { grid-template-columns: 1fr; gap: 48px; }
  .hero__visual { min-height: 460px; order: -1; }
  /* Single-column hero: the visual loses ~40% of its height, so six cards no
     longer fit without colliding. Drop to four and pin them to the corners. */
  .float-card--3, .float-card--6 { display: none; }
  .float-card--1 { top: 0;       left: 2%;  right: auto; bottom: auto; }
  .float-card--2 { top: 4%;      right: 2%; left: auto;  bottom: auto; }
  .float-card--4 { bottom: 6%;   right: 2%; left: auto;  top: auto; }
  .float-card--5 { bottom: 1%;   left: 2%;  right: auto; top: auto; }
  .upload-layout, .profile { grid-template-columns: 1fr; }
  .profile-card { position: static; }
  /* Single column: sticky would pin the queue over the dropzone, and the internal
     scroll is pointless when the panel is full width. */
  .queue-panel { position: static; }
  .queue--panel { max-height: none; overflow-y: visible; }
  .queue--panel .queue-item { grid-template-columns: 42px minmax(0, 1fr) auto; }
  .queue--panel .queue-item__actions { grid-column: auto; }
}

@media (max-width: 1024px) {
  :root { --sidebar-w: 0px; }
  .nav-toggle { display: grid; }
  .sidebar { width: 268px; transform: translateX(-100%); box-shadow: var(--shadow-xl); }
  .sidebar.is-open { transform: none; }
  .main { margin-left: 0; }
  .navbar__search { display: none; }
}

@media (max-width: 760px) {
  .section, .hero { padding-left: 20px; padding-right: 20px; }
  .section { padding-top: 62px; padding-bottom: 62px; }
  .hero { padding-top: 48px; padding-bottom: 68px; }
  .hero__visual { min-height: 340px; }
  .hero__illus { width: 170px; height: 170px; }
  .hero__illus svg { width: 78px; height: 78px; }
  .hero__ring--3 { display: none; }
  .float-card { min-width: 138px; padding: 12px 14px; }
  .float-card__value { font-size: 20px; }
  /* Phone: three cards is the most that reads as decoration rather than clutter. */
  .float-card--3, .float-card--4, .float-card--6 { display: none; }
  .hero__cta .btn { flex: 1 1 auto; }
  .doc-grid, .lab-grid, .med-grid, .summary-grid { grid-template-columns: 1fr; }
  .profile-grid { grid-template-columns: 1fr; }
  .card--pad, .panel, .pipeline-card, .uhid-card, .ws__head { padding: 20px; }
  .uhid-form { flex-direction: column; }
  /* `flex: 1` resolves against the main axis, so turning the form into a column
     pointed flex-basis:0 at the input's HEIGHT and collapsed the 52px field to a
     22px sliver — an unusable, visibly misaligned input beside a 52px button.
     Width is what should fill here, not height. */
  .uhid-form input { flex: 0 0 auto; width: 100%; }
  .uhid-form .btn { width: 100%; }
  /* Section heads carry desktop-scale breathing room that reads as dead space on
     a phone, where the title is already the first thing on screen. */
  .section-head { margin-bottom: 26px; }
  .empty { padding: 40px 22px; }
  .modal__body { padding: 18px; }
  .modal__head { padding: 18px 20px; }
  .loading-row { padding: 30px; }
  .toast-wrap { left: 16px; right: 16px; bottom: 16px; max-width: none; }
  .ai-status span:not(.ai-status__dot) { display: none; }
  .ai-status { padding: 0; width: 30px; justify-content: center; }
  .brand__logo { height: 26px; }
  .navbar { padding: 0 14px; gap: 10px; }
}

/* Phones: four tabs need 538px and a 360px screen gives 320, so the strip
   scrolled — which hid Prescriptions entirely and sliced the Medicines label in
   half, with nothing on screen to suggest either existed. Two rows of two shows
   all four at full width instead. */
@media (max-width: 560px) {
  .ws__tabs {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px; overflow: visible; padding-bottom: 0;
  }
  .ws-tab { width: 100%; justify-content: center; padding: 0 10px; }

  /* Stack the record header: avatar beside the name, then badges, then actions,
     each starting on the same left edge. */
  .ws__head {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "avatar identity"
      "badges badges"
      "actions actions";
  }
  .ws__actions { justify-content: flex-start; }
}

/* Below this the centred title has under ~20px of clearance from the logo, so it
   gives way rather than crowd the controls. Measured: the collision starts at
   480px. The logo alone still brands the header, and the hospital name remains in
   the document title. */
@media (max-width: 520px) {
  .navbar__title { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  /* Entrance animations use `both` fill, so collapsing the duration alone would
     freeze them on their opening (invisible) frame. Neutralise them outright. */
  .hero__inner > div > .eyebrow,
  .hero__title, .hero__sub, .hero__cta, .hero__formats,
  .navbar { animation: none !important; opacity: 1; transform: none; }
  /* Ambient motion has no informational value — remove it rather than run it once. */
  .particles { display: none; }
  .dropzone { animation: none !important; }
  /* Hover lifts stay, but without the scale, which is the part that induces
     motion discomfort on large surfaces. */
  .card--hover:hover { transform: translateY(-4px); }
}
