/* ==========================================================================
   EAS Design System — loaded LAST on every page, after Bootstrap + style.css.
   Refines the existing :root / .dark tokens into one consistent, accessible,
   mobile-first system. Additive: it never renames an existing variable.
   ========================================================================== */

:root {
  /* Brand ramp */
  --eas-navy-900:#08263f; --eas-navy-800:#0b3557; --eas-navy-700:#0e456f;
  --eas-blue-600:#1668b8; --eas-blue-500:#2186e0; --eas-blue-400:#4fa3ec;
  --eas-blue-50:#eaf4fd;
  --eas-amber:#e8912d; --eas-amber-50:#fdf3e6;
  --eas-green:#1c8a55; --eas-green-50:#e7f6ee;
  --eas-red:#c93636;   --eas-red-50:#fdeaea;
  --eas-violet:#6d55c9;

  /* Neutrals */
  --eas-ink:#16202b; --eas-ink-2:#3d4c5c; --eas-ink-3:#66778a;
  --eas-line:#dde4ec; --eas-line-2:#eef2f7;
  --eas-surface:#ffffff; --eas-surface-2:#f6f8fb; --eas-surface-3:#eef2f7;

  /* Semantic */
  --eas-accent:var(--eas-blue-600);
  --eas-accent-hover:var(--eas-navy-700);
  --eas-on-accent:#ffffff;
  --eas-focus:#2186e0;

  /* Type — fluid, capped so it never runs away on desktop */
  --eas-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --fs-display: clamp(2rem, 1.35rem + 2.6vw, 3.25rem);
  --fs-h1: clamp(1.65rem, 1.25rem + 1.6vw, 2.4rem);
  --fs-h2: clamp(1.35rem, 1.12rem + 0.9vw, 1.8rem);
  --fs-h3: clamp(1.12rem, 1.02rem + 0.42vw, 1.35rem);
  --fs-body: 1rem;
  --fs-sm: 0.9rem;
  --fs-xs: 0.8rem;

  /* Space / shape / depth */
  --sp-1:.25rem; --sp-2:.5rem; --sp-3:.75rem; --sp-4:1rem;
  --sp-5:1.5rem; --sp-6:2rem; --sp-7:3rem; --sp-8:4rem;
  --r-sm:8px; --r-md:12px; --r-lg:18px; --r-pill:999px;
  --sh-1:0 1px 2px rgba(16,32,48,.06), 0 1px 3px rgba(16,32,48,.05);
  --sh-2:0 4px 10px rgba(16,32,48,.07), 0 2px 4px rgba(16,32,48,.05);
  --sh-3:0 14px 32px rgba(16,32,48,.11), 0 4px 10px rgba(16,32,48,.06);
}

.dark {
  --eas-ink:#e8edf3; --eas-ink-2:#b3c0cf; --eas-ink-3:#8b9aab;
  --eas-line:#2b3746; --eas-line-2:#222c38;
  --eas-surface:#182430; --eas-surface-2:#121b25; --eas-surface-3:#1f2c3a;
  --eas-accent:var(--eas-blue-400);
  --eas-accent-hover:var(--eas-blue-500);
  --eas-on-accent:#06202f;
  --eas-focus:#7cc0f5;
  --eas-blue-50:#15293c; --eas-amber-50:#33260f;
  --eas-green-50:#102c1f; --eas-red-50:#33191a;
  --sh-1:0 1px 2px rgba(0,0,0,.5);
  --sh-2:0 4px 10px rgba(0,0,0,.45);
  --sh-3:0 14px 32px rgba(0,0,0,.55);
}

/* ---------- Base ---------- */

html { -webkit-text-size-adjust:100%; scroll-behavior:smooth; }

body {
  font-family:var(--eas-font);
  font-size:var(--fs-body);
  line-height:1.65;
  color:var(--eas-ink);
  background:var(--eas-surface-2);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

h1,h2,h3,h4,h5,h6 {
  font-family:var(--eas-font);
  color:var(--eas-ink);
  font-weight:700;
  line-height:1.22;
  letter-spacing:-.015em;
  text-wrap:balance;
}
h1{font-size:var(--fs-h1);} h2{font-size:var(--fs-h2);}
h3{font-size:var(--fs-h3);} h4{font-size:1.05rem;}

p { color:var(--eas-ink-2); }
.eas-lead { font-size:1.1rem; color:var(--eas-ink-2); max-width:62ch; }
.eas-muted { color:var(--eas-ink-3); font-size:var(--fs-sm); }
.eas-eyebrow {
  text-transform:uppercase; letter-spacing:.12em; font-size:var(--fs-xs);
  font-weight:700; color:var(--eas-accent); margin-bottom:var(--sp-2);
}

a { color:var(--eas-accent); text-underline-offset:3px; }
a:hover { color:var(--eas-accent-hover); }

img, svg, video { max-width:100%; height:auto; }

/* ---------- Site header ----------
   The bar must stay one line at every width. When it ran out of room it wrapped
   to a second row, growing taller and overlapping the hero underneath. */

.navbar.fixed-top {
  flex-wrap: nowrap;
  min-height: 62px;
  padding-block: .4rem;
}
.navbar.fixed-top > .container-fluid {
  flex-wrap: nowrap;
  gap: var(--sp-2);
  align-items: center;
}

/* Links never wrap mid-label and never break onto a second line. */
.navbar .navbar-nav { flex-wrap: nowrap; }
.navbar .nav-link { white-space: nowrap; }

/* The logo is the first thing to give up space. */
.navbar-brand { flex: 0 0 auto; margin-right: var(--sp-2); }
.navbar-brand img { max-height: 34px; width: auto; }

/* Auth buttons stay compact so they never push the links into a wrap. */
.navbar .btn { white-space: nowrap; padding-inline: .9rem; }

/* Between the collapse breakpoint and comfortable, tighten rather than wrap. */
@media (min-width: 1200px) and (max-width: 1399.98px) {
  .navbar .nav-link.mx-2 { margin-inline: .35rem !important; font-size: .94rem; }
  .navbar .btn { padding-inline: .75rem; font-size: .88rem; }
}

/* Below the collapse breakpoint only the brand, toggler and auth buttons show. */
@media (max-width: 1199.98px) {
  .navbar.fixed-top { min-height: 56px; }
  .hero { padding-top: 56px; }
}

/* The hero sits under the transparent header by design; give it enough room that
   the headline never tucks behind the bar. */
.hero { padding-top: 62px; }
@media (max-width: 400px) {
  .navbar-brand img { max-height: 28px; }
  .navbar .btn { padding-inline: .6rem; font-size: .82rem; }
}

/* ---------- Accessibility ---------- */

/* Visible focus for keyboard users on every interactive element. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible,
.btn:focus-visible, .form-control:focus-visible, .nav-link:focus-visible,
.list-group-item-action:focus-visible {
  outline:3px solid var(--eas-focus);
  outline-offset:2px;
  border-radius:var(--r-sm);
  box-shadow:none;
}

/* Screen-reader-only text that becomes visible when focused. */
.eas-sr-only {
  position:absolute!important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

.eas-skip-link {
  position:absolute; left:var(--sp-4); top:-100px; z-index:2000;
  background:var(--eas-navy-800); color:#fff; padding:var(--sp-3) var(--sp-5);
  border-radius:0 0 var(--r-md) var(--r-md); font-weight:600; text-decoration:none;
  transition:top .15s ease;
}
.eas-skip-link:focus { top:0; color:#fff; }

/* Every touch target reaches 44px.
   Only real buttons get centred flex — doing this to .nav-link or
   .list-group-item-action collapses sidebars and navbars to content width
   and centres text that should be left-aligned. */
.btn, .eas-btn {
  min-height:44px; display:inline-flex; align-items:center; justify-content:center;
}
.nav-link, .list-group-item-action {
  min-height:44px; display:flex; align-items:center;
}
.navbar-nav .nav-link { display:block; min-height:0; padding-block:.55rem; }
.btn-sm, .eas-btn-sm { min-height:36px; }

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

@media (prefers-contrast: more) {
  :root { --eas-line:#5a6b7d; }
  .eas-card, .form-control, .form-select { border-width:2px; }
}

/* ---------- Layout ---------- */

.eas-section { padding:var(--sp-8) 0; }
.eas-section-tight { padding:var(--sp-7) 0; }
.eas-shell { width:100%; max-width:1180px; margin-inline:auto; padding-inline:var(--sp-4); }
.eas-narrow { max-width:760px; margin-inline:auto; }
.eas-stack > * + * { margin-top:var(--sp-4); }

.eas-grid { display:grid; gap:var(--sp-5); }
.eas-grid-2 { grid-template-columns:repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.eas-grid-3 { grid-template-columns:repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.eas-grid-4 { grid-template-columns:repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }

/* ---------- Cards ---------- */

.eas-card {
  background:var(--eas-surface);
  border:1px solid var(--eas-line);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-1);
  padding:var(--sp-5);
}
.eas-card-hover { transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.eas-card-hover:hover { transform:translateY(-3px); box-shadow:var(--sh-3); border-color:var(--eas-blue-400); }
.eas-card-head {
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sp-3); flex-wrap:wrap; margin-bottom:var(--sp-4);
}
.eas-card-head h2, .eas-card-head h3 { margin:0; }

.eas-icon-tile {
  width:52px; height:52px; border-radius:var(--r-md);
  display:grid; place-items:center; font-size:1.5rem;
  background:var(--eas-blue-50); color:var(--eas-accent);
  margin-bottom:var(--sp-4); flex:0 0 auto;
}

/* ---------- Buttons ---------- */

.eas-btn {
  font-family:var(--eas-font); font-weight:600; font-size:var(--fs-body);
  padding:var(--sp-3) var(--sp-5); border-radius:var(--r-pill);
  border:1.5px solid transparent; cursor:pointer; text-decoration:none;
  gap:var(--sp-2); line-height:1.2; text-align:center;
  transition:background .16s ease, color .16s ease, border-color .16s ease, transform .1s ease;
}
.eas-btn:active { transform:translateY(1px); }
.eas-btn[disabled], .eas-btn.disabled { opacity:.55; cursor:not-allowed; transform:none; }

.eas-btn-primary { background:var(--eas-accent); color:var(--eas-on-accent); }
.eas-btn-primary:hover { background:var(--eas-accent-hover); color:var(--eas-on-accent); }

.eas-btn-ghost { background:transparent; color:var(--eas-accent); border-color:currentColor; }
.eas-btn-ghost:hover { background:var(--eas-blue-50); color:var(--eas-accent-hover); }

.eas-btn-quiet { background:var(--eas-surface-3); color:var(--eas-ink); border-color:var(--eas-line); }
.eas-btn-quiet:hover { background:var(--eas-line-2); color:var(--eas-ink); }

.eas-btn-danger { background:var(--eas-red); color:#fff; }
.eas-btn-danger:hover { background:#a82b2b; color:#fff; }

.eas-btn-sm { padding:var(--sp-2) var(--sp-4); font-size:var(--fs-sm); }
.eas-btn-block { width:100%; }

/* ---------- Forms ---------- */

.eas-field { margin-bottom:var(--sp-4); }
.eas-field label, .eas-label {
  display:block; font-weight:600; font-size:var(--fs-sm);
  color:var(--eas-ink); margin-bottom:var(--sp-2);
}
.eas-hint { font-size:var(--fs-xs); color:var(--eas-ink-3); margin-top:var(--sp-1); }
.eas-required { color:var(--eas-red); }

.eas-input, .eas-select, .eas-textarea,
.eas-card .form-control, .eas-card .form-select {
  width:100%; font-family:var(--eas-font); font-size:var(--fs-body);
  padding:.7rem .9rem; color:var(--eas-ink);
  background:var(--eas-surface); border:1.5px solid var(--eas-line);
  border-radius:var(--r-sm); min-height:44px;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.eas-input:hover, .eas-select:hover, .eas-textarea:hover { border-color:var(--eas-ink-3); }
.eas-input:focus, .eas-select:focus, .eas-textarea:focus {
  border-color:var(--eas-accent); outline:3px solid var(--eas-focus); outline-offset:1px;
}
.eas-input[aria-invalid="true"], .eas-textarea[aria-invalid="true"] { border-color:var(--eas-red); }
.eas-textarea { min-height:120px; resize:vertical; }
.eas-error-text { color:var(--eas-red); font-size:var(--fs-xs); margin-top:var(--sp-1); }

/* Radio / checkbox cards — used by the cassette intake form. */
.eas-choice { position:relative; }
.eas-choice input { position:absolute; opacity:0; width:1px; height:1px; }
.eas-choice-body {
  display:block; cursor:pointer; padding:var(--sp-4);
  border:2px solid var(--eas-line); border-radius:var(--r-md);
  background:var(--eas-surface); transition:border-color .15s ease, background .15s ease;
  height:100%;
}
.eas-choice-body strong { display:block; color:var(--eas-ink); margin-bottom:var(--sp-1); }
.eas-choice-body span { font-size:var(--fs-sm); color:var(--eas-ink-3); }
.eas-choice input:checked + .eas-choice-body { border-color:var(--eas-accent); background:var(--eas-blue-50); }
.eas-choice input:focus-visible + .eas-choice-body { outline:3px solid var(--eas-focus); outline-offset:2px; }

/* ---------- Badges ---------- */

.eas-badge {
  display:inline-flex; align-items:center; gap:var(--sp-1);
  padding:.28rem .7rem; border-radius:var(--r-pill);
  font-size:var(--fs-xs); font-weight:700; letter-spacing:.01em;
  white-space:nowrap; border:1px solid transparent;
}
.eas-badge-info     { background:var(--eas-blue-50);  color:var(--eas-blue-600); border-color:var(--eas-blue-400); }
.eas-badge-progress { background:var(--eas-blue-50);  color:var(--eas-navy-700); border-color:var(--eas-blue-500); }
.eas-badge-warn     { background:var(--eas-amber-50); color:#8a5209; border-color:var(--eas-amber); }
.eas-badge-ready    { background:var(--eas-green-50); color:var(--eas-green); border-color:var(--eas-green); }
.eas-badge-ok       { background:var(--eas-green-50); color:var(--eas-green); border-color:var(--eas-green); }
.eas-badge-danger   { background:var(--eas-red-50);   color:var(--eas-red);   border-color:var(--eas-red); }
.eas-badge-muted    { background:var(--eas-surface-3);color:var(--eas-ink-3); border-color:var(--eas-line); }
.dark .eas-badge-warn { color:var(--eas-amber); }

/* ---------- Tables ---------- */

.eas-table-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; border-radius:var(--r-md); }
.eas-table { width:100%; border-collapse:collapse; font-size:var(--fs-sm); background:var(--eas-surface); }
.eas-table caption { text-align:left; padding:var(--sp-3); color:var(--eas-ink-3); font-size:var(--fs-xs); }
.eas-table th {
  text-align:left; font-weight:700; color:var(--eas-ink);
  background:var(--eas-surface-3); padding:var(--sp-3) var(--sp-4);
  border-bottom:2px solid var(--eas-line); white-space:nowrap;
}
.eas-table td { padding:var(--sp-3) var(--sp-4); border-bottom:1px solid var(--eas-line-2); color:var(--eas-ink-2); vertical-align:middle; }
.eas-table tbody tr:hover { background:var(--eas-surface-2); }
.eas-table tbody tr:last-child td { border-bottom:none; }

/* Stack tables into cards on phones. Needs data-label on each td. */
@media (max-width: 720px) {
  .eas-table-stack thead { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); }
  .eas-table-stack tr {
    display:block; margin-bottom:var(--sp-4); border:1px solid var(--eas-line);
    border-radius:var(--r-md); background:var(--eas-surface); padding:var(--sp-2);
  }
  .eas-table-stack td {
    display:flex; justify-content:space-between; gap:var(--sp-4);
    padding:var(--sp-2) var(--sp-3); border-bottom:1px solid var(--eas-line-2);
    text-align:right;
  }
  .eas-table-stack td::before {
    content:attr(data-label); font-weight:700; color:var(--eas-ink); text-align:left;
  }
  .eas-table-stack td:last-child { border-bottom:none; }
}

/* ---------- Progress tracker ---------- */

.eas-track { display:flex; gap:var(--sp-2); margin:var(--sp-4) 0; }
.eas-track-step { flex:1; text-align:center; font-size:var(--fs-xs); color:var(--eas-ink-3); }
.eas-track-bar { height:6px; border-radius:var(--r-pill); background:var(--eas-surface-3); margin-bottom:var(--sp-2); }
.eas-track-step.done .eas-track-bar { background:var(--eas-accent); }
.eas-track-step.done { color:var(--eas-ink); font-weight:600; }

.eas-meter { height:8px; border-radius:var(--r-pill); background:var(--eas-surface-3); overflow:hidden; }
.eas-meter > span { display:block; height:100%; background:var(--eas-accent); border-radius:var(--r-pill); transition:width .4s ease; }

/* ---------- Timeline ---------- */

.eas-timeline { list-style:none; margin:0; padding:0 0 0 var(--sp-5); border-left:2px solid var(--eas-line); }
.eas-timeline li { position:relative; padding:0 0 var(--sp-4) var(--sp-4); }
.eas-timeline li::before {
  content:''; position:absolute; left:calc(-1 * var(--sp-5) - 5px); top:.45rem;
  width:10px; height:10px; border-radius:50%;
  background:var(--eas-accent); box-shadow:0 0 0 3px var(--eas-surface);
}
.eas-timeline time { display:block; font-size:var(--fs-xs); color:var(--eas-ink-3); }

/* ---------- Notices ---------- */

.eas-notice {
  border-radius:var(--r-md); padding:var(--sp-4);
  border:1px solid var(--eas-line); background:var(--eas-surface-3);
  color:var(--eas-ink-2); font-size:var(--fs-sm);
}
.eas-notice-info   { background:var(--eas-blue-50);  border-color:var(--eas-blue-400); }
.eas-notice-ok     { background:var(--eas-green-50); border-color:var(--eas-green); }
.eas-notice-warn   { background:var(--eas-amber-50); border-color:var(--eas-amber); }
.eas-notice-danger { background:var(--eas-red-50);   border-color:var(--eas-red); }

.eas-empty { text-align:center; padding:var(--sp-7) var(--sp-4); color:var(--eas-ink-3); }
.eas-empty h3 { color:var(--eas-ink-2); margin-bottom:var(--sp-2); }

/* ---------- Staging ribbon ---------- */

.eas-staging-flag {
  /* Below Bootstrap's backdrop (1050) and modal (1055). At z-index 3000 this bar
     sat on top of every modal footer and swallowed the save button. */
  position:fixed; inset:auto 0 0 0; z-index:1040;
  pointer-events:none;
  background:var(--eas-amber); color:#22160a; text-align:center;
  font-size:var(--fs-xs); font-weight:700; padding:var(--sp-1) var(--sp-3);
  letter-spacing:.04em;
}
body.has-staging-flag { padding-bottom:2rem; }

/* ---------- Bootstrap harmonisation ---------- */

.btn-primary { background-color:var(--eas-accent); border-color:var(--eas-accent); }
.btn-primary:hover, .btn-primary:focus { background-color:var(--eas-accent-hover); border-color:var(--eas-accent-hover); }
.modal-content { border-radius:var(--r-lg); border:1px solid var(--eas-line); background:var(--eas-surface); }
.modal-header, .modal-footer { border-color:var(--eas-line); }

/* ---------- Modals always reach their footer ----------
   Bootstrap only scrolls the body of a modal tagged .modal-dialog-scrollable.
   Everything else overflows the viewport on a short screen and the footer —
   with the save button in it — becomes unreachable. Apply that behaviour to
   every modal, and keep the footer pinned so the primary action is always there. */

.modal-dialog:not(.modal-fullscreen) { max-height: calc(100% - 1rem); }
@media (min-width: 576px) {
  .modal-dialog:not(.modal-fullscreen) { max-height: calc(100% - 3.5rem); }
}

.modal-dialog:not(.modal-fullscreen) > .modal-content {
  max-height: 100%;
  overflow: hidden;              /* the body scrolls, not the shell */
}

/* Most of our modals wrap header/body/footer in a <form>, so the form — not the
   body — is .modal-content's flex child. A plain block grows to fit its content,
   which means the height constraint never reaches .modal-body and overflow-y has
   nothing to scroll against. Make any such wrapper a flex column that can shrink. */
.modal-content > form,
.modal-content > *:has(> .modal-body) {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 100%;
  overflow: hidden;
  flex: 1 1 auto;
}

/* Descendant, not child: the body may sit inside that wrapper. */
.modal-dialog:not(.modal-fullscreen) .modal-body {
  overflow-y: auto;
  overscroll-behavior: contain;  /* don't scroll the page behind it */
  min-height: 0;                 /* lets the flex child actually shrink */
  flex: 1 1 auto;
  -webkit-overflow-scrolling: touch;
}

/* Header and footer stay put while the body moves. */
.modal-header,
.modal-footer { flex: 0 0 auto; }

/* Clear the phone's home indicator. */
.modal-footer {
  padding-bottom: calc(var(--sp-4) + env(safe-area-inset-bottom, 0px));
  gap: var(--sp-2);
  flex-wrap: wrap;
}
/* A field scrolled to inside a modal shouldn't hide under the sticky header. */
.modal-body :target,
.modal-body :focus-visible { scroll-margin-block: var(--sp-5); }
.form-control, .form-select { border-radius:var(--r-sm); min-height:44px; }
.card { border-radius:var(--r-lg); border-color:var(--eas-line); }

/* ---------- Nothing gets trapped out of reach ----------
   Same class of bug as the modal footer: a pinned element that stops you
   reaching a control on a short screen. Audited the whole stylesheet for it. */

/* The sidebar's sign-out block was absolutely positioned at bottom:16px inside a
   scrolling container, so on a short viewport it sat on top of the tab list.
   Let it flow, and push it down with auto margin instead. */
.sidebar { display:flex; flex-direction:column; }
.sidebar .list-group { flex:0 0 auto; }
.sidebar .bottom-tabs {
  position:static;
  width:auto;
  margin-top:auto;
  padding-bottom:env(safe-area-inset-bottom, 0px);
}

/* The chat panel had a hard 360px message area, so on a short screen the input
   row fell off the bottom. */
.chat-modal-content {
  display:flex;
  flex-direction:column;
  max-height:calc(100dvh - 2rem);
}
.chat-messages {
  height:auto;
  flex:1 1 auto;
  min-height:120px;
  max-height:min(360px, 45vh);
}

/* style.css pins .alert at z-index 9999, above every modal. Keep toasts visible,
   but just above the modal rather than blanketing it. */
.alert { z-index:1060; }

/* Offcanvas panels scroll their own body and clear the home indicator. */
.offcanvas-body { overflow-y:auto; overscroll-behavior:contain; }
.offcanvas .bottom-tabs { padding-bottom:env(safe-area-inset-bottom, 0px); }

/* ---------- Print ---------- */
@media print {
  .eas-skip-link, .navbar, .eas-staging-flag, footer, .eas-no-print { display:none!important; }
  body { background:#fff; color:#000; }
  .eas-card { box-shadow:none; border:1px solid #999; }
}
