/* Lazar Spinal Care — Patient Portal
   Tokens follow the LSC brand design system (violet/Figtree/white).
   Source: C:\Users\drlaz\iCloudDrive\Claude Cowork\lsc-bridge\brand\colors_and_type.css

   This is the old host's look (app.lazarspinalcare.com) and stays as it is. On
   app.lazaruppercervical.com static/luc/luc.css is layered on top of it (app/brand.py).
   Figtree is linked from base.html on the old host only, not @imported here, so the
   new host makes no request to Google Fonts. */

:root {
  --violet-50:  #f3f1fe;
  --violet-100: #e7e2fc;
  --violet-500: #5540dd;
  --violet-600: #4632c4;
  --violet-700: #3826a0;

  --ink:       #202020;
  --gray-700:  #525257;
  --gray-600:  #6b6b72;
  --gray-500:  #8a8a92;
  --gray-300:  #d4d4da;
  --gray-200:  #e6e6ea;
  --gray-100:  #f2f2f5;
  --gray-50:   #fafafb;
  --white:     #ffffff;
  --violet-tint: #f6f4fe;

  --bg:            var(--white);
  --bg-subtle:     var(--violet-tint);
  --surface:       var(--white);
  --fg:            var(--ink);
  --fg-muted:      var(--gray-600);
  --fg-subtle:     var(--gray-500);
  --accent:        var(--violet-500);
  --accent-hover:  var(--violet-600);
  --accent-press:  var(--violet-700);
  --accent-soft:   var(--violet-100);
  --border:        var(--gray-300);
  --danger:        #d6453f;
  --warning:       #d98a2b;

  --radius-sm: 12px;
  --radius-md: 18px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(32,32,32,0.06), 0 1px 3px rgba(32,32,32,0.05);
  --shadow-md: 0 6px 16px rgba(32,32,32,0.08), 0 2px 6px rgba(32,32,32,0.05);
}

* { box-sizing: border-box; }

/* T-121: the `hidden` attribute is only a UA-stylesheet `display:none`, so ANY
   author rule that gives an element a display value silently defeats it -- a
   panel styled `display:flex` stays on screen no matter what the markup says.
   Several components here toggle visibility with `hidden`, so state it once. */
[hidden] { display: none !important; }

body {
  font-family: 'Figtree', system-ui, -apple-system, "Segoe UI", sans-serif;
  margin: 0;
  background: var(--bg-subtle);
  color: var(--fg);
}

.topbar {
  display: flex;
  align-items: center;
  padding: 1rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  gap: 1.5rem;
}
.topbar .brand { display: inline-flex; align-items: center; text-decoration: none; flex-shrink: 0; }
/* T-121: the wordmark sits on its own violet plate rather than directly on the
   bar. The artwork is a single flat colour, so previously its legibility was a
   property of whatever was behind it -- on the white top bar it disappeared,
   and Chrome for Android's auto-dark theme could invert it independently of the
   bar underneath. Giving it a fixed plate makes the contrast ours to guarantee
   on every page, instead of something each new background has to remember. */
.brand-mark {
  display: inline-flex; align-items: center;
  background: var(--accent);
  border-radius: var(--radius-sm);
  padding: 0.42rem 0.6rem;
}
.brand-logo { height: 20px; width: auto; display: block; }

.topbar-quick { display: flex; gap: 0.5rem; align-items: center; flex-shrink: 0; }

.topbar-nav {
  display: flex; gap: 1.5rem; align-items: center;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  flex: 1; min-width: 0;
  /* Last item needs breathing room so it doesn't sit flush against the viewport
     edge when scrolled all the way -- this was the actual "doesn't scroll all the
     way to the end" bug, not a scrolling capability that was missing. */
  padding-right: 0.25rem;
}
.topbar-nav a, .topbar-nav .link-btn { white-space: nowrap; flex-shrink: 0; }
.topbar-nav a { text-decoration: none; color: var(--fg-muted); font-weight: 500; }
.topbar-nav a:hover { color: var(--accent); }
.topbar-nav form.inline { flex-shrink: 0; }
.link-btn {
  background: none; border: none; color: var(--fg-muted); cursor: pointer; font: inherit; padding: 0;
}
.link-btn:hover { color: var(--accent); }
/* Old host: the global button[type=submit] rule turns the top bar's "Sign out" into a pill; keep it
   the same compact size as every other pill (luc.css, later, makes it a plain link on the new host). */
.topbar-nav button.link-btn[type=submit] { margin-top: 0; padding: 0 14px; height: var(--pill-h, 32px); font-size: 14px; line-height: 1; }

main { max-width: 640px; margin: 0 auto; padding: 2rem 1.5rem; }

h1 { font-weight: 800; letter-spacing: -0.02em; color: var(--fg); }
h2 { font-weight: 700; letter-spacing: -0.02em; color: var(--fg); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
}
.card.narrow { max-width: 420px; margin-left: auto; margin-right: auto; }

label { display: block; margin-top: 0.75rem; margin-bottom: 0.25rem; font-size: 0.9rem; color: var(--fg-muted); font-weight: 500; }
/* `tel` and `number` were missing from this list, so the sign-in page's phone
   field rendered as a bare unstyled box right next to a properly styled date
   field -- on the first screen every patient sees. Any input type that isn't
   listed here silently falls back to the browser default, so add new ones as
   they appear rather than styling them one-off elsewhere. */
input[type=email], input[type=text], input[type=tel], input[type=number],
input[type=date], input[type=time], select, textarea {
  width: 100%; padding: 0.65rem 0.8rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  font: inherit; color: var(--fg); background: var(--white);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

button[type=submit], .btn {
  margin-top: 1rem; padding: 0.7rem 1.4rem; border: none; border-radius: var(--radius-pill);
  background: var(--accent); color: var(--white); cursor: pointer; font: inherit; font-weight: 600;
  transition: background-color 0.15s ease;
}
button[type=submit]:hover, .btn:hover { background: var(--accent-hover); }
button[type=submit]:active, .btn:active { background: var(--accent-press); }

.muted { color: var(--fg-subtle); font-size: 0.9rem; }
.error { color: var(--danger); }
.dev-note {
  background: var(--gray-50); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 0.75rem; word-break: break-all; color: var(--fg-muted);
}

.appt-list, .thread-list { list-style: none; padding: 0; margin: 0; }
.appt-list li, .thread-list li {
  padding: 0.75rem 0; border-bottom: 1px solid var(--gray-200); display: flex; flex-direction: column; gap: 0.15rem;
}
.thread-list li { flex-direction: row; justify-content: space-between; align-items: center; }

.badge {
  background: var(--accent); color: var(--white); border-radius: var(--radius-pill); padding: 0.1rem 0.6rem; font-size: 0.75rem;
}
.balance-badge {
  background: var(--warning); color: var(--white); border-radius: var(--radius-pill);
  padding: 0.1rem 0.6rem; font-size: 0.75rem; font-weight: 700;
}

.ledger-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.ledger-table th {
  text-align: left; padding: 0.5rem 0.6rem; border-bottom: 2px solid var(--border);
  color: var(--fg-muted); font-weight: 600; font-size: 0.8rem;
}
.ledger-table td { padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--gray-200); }
.ledger-table tr:last-child td { border-bottom: none; }
.ledger-table a { color: var(--accent); }
@media (max-width: 520px) {
  .ledger-table { font-size: 0.8rem; }
  .ledger-table th, .ledger-table td { padding: 0.4rem; }
}

.thread { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1.5rem; }
.msg { padding: 0.75rem 1rem; border-radius: var(--radius-md); max-width: 80%; }
.msg-patient { background: var(--violet-100); color: var(--fg); align-self: flex-end; }
.msg-staff { background: var(--white); border: 1px solid var(--border); align-self: flex-start; }
.msg-meta { font-size: 0.75rem; color: var(--fg-subtle); margin-bottom: 0.25rem; }

.channel-toggle {
  display: flex; gap: 0.4rem; margin-top: 1rem; background: var(--gray-100);
  padding: 0.3rem; border-radius: var(--radius-pill);
}
.channel-tab {
  flex: 1; border: none; background: none; padding: 0.5rem 1rem; border-radius: var(--radius-pill);
  font: inherit; font-weight: 600; color: var(--fg-muted); cursor: pointer; transition: all 0.15s ease;
}
.channel-tab.active { background: var(--white); color: var(--accent); box-shadow: var(--shadow-sm); }

/* "Remember my details on this device" — a quiet opt-in under the sign-in
   fields. Checkbox and label on one baseline, full-width tap target. */
.remember-row {
  display: flex; align-items: center; gap: 0.55rem;
  margin: 0.5rem 0 1.1rem; cursor: pointer;
  color: var(--fg-muted); font-size: 0.92rem;
}
.remember-row input[type=checkbox] {
  width: 1.15rem; height: 1.15rem; flex: none; margin: 0; cursor: pointer;
  accent-color: var(--accent);
}

/* Success note (password saved, etc.). The portal only had .error before. */
.ok-note {
  background: var(--green-50, #ecfdf3); color: var(--green-700, #15803d);
  border: 1px solid var(--green-200, #bbf7d0);
  border-radius: var(--radius, 10px); padding: 0.6rem 0.8rem; margin: 0 0 0.9rem;
}

/* Sign-in help: the link under the sign-in button, its pop-up, and the form. */
.access-help-row { margin: 1rem 0 0; font-size: 0.95rem; }
.access-help-row a { color: var(--accent); font-weight: 600; }
.help-dialog {
  width: min(420px, calc(100vw - 32px)); max-height: calc(100vh - 32px); overflow: auto;
  border: none; border-radius: var(--radius-md); padding: 1.5rem 1.5rem 1.25rem;
  box-shadow: var(--shadow-md); color: var(--fg); background: var(--surface);
}
.help-dialog::backdrop { background: rgba(20, 20, 30, 0.45); }
.help-dialog h2 { margin: 0 2rem 0.75rem 0; font-size: 1.2rem; line-height: 1.3; }
.help-dialog p { margin: 0 0 1rem; line-height: 1.5; }
.help-dialog a { color: var(--accent); font-weight: 600; }
.help-dialog-x {
  position: absolute; top: 0.6rem; right: 0.6rem; width: 2.75rem; height: 2.75rem;
  border: none; background: none; font-size: 1.6rem; line-height: 1; color: var(--fg-muted);
  cursor: pointer; border-radius: 50%;
}
.help-dialog-x:hover { background: var(--gray-100); }
.help-dialog-ok {
  display: block; width: 100%; min-height: 2.75rem; border: 1px solid var(--border);
  border-radius: var(--radius-pill); background: var(--white); color: var(--fg);
  font: inherit; font-weight: 600; cursor: pointer;
}
.help-dialog-ok:hover { border-color: var(--accent); color: var(--accent); }
.field-error { color: var(--danger); font-size: 0.88rem; margin: 0.25rem 0 0; }
.help-form input[aria-invalid=true] { border-color: var(--danger, #c0392b); }
.help-form button[type=submit] { width: 100%; min-height: 2.9rem; }
.help-form .name-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 0.75rem; }
@media (max-width: 360px) { .help-form .name-row { grid-template-columns: 1fr; } }
/* The honeypot: off-screen rather than display:none, which some bots skip. */
.hp-field { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* Password sign-in card: a quieter alternative under the magic-link form. */
.pw-card { margin-top: 1rem; }
.pw-card > summary {
  cursor: pointer; font-weight: 600; color: var(--accent);
  list-style: none; padding: 0.2rem 0;
}
.pw-card > summary::-webkit-details-marker { display: none; }
.pw-card[open] > summary { margin-bottom: 0.6rem; }

.day-picker {
  display: flex; gap: 0.5rem; overflow-x: auto; padding-bottom: 0.75rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--gray-200);
}
.day-tab {
  flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
  min-width: 4.25rem; border: 1px solid var(--border); background: var(--white);
  border-radius: var(--radius-sm); padding: 0.5rem 0.4rem; font: inherit; cursor: pointer;
  color: var(--fg-muted); transition: all 0.15s ease;
}
.day-tab:hover { border-color: var(--accent); color: var(--accent); }
.day-tab.active { background: var(--accent); border-color: var(--accent); color: var(--white); }
.day-tab-weekday { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; }
.day-tab-date { font-size: 0.85rem; font-weight: 600; }

.schedule-cta { text-align: center; margin: 0 0 1.5rem; }
.schedule-cta .btn { margin-top: 0; padding: 0.85rem 2.5rem; font-size: 1.05rem; display: inline-block; text-decoration: none; }

.collapse-toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  border: none; background: none; padding: 0; margin: 0 0 0.75rem; cursor: pointer; text-align: left; font: inherit;
}
.collapse-toggle h2 { margin: 0; }
.collapse-chevron { color: var(--fg-subtle); font-size: 1rem; transition: transform 0.15s ease; flex-shrink: 0; }
.collapse-toggle[aria-expanded="false"] .collapse-chevron { transform: rotate(-90deg); }

.quick-call-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; border-radius: var(--radius-pill);
  background: var(--accent-soft); font-size: 1.1rem; text-decoration: none; flex-shrink: 0;
}
.quick-call-btn:hover { background: var(--accent); }

.quick-menu { position: relative; }
.quick-menu-toggle {
  border: 1px solid var(--border); background: var(--white); border-radius: var(--radius-sm);
  width: 2.25rem; height: 2.25rem; font-size: 1.1rem; line-height: 1; cursor: pointer;
  color: var(--fg-muted); transition: all 0.15s ease;
}
.quick-menu-toggle:hover, .quick-menu-toggle[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.quick-menu-panel {
  position: absolute; top: calc(100% + 0.5rem); right: 0; z-index: 20; min-width: 220px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md); padding: 0.5rem; display: flex; flex-direction: column;
}
.quick-menu-panel a {
  padding: 0.6rem 0.75rem; border-radius: var(--radius-sm); text-decoration: none;
  color: var(--fg); font-weight: 500; white-space: nowrap;
}
.quick-menu-panel a:hover { background: var(--bg-subtle); color: var(--accent); }
.quick-menu-item {
  padding: 0.6rem 0.75rem; border: none; background: none; border-radius: var(--radius-sm);
  font: inherit; font-weight: 500; color: var(--fg); text-align: left; cursor: pointer; white-space: nowrap;
}
.quick-menu-item:hover { background: var(--bg-subtle); color: var(--accent); }
@media (max-width: 640px) {
  .quick-menu-panel { right: -0.5rem; }
}

/* ===========================================================================
   T-121 — mobile navigation, add-to-home-screen, safe areas.

   Everything below the breakpoint is phone layout; above it the desktop top
   bar is unchanged. 720px is where the full link row stops fitting without
   horizontal scroll, which is the condition that caused the bug (at 375px the
   row was 977px wide inside a 224px box, so Messages sat 276px off-screen with
   nothing on screen suggesting it existed).
   =========================================================================== */

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

.tabbar, .sheet, .sheet-backdrop, .a2hs-nudge { display: none; }

@media (max-width: 720px) {
  .topbar { padding: 0.75rem 1rem; gap: 0.75rem; justify-content: space-between; }
  /* The scrolling link row is what hid Messages. Below the breakpoint it is
     replaced outright by the tab bar, not merely narrowed. */
  .topbar-nav { display: none; }

  .tabbar {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    background: var(--surface);
    border-top: 1px solid var(--border);
    /* Home-indicator clearance on iPhone; 0 everywhere else. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
    box-shadow: 0 -2px 12px rgba(32,32,32,0.06);
  }
  .tab {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.2rem; padding: 0.5rem 0.15rem 0.55rem;
    border: none; background: none; font: inherit; cursor: pointer;
    color: var(--fg-subtle); text-decoration: none;
    /* 44px is the minimum reliable touch target; the label pushes past it. */
    min-height: 44px;
    -webkit-tap-highlight-color: transparent;
  }
  .tab-icon-wrap { position: relative; display: inline-flex; }
  .tab-icon {
    width: 24px; height: 24px; display: block;
    fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
  }
  .tab-label {
    font-size: 0.68rem; font-weight: 600; letter-spacing: 0.01em;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tab.is-active { color: var(--accent); }
  .tab:active { background: var(--bg-subtle); }

  /* Sits on the tab itself, so an unread message is visible before the patient
     taps anything at all. */
  .tab-badge {
    position: absolute; top: -5px; left: 13px;
    min-width: 17px; height: 17px; padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--danger); color: var(--white);
    font-size: 0.65rem; font-weight: 800; line-height: 17px; text-align: center;
    border: 2px solid var(--surface);
    box-sizing: content-box;
  }
  .tab-dot {
    position: absolute; top: -2px; left: 16px;
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--warning); border: 2px solid var(--surface);
  }

  /* Content must clear the fixed bar or the last card is unreachable. */
  body.signed-in main { padding-bottom: calc(4.75rem + env(safe-area-inset-bottom, 0px)); }
  body.signed-in.has-nudge main { padding-bottom: calc(9.5rem + env(safe-area-inset-bottom, 0px)); }
  body.sheet-open { overflow: hidden; }

  .sheet-backdrop {
    display: block; position: fixed; inset: 0; z-index: 50;
    background: rgba(32,32,32,0.45);
  }
  .sheet {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    background: var(--surface);
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    box-shadow: var(--shadow-md);
    padding: 0.5rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
    max-height: 85vh; overflow-y: auto;
    transform: translateY(100%);
    transition: transform 0.22s ease;
  }
  .sheet.is-open { transform: translateY(0); }
  @media (prefers-reduced-motion: reduce) {
    .sheet { transition: none; }
  }
  .sheet-grip {
    width: 40px; height: 4px; border-radius: var(--radius-pill);
    background: var(--gray-300); margin: 0.4rem auto 0.9rem;
  }
  .sheet-title { margin: 0 0 0.75rem; font-size: 1.1rem; }
  .sheet-links { display: flex; flex-direction: column; }
  .sheet-links a, .sheet-links button {
    display: block; width: 100%; text-align: left;
    padding: 0.85rem 0.5rem; border: none; border-bottom: 1px solid var(--gray-200);
    background: none; font: inherit; font-weight: 500; color: var(--fg);
    text-decoration: none; cursor: pointer;
  }
  .sheet-links a:last-child, .sheet-links button:last-child { border-bottom: none; }
  .sheet-signout { margin-top: 0.75rem; }
  .sheet-signout button {
    width: 100%; padding: 0.7rem 1rem; border: 1px solid var(--border);
    border-radius: var(--radius-pill); background: var(--white);
    font: inherit; font-weight: 600; color: var(--fg-muted); cursor: pointer;
  }
  .sheet-close {
    width: 100%; margin-top: 0.6rem; padding: 0.7rem 1rem;
    border: none; border-radius: var(--radius-pill);
    background: var(--gray-100); font: inherit; font-weight: 600;
    color: var(--fg-muted); cursor: pointer;
  }

  .a2hs-intro { margin-top: 0; }
  .a2hs-steps { margin: 0 0 0.5rem; padding-left: 1.25rem; line-height: 1.7; }
  .a2hs-steps li { margin-bottom: 0.35rem; }
  .a2hs-glyph {
    display: inline-block; padding: 0 0.15rem; color: var(--accent); font-weight: 700;
  }
  .a2hs-note { margin-bottom: 0; }
  .a2hs-install { display: block; width: 100%; text-align: center; }

  .a2hs-nudge {
    display: flex; align-items: center; gap: 0.7rem;
    position: fixed; left: 0.6rem; right: 0.6rem; z-index: 45;
    bottom: calc(4.6rem + env(safe-area-inset-bottom, 0px));
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md);
    padding: 0.7rem 0.8rem;
  }
  .a2hs-nudge[hidden] { display: none; }
  .a2hs-nudge-icon { width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0; }
  .a2hs-nudge-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
  .a2hs-nudge-text strong { font-size: 0.86rem; }
  .a2hs-nudge-text .muted { font-size: 0.76rem; }
  .a2hs-nudge-actions { display: flex; flex-direction: column; gap: 0.3rem; flex-shrink: 0; }
  .a2hs-nudge-yes {
    border: none; border-radius: var(--radius-pill); background: var(--accent);
    color: var(--white); font: inherit; font-size: 0.78rem; font-weight: 700;
    padding: 0.4rem 0.75rem; cursor: pointer; white-space: nowrap;
  }
  .a2hs-nudge-no {
    border: none; background: none; font: inherit; font-size: 0.75rem;
    color: var(--fg-subtle); cursor: pointer; padding: 0.15rem;
  }
}

/* The sheets are the phone menu; on desktop the same actions live in the
   existing quick-menu dropdown, so keep them out of the way entirely. */
@media (min-width: 721px) {
  .tabbar, .sheet-backdrop, .a2hs-nudge { display: none !important; }
  .sheet {
    display: none; position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
    z-index: 60; width: min(420px, 92vw); background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius-md);
    box-shadow: var(--shadow-md); padding: 1.25rem; max-height: 85vh; overflow-y: auto;
  }
  /* The add-to-home-screen sheet is still reachable from the desktop
     quick-menu (a patient on a laptop may be helping themselves set up their
     phone), so it gets a plain centred dialog rather than a bottom sheet. */
  .sheet:not([hidden]) { display: block; }
  .sheet-backdrop:not([hidden]) { display: block !important; position: fixed; inset: 0; z-index: 50; background: rgba(32,32,32,0.45); }
  .sheet-grip { display: none; }
  .sheet-title { margin-top: 0; }
  .sheet-links { display: flex; flex-direction: column; }
  .sheet-links a, .sheet-links button {
    display: block; width: 100%; text-align: left; padding: 0.6rem 0.4rem;
    border: none; border-bottom: 1px solid var(--gray-200); background: none;
    font: inherit; color: var(--fg); text-decoration: none; cursor: pointer;
  }
  .a2hs-steps { padding-left: 1.25rem; line-height: 1.7; }
  .sheet-close {
    width: 100%; margin-top: 0.8rem; padding: 0.6rem 1rem; border: none;
    border-radius: var(--radius-pill); background: var(--gray-100);
    font: inherit; font-weight: 600; color: var(--fg-muted); cursor: pointer;
  }
  .sheet-signout { display: none; }
}

/* ===========================================================================
   T-203 — quick-action bubbles, and the "I'm running late" flow.

   Every target here is sized for a thumb on a phone held one-handed, not for a
   cursor. 44px is the floor; these clear it comfortably because the running-late
   ones in particular may be pressed by someone who has just pulled over.
   =========================================================================== */

.bubbles {
  display: flex; gap: 0.6rem; margin: 0 0 1.25rem;
}
.bubble {
  flex: 1; min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 56px; padding: 0.7rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  text-decoration: none; font-weight: 700; font-size: 0.9rem;
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
}
.bubble:active { transform: translateY(1px); }
.bubble-icon {
  width: 20px; height: 20px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Wraps rather than ellipsises. Two bubbles have to sit side by side at 390px
   (an iPhone 14), and "I'm running lat..." is not a control anyone trusts --
   his exact words are worth two short lines. */
.bubble-label { line-height: 1.2; }

.bubble-directions { color: var(--accent); border-color: var(--accent-soft); background: var(--violet-tint); }

/* The caution-sign bubble Dr. Lazar described. Amber rather than red on
   purpose: running late is a heads-up, not an emergency, and red here would
   compete with the unread-message badge for the same glance. */
.bubble-late { color: #8a5a12; border-color: #f0d9b0; background: #fdf6e9; }
.bubble-late.is-reported {
  color: var(--fg-muted); background: var(--gray-50); border-color: var(--border);
  font-weight: 600;
}

/* --- persistent confirmation ---------------------------------------------
   Nothing is sent to the patient for this feature, so this card is the entire
   feedback loop. It is server-rendered state, not a flash message: it has to
   still be there when the app is closed and reopened at the next red light. */
.late-confirm { border-left: 4px solid #2f8f5b; }
.late-confirm-title {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 0 0 0.4rem; font-size: 1.05rem;
}
.late-confirm-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; flex-shrink: 0;
  border-radius: 50%; background: #2f8f5b; color: var(--white);
  font-size: 0.85rem; font-weight: 800;
}
.late-confirm-detail { margin: 0 0 0.35rem; }
.late-confirm-ack { margin: 0 0 0.35rem; color: #2f8f5b; font-weight: 600; font-size: 0.9rem; }
.late-confirm-change { margin: 0; }

/* --- the picker ----------------------------------------------------------- */
.late-h1 { margin-bottom: 0.25rem; }
.late-sub { margin-top: 0; }
.late-error { font-weight: 600; }

.late-presets {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem;
  margin: 1.25rem 0 1.5rem;
}
/* Deliberately enormous. These are read and pressed at arm's length by someone
   who should be looking at the road, so the number carries the whole meaning
   and the target is most of a phone-width square. */
/* Two-class selector on purpose. The global `button[type=submit]` rule is an
   attribute selector and therefore beats a single class, so a bare .late-preset
   silently inherited the pill radius and the 1rem top margin -- these buttons
   need square-ish corners because a pill throws away the corner tap area, and
   that is area a driver cannot afford to miss. */
.late-presets .late-preset {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.1rem; min-height: 108px; padding: 1rem 0.5rem;
  margin-top: 0;
  border: none; border-radius: var(--radius-md);
  /* Solid rather than outlined: this is the one control on the screen and it
     should be impossible to mistake for anything else at a glance. */
  background: var(--accent); color: var(--white);
  font: inherit; cursor: pointer;
  box-shadow: var(--shadow-sm);
  -webkit-tap-highlight-color: transparent;
}
.late-presets .late-preset:hover { background: var(--accent-hover); }
.late-presets .late-preset:active { background: var(--accent-press); }
.late-preset-num { font-size: 2.4rem; font-weight: 800; line-height: 1; letter-spacing: -0.03em; }
.late-preset-unit { font-size: 0.85rem; font-weight: 600; }

/* Collapsed, quieter, and below the presets — this is the passenger's path.
   A time picker is scrolling and precision; it must never look like the thing
   to reach for first. */
.late-eta {
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface); padding: 0 1rem;
}
.late-eta-summary {
  padding: 0.9rem 0; cursor: pointer; font-weight: 600;
  color: var(--fg-muted); font-size: 0.95rem;
}
.late-eta-form { padding-bottom: 1rem; }
.late-eta-form input[type=time] { font-size: 1.4rem; text-align: center; padding: 0.6rem; }
.late-eta-submit { width: 100%; }

.late-back { margin-top: 1.5rem; text-align: center; }

@media (max-width: 330px) {
  /* Only the very smallest phones (an iPhone SE 1st gen is 320px). Below this
     a half-width pill cannot hold the icon plus two words on two lines without
     the icon crowding the text, so they stack instead. */
  .bubbles { flex-direction: column; }
}

/* ===========================================================================
   T-205 symptom tracker.

   "Super simple" is the spec. The one-tap button is the loudest thing on its
   card -- a full-width solid target sized for a thumb during a flare-up, not a
   cursor. Everything else (retroactive entry, severity, note, history) is
   quieter and below, the same visual hierarchy as the T-203 running-late page.
   =========================================================================== */

.ep-card { display: flex; flex-direction: column; }

/* The one big tap. Two-selector specificity on purpose: the global
   `button[type=submit]` rule is an attribute selector and beats a single class,
   so a bare `.ep-now` would inherit the pill radius and 1rem top margin -- this
   button wants square-ish corners (a pill throws away corner tap area) and no
   stray margin, exactly the reason the running-late presets do the same. */
.ep-now-form { margin: 0; }
.ep-now-form .ep-now {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.2rem; width: 100%; min-height: 88px; padding: 1rem;
  margin: 0;
  border: none; border-radius: var(--radius-md);
  background: var(--accent); color: var(--white);
  font: inherit; cursor: pointer; text-decoration: none;
  box-shadow: var(--shadow-sm);
  -webkit-tap-highlight-color: transparent;
}
.ep-now-form .ep-now:hover { background: var(--accent-hover); }
.ep-now-form .ep-now:active { background: var(--accent-press); transform: translateY(1px); }
.ep-now-title { font-size: 1.35rem; font-weight: 800; letter-spacing: -0.02em; }
.ep-now-sub { font-size: 0.85rem; font-weight: 600; opacity: 0.9; }

/* Dashboard instance, toned down (.ep-now-calm). The dashboard is the FIRST
   thing a brand-new patient sees when they open the app, and a full-bleed solid
   "episode" alarm up top is startling before anything has even happened. Same
   one-tap action and a thumb-sized target, but calmer: a soft tinted card with
   the brand color as an accent instead of a shout. The loud version still lives
   on the dedicated tracker page, which a patient reaches on purpose. */
.ep-now-form .ep-now.ep-now-calm {
  min-height: 60px;
  background: var(--accent-soft, #efedfb);
  color: var(--accent);
  border: 1px solid var(--accent-soft-border, #dcd7f6);
  box-shadow: none;
}
.ep-now-form .ep-now.ep-now-calm:hover { background: var(--accent-soft-hover, #e7e3f8); }
.ep-now-form .ep-now.ep-now-calm:active { background: var(--accent-soft-hover, #e7e3f8); }
.ep-now-calm .ep-now-title { font-size: 1.05rem; font-weight: 700; letter-spacing: 0; }
.ep-now-calm .ep-now-sub { font-weight: 500; opacity: 0.75; }

/* Episode wizard: one card visible at a time, big tap targets, calm throughout. */
.ep-step { margin-top: 0.3rem; }
.ep-wiz-h { font-size: 1.25rem; margin: 0.2rem 0 0.9rem; }
.ep-wiz-back { display: inline-block; margin-bottom: 0.5rem; font-weight: 600; }
.ep-wiz-choices { display: flex; flex-direction: column; gap: 0.55rem; }
.ep-wiz-choice {
  width: 100%; text-align: left; padding: 0.95rem 1rem; margin: 0;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface); color: inherit; font: inherit; font-weight: 600;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.ep-wiz-choice:hover { border-color: var(--accent); }
.ep-wiz-choice:active { transform: translateY(1px); }
.ep-wiz-choice-other { color: var(--fg-muted); font-weight: 500; }
.ep-wiz-rating { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.5rem; }
.ep-wiz-num {
  padding: 0.9rem 0; margin: 0; border: 1px solid var(--border);
  border-radius: var(--radius-md); background: var(--surface); color: var(--accent);
  font: inherit; font-size: 1.1rem; font-weight: 700; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ep-wiz-num:hover { border-color: var(--accent); background: var(--accent-soft, #efedfb); }
.ep-wiz-num:active { transform: translateY(1px); }
.ep-wiz-scale { display: flex; justify-content: space-between; font-size: 0.8rem; margin: 0.5rem 0 0.2rem; }
.ep-wiz-skip { display: inline-block; margin-top: 0.4rem; font-weight: 600; }
.ep-wiz-save { width: 100%; margin-top: 0.8rem; }

/* Optional severity + note for the CURRENT episode — offered as a centered popup
   instead of a scroll-down section, so one tap still logs instantly and a patient
   who wants to add detail answers the two questions without scrolling. */
.ep-detail-open {
  display: inline-block; margin-top: 0.7rem; padding: 0;
  background: none; border: none; box-shadow: none;
  color: var(--accent); font: inherit; font-weight: 600; font-size: 0.95rem;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.ep-modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 1rem; }
.ep-modal[hidden] { display: none; }
.ep-modal-backdrop { position: absolute; inset: 0; background: rgba(19, 30, 82, 0.45); }
.ep-modal-card {
  position: relative; z-index: 1; width: 100%; max-width: 380px;
  background: var(--surface); border-radius: var(--radius-md);
  padding: 1.25rem; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
}
.ep-modal-title { margin: 0 0 0.5rem; font-size: 1.15rem; }
.ep-modal-actions { display: flex; gap: 0.6rem; justify-content: flex-end; align-items: center; margin-top: 1rem; }
.ep-modal-actions .btn { width: auto; margin: 0; }

.ep-card-foot { margin: 0.85rem 0 0; display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: baseline; font-size: 0.9rem; }
.ep-card-foot a { color: var(--accent); text-decoration: none; font-weight: 600; }

/* The dashboard receipt. Same job as the running-late confirmation card: this
   in-app state is the ONLY feedback -- nothing is sent to the patient -- so it
   is server-rendered and survives closing the app, never a toast. */
.ep-logged {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.6rem 0.75rem; margin-bottom: 0.9rem;
  background: #eef7f1; border: 1px solid #cbe6d5; border-radius: var(--radius-sm);
}
.ep-logged-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem; flex-shrink: 0;
  border-radius: 50%; background: #2f8f5b; color: var(--white);
  font-size: 0.8rem; font-weight: 800;
}
.ep-logged-text { display: flex; flex-direction: column; line-height: 1.25; }
.ep-logged-undo { margin-left: auto; }

/* Page (tracker) header. */
.ep-h1 { margin-bottom: 0.25rem; }
.ep-sub { margin-top: 0; }
.ep-today { margin: 0.75rem 0 0; }
.ep-error { font-weight: 600; margin-top: 1rem; }

/* On the tracker page the one-tap button gets its own breathing room above the
   secondary options. */
.ep-now-form + .ep-today, .ep-now-form + .ep-error { margin-top: 1rem; }

/* Retroactive entry -- collapsed, quiet, clearly the passenger's-not-driver's
   path. Matches the running-late exact-time `<details>` treatment. */
.ep-past {
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface); padding: 0 1rem; margin-top: 1.25rem;
}
.ep-past-summary {
  padding: 0.9rem 0; cursor: pointer; font-weight: 600;
  color: var(--fg-muted); font-size: 0.95rem;
}
.ep-past-form { padding-bottom: 1rem; }
/* Two columns that can actually shrink. Plain `1fr 1fr` tracks keep an implicit
   `min-width: auto`, so a native date/time control -- whose intrinsic width can
   exceed a half-column on a narrow phone -- pushes its cell wider than the card
   and spills off to the right. minmax(0, 1fr) (plus min-width:0 on the cells)
   lets the width:100% inputs be constrained to the column instead of overflowing. */
.ep-past-when { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.75rem; }
.ep-past-when > div { min-width: 0; }
/* The native date/time controls carry an intrinsic min-width that width:100%
   alone doesn't beat on iOS, so "Around what time" spilled off the right of the
   card. min-width:0 lets them be constrained to the column; at very narrow widths
   the two fields stack so neither is ever squeezed. */
.ep-past-when input { min-width: 0; max-width: 100%; }
@media (max-width: 380px) { .ep-past-when { grid-template-columns: 1fr; } }
.ep-optional { font-weight: 400; color: var(--fg-subtle); }
.ep-past-submit { width: 100%; }

/* History list. Each row is an episode + its own Undo; the retro tag marks a
   remembered entry as the weaker evidence it is. */
.ep-history { margin-top: 1.5rem; }
.ep-history-title { margin-top: 0; }
.ep-list { list-style: none; padding: 0; margin: 0; }
.ep-item {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem;
  padding: 0.75rem 0; border-bottom: 1px solid var(--gray-200);
}
.ep-item:last-child { border-bottom: none; }
.ep-item-main { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.ep-item-meta { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.ep-sev { font-size: 0.8rem; color: var(--fg-muted); font-weight: 600; }
.ep-tag {
  font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.5rem;
  border-radius: var(--radius-pill);
}
.ep-tag-retro { background: var(--gray-100); color: var(--fg-muted); }
.ep-note-text { font-size: 0.9rem; color: var(--fg-muted); }
.ep-undo { flex-shrink: 0; }

.ep-back { margin-top: 1.5rem; text-align: center; }

/* --- Billing: family bill switcher ------------------------------------- */
/* A parent managing the household sees a chip per person -- themselves first,
   then each managed family member -- with that person's balance on the chip, so
   they can tell who owes what and tap through to pay it. Shown only when the
   login actually manages someone else. Finger-sized for the phone. */
.pay-who { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1rem; }
.pay-who-chip { display: inline-flex; flex-direction: column; gap: 0.15rem;
  min-height: 44px; justify-content: center; padding: 0.4rem 0.9rem;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface); color: var(--fg); text-decoration: none; }
.pay-who-chip:hover { border-color: var(--accent); }
.pay-who-chip.is-active { border-color: var(--accent); background: var(--accent-soft); }
.pay-who-name { font-weight: 700; font-size: 0.95rem; }
.pay-who-bal { font-size: 0.8rem; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.pay-who-bal.owes { color: var(--danger); font-weight: 700; }

/* --- Upload your records (app/records_upload.py) ------------------------------------
   Mobile first: the kinds are full-width tap targets, the two pickers stack on a phone
   and sit side by side from 520px. Colours come from the tokens, so luc.css re-themes
   it on the new host without anything here. */
.ru { max-width: 640px; margin: 0 auto; }
.ru-intro { font-size: 1rem; margin-top: -0.4rem; }
.ru-alert {
  background: color-mix(in srgb, var(--danger) 8%, var(--white)); color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 40%, var(--white));
  border-radius: var(--radius-sm); padding: 0.75rem 1rem; font-weight: 600;
}
.ru-form fieldset { border: 0; padding: 0; margin: 0 0 1.25rem; min-width: 0; }
.ru-form legend { font-weight: 700; font-size: 1.05rem; color: var(--fg); padding: 0; margin-bottom: 0.5rem; }
.ru-form fieldset[aria-invalid=true] legend { color: var(--danger); }
.ru-kinds { display: grid; gap: 0.5rem; }
.ru-kind {
  display: flex; align-items: center; gap: 0.75rem; margin: 0; min-height: 48px;
  padding: 0.7rem 0.9rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--fg); font-size: 1rem; cursor: pointer; background: var(--white);
}
.ru-kind input { width: 1.2rem; height: 1.2rem; margin: 0; accent-color: var(--accent); flex-shrink: 0; }
.ru-kind:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.ru-kind:has(input:focus-visible) { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
.ru-hint { margin: 0 0 0.75rem; }
.ru-pickers { display: grid; gap: 0.6rem; }
@media (min-width: 520px) { .ru-pickers { grid-template-columns: 1fr 1fr; } }
.ru-picker { position: relative; display: block; }
/* The real inputs stay focusable and in the accessibility tree; the label is the button. */
.ru-file-input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.ru-btn {
  display: flex; align-items: center; justify-content: center; min-height: 48px; margin: 0;
  padding: 0.7rem 1rem; border-radius: var(--radius-pill); background: var(--accent);
  color: var(--white); font-weight: 600; font-size: 1rem; cursor: pointer; text-align: center;
}
.ru-btn:hover { background: var(--accent-hover); }
.ru-btn-secondary { background: var(--white); color: var(--accent); border: 2px solid var(--accent); }
.ru-btn-secondary:hover { background: var(--accent-soft); }
.ru-file-input:focus-visible + .ru-btn { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
.ru-chosen { list-style: none; padding: 0; margin: 0.75rem 0 0; }
.ru-chosen li {
  display: flex; justify-content: space-between; align-items: center; gap: 0.75rem;
  padding: 0.5rem 0; border-bottom: 1px solid var(--gray-200); font-size: 0.95rem;
}
.ru-chosen-name { overflow-wrap: anywhere; }
.ru-remove { flex-shrink: 0; }
.ru-client-error { color: var(--danger); font-weight: 600; margin: 0.5rem 0 0; }
.ru-optional { font-weight: 400; color: var(--fg-subtle); }
.ru-form > label[for=ru-note] { font-weight: 700; font-size: 1.05rem; color: var(--fg); }
.ru-form button[type=submit] { width: 100%; min-height: 50px; font-size: 1.05rem; }
.ru-form button[type=submit]:disabled { opacity: 0.6; cursor: progress; }
.ru-sending, .ru-fine { text-align: center; margin-bottom: 0; }
.ru-past h2 { margin-top: 0; font-size: 1.15rem; }
.ru-list { list-style: none; padding: 0; margin: 0; }
.ru-list li {
  display: flex; justify-content: space-between; align-items: center; gap: 0.75rem;
  padding: 0.7rem 0; border-bottom: 1px solid var(--gray-200);
}
.ru-list li:last-child { border-bottom: 0; }
.ru-list-main { display: flex; flex-direction: column; }
.ru-status {
  flex-shrink: 0; font-size: 0.8rem; font-weight: 700; padding: 0.2rem 0.65rem;
  border-radius: var(--radius-pill); background: var(--gray-100); color: var(--gray-700);
}
.ru-status-reviewed { background: var(--accent-soft); color: var(--accent-press); }
.ru-legend { margin-bottom: 0; }
.ru-help-list { padding-left: 1.2rem; margin: 0.5rem 0; }
.ru-help-list li { margin-bottom: 0.6rem; line-height: 1.6; }
.ru-done { text-align: center; }
.ru-done-mark {
  width: 56px; height: 56px; margin: 0 auto 0.5rem; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; background: var(--accent-soft); color: var(--accent);
}
.ru-done-actions { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; }
.ru-done-actions .btn { text-decoration: none; display: inline-block; }
