/* ==========================================================================
   KHC Message Center — mobile + polish layer (mobile.css)
   Loaded AFTER styles.css so it wins cascade ties. Phone rules live inside
   @media (max-width: 760px); the handful of desktop-visible rules at the top
   are deliberately tiny, additive polish only. Companion script: polish.js
   (More sheet, team-chat sheet toggle, progress bar — classes .mc-*).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Cross-device micro-polish (safe everywhere)
   -------------------------------------------------------------------------- */

::selection { background: color-mix(in srgb, var(--primary) 26%, transparent); }

/* Instant press feedback on every button-like control. */
@media (prefers-reduced-motion: no-preference) {
  .btn:active, .icon-btn:active, .tab:active, .mobile-nav button:active,
  .compose-ch:active, .ap-cab-tab:active, .pk-hchip:active, .pk-add:active,
  .pk-submit:active, .ghost-btn:active, .tb-btn:active, .linkbtn:active,
  .uni-card:active, .apv-row:active, .ap-inv-row:active, .rc-photobtn:active {
    transform: scale(.97);
  }
}

/* Team-chat close chip exists only for the phone sheet (polish.js injects it). */
.mc-team-close { display: none; }

/* Notched iPhones in landscape sit wider than the phone block — keep the top bar
   clear of the rounded corners (env() is 0 everywhere else, so this is a no-op). */
@media (max-width: 1100px) {
  .topbar {
    padding-left: max(var(--s3), env(safe-area-inset-left, 0px));
    padding-right: max(var(--s3), env(safe-area-inset-right, 0px));
  }
}

/* Money and counts read best with equal-width digits. */
.ap-num, .ap-sign-total, .apv-tile-v, .ap-fac-row .rval, .coin-pill,
.ap-inv-amt, .ap-vc-balance, .goal-num, .mcount, .tab .count {
  font-variant-numeric: tabular-nums;
}

/* Long toast messages: wrap instead of running off small screens. */
.toast { max-width: min(92vw, 600px); text-align: center; }

/* Slim top progress bar (created by polish.js when a tap triggers slow network). */
#mcProgress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 9998;
  background: linear-gradient(90deg, var(--primary), var(--primary-hover));
  box-shadow: 0 0 8px rgba(31,138,118,.55);
  border-radius: 0 2px 2px 0; opacity: 0; pointer-events: none;
  transition: width .25s var(--ease), opacity .3s ease;
}
#mcProgress.mc-on   { opacity: 1; width: 70%; transition: width 6s cubic-bezier(.1,.6,.2,1), opacity .15s ease; }
#mcProgress.mc-done { opacity: 0; width: 100%; transition: width .18s ease-out, opacity .45s ease .18s; }

/* Hidden switch input used only to trigger iPhone haptics (polish.js). */
.mc-haptic { position: fixed; width: 0; height: 0; overflow: hidden; opacity: 0; pointer-events: none; }

/* --------------------------------------------------------------------------
   "Install this app" invitation (built by polish.js — classes .mc-inst*)
   A calm card, not a browser-style banner: app icon, one line of why, then either
   a single Install button (Chrome/Edge/Android) or numbered Share → Add steps
   (Safari, which gives no install API). Sits above the update nudge (z 400) and
   well below every modal layer (3300+), so nothing it can cover is interactive.
   -------------------------------------------------------------------------- */
.mc-inst {
  position: fixed; right: 16px; bottom: 16px; width: min(380px, calc(100vw - 32px));
  z-index: 500; background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); padding: 16px 18px 14px;
  display: flex; flex-direction: column; gap: 12px;
  opacity: 0; transform: translateY(10px);
  transition: opacity .22s ease, transform .22s var(--ease);
}
.mc-inst.mc-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .mc-inst { transition: none; } }

.mc-inst-x {
  position: absolute; top: 8px; right: 8px; width: 30px; height: 30px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: none; color: var(--muted); cursor: pointer; border-radius: var(--r-full);
}
.mc-inst-x:hover { background: var(--surface-3); color: var(--ink); }
.mc-inst-x svg { width: 16px; height: 16px; }

.mc-inst-head { display: flex; gap: 12px; align-items: flex-start; padding-right: 26px; }
.mc-inst-logo { width: 44px; height: 44px; border-radius: 11px; flex: 0 0 auto; box-shadow: var(--sh-1); }
.mc-inst-copy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.mc-inst-copy strong { font-size: var(--t-base); font-weight: 700; line-height: 1.3; }
.mc-inst-copy span { font-size: var(--t-sm); color: var(--muted); line-height: 1.45; }

.mc-inst-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.mc-inst-steps li { display: flex; gap: 10px; align-items: center; font-size: var(--t-sm); color: var(--ink-soft); }
.mc-inst-num {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: var(--r-full);
  background: var(--primary-soft); color: var(--primary-ink);
  font-size: var(--t-xs); font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center;
}
.mc-inst-txt { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mc-inst-ic { display: inline-flex; align-items: center; color: var(--primary); }
.mc-inst-ic svg { width: 17px; height: 17px; }
.mc-inst-note { margin: 0; font-size: var(--t-sm); color: var(--muted); line-height: 1.45; }

.mc-inst-actions { display: flex; gap: 8px; align-items: center; justify-content: flex-end; }
.mc-inst-go {
  display: inline-flex; align-items: center; gap: 8px; border: 0; cursor: pointer; font-family: inherit;
  background: var(--primary); color: var(--on-primary); border-radius: var(--r-full);
  padding: 10px 20px; font-weight: 700; font-size: var(--t-sm);
}
.mc-inst-go:hover { background: var(--primary-hover); }
.mc-inst-go svg { width: 16px; height: 16px; }
.mc-inst-later {
  border: 0; background: none; cursor: pointer; font-family: inherit; color: var(--muted);
  font-weight: 600; font-size: var(--t-sm); padding: 10px 12px; border-radius: var(--r-full);
}
.mc-inst-later:hover { background: var(--surface-3); color: var(--ink); }

/* The same invitation as a permanent row INSIDE the rounding kiosk — providers have no
   topbar button and no More sheet, so this is their only standing doorway. Inline and calm:
   it scrolls with the capture form rather than floating over it, and it borrows .pk-logout's
   pill so it reads as part of the kiosk, not as a web banner. */
.mc-inst-pk {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 18px 0 0; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.mc-inst-pk-logo { width: 36px; height: 36px; border-radius: 9px; flex: 0 0 auto; box-shadow: var(--sh-1); }
.mc-inst-pk-copy { display: flex; flex-direction: column; gap: 2px; flex: 1 1 190px; min-width: 0; }
.mc-inst-pk-copy strong { font-size: var(--t-sm); font-weight: 700; color: var(--ink); line-height: 1.3; }
.mc-inst-pk-copy span { font-size: var(--t-xs); color: var(--muted); line-height: 1.45; }
.mc-inst-pk-go {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px;                    /* full thumb target — this is a phone screen */
  border: 1px solid var(--line-strong); background: var(--surface-2); color: var(--ink-soft);
  border-radius: var(--r-full); padding: 8px 16px;
  font-size: var(--t-sm); font-weight: 600; cursor: pointer;
}
.mc-inst-pk-go:hover { background: var(--surface-3); color: var(--ink); }
.mc-inst-pk-go svg { width: 16px; height: 16px; }
/* The card repeats this row's headline, so the row recedes while the card is open.
   Opacity only — removing it would shift the form under the reader's thumb. */
body.mc-inst-open .mc-inst-pk { opacity: 0; pointer-events: none; }
.mc-inst-pk { transition: opacity .18s ease; }
@media (prefers-reduced-motion: reduce) { .mc-inst-pk { transition: none; } }


/* --------------------------------------------------------------------------
   2. The phone layer
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {

  /* ---- 2a. Shell: notch-safe topbar, roomier controls ---- */
  .topbar { padding-top: calc(var(--s2) + env(safe-area-inset-top, 0px)); flex-wrap: nowrap; }
  /* The bar must fit one line: brand + Tutorial go icon-only (font-size:0 hides
     their text nodes; the svg keeps its own size) so mute/sign-out stay on screen. */
  .topbar .brand { font-size: 0; gap: 0; flex: 0 0 auto; }
  .topbar .brand svg { width: 22px; height: 22px; }
  #tutorialBtn { font-size: 0; gap: 0; }
  #tutorialBtn svg { width: 16px; height: 16px; }
  #roleBadge { flex: 0 0 auto; }
  .topbar .icon-btn { flex: 0 0 auto; width: 40px; height: 40px; }
  .icon-btn { width: 42px; height: 42px; }
  .btn { min-height: 44px; }
  .btn.btn-sm { min-height: 36px; }

  /* ---- 2a-fix. Stop the whole shell from being dragged wider than the screen ----
     .app is a single-column grid (grid-template-rows: auto 1fr; no columns), so its
     implicit column sizes to `auto` = its widest child's min-content. On a phone the
     topbar's min-content ran to ~570px (the nowrap "by Credence…" brand-owner line +
     every icon button), which forced the app column to 570px. That width then cascaded
     into .body → .rail-center → .list, stretching the .msg grid's 1fr column so every
     row overflowed and got clipped by html/body{overflow-x:hidden}. Everything looked
     "cut off on the right" on every screen for this one reason.
     (a) Cap the app column at the viewport so no wide child can ever expand the shell. */
  .app { grid-template-columns: minmax(0, 1fr); }
  /* (b) The ownership subtitle carries its own explicit font-size, so the existing
     `.brand { font-size: 0 }` (icon-only brand on phones) could not hide it. Drop it on
     phones — it stays on login, the desktop bar, meta tags, PWA + University footers. */
  .brand-owner { display: none; }

  /* Inputs at 16px so iPhones stop zooming in on focus. */
  input, select, textarea, .field-input, .compose-editor { font-size: 16px !important; }

  /* Checkboxes big enough for thumbs. */
  input[type="checkbox"] { width: 20px; height: 20px; }

  /* ---- 2b. Bottom nav: 6 items fit (polish.js adds "More") ---- */
  .mobile-nav button { min-width: 0; }
  .mobile-nav button.mc-more.has-dot::after {
    content: ''; position: absolute; top: 3px; right: 26%; width: 8px; height: 8px;
    border-radius: 50%; background: var(--danger);
  }
  /* Reader open = full-screen page; the nav underneath would only steal reply space. */
  body:has(.detail.open) .mobile-nav, body.mc-team-open .mobile-nav { display: none; }

  /* ---- 2c. Reading pane ---- */
  .detail-actions { padding-bottom: calc(var(--s4) + env(safe-area-inset-bottom, 0px)); }
  .email-frame { max-width: 100% !important; }

  /* List header: deterministic rows — title, then a full-width swipeable
     Active/Sent/Drafts strip, then the action buttons, then search. */
  .list-head { flex-wrap: wrap; row-gap: 6px; }
  .list-head h2 { flex: 1 1 100%; min-width: 0; }
  .mode-toggle {
    order: 3; flex: 1 1 100%; min-width: 0;
    overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none;
  }
  .mode-toggle::-webkit-scrollbar { display: none; }
  .mode-toggle button { flex: 0 0 auto; white-space: nowrap; }
  #composeBtn { order: 4; }
  #selectModeBtn { order: 5; }
  #overdueToggle { order: 6; flex: 0 0 auto; }
  .ap-tour-chip { order: 7; }
  #boxSearch { min-width: 0 !important; width: 100%; order: 9; margin-left: 0 !important; }
  /* Category / tag filter: a bigger, HORIZONTAL-only scroll strip that stays put. Swipe
     left/right through the tags. Three things make it behave:
       • flex:0 0 auto — a scroll container's min-height collapses to 0, so the parent flex
         column was crushing this strip to a clipped sliver; pin its size instead.
       • touch-action:pan-x — a downward finger pans nothing here, so the strip never gets
         dragged out of view while you swipe the tags.
       • position:sticky — if a view ever scrolls its header, the tag bar pins and stays. */
  .cat-filter {
    flex: 0 0 auto; flex-wrap: nowrap; white-space: nowrap;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    touch-action: pan-x; overscroll-behavior-x: contain; scrollbar-width: none;
    gap: 8px; padding: 11px 12px;
    position: sticky; top: 0; z-index: 6; background: var(--surface);
  }
  .cat-filter::-webkit-scrollbar { display: none; }
  .cat-filter button { flex: 0 0 auto; min-height: 42px; padding: 10px 16px; }
  .bulk-bar, .completed-tools { flex-wrap: wrap; row-gap: 6px; }

  /* Message rows: long subjects clamp to two lines instead of five-line towers. */
  .msg .who {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .msg .prev {
    white-space: normal;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .ct-pop { position: fixed; left: 8px; right: 8px; top: auto; bottom: calc(88px + env(safe-area-inset-bottom, 0px)); width: auto; max-height: 46dvh; overflow: auto; }

  /* ---- 2d. Modals become bottom sheets ---- */
  .modal-overlay { align-items: flex-end; padding: 0; }
  .modal-overlay .modal {
    width: 100% !important; max-width: 100% !important;
    border-radius: var(--r-lg) var(--r-lg) 0 0; max-height: 92dvh;
  }
  .modal-overlay .modal .modal-body { max-height: calc(92dvh - 64px); }
  .compose-channels { grid-template-columns: 1fr; }
  .composer-row { flex-wrap: wrap; }
  .compose-toolbar { flex-wrap: wrap; }
  .tb-btn { width: 40px; height: 40px; }
  .suggest-pop { max-height: 38dvh; overflow: auto; }

  /* Chooser cards (vendor panels, prompts, pickers): full-width sheets with a
     visible scrim (the desktop click-through-beside-PDF idea has no meaning here). */
  .chooser-overlay { align-items: flex-end !important; padding: 0 !important; }
  .chooser-overlay .chooser-card {
    width: 100% !important; max-width: 100% !important; margin: 0 !important;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    max-height: 92dvh; overflow: auto;
    padding-bottom: calc(var(--s4) + env(safe-area-inset-bottom, 0px));
  }
  .chooser-overlay.docked-panel { background: rgba(15, 30, 25, .38) !important; pointer-events: auto !important; }
  .ap-grid2 { grid-template-columns: 1fr !important; }

  /* Attachment / document preview: use the whole screen. */
  .att-card { width: 100vw !important; height: 100dvh !important; max-height: 100dvh !important; border-radius: 0; }

  /* ---- 2e. Floating drawers: full sheets (beat any stale inline width) ---- */
  .ap-bill-drawer, .ecw-chart-drawer {
    width: 100% !important; max-width: 100% !important; left: 0 !important; right: 0 !important;
    top: calc(var(--topbar-h, 56px)) !important; bottom: 0 !important; border-radius: 0;
  }

  /* ---- 2f. AP invoice workspace / Create Bill ---- */
  /* Un-squish the WHOLE AP inbox on phones (reader AND build form). The desktop rule
     `.body:has(.ap-inbox-layout){grid-template-columns:232px 1fr}` (specificity 0,2,0)
     out-weighs the plain mobile `.body{grid-template-columns:1fr}` (0,1,0), so the entire
     workspace was being dumped into a ~232px column with the right half of the screen left
     blank — form fields at half width, etc. Match specificity + load-after to force full width. */
  .body:has(.ap-inbox-layout) { grid-template-columns: 1fr; }

  /* ⚠ THE SAME TRAP, LATENT IN DIALYSIS COMPLIANCE. styles.css:330
     `.body:has(#list .wtr-wrap){grid-template-columns:256px 1fr}` carries an id, so its
     specificity is (1,1,0) — it out-weighs the plain mobile `.body{grid-template-columns:1fr}`
     at (0,1,0) exactly as the AP rule above did, reserving a 256px column on a phone. It went
     unnoticed because there was not one wtr- rule in this file. Raised to (1,1,0) to match. */
  .body:has(#list .wtr-wrap) { grid-template-columns: 1fr; }

  /* The five-section strip: let it wrap rather than scroll off-screen. "Emergency Crash Cart
     Audit" alone is wide, and Audit Alerts — the only tab carrying a number — sits last, so a
     hidden horizontal scroll would put the one thing worth seeing off the edge with no cue. */
  .wtr-tabs { gap: var(--s3); }
  .wtr-tab { font-size: 12px; padding: var(--s2) 2px; }
  .wtr-wrap { padding: var(--s3); gap: var(--s4); }

  /* Building mode: kill the 14px hover-sliver list trap — the Back button is the way out. */
  .ap-inbox-layout.building .ap-inbox-list { display: none !important; }

  /* Create Bill on a phone = a clean SPLIT: the form scrolls up top (full-width, labelled
     fields), and the invoice PDF is PINNED at the bottom of the screen as a live reference you
     read while you type — the PDF is the hovering element, NOT the Save/Send bar (owner ask).
     Save draft / Send sit inline at the end of the form. Full-screen mode (.ap-fs) untouched. */
  .ap-inbox-layout.building { height: 100%; }
  .ap-inbox-layout.building .ap-inbox-main {
    display: flex; flex-direction: column; height: 100%; min-height: 0;
  }
  .ap-inbox-viewer.building {
    display: flex !important; flex-direction: column; width: auto !important;
    flex: 1; min-height: 0; overflow: hidden;
  }
  .ap-inbox-viewer.building .ap-inbox-form {
    order: -1; width: auto !important; flex: 1 1 auto; min-height: 160px; max-height: none;
    overflow: auto; -webkit-overflow-scrolling: touch; border: 0; padding-bottom: 12px;
  }
  /* flex 0 1 (not 0 0): the pinned PDF may SHRINK below 40vh when the header bar runs tall
     (long subject → wrapped title), instead of starving the form into a sliver. min-height
     keeps a readable reference strip; the form's min-height above guarantees typing room. */
  .ap-inbox-viewer.building .ap-inbox-pdf {
    flex: 0 1 40vh !important; height: 40vh !important; min-height: 132px;
    overflow: hidden !important; border-top: 1px solid var(--line-strong);
  }
  /* The pinned PDF scrolls inside its own 40vh (override the reader's flow rules for build). */
  .ap-inbox-viewer.building .ap-inbox-pdf .ap-hl-scroll {
    height: 100% !important; overflow: auto !important; touch-action: auto;
  }
  /* Full-screen button rides over the PDF (bottom-left), not the form above it. */
  .ap-inbox-viewer.building .ap-fs-btn { top: auto; bottom: 12px; left: 12px; }
  .ap-form-resize { display: none !important; }

  /* While the bill form is open, the header bar must not eat the screen: the title drops to
     one ellipsized line and only the buttons that matter MID-ENTRY stay (Back to invoices,
     ‹ Prev / Next › and its position label). Reply / Forward / Not-a-bill / Resolve / Create
     all return the moment you tap Back — nothing is lost, the form's own Save / Send are the
     real actions here. Without this, a long email subject wrapped the title to 3 lines, the
     wrapped 44px buttons stacked 4 rows deep, and the pinned PDF squeezed the form to a
     ~38px sliver (the "all the mobile invoice work is gone" report, 2026-07-31). */
  .ap-inbox-main:has(.ap-inbox-viewer.building) .ap-inbox-barvendor {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--t-sm);
  }
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apReplyDoc,
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apFwdDoc,
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apNotBill,
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apResolve,
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apInboxCreate,
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apCombineBtn,
  .ap-inbox-main:has(.ap-inbox-viewer.building) #apSeparateBtn { display: none !important; }

  /* The bill form is a grid on desktop; block flow restores single-column reading. */
  .ap-form { display: block !important; }
  .ap-form > * + * { margin-top: 10px; }
  /* Save draft / Send: a clean two-button row at the END of the form (not a hovering bar —
     the PDF is what hovers at the bottom now). */
  .ap-form-actions { display: flex; gap: 8px; align-items: stretch; }
  .ap-form-actions .btn { min-height: 48px; flex: 1 1 0; width: auto; margin: 0; }
  .ap-form-actions .btn-primary { flex: 1.7 1 0; }

  /* Expense lines: each field gets a LABEL above it. The desktop column header (.ap-lines-head)
     is hidden on phones, so bare dropdowns/inputs read as a confusing stack of unlabelled boxes.
     app.js wraps each field in .ap-lcell (a <label> with a .ap-lcell-lbl caption); on desktop
     .ap-lcell is display:contents so the grid is unchanged and the caption is hidden — here the
     cell becomes a label-over-field column. */
  .ap-lines-head { display: none !important; }
  .ap-form .ap-line { display: flex !important; flex-wrap: wrap; gap: 8px; align-items: end; }
  .ap-form .ap-line .ap-lcell { display: flex; flex-direction: column; gap: 3px; }
  .ap-form .ap-line .ap-lcell-lbl { display: block; font-size: 12px; font-weight: 600; color: var(--muted); }
  .ap-form .ap-line .ap-lcell:has(.ap-l-class) { flex: 1 1 46%; }
  .ap-form .ap-line .ap-lcell:has(.ap-acc-combo) { flex: 1 1 100%; }
  .ap-form .ap-line .ap-lcell:has(.ap-l-amt) { flex: 1 1 42%; }
  .ap-form .ap-line .ap-lcell:has(.ap-l-desc) { flex: 1 1 100%; }
  .ap-form .ap-line .ap-lcell:has(.ap-l-kind) { flex: 1 1 55%; }
  .ap-form .ap-line .ap-l-del { flex: 0 0 auto; align-self: end; margin-bottom: 2px; }
  /* Payment-plan rows keep their existing bare (bank + amount) layout. */
  .ap-form .ap-line.ap-payrow .ap-p-bank { flex: 1 1 100%; }
  .ap-form .ap-line.ap-payrow .ap-p-amt { flex: 1 1 60%; }

  /* Vendor + account pickers: fixed sheets so the phone keyboard can't swallow
     them. polish.js sets --mc-pick-top just under the focused field. */
  .ap-vendor-dd, .ap-acc-pop {
    position: fixed !important; left: 8px !important; right: 8px !important;
    top: var(--mc-pick-top, calc(env(safe-area-inset-top, 0px) + 60px)) !important;
    bottom: auto !important;
    width: auto !important; max-height: 38dvh !important; overflow: auto; z-index: 3300 !important;
    box-shadow: var(--sh-3);
  }
  .ap-vendor-dd[hidden], .ap-acc-pop[hidden] { display: none !important; }
  .ap-vend-row, .ap-acc-row { min-height: 44px; }

  /* Bar actions wrap into two clean rows instead of one crushed line. */
  .ap-inbox-bar, #apInboxBarActions { flex-wrap: wrap; row-gap: 6px; }

  /* ---- 2f-mobile. Invoice reader (the "Create Bill" screen) on phones ----
     The reader stacks list-over-viewer, but the whole thing was pinned to the viewport
     with the PDF trapped in a ~60vh inner-scroll box mostly below the fold — the classic
     "I can only see the top of the invoice, can't reach the rest." Let the reader scroll
     as ONE natural page so the entire PDF is reachable inline (Page 1 → 2 → 3 just keep
     going), and give the action buttons phone-sized targets + a little more type.
     Full-screen mode (.ap-fs) and the Create-Bill BUILD form (.building) are left exactly
     as they were — only the plain reader/preview changes. */
  .rail-center:has(.ap-inbox-layout) .list { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .ap-inbox-layout:not(.building) { height: auto; }
  .ap-inbox-viewer:not(.building) { overflow: visible; }
  .ap-inbox-pdf:not(.ap-fs) { height: auto; min-height: 46vh; overflow: visible; }
  .ap-inbox-pdf.hl-mode:not(.ap-fs) { overflow: visible; }
  /* Let the PDF.js page stack flow into the page scroll (pan-y = native vertical scroll,
     not the desktop drag-to-pan). Scoped away from .ap-fs so full screen keeps its own scroll. */
  .ap-inbox-pdf:not(.ap-fs) .ap-hl-scroll { height: auto; overflow: visible; cursor: auto; touch-action: pan-y; }
  .ap-inbox-pdf:not(.ap-fs) .ap-hl-pages { width: 100%; align-items: center; }

  /* Roomier, more readable action bar (bigger tap targets + slightly larger labels). */
  .ap-inbox-bar { padding: 10px 12px; }
  .ap-inbox-barvendor { font-size: var(--t-md); font-weight: 700; white-space: normal; }
  #apInboxBarActions { gap: 8px; }
  #apInboxBarActions .btn { font-size: var(--t-sm); min-height: 44px; padding: 9px 14px; }
  .ap-nav .btn { min-height: 44px; }

  /* Desk-only actions a phone doesn't need: Download (save a PDF to the phone) and Upload
     (scan a mailed invoice from a computer). Hide them so the phone bar stays focused. */
  #apDlDoc, #apInboxUpload { display: none !important; }

  /* Tables (Sign queue, Bills, vendor history): pan smoothly, comfy rows. */
  #abList { overflow-x: auto; }
  .ap-table td, .ap-table th { padding-top: 10px; padding-bottom: 10px; }
  .ap-queue-tablewrap, .apv-tablewrap, .rm-scroll, .rounds-scroll, #abList { -webkit-overflow-scrolling: touch; }

  /* ---- 2g. Sign screen: amount + Sign button first, document below ---- */
  .ap-sign-wrap { display: flex !important; flex-direction: column; }
  .ap-sign-right { order: -1; position: static !important; }
  .ap-sign-left { min-height: 0; }
  .ap-sign-frame { height: 58dvh !important; min-height: 300px !important; }
  .ap-sign-wrap #apInboxViewer { height: 58dvh !important; }
  .ap-sign-right .action-row .btn { flex: 1 1 auto; min-height: 48px; }

  /* Vendor payment history: three money columns cannot share a phone's width — squeezed to fit, the
     "how it was paid" line broke into five words-per-line fragments. So each past invoice becomes a
     small block instead: date and amount on the top line (the two things scanned down the list),
     invoice number and how it was paid across the full width underneath. */
  .ap-hist-table tr { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
    padding: 8px 0; border-bottom: 1px solid var(--line); }
  .ap-hist-table td { padding: 0 !important; border-bottom: 0; }
  /* width:1% is the desktop shrink-to-fit trick; inside this grid it collapses the cell to its
     narrowest word, which broke "Accu Lab LLC" onto three lines. Undone at the SAME selector
     specificity as the desktop rule — a plain `td { width: auto }` loses to `td:first-child`. */
  .ap-hist-table td:first-child { grid-column: 1; grid-row: 1; width: auto; }
  .ap-hist-table td:last-child { grid-column: 2; grid-row: 1; width: auto; text-align: right; font-weight: 700; }
  .ap-hist-table td:nth-child(2) { grid-column: 1 / -1; grid-row: 2; }
  .ap-hist-tiles { grid-template-columns: 1fr 1fr; }

  /* The Bill.com archive gets the same treatment for the same reason: seven columns on a 390px
     screen pushed the amount, the status and the View button off the right-hand edge — i.e. the
     three things somebody opening an old invoice is actually after. Each row becomes a block. */
  .ap-arc-wrap { overflow-x: visible; }
  .ap-arc-table thead { display: none; }
  .ap-arc-table tr { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
    padding: 10px var(--s3); border-bottom: 1px solid var(--line); }
  .ap-arc-table td { padding: 0 !important; border-bottom: 0; }
  .ap-arc-table td:nth-child(1) { grid-column: 1; grid-row: 1; color: var(--muted); }        /* date */
  .ap-arc-table td:nth-child(5) { grid-column: 2; grid-row: 1; text-align: right; font-weight: 700; } /* amount */
  .ap-arc-table td:nth-child(2) { grid-column: 1 / -1; grid-row: 2; font-weight: 600; }      /* vendor */
  .ap-arc-table td:nth-child(3) { grid-column: 1 / -1; grid-row: 3; }                        /* invoice # */
  .ap-arc-table td:nth-child(4) { grid-column: 1; grid-row: 4; color: var(--muted); }        /* company */
  .ap-arc-table td:nth-child(6) { grid-column: 2; grid-row: 4; text-align: right; }          /* status */
  .ap-arc-table td:nth-child(7) { grid-column: 1 / -1; grid-row: 5; margin-top: 4px; }       /* the file */

  /* ---- 2h. Hospital rounds worklist: pin identity columns, thumb-size inputs ---- */
  .rounds-table th:nth-child(1), .rounds-table td:nth-child(1) {
    position: sticky; left: 0; z-index: 3; background: var(--surface);
    width: 52px; min-width: 52px; max-width: 52px;
    overflow: hidden; text-overflow: ellipsis;
  }
  .rounds-table th:nth-child(2), .rounds-table td:nth-child(2) {
    position: sticky; left: 52px; z-index: 3; background: var(--surface);
    width: 60px; min-width: 60px; max-width: 60px;
    box-shadow: 6px 0 8px -6px rgba(15, 30, 25, .25);
  }
  .rounds-table th:nth-child(1), .rounds-table th:nth-child(2) { z-index: 4; background: var(--surface-3); }
  .rc-in { min-width: 120px; padding: 8px 9px; }
  .rc-phactions a, .rc-phactions button { min-width: 36px; min-height: 36px; }
  /* Phone cell only: the enlarged call/text buttons overlay the input's right
     edge (~78px). Reserve that lane + a little width so the number is never
     hidden behind the icons. Scoped by :has(.rc-phactions) → phone column only. */
  .rc-cell:has(.rc-phactions) .rc-in { min-width: 210px; padding-right: 84px; }
  /* Patient directory (2026-09-08): a THIRD icon — "who is this?" (.pp-trig) — sits beside Call/Text
     while the account is still blank, so that lane needs room for three 36px icons + gaps (≥ 108px);
     and the account cell carries the lone directory icon in its own .rc-phactions, which must NOT
     inherit the phone cell's 210px lane — one icon, one narrow lane. */
  .rc-cell:has(.rc-phactions .pp-trig[data-phone]) .rc-in { padding-right: 122px; }
  .rc-cell:has(.rc-phactions > .pp-trig[data-acct]:only-child) .rc-in { min-width: 120px; padding-right: 44px; }
  .rc-lightbox .rc-lb-inner { width: 96vw; max-height: 92dvh; overflow: auto; }
  .rc-lb-canvas { max-width: 100%; height: auto; }
  .rc-pickbox { min-width: 0 !important; width: 92vw; }

  /* Provider kiosk niceties (already phone-first). */
  .pk-top { padding-top: calc(8px + env(safe-area-inset-top, 0px)); }
  .pk-del { width: 32px; height: 32px; }
  .pk-submit { min-height: 52px; }
  .pk-wrap { padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }

  /* ---- 2i. Team chat on phones: full-screen sheet via body.mc-team-open ----
     :not(.hidden) keeps a logout (which re-hides the dock) from leaving a dead
     panel over the login form. */
  body.mc-team-open .team-dock:not(.hidden) {
    display: flex !important; flex-direction: column;
    position: fixed; left: 0 !important; right: 0 !important;
    top: 0 !important; bottom: 0 !important; width: 100% !important; max-width: 100% !important;
    border-radius: 0; z-index: 3400; padding-top: env(safe-area-inset-top, 0px);
  }
  body.mc-team-open .mc-team-close { display: inline-flex; }
  body.mc-team-open .team-body { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: auto; }
  body.mc-team-open #teamChat { display: flex; flex-direction: column; flex: 1; min-height: 0; }
  body.mc-team-open .team-chat-msgs { flex: 1; min-height: 0; overflow-y: auto; }
  body.mc-team-open .team-chat-input { padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
  .mc-team-close { margin-left: 6px; }
  /* Video/call panels sized for a phone. */
  .video-panel, .share-panel { width: 100vw !important; max-width: 100vw !important; left: 0; right: 0; }
  .vc-local { width: 28vw; }

  /* ---- 2j. polish.js "More" sheet ---- */
  .mc-scrim {
    position: fixed; inset: 0; z-index: 3480; background: rgba(15, 30, 25, .42);
    opacity: 0; transition: opacity .18s ease;
  }
  .mc-scrim.mc-in { opacity: 1; }
  .mc-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 3490;
    background: var(--surface); border-top: 1px solid var(--line);
    border-radius: var(--r-lg) var(--r-lg) 0 0; box-shadow: var(--sh-3);
    max-height: 78dvh; overflow: auto;
    padding: 6px 10px calc(12px + env(safe-area-inset-bottom, 0px));
    transform: translateY(14px); opacity: 0; transition: transform .2s var(--ease), opacity .2s ease;
  }
  .mc-sheet.mc-in { transform: translateY(0); opacity: 1; }
  .mc-sheet-grab { width: 40px; height: 4px; border-radius: 4px; background: var(--line-strong); margin: 4px auto 10px; }
  .mc-sheet .tab {
    display: flex; width: 100%; min-height: 48px; align-items: center;
    font-size: var(--t-md);
  }
  .mc-sheet-row {
    display: flex; width: 100%; min-height: 48px; align-items: center; gap: 10px;
    padding: 6px 10px; border-radius: var(--r-md); color: var(--ink); font-weight: 600;
    font-size: var(--t-md); background: none; border: 0; text-align: left;
  }
  .mc-sheet-row:active { background: var(--primary-soft); }
  .mc-sheet-row svg { width: 20px; height: 20px; color: var(--muted); }
  .mc-sheet-sep { height: 1px; background: var(--line); margin: 8px 2px; }

  /* ---- 2k. Fixed bits that collided with the bottom nav ---- */
  .update-nudge { bottom: calc(86px + env(safe-area-inset-bottom, 0px)); }
  .reconn-pill { bottom: calc(86px + env(safe-area-inset-bottom, 0px)); }
  /* Install card sits above the nav, full width. Its topbar twin is desktop-only —
     the phone bar has no room, so the More sheet carries "Install app" instead. */
  .mc-inst { left: 12px; right: 12px; width: auto; bottom: calc(86px + env(safe-area-inset-bottom, 0px)); }
  .mc-inst-btn { display: none !important; }
  .mc-sheet .tab .tab-caret { display: none; }

  /* ---- 2l. Admin & wide tables: contained horizontal panning ---- */
  .admin-table { display: block; overflow-x: auto; white-space: nowrap; }
  .pulse-grid { grid-template-columns: 1fr 1fr; }
  .uni-frame { height: calc(100dvh - 210px); }
  .ap-cmp-pane { min-height: 36dvh; }
}

/* --------------------------------------------------------------------------
   3. Installed-app (home screen) mode
   -------------------------------------------------------------------------- */
@media (display-mode: standalone) {
  .topbar { padding-top: calc(var(--s2) + env(safe-area-inset-top, 0px)); }
  /* Already installed — never offer to install again (belt and braces: polish.js
     also checks this, but a stale flag or an odd browser can't get past CSS). */
  .mc-inst, .mc-inst-btn, .mc-inst-pk { display: none !important; }
}

/* --------------------------------------------------------------------------
   4. Documents (scanned mail) — phone layer. Appended by the Documents
   feature: the queue table becomes cards, the inline viewer becomes a
   full-screen sheet with a Back button, and every control is thumb-sized.
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {
  .docs-head { flex-direction: column; align-items: stretch; }
  .docs-tools { flex-wrap: wrap; }
  .docs-search { flex: 1 1 100%; min-width: 0; }
  .docs-summary { grid-template-columns: 1fr 1fr; }
  .docs-tools .ghost-btn, .docs-chip, .docs-act, .docs-pill, .docs-dtile { min-height: 44px; }
  /* Bare ghost-btns/linkbtns the blanket rule above misses — all of them thumb targets here. */
  .docs-page-nav .ghost-btn, .docs-more, .docs-hint, .docs-mine-row .linkbtn, #docsUpSwap { min-height: 44px; }
  /* The filter row lives in the thead, which the card layout hides — a Filters button that
     visibly does nothing is worse than none. openDocs() also forces filtersOn off on phones. */
  #docsFilters { display: none; }

  /* The table reflows into cards (the .ap-arc-table recipe): type + date up top, sender and
     summary across the full width, pages and status on the bottom line. */
  .docs-table thead { display: none; }
  .docs-table tr.docs-row { display: grid; grid-template-columns: auto 1fr auto; gap: 2px 10px; padding: 10px var(--s3); border-bottom: 1px solid var(--line); }
  .docs-table tr.docs-row td { padding: 0 !important; border-bottom: 0; background: none !important; }
  .docs-ck { grid-column: 1; grid-row: 1 / span 2; align-self: start; width: auto; }
  .docs-table tr.docs-row td.docs-ck { padding: 4px 8px 4px 0 !important; }
  .docs-ck input { width: 24px; height: 24px; }
  .docs-type { grid-column: 2; grid-row: 1; }
  .docs-when { grid-column: 3; grid-row: 1; text-align: right; }
  .docs-from { grid-column: 2 / -1; grid-row: 2; }
  .docs-summ { grid-column: 2 / -1; grid-row: 3; }
  .docs-pg { grid-column: 2; grid-row: 4; }
  .docs-stcell { grid-column: 3; grid-row: 4; text-align: right; }
  .docs-asg { grid-column: 2 / -1; grid-row: 5; color: var(--muted); }
  tr.docs-row.is-open { background: var(--primary-softer); }

  /* The inline viewer takes the whole screen — pages squeezed beside a card help nobody. The
     Back button (hidden on desktop) is the way out. */
  tr.docs-inline { display: block; }
  tr.docs-inline > td { display: block; padding: 0; border: 0; }
  /* Below the dialog tier ON PURPOSE: chooser-overlay (3000) and the page reader (3100) must
     paint OVER this sheet — at 3200 it buried every dialog it launched. 2900 still covers the
     bottom nav (45) and everything else on the page. */
  .docs-inline-box { position: fixed; inset: 0; z-index: 2900; background: var(--bg); overflow-y: auto;
    padding: calc(env(safe-area-inset-top, 0px) + 12px) 14px calc(env(safe-area-inset-bottom, 0px) + 24px); }
  .docs-back { display: inline-flex; flex-basis: 100%; justify-content: flex-start; }
  .docs-thumbs { max-height: none; overflow-y: visible; justify-content: center; }
  .docs-thumb { width: min(46vw, 170px); }
  .docs-cut { min-width: 44px; }

  /* Bulk bar floats above the bottom nav. */
  .docs-bulkbar { position: fixed; left: 10px; right: 10px; bottom: calc(86px + env(safe-area-inset-bottom, 0px));
    border: 1px solid var(--line-strong); border-radius: var(--r-lg); z-index: 60; }

  /* Upload screen: two-up department tiles, full-width page reader. */
  .docs-upload-wrap { padding: 12px 12px 96px; }
  .docs-dept-grid, .docs-dept-grid-sm { grid-template-columns: 1fr 1fr; }
  .docs-page-card { max-width: 100vw; max-height: 100dvh; }
  .docs-mine-row { flex-wrap: wrap; }
}

/* ---- Bill conversation on a phone (2026-09-05) ---------------------------------------------
   The thread sits above the Sign / Reject row (section 2g already puts the facts panel first). No
   inner scroll box here — the messages flow with the page — and the composer gets phone-sized
   targets. 16px in the box is deliberate: iOS zooms the page into any smaller input when tapped. */
@media (max-width: 760px) {
  .apt { padding: var(--s3); }
  .apt-list { max-height: none; overflow: visible; }
  .apt-msg { max-width: 92%; }
  .apt-input { font-size: 16px; min-height: 48px; }
  .apt-send { min-height: 48px; padding-left: 14px; padding-right: 14px; }
  .apt-q { font-size: var(--t-sm); padding: 9px 12px; }
  .apt-priv { width: 100%; }
  .apt-toast { max-width: 94vw; }
}
