/* Aangan Clinic App — shared design tokens
   Extracted from the mockup screens (overview.html, call-queue.html, etc.)
   so every route shares one source of truth instead of nine copies. */

:root {
  --bg-page:      #f4f5f7;
  --bg-sidebar:   #fbfbfa;
  --surface:      #ffffff;
  --surface-tint: #f7f8fa;
  --border:       #e4e6eb;
  --border-strong:#d5d8df;
  --text:         #1a1d24;
  --text-secondary:#5b616e;
  --text-muted:   #8b909c;

  --coral:        #d85a30;
  --coral-bg:      #faece7;
  --coral-border: #f0997b;
  --coral-text:   #993c1d;

  --teal:         #1d9e75;
  --teal-bg:       #e1f5ee;
  --teal-text:    #0f6e56;

  --blue:         #378add;
  --blue-bg:       #e6f1fb;
  --blue-text:    #185fa5;

  --amber:        #ba7517;
  --amber-bg:      #faeeda;
  --amber-text:   #854f0b;

  --gray-bg:      #f1efe8;
  --gray-text:    #5f5e5a;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Figtree', sans-serif;
  background: var(--bg-page);
  color: var(--text);
  min-height: 100vh;
}

#app { display: flex; flex-direction: column; min-height: 100vh; }
.app-row { display: flex; flex: 1; min-height: 0; }

/* ── OFFLINE / SYNC BANNER (Phase 10) ── */
.offline-banner {
  background: var(--amber-bg, #fdf3e1); color: var(--amber-text, #8a5a12);
  font-size: 12.5px; font-weight: 500; text-align: center;
  padding: 8px 16px; border-bottom: 1px solid var(--border);
}
.offline-banner.syncing { background: var(--teal-bg); color: var(--teal-text); }

/* ── SIDEBAR (shared shell) ── */
.sidebar { width: 220px; background: var(--bg-sidebar); border-right: 1px solid var(--border); padding: 24px 16px; flex-shrink: 0; display: flex; flex-direction: column; }
.brand { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.brand-mark { width: 34px; height: 34px; border-radius: 9px; background: var(--blue-bg); color: var(--blue-text); display: flex; align-items: center; justify-content: center; font-size: 17px; font-weight: 700; flex-shrink: 0; }
.brand-title { font-size: 16px; font-weight: 600; line-height: 1.2; }
.brand-sub { font-size: 11px; color: var(--text-muted); letter-spacing: 0.04em; margin: 6px 0 24px 0; }
.nav-list { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.nav-item { display: flex; align-items: center; justify-content: space-between; padding: 9px 12px; border-radius: var(--radius-sm); font-size: 13.5px; font-weight: 500; color: var(--text-secondary); cursor: pointer; transition: background 0.15s; text-decoration: none; }
.nav-item:hover { background: var(--surface-tint); }
.nav-item.active { background: var(--blue-bg); color: var(--blue-text); }
.nav-left { display: flex; align-items: center; gap: 10px; line-height: 1.25; }

/* ── ICONS (2026-07-29) — hand-drawn line set, shared/icons.js.
   stroke:currentColor is the whole point: an icon takes the colour of
   whatever it sits in, so an active nav row's icon turns blue with its
   label and a coral panel heading gets a coral icon, with no per-use
   colour rules. Replaces emoji, which the OS drew and the app could not
   style, size or recolour. ── */
.app-icon {
  fill: none; stroke: currentColor; stroke-width: 1.75;
  stroke-linecap: round; stroke-linejoin: round;
  flex-shrink: 0; vertical-align: middle;
}
/* Optical correction: small icons read thin, large ones read heavy. */
.app-icon[width="16"] { stroke-width: 1.9; }
.app-icon[width="26"], .app-icon[width="28"] { stroke-width: 1.6; }
/* A two-word label ("Reminders & Calls") wraps at the narrowed tablet
   sidebar width. Keep the icon aligned to the first line and the rows
   evenly tall so a wrapped item reads as deliberate rather than broken. */
.nav-item { min-height: 38px; }
.nav-icon { display: flex; align-items: center; flex-shrink: 0; align-self: flex-start; margin-top: 1px; }
.nav-badge { background: var(--coral); color: #fff; font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 20px; }

/* ── GLOBAL SEARCH + PATIENT CONTEXT (2026-07-29) ──
   Both live in the app shell (App.js) above <router-view>, so they are
   present on every screen rather than re-implemented per view. */
.app-topbar { display: flex; justify-content: flex-end; margin-bottom: 14px; }
.global-search { position: relative; width: 340px; max-width: 100%; }
.global-search-box {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 8px 12px; display: flex; align-items: center; gap: 8px;
}
.global-search-box:focus-within { border-color: var(--blue); }
.global-search-box input { border: none; background: none; padding: 0; font-size: 13px; width: 100%; }
.global-search-box input:focus { background: none; }
.global-search-clear { cursor: pointer; color: var(--text-muted); font-size: 12px; }
.global-search-results {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 60;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: 0 4px 16px rgba(0,0,0,0.10); max-height: 300px; overflow-y: auto;
}
.global-search-row {
  padding: 10px 14px; cursor: pointer; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.global-search-row:last-child { border-bottom: none; }
.global-search-row:hover { background: var(--surface-tint); }
/* Actions stay visible rather than hover-revealed — the reception device
   is a touchscreen, where there is no hover to reveal them with. */
.global-search-actions { display: flex; gap: 6px; flex-shrink: 0; }
.global-search-actions .btn { padding: 5px 10px; font-size: 11.5px; }
.global-search-empty { padding: 14px; font-size: 12.5px; color: var(--text-muted); text-align: center; }

.patient-context-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  background: var(--blue-bg); border: 1px solid var(--blue); border-radius: var(--radius-sm);
  padding: 10px 14px; margin-bottom: 16px;
}
.pcb-who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.pcb-avatar {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--blue-text); font-size: 11px; font-weight: 700;
}
.pcb-name { font-size: 13.5px; font-weight: 700; color: var(--blue-text); }
.pcb-meta { font-size: 11px; color: var(--blue-text); opacity: 0.75; }
.pcb-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pcb-actions .btn { padding: 6px 11px; font-size: 12px; text-decoration: none; display: inline-block; }
.pcb-clear {
  border: none; background: none; cursor: pointer; font-family: inherit;
  color: var(--blue-text); font-size: 13px; padding: 4px 6px; opacity: 0.7;
}
.pcb-clear:hover { opacity: 1; }

/* ── TODAY'S WORK (2026-07-29) — Overview's actionable worklist, which
   replaced four passive stat cards. Rows with nothing to do fade to a
   done state rather than shouting an empty count. ── */
.worklist-panel { padding: 0; overflow: hidden; margin-bottom: 20px; }
.worklist-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.worklist-row {
  display: flex; align-items: center; gap: 12px; padding: 14px 18px;
  border-bottom: 1px solid var(--border); text-decoration: none; color: inherit;
  transition: background 0.15s;
}
.worklist-row:last-child { border-bottom: none; }
.worklist-row:hover { background: var(--surface-tint); }
.worklist-row.done { opacity: 0.55; }
.worklist-row.done:hover { opacity: 0.8; }
/* Was sized by font-size when these were emoji; now an SVG with its
   own width/height, so this only needs to reserve the column. */
.worklist-icon { width: 22px; flex-shrink: 0; color: var(--text-secondary); }
.worklist-label { font-size: 13.5px; }
.worklist-label b { font-size: 16px; font-weight: 700; }
.worklist-detail { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.worklist-cta { font-size: 12.5px; font-weight: 600; color: var(--blue-text); flex-shrink: 0; }

/* Grouped nav (2026-07-29) — the main list is now several small lists
   with section labels (Today / Follow-up / Records), so each must hug
   its own items rather than stretching. .nav-spacer takes the leftover
   height instead, which is what pushes Settings to the bottom. */
.nav-list-group { flex: none; }
.nav-spacer { flex: 1; min-height: 8px; }

/* Settings section (2026-07-25 nav restructure) — sits just above
   AccountFooter, pushed to the bottom via margin-top:auto so the main
   .nav-list above it doesn't need its own flex math changed. Its own
   .nav-list is flex:none so it hugs its 1-3 items instead of stretching. */
.nav-settings-section { margin-top: auto; }
.nav-settings-section .nav-list { flex: none; }
.nav-section-label {
  font-size: 10px; font-weight: 700; color: var(--text-muted); text-transform: uppercase;
  letter-spacing: 0.06em; padding: 10px 12px 6px;
}

/* ── ACCOUNT FOOTER (Phase 10, 3-tier roles) — shared by Sidebar and
   MobileDrawer. Sidebar's flex-column + .nav-list's flex:1 pushes this
   to the bottom there; in the drawer (not a flex column) it just sits
   right after the nav list, which is fine at phone width. ── */
.account-footer { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 12px; }
.account-footer-info { margin-bottom: 8px; }
.account-footer-email { font-size: 11.5px; font-weight: 600; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-footer-role { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; margin-top: 2px; display: inline-block; padding: 1px 8px; border-radius: 20px; }
.account-footer-role.role-staff { background: var(--gray-bg); color: var(--gray-text); }
.account-footer-role.role-admin { background: var(--blue-bg); color: var(--blue-text); }
.account-footer-role.role-superuser { background: var(--teal-bg); color: var(--teal-text); }
.account-footer-logout { width: 100%; font-family: inherit; font-size: 12px; font-weight: 600; padding: 7px 10px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--surface); color: var(--text-secondary); cursor: pointer; }
.account-footer-logout:hover { background: var(--surface-tint); }
.account-footer-logout:disabled { cursor: not-allowed; opacity: 0.6; }

/* ── MAIN ── */
.main { flex: 1; padding: 24px 32px; min-width: 0; overflow-x: hidden; }

/* ── RESPONSIVE LAYOUT PRIMITIVES (Phase 10) ──
   Views use these instead of inline grid-template-columns so the
   breakpoints below can override them. Desktop value is set per-view
   via the --split-col custom property (inline style="--split-col:340px"
   etc.) so one class serves every screen's own column width. */
.split-panel { display: grid; grid-template-columns: var(--split-col, 320px) 1fr; gap: 20px; align-items: start; }
.split-panel-right { display: grid; grid-template-columns: 1fr var(--split-col, 340px); gap: 20px; align-items: start; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.info-grid { display: grid; grid-template-columns: repeat(4, auto); gap: 28px; }
.card-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }

/* ── SHARED FORM/BUTTON PRIMITIVES (used across every view) ── */
/* .topbar — restores a rule present in every original mockup's own
   <style> block (screens/*.html) but never carried into this shared
   file during the Phase 2 consolidation. OverviewView.js is the only
   view still using bare class="topbar" (everyone else inlines their
   own flex row), so this was a real, currently-live bug there: the
   title and the search/bell/avatar row were stacking vertically
   instead of sitting side by side. Found and fixed 2026-07-21 while
   making Overview responsive. */
.topbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
.topbar-title { font-size: 18px; font-weight: 600; }
.topbar-sub { font-size: 13px; color: var(--text-secondary); margin-top: 2px; }
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 20px; }
.btn { font-family: inherit; font-size: 13px; font-weight: 600; padding: 9px 16px; border-radius: var(--radius-sm); cursor: pointer; border: 1px solid var(--border); background: var(--surface); }
.btn.primary { background: var(--teal); color: #fff; border: none; }
.btn.primary:disabled { background: var(--border-strong); cursor: not-allowed; }
label.field-label { font-size: 12px; font-weight: 600; color: var(--text-secondary); display: block; margin-bottom: 6px; }
input, select, textarea {
  font-family: inherit; font-size: 13.5px; padding: 9px 12px; width: 100%;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-tint);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--blue); background: var(--surface); }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th { text-align: left; padding: 10px 18px; font-size: 10.5px; font-weight: 700; color: var(--text-muted); letter-spacing: 0.05em; text-transform: uppercase; border-bottom: 1px solid var(--border); }
tbody td { padding: 12px 18px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
.tag { font-size: 10.5px; padding: 2px 8px; border-radius: 20px; font-weight: 500; }
.tag-dept { background: var(--gray-bg); color: var(--gray-text); }

/* ── OUTREACH BOARD (2026-07-25) — merged Reminders + Call Queue ──
   Desktop/tablet: a 5-column Kanban, drag-and-drop between columns.
   Phone: a segmented control + single-column list instead (see
   OutreachView.js header comment for why — dragging a card on a
   narrow, vertically-scrolling screen doesn't work well). Both markups
   are always in the DOM; these rules pick which one shows, matching
   this app's existing CSS-driven responsive pattern (sidebar/bottom-nav,
   table→card) rather than JS-toggling. */
/* Greet calls (2026-07-26) — the 10 AM ritual, pinned above the board.
   Grid rather than the Kanban's columns: it's a flat worklist for a
   single sitting, not a pipeline with states. */
.greet-panel { margin-bottom: 16px; border-color: var(--teal); }
.greet-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); gap: 10px; }
.greet-card { padding: 14px; border-left: 3px solid var(--teal); border-radius: 0 var(--radius-md) var(--radius-md) 0; }

.outreach-mobile { display: none; }
.outreach-board { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 14px; align-items: start; }
.outreach-column { min-width: 0; }
.outreach-column-head {
  font-size: 12px; font-weight: 700; color: var(--text-secondary); text-transform: uppercase;
  letter-spacing: 0.04em; padding: 0 4px 10px; display: flex; align-items: center; gap: 6px;
}
.outreach-column-count {
  background: var(--gray-bg); color: var(--gray-text); border-radius: 20px; padding: 1px 8px;
  font-size: 10.5px; font-weight: 700; text-transform: none; letter-spacing: normal;
}
.outreach-column-empty {
  font-size: 12px; color: var(--text-muted); text-align: center; padding: 24px 8px;
  border: 1px dashed var(--border); border-radius: var(--radius-md);
}
.outreach-card { padding: 14px; margin-bottom: 10px; cursor: grab; }
.outreach-card:active { cursor: grabbing; }
.outreach-card-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.outreach-card-actions .btn { padding: 7px 10px; font-size: 12px; text-decoration: none; display: inline-block; }
.outreach-outcome-panel { border-top: 1px solid var(--border); margin-top: 14px; padding-top: 14px; }
.segmented-control {
  display: flex; gap: 4px; overflow-x: auto; padding: 4px; margin-bottom: 14px;
  background: var(--surface-tint); border-radius: var(--radius-sm); border: 1px solid var(--border);
}
.segmented-control button {
  font-family: inherit; flex-shrink: 0; border: none; background: none; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--text-secondary); padding: 8px 12px; border-radius: 7px;
}
.segmented-control button.active { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.segmented-count {
  background: var(--gray-bg); color: var(--gray-text); border-radius: 20px; padding: 0px 6px;
  font-size: 10px; font-weight: 700; margin-left: 3px;
}

/* Below the tablet breakpoint, five columns no longer fit — collapse to
   two so it stays a real board rather than a horizontal-scroll mess;
   phone (≤640px) drops the board entirely for the segmented list below. */
@media (max-width: 1023px) {
  .outreach-board { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── LOADING / AUTH ── */
.centered-screen { display: flex; align-items: center; justify-content: center; min-height: 100vh; width: 100%; }

/* ══════════════════════════════════════════════════════════════
   RESPONSIVE (Phase 10) — three tiers:
     ≥1024px  desktop  — unchanged from Phases 2-9
     641-1023px tablet — sidebar narrows but KEEPS labels (decision,
                          2026-07-21 — reception still needs always-
                          visible nav, just more compact)
     ≤640px   phone    — sidebar replaced by bottom nav + drawer;
                          tables become stacked cards; forms go
                          single-column
   A separate ≤900px step collapses two-column "list + detail" panels
   (Appointments, Billing, Staff, Checkout step 3) a little earlier
   than the phone breakpoint — those need real room for the detail
   side and don't fit next to a 300-340px list panel once the tablet
   itself drops below ~900px, even before phone-specific changes kick in.
   ══════════════════════════════════════════════════════════════ */

/* Elements that exist for phone only — hidden everywhere else by
   default so the tablet/desktop tiers never see them, regardless of
   DOM order. */
.mobile-topbar, .bottom-nav, .drawer, .drawer-scrim { display: none; }

/* ── TABLET (≤1023px): sidebar narrows, keeps labels ── */
@media (max-width: 1023px) {
  .sidebar { width: 172px; padding: 20px 12px; }
  .sidebar .brand-title { font-size: 14.5px; }
  .sidebar .nav-item { font-size: 12.5px; padding: 8px 10px; }
  .sidebar .nav-left { gap: 8px; }
  .main { padding: 20px 22px; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .info-grid { grid-template-columns: repeat(2, auto); }
}

/* ── List+detail panels stack a step before the phone breakpoint —
   see rationale in the header comment above. ── */
@media (max-width: 900px) {
  .split-panel, .split-panel-right { grid-template-columns: 1fr; }
}

/* ── PHONE (≤640px): sidebar → bottom nav + drawer, tables → cards ── */
@media (max-width: 640px) {
  .sidebar { display: none; }
  .app-row { flex-direction: column; }
  .main { padding: 14px 16px 84px; } /* bottom padding clears the fixed bottom nav */
  .form-grid { grid-template-columns: 1fr; }

  .mobile-topbar {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 16px; background: var(--surface); border-bottom: 1px solid var(--border);
  }
  .mobile-topbar .brand-mark { width: 28px; height: 28px; font-size: 13px; }
  .mobile-topbar-title { font-size: 14px; font-weight: 700; }
  .hamburger {
    display: flex; align-items: center; justify-content: center; width: 34px; height: 34px;
    border-radius: 8px; background: var(--surface-tint); border: none; font-size: 16px; cursor: pointer;
  }

  .bottom-nav {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    background: var(--surface); border-top: 1px solid var(--border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
  }
  .bn-item {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 6px 0; font-size: 10px; font-weight: 600; color: var(--text-muted);
    text-decoration: none; border: none; background: none; font-family: inherit;
    position: relative; cursor: pointer;
  }
  .bn-item.active { color: var(--teal-text); }
  /* SVG now — sized by its width/height attrs, not font-size. */
  .bn-icon { display: block; margin: 0 auto; }
  .bn-dot { position: absolute; top: 2px; right: 25%; width: 7px; height: 7px; border-radius: 50%; background: var(--coral); }

  .drawer-scrim { display: block; position: fixed; inset: 0; background: rgba(20,24,32,0.45); z-index: 48; }
  .drawer {
    display: block; position: fixed; top: 0; bottom: 0; left: 0; width: 80%; max-width: 300px;
    background: var(--bg-sidebar); z-index: 49; padding: 20px 16px; overflow-y: auto;
    box-shadow: 8px 0 24px rgba(0,0,0,0.18);
  }
  .drawer .nav-item { padding: 11px 10px; font-size: 14px; }
  .drawer-close { text-align: right; font-size: 20px; color: var(--text-muted); margin-bottom: 14px; cursor: pointer; }

  /* Data tables → stacked cards. Scoped to .panel table so it never
     touches anything outside a real data table. */
  .panel table thead { display: none; }
  .panel table, .panel table tbody, .panel table tr, .panel table td { display: block; width: 100%; }
  .panel table tr { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; margin: 10px; }
  .panel table td { border: none; padding: 3px 0; }
  .panel table td[data-label]::before {
    content: attr(data-label); display: block; font-size: 9.5px; font-weight: 700;
    color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 1px;
  }
  .panel table td.row-primary::before { content: none; }

  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .info-grid { grid-template-columns: repeat(2, auto); }
  .card-grid-2 { grid-template-columns: 1fr; }
  .topbar-right { flex-wrap: wrap; }
  .overview-search { width: 100% !important; order: 3; }
  .patient-header { flex-direction: column; gap: 16px; }
  .patient-header-actions { text-align: left !important; width: 100%; }
  .patient-header-actions > div:last-child { justify-content: flex-start !important; }

  /* Prescription photo modal: side-by-side → stacked */
  .rx-modal { flex-direction: column; max-height: 92vh; }
  .rx-modal .rx-photo { width: 100% !important; height: 200px; }

  /* Checkout stepper: numbers-only on phone, labels reappear at tablet+ */
  .step-label { display: none; }

  /* Rows of controls that are fine side-by-side on a wide screen but
     need to wrap on a phone (checkout step indicator, billing line
     items) — opt in per-row via this class rather than a blanket rule. */
  .wrap-on-phone { flex-wrap: wrap; }

  /* Outreach board (2026-07-25): segmented list replaces the Kanban board. */
  .outreach-mobile { display: block; }
  .outreach-board { display: none; }

  /* Global search goes full width on a phone; the context bar stacks so
     the four task buttons stay thumb-sized rather than shrinking. */
  .global-search { width: 100%; }
  .app-topbar { margin-bottom: 12px; }
  .patient-context-bar { flex-direction: column; align-items: stretch; }
  .pcb-actions { justify-content: space-between; }
  .pcb-actions .btn { flex: 1; text-align: center; }
}

/* ── PRINT (invoice modal) — used by Checkout step 4/5 and, later, the
   standalone Billing screen; both scope printable content to this id */
@media print {
  /* Printing is invoice-only by design (Phase 10 decision): the only
     print entry points in the UI are the invoice modals, and everything
     except #printable-invoice is hidden. If another screen ever needs
     printing, give it its own printable container id and extend this. */
  body * { visibility: hidden; }
  #printable-invoice, #printable-invoice * { visibility: visible; }
  #printable-invoice { position: fixed; top: 0; left: 0; width: 100%; box-shadow: none; }
  .no-print, .sidebar, .offline-banner, .mobile-topbar, .bottom-nav, .drawer, .drawer-scrim { display: none !important; }
  @page { margin: 12mm; }
}
