/* =============================================================================
   THE VAULT — Client Evidence Portal
   Surface styles layered on top of colors_and_type.css.
   ============================================================================= */

* {
  box-sizing: border-box;
}

html,
body,
#root {
  height: calc(100dvh);
  /* Prevent any rogue child (e.g., the 520-px-wide vault sculpture box) from
     ever pushing the page wider than the viewport on narrow phones. The
     visual content is always smaller than its layout box thanks to the
     transform-scale, but the box itself has a fixed width and CSS Grid
     can't naturally clip it. */
  max-width: 100vw;
  overflow-x: hidden;
}

html:has(.login-stage), html:has(.picker-stage),
body:has(.login-stage), body:has(.picker-stage) {
  /* Deep navy as the document bg so any chrome / safe-area bleed reads
     as part of the splash / picker, not a white seam. */
  background: #0A1219;
  color-scheme: dark;
}

/* Splash pages (login + picker) are LOCKED to the visible viewport on
   every device — no scroll, no rubber-band, no chrome-induced reflow.
   With the theme-color approach (meta theme-color matches the page bg)
   iOS Safari paints its URL bar and home-indicator chrome in the SAME
   navy as the page background, so the chrome reads as a continuation
   of the splash rather than an overlay. That means we don't need any
   scroll-nudge / oversized-page trickery; we just clamp body + html
   to 100lvh (the max possible viewport height) with overflow: hidden
   and the splash visually fills the entire device. */
body:has(.login-stage),
body:has(.picker-stage),
html:has(.login-stage),
html:has(.picker-stage),
#root:has(.login-stage),
#root:has(.picker-stage) {
  /* APPROACH 1 (scroll-nudge) — ported from db.chirica.law/parcchestnut.
     The page is 200px TALLER than the viewport and SCROLLABLE so the
     load-time window.scrollTo(0,100) in LoginScreen retracts iOS Safari's
     chrome; the oversized stage + background then fill behind where the
     chrome was. NOT overflow:hidden — that lock is what blocked the nudge.
     height:auto + min-height override the global html,body,#root{height:100dvh}. */
  height: auto;
  min-height: calc(100lvh + 200px);
  overflow-x: hidden;
  overscroll-behavior-y: none;
  /* The page is intentionally taller than the viewport so the load-time
     window.scrollTo(0,100) nudge can retract iOS chrome — but the user must
     NOT be able to scroll the splash. touch-action: none blocks finger
     scrolling/rubber-band while leaving taps (Sign in, inputs) and the
     programmatic nudge working. The picker's inner list re-enables pan-y on
     itself so it still scrolls. */
  touch-action: none;
}

/* Desktop scroll-lock. The splash is sized 200px taller than the viewport
   ONLY so the iOS chrome-retraction nudge (window.scrollTo(0,100) in
   LoginScreen) has room to scroll. Pointer devices — desktop browsers — have
   no retractable chrome, so that extra height is pure dead scroll there
   (touch-action:none already neutralizes it on touch devices, but it does not
   stop a mouse wheel). On hover-capable, fine-pointer devices we collapse the
   splash back to exactly the viewport and lock overflow, so there is no
   residual scroll. The iOS / touch path above is left entirely untouched. */
@media (hover: hover) and (pointer: fine) {
  html:has(.login-stage),
  html:has(.picker-stage),
  body:has(.login-stage),
  body:has(.picker-stage),
  #root:has(.login-stage),
  #root:has(.picker-stage) {
    height: 100dvh;
    min-height: 100dvh;
    overflow: hidden;
  }
  /* The .login-stage / .picker-stage / .background-clip panels are absolutely
     positioned against the viewport and sized 200px taller than it, so #root's
     overflow:hidden does NOT clip them — they keep the document 200px taller
     and the load-time scrollTo(0,100) parks the page at y=100. Clamp them to
     the viewport here so the document has zero scrollable overflow and the
     nudge resolves to 0, leaving content centered with no scroll. The
     .login-stage / .background-clip height rules live at the END of the file
     "so they win the cascade", so this clamp uses a body:has() ancestor to
     outrank them on specificity rather than source order. */
  body:has(.login-stage) .login-stage,
  body:has(.picker-stage) .picker-stage,
  body:has(.login-stage) .background-clip,
  body:has(.picker-stage) .background-clip {
    height: 100dvh;
    min-height: 100dvh;
  }
}

/* Viewport-sized clipping container for the oversized .background panel.
   The .background panel itself is bigger than the viewport so its
   gradient bleeds gracefully past every screen edge; this wrapper
   clips it to the exact viewport so nothing leaks into document
   scrollable area. */
.background-clip {
  /* Full-viewport clip for the oversized .background panel. The panel
     itself (top: -300px, height 100lvh+800) bleeds well past every edge;
     this wrapper clips it to the viewport. The iOS status-bar strip at the
     very top is NOT covered by this (a Safari tab can't render behind the
     status bar) — that strip's color is handled by the theme-color meta in
     index.html. position: absolute (NOT fixed — iOS WebKit clips fixed at
     the chrome boundary). */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  /* Match the stage's overscan so the background fills behind the chrome
     once the scroll-nudge retracts it (top) and past the bottom edge. */
  height: calc(100lvh + 200px);
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}

/* Top fade — dissolve the brushed-steel texture into the theme-color strip
   at the very top of the viewport. Safari desktop paints its toolbar with
   the meta theme-color (#0A1219); without this the textured panel meets that
   toolbar at a hard seam. Opaque theme navy at the top edge fades to
   transparent ~160px down, where the full texture takes over, so the toolbar
   reads as a clean continuation of the page. z-index:1 lifts it above the
   .background panel (z-index:0); the whole clip subtree still sits below the
   splash content (.login-shell), so nothing interactive is covered. */
.background-clip::after {
  content: '';
  /* fixed (not absolute): the splash deliberately auto-scrolls 100px on load
     (iOS chrome-retraction nudge in LoginScreen), which also runs on desktop.
     An absolute fade anchored to the document top scrolls out of view, leaving
     only its transparent tail at the viewport top. Fixed pins the navy cap to
     the visible viewport top on every device, directly under Safari's
     theme-colored toolbar, so there is no seam. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 160px;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg,
    #0A1219 0%,
    rgba(10, 18, 25, 0.85) 32%,
    rgba(10, 18, 25, 0.45) 62%,
    transparent 100%);
}

html {
  background: #FAFBFC;
}

body {
  margin: 0;
  background: #FAFBFC;
  font-family: var(--font-ui);
  color: var(--fg-1);
  overflow: hidden;
}

/* numeric tabular by default for the whole app */
body {
  font-variant-numeric: tabular-nums;
}

/* ---------- BRAND ACCENT STRIP (left edge) ---------- */
.brand-strip {
  position: fixed;
  left: 0;
  top: 0;
  width: 3px;
  height: 100vh;
  background: linear-gradient(180deg,
      var(--knowledgeable-blue) 0%,
      var(--knowledgeable-blue) 38%,
      var(--victory-red) 62%,
      var(--victory-red) 100%);
  z-index: 9999;
  pointer-events: none;
}

/* ---------- TOPBAR (client portal) ----------
   Layout note: previously a single flex row that squeezed unpredictably
   when the client display name was long — at 1024px the user-card text
   collided with the avatar. Now an explicit gap + min-width:0 on the
   brand and user blocks so the name truncates with ellipsis instead of
   pushing the actions off-screen. Narrow-screen behavior is centralized
   in the consolidated mobile pass at the bottom of this file (action
   labels collapse to icons below 760px; the Tour button hides below 480). */
.vault-topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 64px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--border);
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 20px 0 24px;
  padding-top: env(safe-area-inset-top, 0px);
  height: calc(64px + env(safe-area-inset-top, 0px));
}

.vault-topbar__brand {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  flex: 0 1 auto;
}

.vault-topbar__mark {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--knowledgeable-blue);
  border-radius: 7px;
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 16px;
  letter-spacing: -0.5px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
}

.vault-topbar__crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.vault-topbar__crumb {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  color: var(--fg-1);
  letter-spacing: -0.1px;
  white-space: nowrap;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
}

.vault-topbar__crumb--muted {
  color: var(--fg-3);
  cursor: default;
}

.vault-topbar__crumb--current {
  color: var(--fg-1);
}

.vault-topbar__crumbsep {
  color: #CBD5E0;
  font-weight: 400;
}

.vault-topbar__product {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: 2px;
  font-size: 12px;
  color: var(--victory-red);
  text-transform: uppercase;
  padding: 3px 8px;
  border: 1px solid rgba(220, 32, 21, 0.25);
  border-radius: 4px;
  background: rgba(220, 32, 21, 0.04);
  margin-left: 4px;
}

/* Stacked brand: client display name on top, product line below.
   Shared between Dashboard and Explorer so both screens read with
   the same hierarchy. */
.vault-topbar__brand-text {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  line-height: 1.1;
}
.vault-topbar__brand-name {
  font-family: var(--font-francy);
  font-weight: 400;
  font-size: 28px;
  line-height: 1;
  color: var(--fg-1);
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 320px;
}
.vault-topbar__brand-product {
  font-family: var(--font-anton);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--victory-red);
  margin-top: -3px;
}

/* The Chirica Law Office logo must NEVER be filtered/inverted —
   dark-mode (Explorer) flips surrounding chrome but the mark stays
   true to brand. !important because various dark-mode rules below
   apply broad filter inversions. */
.vault-topbar__logo {
  filter: none !important;
  -webkit-filter: none !important;
}

/* Explorer-only dark-mode override for the shared topbar. Flips
   surface, text, borders, and button hover states; leaves the logo
   alone (locked above) and leaves the victory-red product label red. */
.vault-topbar--surround-dark {
  background: #0F1820;
  border-bottom-color: rgba(255, 255, 255, 0.08);
}
.vault-topbar--surround-dark .vault-topbar__brand-name {
  color: rgba(255, 255, 255, 0.92);
}
.vault-topbar--surround-dark .vault-topbar__action {
  color: rgba(255, 255, 255, 0.72);
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.10);
}
.vault-topbar--surround-dark .vault-topbar__action:hover {
  background: rgba(255, 255, 255, 0.10);
  color: #FFFFFF;
}
.vault-topbar--surround-dark .vault-topbar__user {
  background: rgba(255, 255, 255, 0.06);
}
.vault-topbar--surround-dark .vault-topbar__user:hover {
  background: rgba(255, 255, 255, 0.10);
}
.vault-topbar--surround-dark .vault-topbar__user-name {
  color: rgba(255, 255, 255, 0.92);
}
.vault-topbar--surround-dark .vault-topbar__user-role {
  color: rgba(255, 255, 255, 0.55);
}
.vault-topbar--surround-dark .vault-topbar__usermenu .vault-topbar__user > svg {
  color: rgba(255, 255, 255, 0.55);
}

.vault-topbar__spacer {
  flex: 1;
}

.vault-topbar__search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: #F1F5F9;
  border: 1px solid transparent;
  border-radius: 8px;
  width: 320px;
  transition: all 0.15s var(--ease-standard);
}

.vault-topbar__search:focus-within {
  background: #fff;
  border-color: rgba(220, 32, 21, 0.4);
  box-shadow: 0 0 0 3px rgba(220, 32, 21, 0.08);
}

.vault-topbar__search input {
  flex: 1;
  border: none;
  background: transparent;
  outline: none;
  font-family: var(--font-ui);
  font-size: 15px;
  color: var(--fg-1);
}

.vault-topbar__search input::placeholder {
  color: var(--fg-4);
}

.vault-topbar__kbd {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fg-3);
  padding: 2px 6px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
}

.vault-topbar__user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 14px 5px 6px;
  border-radius: 999px;
  background: #F7FAFC;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.15s var(--ease-standard);
  margin-left: 4px;
  min-width: 0;
  max-width: 240px;
  flex: 0 1 auto;
  font-family: inherit;
}

.vault-topbar__user > div {
  min-width: 0;
  text-align: left;
}

.vault-topbar__user:hover {
  background: #EDF2F7;
  border-color: var(--border);
}

.vault-topbar__user-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--fg-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
}

.vault-topbar__user-role {
  font-size: 12px;
  color: var(--fg-3);
  margin-top: 1px;
  letter-spacing: 0.2px;
  white-space: nowrap;
}

/* Wrapper for the topbar identity pill + its click-to-open menu.
   Relative so the absolute-positioned menu anchors to it. */
.vault-topbar__usermenu {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.vault-topbar__usermenu .vault-topbar__user {
  /* The wrapper takes the margin-left now; pill resets so the chevron
     and the avatar sit tight together. */
  margin-left: 0;
}
.vault-topbar__usermenu .vault-topbar__user > svg {
  color: var(--fg-3);
  transition: transform 0.15s var(--ease-standard);
  flex-shrink: 0;
}
.vault-topbar__usermenu.is-open .vault-topbar__user > svg {
  transform: rotate(180deg);
}
.vault-topbar__menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: #FFFFFF;
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.08);
  padding: 6px;
  z-index: 200;
  animation: vault-topbar-menu-in 0.14s var(--ease-standard) both;
}
@keyframes vault-topbar-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.vault-topbar__menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  background: none;
  border: none;
  border-radius: 6px;
  color: var(--fg-1);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s var(--ease-standard);
}
.vault-topbar__menu-item:hover {
  background: #F7FAFC;
}
.vault-topbar__menu-item:focus-visible {
  outline: 2px solid var(--victory-red);
  outline-offset: 1px;
}

/* ===== Generic modal — used for the change-password dialog and any
   future single-purpose dialog mounted from the topbar. */
.vault-modal {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  /* No align/justify centering: the panel centers itself with margin:
     auto, which (unlike flex centering) keeps the top edge reachable
     and scrollable when the panel is taller than the viewport — e.g.
     a phone with the keyboard up. */
  overflow-y: auto;
  background: rgba(10, 18, 25, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  padding: 24px;
  animation: vault-modal-in 0.16s var(--ease-standard) both;
}
@keyframes vault-modal-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.vault-modal__panel {
  position: relative;
  margin: auto;
  width: 100%;
  max-width: 420px;
  background: #FFFFFF;
  border-radius: 14px;
  padding: 28px 28px 22px;
  box-shadow: 0 24px 64px rgba(15, 23, 42, 0.30), 0 4px 12px rgba(15, 23, 42, 0.10);
  animation: vault-modal-panel-in 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes vault-modal-panel-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.vault-modal__close {
  position: absolute;
  top: 12px; right: 12px;
  background: none; border: none;
  width: 32px; height: 32px;
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  color: var(--fg-3);
  cursor: pointer;
  transition: background 0.12s var(--ease-standard);
}
.vault-modal__close:hover {
  background: #F7FAFC;
  color: var(--fg-1);
}
.vault-modal__title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--fg-1);
  margin: 0 0 18px;
  letter-spacing: 1px;
}
.vault-modal__form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.vault-modal__label {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.vault-modal__label > span {
  font-size: 14px;
  font-weight: 600;
  color: var(--fg-2);
  letter-spacing: 0.2px;
}
.vault-modal__label > input {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-ui);
  font-size: 16px;
  color: var(--fg-1);
  background: #FFFFFF;
  transition: border-color 0.12s var(--ease-standard), box-shadow 0.12s var(--ease-standard);
}
.vault-modal__label > input:focus {
  outline: none;
  border-color: var(--victory-red);
  box-shadow: 0 0 0 3px rgba(220, 32, 21, 0.12);
}
.vault-modal__error {
  font-size: 15px;
  color: var(--victory-red);
  background: rgba(220, 32, 21, 0.06);
  border: 1px solid rgba(220, 32, 21, 0.18);
  padding: 8px 10px;
  border-radius: 6px;
}
.vault-modal__success {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  color: #1F7A3F;
  background: rgba(45, 138, 71, 0.08);
  border: 1px solid rgba(45, 138, 71, 0.20);
  padding: 14px 16px;
  border-radius: 8px;
}
.vault-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}
.vault-modal__btn {
  padding: 10px 16px;
  border-radius: 8px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: all 0.12s var(--ease-standard);
}
.vault-modal__btn--ghost {
  background: none;
  border: 1px solid var(--border);
  color: var(--fg-2);
}
.vault-modal__btn--ghost:hover {
  background: #F7FAFC;
  color: var(--fg-1);
}
.vault-modal__btn--primary {
  background: var(--victory-red);
  border: 1px solid var(--victory-red);
  color: #FFFFFF;
  box-shadow: 0 2px 6px rgba(220, 32, 21, 0.25);
}
.vault-modal__btn--primary:hover {
  background: var(--victory-red-hover);
  border-color: var(--victory-red-hover);
}
.vault-modal__btn:disabled {
  opacity: 0.55;
  cursor: progress;
}

.vault-topbar__avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--knowledgeable-blue), var(--knowledgeable-blue-light));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.3px;
}
/* When the avatar is an <img> (firm staff Google profile picture) we
   need to crop it to the circle and zero the inherited padding/gap so
   the photo fills the disc cleanly. */
.vault-topbar__avatar--photo {
  object-fit: cover;
  object-position: center;
  background: none;
}

/* ---------- MAIN PAGE LAYOUT ----------
   Layout note: top/bottom: -100px gives the scroll container 100px of
   elastic overscroll above and below the viewport. The fixed .vault-topbar
   (64px tall) sits at viewport y=0, so content needs enough top padding
   to clear BOTH the -100px offset AND the topbar — otherwise the first
   ~164px of content is hidden behind the topbar when scrollTop=0.
   Mirrors the mobile rules at lines 4481 and 5114. */
.vault-page {
  position: absolute;
  top: -100px;
  left: 0;
  right: 0;
  /* Bottom edge sits at the viewport bottom (not -100px). The -100px top is
     hidden above the fold and is compensated by the padding-top calc; a
     matching -100px bottom, by contrast, pushed this scroll container's box
     100px past the viewport and created 100px of pure dead scroll below the
     content on desktop. The dashboard does no iOS chrome-retraction nudge
     (unlike the splash), so there is nothing to overscan for. */
  bottom: 0;
  overflow: auto;
  padding: calc(100px + 64px + env(safe-area-inset-top, 0px) + 24px) 32px 80px;
}

.vault-shell {
  max-width: 1200px;
  margin: 0 auto;
}

/* ---------- DASHBOARD CASE HEADER ---------- */
.case-header {
  background: linear-gradient(180deg, #fff 0%, #fbfcfd 100%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 32px;
  box-shadow: var(--shadow-premium);
  margin-bottom: 24px;
  position: relative;
  overflow: hidden;
}

.case-header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--victory-red) 0%, transparent 50%);
}

.case-header__row {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.case-header__main {
  flex: 1;
  min-width: 280px;
}

.case-header__eyebrow {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: var(--victory-red);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.case-header__eyebrow::before {
  content: '';
  width: 16px;
  height: 1px;
  background: currentColor;
  display: inline-block;
}

.case-header__title {
  font-family: var(--font-francy);
  font-size: 32px;
  font-weight: 400;
  letter-spacing: -0.5px;
  color: var(--knowledgeable-blue);
  margin: 0 0 6px;
}

.case-header__title em {
  font-style: italic;
  font-weight: 700;
}

.case-header__sub {
  font-size: 16px;
  color: var(--fg-2);
  margin: 0;
  line-height: 1.55;
}

.case-header__counsel {
  display: flex;
  gap: 28px;
  border-left: 1px solid var(--border);
  padding-left: 28px;
}

.counsel-box {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.counsel-box__label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--fg-3);
}

.counsel-box__name {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--fg-1);
  letter-spacing: -0.1px;
}

.counsel-box__contact {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fg-3);
}

/* status pill row */
.case-header__stats {
  display: flex;
  gap: 24px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid #EDF2F7;
}

.case-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: relative;
  padding-right: 24px;
}

.case-stat:not(:last-child)::after {
  content: '';
  position: absolute;
  right: 0;
  top: 4px;
  bottom: 4px;
  width: 1px;
  background: #EDF2F7;
}

.case-stat__value {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 700;
  color: var(--knowledgeable-blue);
  letter-spacing: -0.4px;
  line-height: 1;
}

.case-stat__value--accent {
  color: var(--victory-red);
}

.case-stat__label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--fg-3);
  font-weight: 600;
  margin-top: 6px;
}

/* ---------- FILE LIST ---------- */
.file-section+.file-section {
  margin-top: 32px;
}

.file-section__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 4px;
  border-radius: 10px 10px 0 0;
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 24px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  position: relative;
  transition: filter 0.18s ease-out, transform 0.18s ease-out;
}
.file-section__bar:hover {
  filter: brightness(1.06);
}
.file-section__chev {
  transition: transform 0.2s ease-out;
}
.file-section.is-collapsed .file-section__chev {
  transform: rotate(0deg);
}

.file-section__bar--blue {
  background: linear-gradient(135deg, var(--knowledgeable-blue) 0%, #2D4A5E 60%, #3B6B8A 100%);
}

.file-section__bar--red {
  background: linear-gradient(135deg, var(--victory-red) 0%, #C41D13 50%, #A01810 100%);
}

.file-section__count {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1px;
  opacity: 0.85;
}

.file-list {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 0 0 12px 12px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}

.file-list__head {
  display: grid;
  /* icon | name | type | size | modified | actions
     name uses minmax so long file names stay legible at all viewport widths
     instead of being squeezed into ellipsis at 1024-1280px (the previous bug). */
  grid-template-columns: 28px minmax(220px, 1fr) 88px 88px 130px 56px;
  gap: 16px;
  align-items: center;
  padding: 11px 18px 11px 14px;
  background: #FAFBFC;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--fg-3);
  font-family: var(--font-display);
}

.file-list__head .sortable {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
}

.file-list__head .sortable:hover {
  color: var(--fg-1);
}

.file-list__head .sortable.is-active {
  color: var(--fg-1);
}

.file-list__head .sortable__arrow {
  font-size: 11px;
  font-weight: 800;
  color: var(--victory-red);
  letter-spacing: 0;
  line-height: 1;
}

.file-row {
  display: grid;
  grid-template-columns: 28px minmax(220px, 1fr) 88px 88px 130px 56px;
  gap: 16px;
  align-items: center;
  padding: 12px 18px 12px 14px;
  border-bottom: 1px solid #F2F4F7;
  cursor: pointer;
  transition: background 0.12s var(--ease-standard);
  position: relative;
}

.file-row:last-child {
  border-bottom: none;
}

.file-row:hover {
  background: #FAFBFC;
}

.file-row:hover .file-row__actions {
  opacity: 1;
}

.file-row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--victory-red);
  opacity: 0;
  transition: opacity 0.12s var(--ease-standard);
}

.file-row:hover::before {
  opacity: 1;
}

.file-row__icon {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.file-row__icon--folder {
  background: linear-gradient(180deg, #E0E9F0, #C9D5E2);
  color: var(--knowledgeable-blue);
}

.file-row__icon--video {
  background: linear-gradient(180deg, #FEE8E8, #FDD5D5);
  color: var(--victory-red);
}

.file-row__icon--image {
  background: linear-gradient(180deg, #E8F2FF, #D1E3FF);
  color: #2563EB;
}

.file-row__icon--pdf {
  background: linear-gradient(180deg, #FEE8E8, #FDD5D5);
  color: #C41D13;
}

.file-row__icon--audio {
  background: linear-gradient(180deg, #F3E8FF, #E9D5FF);
  color: #7C3AED;
}

.file-row__icon--sheet {
  background: linear-gradient(180deg, #E8FAF0, #D1F5E0);
  color: #059669;
}

.file-row__icon--doc {
  background: linear-gradient(180deg, #E4EAF0, #C9D5E2);
  color: var(--knowledgeable-blue);
}

/* MultiCam folder — a specialty synchronized-video player, not an ordinary
   folder. The row is tinted purple with a persistent left accent bar so it
   always stands out in the listing, and the icon carries the same hue. */
.file-row__icon--multicam {
  background: linear-gradient(180deg, #F3E8FF, #E9D5FF);
  color: #7E22CE;
}

.file-row.is-multicam {
  background: rgba(126, 34, 206, 0.07);
}

.file-row.is-multicam:hover {
  background: rgba(126, 34, 206, 0.12);
}

.file-row.is-multicam::before {
  background: #7E22CE;
  opacity: 1;
}

.file-row__name {
  font-size: 16px;
  font-weight: 500;
  color: var(--fg-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -0.1px;
}

.file-row__sub {
  font-size: 12px;
  color: var(--fg-3);
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.file-row__sub .dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #CBD5E0;
  display: inline-block;
}

.file-row__name-cell {
  min-width: 0;
}

.file-row__type {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.file-row__size {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--fg-2);
}

.file-row__date {
  font-size: 14px;
  color: var(--fg-3);
}

.file-row__actions {
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.file-row__action {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--fg-3);
  cursor: pointer;
}

.file-row__action:hover {
  color: var(--victory-red);
  border-color: rgba(220, 32, 21, 0.3);
}

.file-row__commentcount {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  background: rgba(220, 32, 21, 0.08);
  color: var(--victory-red);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--font-mono);
  letter-spacing: 0.2px;
}

/* breadcrumb-row inside dashboard */
.dash-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  font-size: 15px;
}

.dash-breadcrumb__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--fg-2);
  cursor: pointer;
  transition: all 0.12s ease;
}

.dash-breadcrumb__chip:hover {
  color: var(--fg-1);
  border-color: var(--border-strong);
}

.dash-breadcrumb__chip--current {
  background: var(--knowledgeable-blue);
  color: #fff;
  border-color: var(--knowledgeable-blue);
  cursor: default;
}

/* secure footer note */
.secure-note {
  margin: 32px auto 0;
  text-align: center;
  font-size: 12px;
  color: var(--fg-4);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  letter-spacing: 0.3px;
}

.secure-note__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #16a34a;
  box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.15);
}

/* ---------- BUTTONS ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: 7px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.1px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.12s var(--ease-standard);
  user-select: none;
  white-space: nowrap;
}

.btn--red {
  background: var(--victory-red);
  color: #fff;
  box-shadow: 0 1px 2px rgba(220, 32, 21, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
}

.btn--red:hover {
  background: var(--victory-red-hover);
  box-shadow: 0 3px 10px rgba(220, 32, 21, 0.35), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
}

.btn--red:active {
  transform: translateY(1px);
}

.btn--blue {
  background: var(--knowledgeable-blue);
  color: #fff;
  box-shadow: 0 1px 2px rgba(29, 50, 66, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.18);
}

.btn--blue:hover {
  background: #142736;
}

.btn--ghost {
  background: #fff;
  color: var(--fg-1);
  border-color: var(--border);
}

.btn--ghost:hover {
  border-color: var(--border-strong);
  background: #FAFBFC;
}

.btn--quiet {
  background: transparent;
  color: var(--fg-2);
}

.btn--quiet:hover {
  color: var(--victory-red);
  background: rgba(220, 32, 21, 0.06);
}

.btn--sm {
  padding: 6px 11px;
  font-size: 14px;
  border-radius: 6px;
}

.btn--icon {
  padding: 8px;
}

.icon-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--fg-2);
  cursor: pointer;
  transition: all 0.12s ease;
}

.icon-btn:hover {
  color: var(--fg-1);
  border-color: var(--border-strong);
}

.icon-btn--active {
  background: var(--knowledgeable-blue);
  border-color: var(--knowledgeable-blue);
  color: #fff;
}

.icon-btn--red.icon-btn--active {
  background: var(--victory-red);
  border-color: var(--victory-red);
}

/* =============================================================================
   LOGIN — Vault Door
   The original dark threshold tableau: a 520x520 chromed bank-vault sculpture
   anchored to the right of a sign-in form, on a deep knowledgeable-blue
   gradient. The phase state machine in LoginScreen.jsx (closed | spinning |
   open) drives the spoke spin, the door opening on its hinges, the interior
   reveal, and the stage flash + fade-out before redirect.
   Only `.login-*` / `.vault-*` selectors here use dark tones — every other
   surface in the app remains light per brand.
   ============================================================================= */
.login-stage {
  /* position: absolute (NOT fixed) per the firm-standard
     mobile-fullscreen-splash skill — iOS 26 / WebKit Bug 300965 clips
     position: fixed at the chrome boundary (memory 4847684e). The
     stage spans the entire viewport (100lvh) on every device. With
     the theme-color approach in index.html, iOS Safari paints its
     chrome the same navy as the stage's gradient — so the stage
     visually fills the device edge-to-edge, no offset needed.
     All centering/spacing geometry lives in the unified "LOGIN STAGE
     — magazine geometry" block at the END of this file. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  /* 200px overscan to pair with the scroll-nudge: the stage centers its
     content in (100lvh + 200px); the load-time scrollTo(0,100) then shifts
     the view up 100px so that center lands at the viewport center while the
     top 100px scrolls behind the retracted chrome. */
  height: calc(100lvh + 200px);
  overflow: hidden;
  z-index: 5000;
}

/* Splash backdrop — oversized container per the firm-standard
   mobile-fullscreen-splash skill (memory 55637549), with extra vertical
   slack so the gradient pushes well below where iOS Safari's bottom URL
   bar sits. 125 vw width with left: -12.5vw gives 12.5 vw side bleed;
   height = calc(100lvh + 800px) with top: -300px gives ~300 px above +
   ~500 px below the visible viewport. The extra 500 px under the
   visible bottom guarantees that on every iOS variant (Safari 15+
   bottom URL bar, Safari 14 top URL bar, Chrome iOS, PWA standalone)
   the gradient extends past the chrome edge — never a chrome-colored
   seam beneath the page content.

   position: absolute (NOT fixed) — iOS 26 clips fixed positioning at
   the chrome boundary even with these oversized dimensions. The
   useIosChromeFreeze hook owns the chrome behavior; this element just
   needs to be tall and wide enough to cover every possible viewport. */
.background {
  position: absolute;
  top: -300px;
  left: -12.5vw;
  width: 125vw;
  height: calc(100lvh + 800px);
  z-index: 0;
  overflow: hidden;
  background:
    /* Center highlight — broader steel glow. Larger ellipse + later
       fade-out stop so the light reaches farther toward the edges
       before surrendering to the vignette. */
    radial-gradient(ellipse 1600px 1150px at 50% 45%, rgba(150, 175, 195, 0.18) 0%, rgba(150, 175, 195, 0.085) 45%, transparent 85%),
    /* Vignette — held off until ~55% of the radius so the highlight has
       room to breathe before the edges dim down. */
    radial-gradient(ellipse 1900px 1350px at 50% 50%, transparent 50%, rgba(0,0,0,0.50) 88%, rgba(0,0,0,0.70) 100%),
    /* Brand accents — kept but dialed back so they don't fight the new
       center-light/edge-dark read. */
    radial-gradient(1400px 900px at 18% -8%, rgba(36, 62, 82, 0.18), transparent 62%),
    radial-gradient(1000px 800px at 112% 108%, rgba(220, 32, 21, 0.09), transparent 60%),
    #070C11;
}

/* Slow drifting bloom — adds ambient motion to the static gradient so
   the splash feels alive. Same idea as the coachclass .ambient-bg orbs.
   Single victory-red glow because more would compete with the vault
   sculpture; one quiet pulse is enough to register motion peripherally. */
.background::before {
  content: '';
  position: absolute;
  top: -180px;
  right: -160px;
  width: 720px;
  height: 720px;
  background: radial-gradient(circle, rgba(220, 32, 21, 0.18) 0%, transparent 65%);
  pointer-events: none;
  animation: splash-orb 28s ease-in-out infinite;
  will-change: transform;
}
@keyframes splash-orb {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33%      { transform: translate(60px, -40px) scale(1.08); }
  66%      { transform: translate(-30px, 50px) scale(0.94); }
}
@media (prefers-reduced-motion: reduce) {
  .background::before { animation: none; }
}

/* Surface texture — two stacked SVG noise layers that together read as
   brushed steel:
     1. Brushed striations: feTurbulence with very low X frequency
        (0.012, ~continuous horizontally) and very high Y frequency
        (0.95, fine vertical variation) yields the directional micro-
        scratches of a brushed-metal finish.
     2. Fine film grain: high-frequency isotropic noise sits on top so
        the striations don't read as a mechanical pattern at close
        viewing distances.
   Both layers use overlay blending so they brighten the steel highlight
   and darken the vignette without flattening the gradient underneath. */
.background::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Overlay blend with grayscale (not white-tinted) noise: where the
     noise is bright the gradient brightens, where it's dark the gradient
     darkens, where it's mid-gray nothing happens. That preserves the
     dark-blue hue while still etching visible scratches into it. The
     wrapper opacity controls overall texture strength. */
    opacity: 0.5;
  mix-blend-mode: overlay;
  pointer-events: none;
  background-image:
    /* Broad brushed sweeps — wide continuous horizontal bands so the
       eye reads a directional brush stroke before noticing the fine
       grit on top. Grayscale via passing R into G and B. */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='800'%3E%3Cfilter id='broad'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.006 0.35' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0  1 0 0 0 0  1 0 0 0 0  0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23broad)'/%3E%3C/svg%3E"),
    /* Fine micro-scratches — high Y freq, low X freq → dense per-pixel
       horizontal striations. Same grayscale trick so it both brightens
       and darkens the base without shifting hue. */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='480'%3E%3Cfilter id='brushed'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.95' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0  1 0 0 0 0  1 0 0 0 0  0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23brushed)'/%3E%3C/svg%3E");
  background-size: 800px 800px, 480px 480px;
  background-blend-mode: multiply;
}

/* =============================================================================
   Splash ornament — four corner registration marks. Reads as a legal slate /
   case-file cover sheet without any interactive cost. Aria-hidden in JSX.
   ============================================================================= */
.login-regmark {
  /* Decorative corner registration marks (case-file slate motif). Hidden:
     in empty corners they read as stray white dots rather than an ornament.
     Re-enable by removing this display:none to restore the four corner marks. */
  display: none;
  position: absolute;
  width: 22px;
  height: 22px;
  z-index: 2;
  pointer-events: none;
  /* Two perpendicular hairlines that intersect 4 px inside the corner —
     drawn with CSS gradients so we don't have to ship four SVGs. */
  background:
    linear-gradient(90deg,
      transparent calc(50% - 0.5px),
      rgba(255, 255, 255, 0.55) calc(50% - 0.5px),
      rgba(255, 255, 255, 0.55) calc(50% + 0.5px),
      transparent calc(50% + 0.5px)),
    linear-gradient(0deg,
      transparent calc(50% - 0.5px),
      rgba(255, 255, 255, 0.55) calc(50% - 0.5px),
      rgba(255, 255, 255, 0.55) calc(50% + 0.5px),
      transparent calc(50% + 0.5px));
  background-size: 100% 1px, 1px 100%;
  background-position: center, center;
  background-repeat: no-repeat;
}
.login-regmark--tl { top: max(14px, env(safe-area-inset-top, 0px) + 8px); left: max(14px, env(safe-area-inset-left, 0px) + 8px); }
.login-regmark--tr { top: max(14px, env(safe-area-inset-top, 0px) + 8px); right: max(14px, env(safe-area-inset-right, 0px) + 8px); }
.login-regmark--bl { bottom: max(14px, env(safe-area-inset-bottom, 0px) + 8px); left: max(14px, env(safe-area-inset-left, 0px) + 8px); }
.login-regmark--br { bottom: max(14px, env(safe-area-inset-bottom, 0px) + 8px); right: max(14px, env(safe-area-inset-right, 0px) + 8px); }

@media (max-width: 460px) {
  .login-regmark { width: 18px; height: 18px; }
  /* The bottom info bar already provides a strong horizontal anchor on
     phones; corner marks at the bottom would only fight it. Keep just
     the two top marks so the splash still reads as a slated case-file
     cover sheet. */
  .login-regmark--bl,
  .login-regmark--br {
    display: none;
  }
}
.login-stage::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    radial-gradient(rgba(255,255,255,0.04) 1px, transparent 1px);
  background-size: 24px 24px;
  pointer-events: none;
  mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
}

/* .login-shell base width / grid lives in the "LOGIN STAGE — magazine
   geometry" block at the END of this file (source-ordered last so it
   wins the cascade). This shell box exists only so earlier selectors
   like .login-shell .x can still resolve their parent. */
.login-shell {
  position: relative;
  z-index: 1;
}

.login-form-side {
  color: #fff;
  display: flex; flex-direction: column;
  width: 100%;
  justify-self: end;
}

.login-eyebrow {
  font-family: var(--font-display);
  font-size: 12px; font-weight: 700;
  letter-spacing: 3px;
  color: var(--victory-red);
  text-transform: uppercase;
  margin-bottom: 16px;
  display: flex; align-items: center; gap: 12px;
}
.login-eyebrow::before { content: ''; width: 22px; height: 1px; background: currentColor; }

.login-title {
  font-family: 'Archivo Black', var(--font-display);
  font-size: 63px;
  font-weight: 400; /* Archivo Black ships a single 400 face that's already heavy */
  letter-spacing: -1px;
  line-height: 1.06; /* Archivo Black is tall — needs more leading than Montserrat so wrapped lines don't collide */
  color: #fff;
  margin: 0 0 18px;
}
/* Editorial italic accent — Playfair Display for the "under lock." line,
   echoing the magazine-cover serif move used on db.chirica.law/coachclass.
   The italic carries the entire weight of the brand voice here: the
   Montserrat above is the byline; this is the headline. */
.login-title em {
  font-family: 'IBM Plex Sans', var(--font-ui), sans-serif;
  font-style: italic;
  font-weight: 700;
  color: var(--victory-red);
  letter-spacing: -0.5px;
  display: block;
  white-space: nowrap;
  /* Slight optical lift so the serif x-height aligns with the sans cap-height
     on the line above instead of dropping low. */
  margin-top: 2px;
}
.login-sub {
  font-size: 17px;
  color: rgba(255,255,255,0.65);
  line-height: 1.6;
  margin-bottom: 36px;
  max-width: 360px;
}

.login-field { margin-bottom: 16px; }
.login-field__label {
  font-size: 11px; font-weight: 700; letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  margin-bottom: 8px;
  display: block;
}
.login-field__input {
  width: 100%;
  padding: 13px 16px;
  /* Dark navy surface — opaque enough to mute the brushed-metal texture
     behind the field so the email reads on a calm slab instead of on
     the splash's grain. Matches the picker-card opacity language. */
  background: rgba(10, 18, 28, 0.80);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 8px;
  color: #fff;
  font-family: var(--font-ui);
  font-size: 16px;
  outline: none;
  transition: all 0.15s var(--ease-standard);
  font-variant-numeric: tabular-nums;
}
.login-field__input::placeholder { color: rgba(255,255,255,0.3); }
.login-field__input:focus {
  background: rgba(15, 24, 35, 0.88);
  border-color: rgba(220,32,21,0.6);
  box-shadow: 0 0 0 4px rgba(220,32,21,0.10);
}
.login-field__pwwrap { position: relative; }
.login-field__pweye {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  color: rgba(255,255,255,0.5);
  padding: 6px; display: flex; align-items: center; justify-content: center;
}
.login-field__pweye:hover { color: #fff; }

.login-submit {
  margin-top: 8px;
  width: 100%;
  padding: 14px 16px;
  background: var(--victory-red);
  border: none;
  border-radius: 8px;
  color: #fff;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.15s var(--ease-standard);
  display: flex; align-items: center; justify-content: center; gap: 10px;
  box-shadow: 0 4px 16px rgba(220,32,21,0.4), inset 0 -2px 0 rgba(0,0,0,0.2);
}
.login-submit:hover {
  background: var(--victory-red-hover);
  box-shadow: 0 8px 28px rgba(220,32,21,0.55), inset 0 -2px 0 rgba(0,0,0,0.2);
  transform: translateY(-1px);
}
.login-submit:active { transform: translateY(1px); }
.login-submit:disabled { opacity: 0.6; cursor: progress; transform: none; }

.login-forgot {
  background: none;
  border: 0;
  color: rgba(255,255,255,0.5);
  font-size: 14px;
  margin-top: 12px;
  cursor: pointer;
  padding: 6px 0;
  font-family: var(--font-ui);
  text-align: left;
}
.login-forgot:hover {
  color: var(--victory-red-light);
}

.login-meta {
  margin-top: 24px;
  font-size: 14px;
  color: rgba(255,255,255,0.45);
  display: flex; align-items: center; gap: 10px;
  line-height: 1.5;
}
.login-meta__pulse {
  width: 8px; height: 8px; border-radius: 50%;
  background: #16a34a;
  box-shadow: 0 0 0 0 rgba(22,163,74,0.6);
  animation: secure-pulse 2s ease-out infinite;
  flex-shrink: 0;
}
@keyframes secure-pulse {
  0% { box-shadow: 0 0 0 0 rgba(22,163,74,0.6); }
  100% { box-shadow: 0 0 0 12px rgba(22,163,74,0); }
}

.login-error {
  margin-top: 12px;
  font-size: 14px;
  color: #FCA5A5;
  display: flex; align-items: center; gap: 8px;
}

/* ===== Two-step sign-in ===========================================
   Step 1 shows just the email field. On Continue the field is swapped
   for an engraved brass-on-steel identity plaque (.login-identity) —
   visual cue that the email is now "set in stone" — and the password
   field is revealed beneath via .login-pw-reveal (grid-template-rows
   trick so we can animate from 0 to auto height).
   The dial also nudges one major tick on the same transition — see
   .vault-door.is-primed below.
   ================================================================== */

/* Fade-in for the freshly mounted email field on the email step, so
   when the user clicks Change the field doesn't snap in. */
.login-field--enter {
  animation: login-field-in 0.32s var(--ease-standard) both;
}
@keyframes login-field-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* The engraved plaque. Steel-tinted bezel with two highlights
   (top-light, bottom-shadow) gives the inset/cast-metal feel; four
   tiny rivets at the corners echo the vault door's rivet ring.
   Brass/champagne accents replaced with steel + white to stay on the
   brand palette (knowledgeable blue + victory red + white). */
.login-identity {
  position: relative;
  /* 8px keeps the Google SSO button close to the plaque — matches the
     gap the email-step Continue button used to sit at below the email
     field, so the firm flow doesn't push the CTA noticeably further
     down than the old continue did. */
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 8px 12px 16px;
  border-radius: 8px;
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.08) 0%,
      rgba(255, 255, 255, 0.03) 55%,
      rgba(0, 0, 0, 0.20) 100%),
    rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 -1px 0 rgba(0, 0, 0, 0.40),
    inset 0 0 0 1px rgba(0, 0, 0, 0.25),
    0 1px 0 rgba(255, 255, 255, 0.04);
  animation: login-identity-in 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes login-identity-in {
  0%   { opacity: 0; transform: translateY(-6px) scale(0.985); filter: blur(2px); }
  60%  { filter: blur(0); }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}
.login-identity__rivet {
  position: absolute;
  width: 4px; height: 4px;
  border-radius: 50%;
  /* Brushed-steel rivet — replaces the brass radial gradient. */
  background: radial-gradient(circle at 30% 30%, #D8E0E8 0%, #6A7884 60%, #1A2632 100%);
  box-shadow:
    inset 0 -0.5px 0.5px rgba(0,0,0,0.6),
    0 0.5px 0 rgba(255, 255, 255, 0.15);
}
.login-identity__rivet--tl { top: 5px; left: 6px; }
.login-identity__rivet--tr { top: 5px; right: 6px; }
.login-identity__rivet--bl { bottom: 5px; left: 6px; }
.login-identity__rivet--br { bottom: 5px; right: 6px; }

.login-identity__icon {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 6px;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(0, 0, 0, 0.28);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), inset 0 -1px 0 rgba(0,0,0,0.4);
  flex-shrink: 0;
}
.login-identity__body {
  display: flex; flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.login-identity__label {
  font-family: var(--font-display);
  font-size: 10px; font-weight: 700;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.login-identity__email {
  font-family: var(--font-display);
  font-size: 18px; font-weight: 600;
  letter-spacing: 0.4px;
  color: #FFFFFF;
  /* Engraved-on-steel effect: highlight above, shadow below. */
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.55),
    0 -1px 0 rgba(255, 255, 255, 0.10);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.login-identity__change {
  flex-shrink: 0;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
  padding: 7px 10px 7px 8px;
  color: rgba(255, 255, 255, 0.55);
  font-family: var(--font-display);
  font-size: 11px; font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all 0.15s var(--ease-standard);
}
.login-identity__change:hover {
  color: #fff;
  background: rgba(0, 0, 0, 0.36);
  border-color: rgba(220, 32, 21, 0.45);
}
.login-identity__change:disabled { opacity: 0.4; cursor: not-allowed; }

/* Password reveal: grid-template-rows: 0fr → 1fr animates height-auto
   smoothly. The inner wrapper carries overflow: hidden so children get
   clipped while the row collapses. */
.login-pw-reveal {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transform: translateY(-4px);
  transition:
    grid-template-rows 0.42s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.32s var(--ease-standard) 0.06s,
    transform 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}
.login-pw-reveal.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
  transform: translateY(0);
}
.login-pw-reveal__inner {
  overflow: hidden;
  min-height: 0;
}

/* Step-1 button is a quiet outline; step-2 keeps the heavy red CTA.
   Opacity dialed up so the brushed-metal splash texture doesn't bleed
   through the button face. Same dark-navy surface as the email field
   and picker cards, for visual continuity. */
.login-submit--email {
  background: rgba(15, 24, 35, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 1.4px;
}
.login-submit--email:hover {
  background: rgba(28, 42, 58, 0.88);
  border-color: rgba(220, 32, 21, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 4px 18px rgba(0, 0, 0, 0.35);
  transform: translateY(-1px);
}

/* ===== Firm SSO panel — shown in step 2 when the email is @chirica.law.
   Replaces the password reveal with a hint card explaining why the password
   is bypassed, plus a Google brand CTA that fires .launchGoogle(). */
.login-sso {
  margin-bottom: 16px;
  animation: login-sso-in 0.36s var(--ease-standard) both;
}
@keyframes login-sso-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.login-sso__rule {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  color: rgba(255, 255, 255, 0.42);
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2.4px;
  text-transform: uppercase;
}
.login-sso__rule::before,
.login-sso__rule::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent);
}
.login-sso__rule span { white-space: nowrap; }
.login-sso__hint {
  font-size: 15px;
  color: rgba(255, 255, 255, 0.62);
  line-height: 1.6;
  margin: 0;
}
.login-sso__hint strong {
  font-family: var(--font-display);
  font-weight: 600;
  color: #F1E1BC;
  /* same engraved feel as the identity plaque so the email reads as one
     continuous "set in stone" object even though it appears twice. */
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  letter-spacing: 0.2px;
}
.login-sso__hint em {
  font-style: italic;
  color: rgba(255, 255, 255, 0.88);
}

/* Google-brand CTA. Dark variant per Google's brand guidelines so it
   reads as the official entry into Google, while still belonging on the
   vault's near-black surface. The multicolor G is inlined as SVG in
   GoogleG.jsx so it sits crisp at any DPR. */
.login-submit--google {
  background: #131314;
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: #E3E3E3;
  /* Drop the heavy display-font uppercase look — Google's button is
     Roboto-cased and proportional. Fall back to the OS UI sans, never
     Inter (brand-blacklisted). */
  font-family: 'Roboto', var(--font-ui);
  font-size: 16px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.25px;
  gap: 12px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 6px 18px rgba(0, 0, 0, 0.4);
  transition: all 0.18s var(--ease-standard);
}
.login-submit--google:hover {
  background: #1F1F1F;
  border-color: rgba(255, 255, 255, 0.28);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 10px 26px rgba(0, 0, 0, 0.5);
}
.login-submit--google:active { transform: translateY(0); }
.login-submit--google:disabled {
  opacity: 0.55; cursor: not-allowed; transform: none;
}
.login-submit--google svg {
  flex-shrink: 0;
  /* Google's G mark sits 1px above optical center next to body text. */
  transform: translateY(-0.5px);
}

/* ===== Vault door ===== */
.vault-side {
  justify-self: start;
  position: relative;
  width: 520px; height: 520px;
}
.vault-frame {
  position: absolute; inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #1A2B38 0%, #0E1820 80%);
  box-shadow:
    inset 0 0 0 6px #0A1219,
    inset 0 0 0 8px #2A3D4D,
    inset 0 0 0 10px #0A1219,
    0 0 80px rgba(0,0,0,0.6),
    0 30px 80px rgba(0,0,0,0.5);
}
/* rivets ring */
.vault-rivets {
  position: absolute; inset: 18px;
  border-radius: 50%;
  pointer-events: none;
}
.vault-rivet {
  position: absolute;
  width: 8px; height: 8px;
  background: radial-gradient(circle at 30% 30%, #6A7B8A, #1D2A36 70%);
  border-radius: 50%;
  box-shadow: inset 0 -1px 1px rgba(0,0,0,0.5);
  top: 50%; left: 50%;
  transform-origin: 0 0;
}
/* the door */
.vault-door-wrap {
  position: absolute;
  inset: 38px;
  border-radius: 50%;
  overflow: visible;
  perspective: 2200px;
  perspective-origin: 0% 50%;
}
.vault-door {
  position: absolute; inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 30%, #4A5C6E 0%, #2D3D4D 35%, #1A2632 70%, #0F1820 100%);
  box-shadow:
    inset 0 0 0 4px #2A3D4D,
    inset 0 0 0 6px #0A1219,
    inset 0 0 0 10px #3A4D60,
    inset 0 0 60px rgba(0,0,0,0.4),
    0 20px 50px rgba(0,0,0,0.6);
  transform-origin: 0% 50%;
  transition:
    transform 1.6s cubic-bezier(0.55, 0.05, 0.4, 1),
    box-shadow 1s var(--ease-standard);
}
.vault-door::before {
  /* concentric ring */
  content: '';
  position: absolute;
  inset: 36px;
  border-radius: 50%;
  border: 2px solid rgba(0,0,0,0.4);
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,0.04),
    inset 0 0 30px rgba(0,0,0,0.5);
}
.vault-door::after {
  /* outer rivets glow */
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 25%, rgba(255,255,255,0.08), transparent 50%);
  pointer-events: none;
}

/* hinges (left side) */
.vault-hinge {
  position: absolute;
  width: 28px; height: 56px;
  background: linear-gradient(180deg, #2A3D4D 0%, #0E1820 50%, #2A3D4D 100%);
  border-radius: 4px;
  left: -14px;
  box-shadow: inset 0 0 0 1px #0A1219, 0 2px 8px rgba(0,0,0,0.5);
  z-index: 0;
}
.vault-hinge::before {
  content: '';
  position: absolute;
  inset: 6px 4px;
  background: repeating-linear-gradient(180deg, #4A5C6E 0 4px, #1A2632 4px 6px);
  border-radius: 2px;
}
.vault-hinge--top { top: 18%; }
.vault-hinge--bot { bottom: 18%; }

/* central spoked wheel */
.vault-spoke {
  position: absolute;
  top: 50%; left: 50%;
  width: 220px; height: 220px;
  margin: -110px 0 0 -110px;
  pointer-events: none;
  transition: transform 1.4s cubic-bezier(0.4, 0.05, 0.2, 1);
}
.vault-spoke__hub {
  position: absolute; inset: 38%;
  background: radial-gradient(circle at 35% 35%, #6A7B8A, #2A3D4D 70%);
  border-radius: 50%;
  box-shadow:
    inset 0 0 0 2px rgba(0,0,0,0.5),
    inset 0 -3px 6px rgba(0,0,0,0.4),
    0 4px 14px rgba(0,0,0,0.5);
}
.vault-spoke__hub::after {
  content: '';
  position: absolute; inset: 28%;
  background: radial-gradient(circle at 30% 30%, #1A2632, #0E1820);
  border-radius: 50%;
  border: 1px solid rgba(0,0,0,0.5);
}
.vault-spoke__arm {
  position: absolute; top: 50%; left: 50%;
  width: 100px; height: 14px;
  margin-top: -7px;
  background: linear-gradient(180deg, #4A5C6E, #2A3D4D 50%, #1A2632);
  border-radius: 7px;
  transform-origin: 0 50%;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.1),
    inset 0 -1px 0 rgba(0,0,0,0.5),
    0 2px 6px rgba(0,0,0,0.4);
}
.vault-spoke__arm::after {
  content: '';
  position: absolute; right: -6px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px;
  background: radial-gradient(circle at 30% 30%, #6A7B8A, #2A3D4D 70%);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.5), 0 1px 4px rgba(0,0,0,0.5);
}
.vault-spoke__arm--1 { transform: rotate(0deg); }
.vault-spoke__arm--2 { transform: rotate(72deg); }
.vault-spoke__arm--3 { transform: rotate(144deg); }
.vault-spoke__arm--4 { transform: rotate(216deg); }
.vault-spoke__arm--5 { transform: rotate(288deg); }

/* dial markings ring */
.vault-dial {
  position: absolute; inset: 12%;
  border-radius: 50%;
  pointer-events: none;
}
.vault-dial__tick {
  position: absolute;
  top: 50%; left: 50%;
  width: 1px; height: 6px;
  background: rgba(255,255,255,0.35);
  transform-origin: 0 0;
}
.vault-dial__tick--major { height: 10px; background: rgba(255,255,255,0.6); width: 1.5px; }

/* nameplate — engraved labels on a curved path wrapping the upper arc of
   the lock. SVG lives inside .vault-spoke, so it spins with the wheel
   during `is-spinning` and rotates with the door when it swings open. The
   half-arc runs at radius 130 (in 320x320 viewBox), comfortably outside
   the 100 px spoke arms and inside the dial-tick ring at ~169 px. */
.vault-nameplate {
  display: block;
  position: absolute;
  top: 50%; left: 50%;
  width: 320px; height: 320px;
  margin: -160px 0 0 -160px;
  pointer-events: none;
  overflow: visible;
}
.vault-nameplate__text {
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 3px;
  fill: rgba(255,255,255,0.5);
  text-transform: uppercase;
}
.vault-nameplate__text--lg {
  font-size: 11px;
  letter-spacing: 5px;
  fill: rgba(255,255,255,0.72);
}

/* interior (revealed when door opens) */
.vault-interior {
  position: absolute; inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #1A1410 0%, #0A0604 80%);
  box-shadow:
    inset 0 0 60px rgba(0,0,0,0.9),
    inset 0 0 0 4px #0A0604;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  z-index: -1;
}
.vault-interior__glow {
  position: absolute;
  width: 60%; height: 60%;
  background: radial-gradient(circle, rgba(220,32,21,0.4) 0%, transparent 70%);
  filter: blur(20px);
  opacity: 0;
}
.vault-interior__mark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 72px;
  letter-spacing: -2px;
  color: var(--victory-red);
  text-shadow: 0 0 40px rgba(220,32,21,0.6);
  opacity: 0;
  transform: scale(0.7);
  transition: all 0.6s var(--ease-standard) 0.4s;
}
.vault-interior__sub {
  position: absolute;
  bottom: 30%;
  font-size: 11px;
  letter-spacing: 4px;
  color: rgba(255,255,255,0.4);
  text-transform: uppercase;
  opacity: 0;
  transition: all 0.4s var(--ease-standard) 0.7s;
}

/* ===== STATES ===== */
/* "Primed" — fired when the user advances from the email step to the
   password step. One major tick (36°) of dial rotation telegraphs that
   the lock has registered the identity and is ready to receive the
   combination. The 0.6s spring is deliberately shorter than the 1.4s
   spin so it reads as a discrete "click," not a windup. */
.vault-door.is-primed .vault-spoke {
  transform: rotate(36deg);
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.vault-door.is-spinning .vault-spoke {
  transform: rotate(540deg);
}
.vault-door.is-open {
  transform: rotateY(-92deg);
  box-shadow:
    inset 0 0 0 4px #2A3D4D,
    inset 0 0 0 6px #0A1219,
    20px 0 60px rgba(0,0,0,0.7),
    20px 0 30px rgba(0,0,0,0.5);
}
.vault-door.is-open + .vault-interior .vault-interior__glow {
  opacity: 1;
  transition: opacity 1s ease-out 0.6s;
}
.vault-door.is-open + .vault-interior .vault-interior__mark {
  opacity: 1; transform: scale(1);
}
.vault-door.is-open + .vault-interior .vault-interior__sub {
  opacity: 1;
}

/* corner brand mark — top left.
   Per the mobile-fullscreen-splash skill (memory 5fe138db): foreground
   corner elements use position: fixed with safe-area padding so they
   pin to the viewport corner regardless of any scroll position. */
.login-corner-logo {
  position: fixed;
  top: max(28px, env(safe-area-inset-top, 0px) + 16px);
  left: max(32px, env(safe-area-inset-left, 0px) + 16px);
  z-index: 5001;
  display: flex; align-items: center;
  text-decoration: none;
}
.login-corner-logo img {
  display: block;
  width: auto;
  min-width: 280px;
  height: auto;
}
/* corner slogan — top right, uses canonical .tagline component.
   Montserrat Bold on dark: override --tagline-weight to bold (default is
   medium) so the body of the slogan matches the bolded `<em>` accents.
   --tagline-color is overridden for dark-background readability;
   --tagline-accent stays Victory Red per brand spec. */
.login-corner-slogan {
  /* Foreground corner element — position: fixed per the
     mobile-fullscreen-splash skill (memory 5fe138db). */
  position: fixed;
  top: max(28px, env(safe-area-inset-top, 0px) + 16px);
  right: max(32px, env(safe-area-inset-right, 0px) + 16px);
  z-index: 5001;
  /* Montserrat only — no Inter fallback. With Inter in the stack the
     slogan was painting in Inter during the font-swap window (visible
     tell: Inter's Z has a horizontal crossbar, Montserrat's doesn't).
     Montserrat-Bold/Medium are preloaded in index.html so this should
     resolve before first paint; the system sans is here just to keep
     metrics from collapsing if the preload itself fails. */
  font-family: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
  /* Body sets font-feature-settings: "liga","calt","ss01","ss02","zero",
     which is inherited here and can activate alternate uppercase glyphs
     in some Montserrat builds — including a barred Z. Reset to defaults
     on the slogan so the Z reads as the standard plain Montserrat Z. */
  font-feature-settings: normal !important;
  font-variant: normal !important;
  --tagline-color: rgba(255,255,255,0.92);
  --tagline-weight: var(--fw-bold);
  --tagline-align: right;
  font-size: 25px;
  line-height: 1.3;
  max-width: 560px;
  /* align-items: flex-end shrink-wraps each .tagline__line to its own
     text width and pins them all to the container's right edge. Without
     this, the default stretch + text-align:right "works" only when every
     line is exactly the container's content width — but the container
     shrink-wraps to the widest line, so subpixel rounding and font-swap
     width shifts visibly misalign the right edges. */
  align-items: flex-end;
  text-align: right !important;
}
.login-corner-slogan .tagline__line {
  text-align: right;
}

/* Bottom bar — two groups, four atomic items.
   Outer flex with space-between pins the TLS group left and the firm
   group right. Each group is its own flex-wrap row, so its two items lay
   out side-by-side when there's space and stack within the group when the
   group runs out of room. The outer flex is also wrap, so on the
   narrowest viewports the right group falls below the left rather than
   colliding. Each item is white-space: nowrap so phrases never break
   mid-text.
   Foreground bottom bar — position: fixed per the
   mobile-fullscreen-splash skill (memory 5fe138db); pinned to the
   viewport bottom edge with safe-area padding so it never overlaps the
   iOS home indicator on devices with rounded screens. */
.login-bottom-bar {
  position: fixed;
  left: max(32px, env(safe-area-inset-left, 0px) + 16px);
  right: max(32px, env(safe-area-inset-right, 0px) + 16px);
  bottom: max(12px, env(safe-area-inset-bottom, 0px) + 8px);
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  justify-content: space-between;
  column-gap: 32px;
  row-gap: 8px;
  font-size: 12px;
  color: rgba(255,255,255,0.45);
  z-index: 5001;
  pointer-events: none;
}
.login-bottom-bar__group {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  column-gap: 24px;
  row-gap: 4px;
  min-width: 0;
}
.login-bottom-bar__group--firm {
  margin-left: auto;
  justify-content: flex-end;
  text-align: right;
}

/* Progressive wrap cascade. Each viewport breakpoint unlocks one more
   level of wrapping, in the order the user asked for:
     1. TLS group wraps internally first — Session line on top, TLS+pulse
        below (wrap-reverse keeps the wide-screen order intact while
        flipping the vertical stacking direction).
     2. Then FIRM group wraps internally — CHIRICA LAW OFFICE on top,
        CHICAGO · IL below (plain wrap, JSX order matches desired stack).
     3. Finally, on the very narrowest viewports the outer bar itself
        wraps so the firm group falls below the TLS group; margin-left:
        auto keeps it right-aligned on its own row. */
@media (max-width: 900px) {
  .login-bottom-bar__group--tls { flex-wrap: wrap-reverse; }
}
@media (max-width: 600px) {
  /* wrap-reverse so the stacking order is CHICAGO · IL on top, CHIRICA
     LAW OFFICE underneath — the city pairing reads better as the
     subtitle to the firm name on mobile portrait. */
  .login-bottom-bar__group--firm { flex-wrap: wrap-reverse; }
}
@media (max-width: 460px) {
  .login-bottom-bar {
    flex-wrap: wrap;
    /* On the very narrowest viewports, pull the bar's outer offsets in
       so the TLS items hug the left edge and the FIRM items hug the
       right — gives the four phrases the most breathing room before
       they'd otherwise have to truncate. iOS safe-area insets keep the
       text clear of any rounded-screen chrome. */
    left: max(8px, env(safe-area-inset-left, 0px));
    right: max(8px, env(safe-area-inset-right, 0px));
    column-gap: 8px;
  }
}
.login-bottom-bar__item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.login-bottom-bar__group--tls .login-bottom-bar__item {
  font-family: var(--font-mono);
  letter-spacing: 0.4px;
}
.login-bottom-bar__group--firm .login-bottom-bar__item {
  font-family: var(--font-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 600;
}

@media (max-width: 900px) {
  .login-corner-slogan { display: none; }
  .login-corner-logo img { min-width: 160px; }
}

/* whole stage flash on unlock */
.login-stage.is-unlocking::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(circle at center, rgba(220,32,21,0.3), transparent 50%);
  animation: unlock-flash 1.4s var(--ease-standard) forwards;
  pointer-events: none;
}
@keyframes unlock-flash {
  0% { opacity: 0; }
  60% { opacity: 1; }
  100% { opacity: 0; }
}

/* fade out the whole login stage when transitioning */
.login-stage.is-leaving {
  animation: stage-leave 0.7s var(--ease-standard) forwards;
}
@keyframes stage-leave {
  to { opacity: 0; transform: scale(1.08); filter: blur(8px); }
}

/* =============================================================================
   VIEWER SHELL — Document / Image / Video
   ============================================================================= */
.viewer {
  position: fixed;
  inset: 0;
  background: #1A2632;
  display: grid;
  grid-template-columns: 64px 1fr 360px;
  grid-template-rows: 56px 1fr 56px;
  grid-template-areas:
    "head head head"
    "tools canvas side"
    "head2 footer side";
}

.viewer.surround-light {
  background: #F2F4F7;
}

.viewer.surround-light .viewer__canvas-bg {
  background: linear-gradient(180deg, #F7FAFC 0%, #E9EDF2 100%);
}

.viewer.surround-light .viewer__head,
.viewer.surround-light .viewer__footer {
  background: rgba(255, 255, 255, 0.9);
  border-color: var(--border);
  color: var(--fg-1);
}

.viewer.surround-light .viewer__title {
  color: var(--fg-1);
}

.viewer.surround-light .viewer__sub {
  color: var(--fg-3);
}

.viewer.surround-light .viewer__tools {
  background: #fff;
  border-color: var(--border);
}

.viewer.surround-light .viewer__tool {
  color: var(--fg-3);
}

.viewer.surround-light .viewer__tool:hover {
  color: var(--fg-1);
  background: #F1F5F9;
}

.viewer.surround-light .viewer__tool.is-active {
  background: var(--victory-red);
  color: #fff;
}

.viewer__head {
  grid-area: head / head / head / head;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 20px;
  background: rgba(10, 18, 25, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  color: #fff;
  z-index: 10;
}

.viewer__back {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px 6px 8px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  font-family: var(--font-display);
  transition: all 0.12s ease;
}

.viewer__back:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.viewer__title-wrap {
  min-width: 0;
  flex: 1;
}

.viewer__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  color: #fff;
  letter-spacing: -0.1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.viewer__sub {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
  letter-spacing: 0.1px;
  margin-top: 1px;
  font-family: var(--font-mono);
}

.viewer__head-actions {
  display: flex;
  gap: 6px;
}

.viewer__head-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 7px;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  transition: all 0.1s ease;
}

.viewer__head-btn:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

.viewer__head-btn:disabled {
  opacity: 0.55;
  cursor: default;
}

/* Labeled variant — the export button carries text alongside its icon, so
   it widens to fit instead of staying a 32px square. */
.viewer__head-btn--export {
  width: auto;
  gap: 6px;
  padding: 0 11px;
}
.viewer__head-btn-label {
  font-family: var(--font-display, sans-serif);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.2px;
}
/* On narrow screens drop the label and fall back to an icon-only square. */
@media (max-width: 640px) {
  .viewer__head-btn--export { width: 32px; padding: 0; }
  .viewer__head-btn-label { display: none; }
}

/* HTML iframe wrapper (Viewer.jsx kind === 'html'). Position: relative
   + absolute-fill iframe defeats the iOS Safari quirk where an iframe
   with height: 100% inside a flex/grid cell snaps to its CONTENT height
   instead of stretching — leaving a strip of the viewer's dark surround
   visible underneath (the "black bar" users see on iPhone). The sheet's
   solid white background also covers any narrow gap if the iframe
   briefly shrinks during scroll. Applies on every viewport size. */
.viewer__html-frame {
  position: relative;
  width: 100%;
  height: 100%;
  flex: 1 1 auto;
  align-self: stretch;
  background: #fff;
  min-height: 0;
}
.viewer__html-frame > iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
}

.viewer__tools {
  grid-area: tools / tools / tools / tools;
  background: rgba(10, 18, 25, 0.6);
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  padding: 12px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}

/* Desktop hides mobile-only undo/redo inside the pill — they live in the
   header bar there. Mobile breakpoint re-enables them. */
.viewer__tool--mobile-only,
.viewer__tool-divider--mobile-only {
  display: none;
}

.viewer__tool {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  transition: all 0.12s ease;
  position: relative;
}

.viewer__tool:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

.viewer__tool.is-active {
  background: var(--victory-red);
  color: #fff;
  box-shadow: 0 4px 12px rgba(220, 32, 21, 0.4);
}

.viewer__tool-divider {
  width: 28px;
  height: 1px;
  background: rgba(255, 255, 255, 0.08);
  margin: 4px 0;
}

.viewer__tool-tip {
  position: absolute;
  left: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  background: #0A1219;
  color: #fff;
  font-size: 12px;
  font-family: var(--font-display);
  font-weight: 500;
  padding: 5px 9px;
  border-radius: 5px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform-origin: left center;
  transform: translateY(-50%) scale(0.9);
  transition: all 0.15s var(--ease-standard);
  z-index: 20;
}

.viewer__tool:hover .viewer__tool-tip {
  opacity: 1;
  transform: translateY(-50%) scale(1);
}

.viewer__canvas,
.viewer__canvas-wrap {
  grid-area: canvas / canvas / canvas / canvas;
  position: relative;
  overflow: auto;
  display: flex;
  /* `safe center` — center when content fits, fall back to flex-start
     when it doesn't. Without `safe`, taller-than-container content gets
     pushed above the visible area and the top is unreachable via scroll,
     which read as "everything is under the top bar". */
  align-items: safe center;
  justify-content: safe center;
  padding: 24px;
}

/* ── PDF bookmarks tree (Bookmarks tab in the discussion sidebar) ─────────── */
.bm-list {
  padding: 8px 8px 16px;
}
.bm-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 7px 8px 7px calc(8px + var(--depth, 0) * 14px);
  background: transparent;
  border: 0;
  border-radius: 7px;
  color: var(--fg-2);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1.35;
  transition: background 0.1s ease, color 0.1s ease;
}
.bm-row:hover { background: #F1F5F9; color: var(--fg-1); }
.bm-row:disabled { opacity: 0.5; cursor: default; }
.bm-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-page {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}
/* Hairline guide down each nesting level for scannability. */
.bm-node .bm-node {
  margin-left: 7px;
  border-left: 1px solid var(--border);
}

/* ── pdfjs text layer — selectable transparent text over each page canvas ──── */
.textLayer {
  position: absolute;
  inset: 0;
  overflow: clip;
  opacity: 1;
  line-height: 1;
  text-align: initial;
  text-size-adjust: none;
  forced-color-adjust: none;
  transform-origin: 0 0;
  /* z-index:0 creates a stacking context so the spans' internal z-index:1
     stays contained here, while the layer itself paints in tree order — i.e.
     below the later-in-DOM stroke layer and pins. */
  z-index: 0;
}
.textLayer :is(span, br) {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}
.textLayer span.markedContent { top: 0; height: 0; }
.textLayer ::selection { background: rgba(96, 145, 255, 0.42); }
.textLayer br::selection { background: transparent; }
.textLayer .endOfContent {
  display: block; position: absolute; inset: 100% 0 0; z-index: 0;
  cursor: default; user-select: none;
}

.viewer__canvas-bg {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 30% 0%, rgba(255, 255, 255, 0.04), transparent 50%),
    linear-gradient(180deg, #1A2632 0%, #0E1820 100%);
  pointer-events: none;
}

.viewer__footer {
  grid-area: footer / footer / footer / footer;
  background: rgba(10, 18, 25, 0.85);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  color: rgba(255, 255, 255, 0.7);
  font-size: 14px;
}

.viewer__zoom {
  display: flex;
  align-items: center;
  gap: 4px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 2px;
}

.viewer__zoom-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
}

.viewer__zoom-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.viewer__zoom-val {
  font-family: var(--font-mono);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
  padding: 0 8px;
  min-width: 48px;
  text-align: center;
}

/* ---------- SIDEBAR ---------- */
.viewer__side {
  grid-area: side / side / side / side;
  grid-row: 1 / span 3;
  background: #fff;
  border-left: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.side-head {
  /* Push the sidebar's first row down so its title clears the viewer
     header band — without this it sits under the dark chrome. */
  margin-top: 60px;
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.side-head__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.side-head__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--knowledgeable-blue);
}

.side-head__count {
  font-family: var(--font-mono);
  font-size: 12px;
  background: rgba(220, 32, 21, 0.08);
  color: var(--victory-red);
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 700;
}

.side-head__hint {
  font-size: 14px;
  color: var(--fg-3);
  margin-top: 8px;
  line-height: 1.5;
}

.side-tabs {
  display: flex;
  gap: 4px;
  margin-top: 10px;
  padding: 3px;
  background: #F1F5F9;
  border-radius: 8px;
}

.side-tab {
  flex: 1;
  padding: 6px 10px;
  border-radius: 5px;
  background: transparent;
  border: none;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  color: var(--fg-3);
  cursor: pointer;
  letter-spacing: 0.4px;
  transition: all 0.12s ease;
}

.side-tab.is-active {
  background: #fff;
  color: var(--fg-1);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}

.side-list {
  overflow-y: auto;
  flex: 1;
  padding: 8px 8px;
}

.side-empty {
  padding: 60px 24px;
  text-align: center;
  color: var(--fg-3);
  font-size: 15px;
  line-height: 1.6;
}

.side-empty__icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: #F1F5F9;
  color: var(--fg-3);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 14px;
}

.cmt {
  padding: 12px 12px;
  border-radius: 10px;
  cursor: pointer;
  margin-bottom: 4px;
  border: 1px solid transparent;
  transition: all 0.12s ease;
}

.cmt:hover {
  background: #FAFBFC;
  border-color: var(--border);
}

.cmt.is-active {
  background: rgba(220, 32, 21, 0.04);
  border-color: rgba(220, 32, 21, 0.2);
}

/* Attention flash on the DOCUMENT marking — played when its comment is
   clicked in the discussion. Two quick pulses, then back to normal. Re-fires
   on every click via a JS class re-add (see Viewer.jsx). */

/* Pin teardrops: bounce + glow. */
@keyframes pin-flash {
  0%   { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(220, 32, 21, 0)); }
  20%  { transform: scale(1.4);  filter: drop-shadow(0 0 7px rgba(220, 32, 21, 0.95)); }
  40%  { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(220, 32, 21, 0)); }
  60%  { transform: scale(1.35); filter: drop-shadow(0 0 7px rgba(220, 32, 21, 0.95)); }
  100% { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(220, 32, 21, 0)); }
}
.pin.is-flash .pin__teardrop {
  animation: pin-flash 1.15s ease-in-out;
  transform-origin: center bottom;
}

/* Strokes / shapes / text labels: a pulsing glow drawn around the mark. */
@keyframes mark-flash {
  0%   { filter: drop-shadow(0 0 0 rgba(220, 32, 21, 0)); }
  20%  { filter: drop-shadow(0 0 5px rgba(220, 32, 21, 0.95)); }
  40%  { filter: drop-shadow(0 0 0 rgba(220, 32, 21, 0)); }
  60%  { filter: drop-shadow(0 0 5px rgba(220, 32, 21, 0.95)); }
  100% { filter: drop-shadow(0 0 0 rgba(220, 32, 21, 0)); }
}
.draw-layer .is-flash {
  animation: mark-flash 1.15s ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  .pin.is-flash .pin__teardrop,
  .draw-layer .is-flash { animation: none; }
}

.cmt__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.cmt__pin {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--victory-red);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 1px;
  flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(220, 32, 21, 0.3);
}

.cmt__author {
  font-size: 15px;
  font-weight: 600;
  color: var(--fg-1);
  font-family: var(--font-display);
}

.cmt__time {
  font-size: 12px;
  color: var(--fg-3);
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

.cmt__loc {
  font-size: 12px;
  color: var(--fg-3);
  margin-bottom: 4px;
  font-family: var(--font-mono);
  display: flex;
  align-items: center;
  gap: 6px;
}

.cmt__loc-chip {
  background: #F1F5F9;
  padding: 1px 6px;
  border-radius: 3px;
  border: 1px solid var(--border);
}

.cmt__body {
  font-size: 15px;
  color: var(--fg-1);
  line-height: 1.5;
}

/* Condensed replies — rendered inside the comment bubble. Each is a tight
   single block (author then body) on a subtle inset rail, so a thread reads
   compactly without sprawling into separate cards. */
.cmt__replies {
  margin-top: 8px;
  padding-left: 10px;
  border-left: 2px solid var(--border, #e6eaf0);
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.cmt__reply {
  position: relative;
  font-size: 14px;
  color: var(--fg-2);
  line-height: 1.45;
  padding-right: 16px;
}
.cmt__reply-author {
  font-weight: 700;
  color: var(--fg-1);
  margin-right: 5px;
}
.cmt__reply-author.is-firm { color: var(--victory-red, #DC2015); }
.cmt__reply-body { color: var(--fg-2); }
.cmt__reply-del {
  position: absolute;
  top: 0; right: 0;
  width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: 4px;
  color: var(--fg-3); cursor: pointer; opacity: 0;
  transition: opacity 0.12s ease, background 0.1s ease, color 0.1s ease;
}
.cmt__reply:hover .cmt__reply-del { opacity: 1; }
.cmt__reply-del:hover { background: rgba(220,32,21,0.10); color: var(--victory-red, #DC2015); }

/* Completed comment — struck through and dimmed. */
.cmt.is-completed .cmt__body { text-decoration: line-through; }
.cmt.is-completed { opacity: 0.72; }
.cmt.is-completed:hover { opacity: 1; }

/* Location-chip variants. */
.cmt__loc-chip--firm { background: #FEE2E2; color: #991B1B; margin-left: 6px; }
.cmt__loc-chip--done {
  display: inline-flex; align-items: center; gap: 3px;
  background: rgba(16,122,68,0.12); color: #0b7a44; border-color: rgba(16,122,68,0.25);
  margin-left: 6px;
}

/* Completed-view toggle in the Discussion header. */
.side-head__row .side-head__title { margin-right: auto; }
.side-head__toggle {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px;
  background: var(--surface-2, #f1f5f9);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 999px;
  color: var(--fg-2);
  font-family: var(--font-display, sans-serif);
  font-size: 12px; font-weight: 700;
  cursor: pointer;
  transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}
.side-head__toggle:hover { background: #e7ecf2; color: var(--fg-1); }
.side-head__toggle.is-active {
  background: rgba(16,122,68,0.12); color: #0b7a44; border-color: rgba(16,122,68,0.3);
}

.cmt-compose {
  border-top: 1px solid var(--border);
  padding: 12px 14px 14px;
  background: #FAFBFC;
  flex-shrink: 0;
}

.cmt-compose__hint {
  font-size: 12px;
  color: var(--fg-3);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  letter-spacing: 0.2px;
}

.cmt-compose__hint .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--victory-red);
  box-shadow: 0 0 0 0 rgba(220, 32, 21, 0.6);
  animation: secure-pulse 1.6s ease-out infinite;
}

.cmt-compose__hint--ready .dot {
  background: var(--knowledgeable-blue);
  animation: none;
}

.cmt-compose__textarea {
  width: 100%;
  min-height: 60px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-ui);
  font-size: 15px;
  resize: none;
  outline: none;
  color: var(--fg-1);
  transition: all 0.12s ease;
}

.cmt-compose__textarea:focus {
  border-color: rgba(220, 32, 21, 0.4);
  box-shadow: 0 0 0 3px rgba(220, 32, 21, 0.08);
}

.cmt-compose__textarea:disabled {
  background: #fff;
  color: var(--fg-3);
  cursor: not-allowed;
}

.cmt-compose__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
}

/* ---------- DOCUMENT / IMAGE CANVAS ---------- */
.doc-page {
  position: relative;
  background: #fff;
  width: 720px;
  min-height: 932px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.04);
  font-family: var(--font-legal);
  font-size: 15px;
  line-height: 1.7;
  padding: 80px 80px 100px;
  color: #000;
  user-select: text;
}

.doc-page__pageno {
  position: absolute;
  bottom: 36px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-legal);
  font-size: 12px;
  color: var(--fg-3);
}

.doc-page h1.doc-h1 {
  font-family: var(--font-legal);
  font-size: 16px;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin: 0 0 18px;
}

.doc-page h2.doc-h2 {
  font-family: var(--font-legal);
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  margin: 18px 0 14px;
  text-transform: uppercase;
}

.doc-page p.doc-p {
  text-indent: 0.5in;
  margin: 0 0 8px;
}

.doc-page .doc-num {
  display: flex;
  gap: 14px;
  margin-bottom: 8px;
}

.doc-page .doc-num span:first-child {
  color: var(--fg-3);
  width: 20px;
  flex-shrink: 0;
}

/* image canvas */
.image-frame {
  position: relative;
  background: #000;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  overflow: hidden;
}

.image-frame img {
  display: block;
  max-width: 90vw;
  max-height: calc(100vh - 200px);
  user-select: none;
  -webkit-user-drag: none;
}

/* the markup overlay */
.markup-overlay {
  position: absolute;
  inset: 0;
  cursor: crosshair;
}

.markup-overlay--pin {
  cursor: copy;
}

.markup-overlay--none {
  cursor: default;
  pointer-events: none;
}

/* a placed pin */
.pin {
  position: absolute;
  width: 28px;
  height: 28px;
  margin-left: -14px;
  margin-top: -28px;
  /* anchor at bottom point */
  pointer-events: auto;
  cursor: pointer;
  filter: drop-shadow(0 4px 10px rgba(220, 32, 21, 0.45));
  transition: transform 0.12s var(--ease-bounce);
  animation: pin-drop 0.4s var(--ease-bounce);
}

@keyframes pin-drop {
  0% {
    transform: translateY(-12px) scale(0.6);
    opacity: 0;
  }

  60% {
    transform: translateY(2px) scale(1.05);
    opacity: 1;
  }

  100% {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
}

.pin:hover {
  transform: scale(1.1);
}

.pin.is-active {
  transform: scale(1.15);
  z-index: 5;
}

.pin__teardrop {
  width: 28px;
  height: 28px;
  background: var(--victory-red);
  border: 2px solid #fff;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.2);
}

.pin__num {
  transform: rotate(45deg);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 1px;
  margin-top: -2px;
  margin-left: -1px;
}

.pin--style-dot {
  filter: drop-shadow(0 2px 6px rgba(220, 32, 21, 0.4));
  margin-top: -14px;
}

.pin--style-dot .pin__teardrop {
  border-radius: 50%;
  transform: none;
  width: 22px;
  height: 22px;
}

.pin--style-dot .pin__num {
  transform: none;
  margin: 0;
}

.pin--style-dot {
  width: 22px;
  height: 22px;
  margin-left: -11px;
}

/* preview crosshair pin */
.pin-ghost {
  position: absolute;
  pointer-events: none;
  width: 28px;
  height: 28px;
  margin-left: -14px;
  margin-top: -28px;
  opacity: 0.5;
}

/* drawing layer */
.draw-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.draw-layer svg {
  width: 100%;
  height: 100%;
  display: block;
}

.draw-layer .stroke {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* All markup shapes use vector-effect: non-scaling-stroke so the rendered
   width stays consistent regardless of the SVG viewBox / page scale. The
   SVG uses preserveAspectRatio="none" on a 1000x1000 box, which would
   otherwise squash strokes anisotropically. */
.draw-layer .stroke--pen,
.draw-layer .stroke--high,
.draw-layer .rect-shape,
.draw-layer .arrow-shape,
.draw-layer .arrow-head,
.draw-layer .textmark-strike {
  vector-effect: non-scaling-stroke;
}

/* Text marks — highlight box (translucent, multiplies so the text below shows
   through) and strikethrough line. Fill/stroke color is set inline per mark. */
.draw-layer .textmark-hl {
  fill-opacity: 0.40;
  mix-blend-mode: multiply;
}
.draw-layer .textmark-strike {
  stroke-width: 2.5;
  stroke-linecap: round;
}

/* Selected mark (Select mode) — a blue glow marks the Delete target. */
.draw-layer .is-selected {
  filter: drop-shadow(0 0 1px #2563eb) drop-shadow(0 0 4px rgba(37, 99, 235, 0.9));
}

/* ── Text-selection toolbar ─────────────────────────────────────────────── */
.seltoolbar {
  position: fixed;
  z-index: 60;
  transform: translate(-50%, calc(-100% - 9px));
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 7px;
  background: rgba(22, 28, 36, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  animation: seltoolbar-in 0.12s ease-out;
}
@keyframes seltoolbar-in {
  from { opacity: 0; transform: translate(-50%, calc(-100% - 3px)); }
  to   { opacity: 1; transform: translate(-50%, calc(-100% - 9px)); }
}
.seltoolbar::after {
  content: '';
  position: absolute;
  left: 50%; bottom: -5px;
  width: 10px; height: 10px;
  transform: translateX(-50%) rotate(45deg);
  background: rgba(22, 28, 36, 0.97);
  border-right: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.seltoolbar__swatches { display: inline-flex; align-items: center; gap: 4px; }
.seltoolbar__swatch {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.35);
  cursor: pointer;
  padding: 0;
  transition: transform 0.08s ease, border-color 0.08s ease;
}
.seltoolbar__swatch:hover { transform: scale(1.18); border-color: #fff; }
.seltoolbar__sep {
  width: 1px; height: 20px;
  background: rgba(255, 255, 255, 0.16);
  margin: 0 2px;
}
.seltoolbar__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 28px;
  background: transparent;
  border: 0; border-radius: 7px;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  transition: background 0.1s ease, color 0.1s ease;
}
.seltoolbar__btn:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
.seltoolbar__btn--underline { color: #ff7d73; }
.seltoolbar__btn--underline:hover { background: rgba(220, 32, 21, 0.22); color: #ff9a92; }

.draw-layer .stroke--pen {
  stroke: #DC2015;
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.draw-layer .stroke--high {
  stroke: rgba(255, 200, 0, 0.45);
  stroke-width: 22;
  stroke-linecap: butt;
  fill: none;
}

.draw-layer .rect-shape {
  fill: none;
  stroke: #DC2015;
  stroke-width: 3.5;
}

.draw-layer .arrow-shape {
  fill: none;
  stroke: #DC2015;
  stroke-width: 4;
  stroke-linecap: round;
}
/* Solid filled arrowhead triangle (replaces the old open polyline). */
.draw-layer .arrow-head {
  fill: #DC2015;
  stroke: #DC2015;
  stroke-width: 2;
  stroke-linejoin: round;
}

/* Tight drop-shadow on every markup shape EXCEPT text. CSS filter on the
   parent <svg> composites into all children and can't be undone per-child,
   so we apply the shadow to each shape class instead. Text labels stay
   filter-less so typed text looks like real text on the page. */
.draw-layer .stroke--pen,
.draw-layer .stroke--high,
.draw-layer .rect-shape,
.draw-layer .arrow-shape,
.draw-layer .arrow-head {
  /* Tight shadow — close to the shape, low blur, just enough to read as
     depth without looking like a graphic effect. */
  filter: drop-shadow(0 0.5px 0.8px rgba(0, 0, 0, 0.28));
}

/* HTML-rendered text labels (outside the SVG so they keep screen pixel
   sizing). Same font/size as the live composer so committing produces
   no visual jump. */
.draw-layer .text-label-html {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-weight: 400;
  font-size: 18px;
  line-height: 1.2;
  padding: 2px 4px;
}

/* tool option strip below tools */
.tool-options {
  position: absolute;
  top: 12px;
  left: 76px;
  background: rgba(10, 18, 25, 0.92);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  padding: 6px;
  display: flex;
  align-items: center;
  gap: 4px;
  color: #fff;
  z-index: 12;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  animation: pop-in 0.2s var(--ease-standard);
}

@keyframes pop-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.tool-options__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  padding: 0 8px;
}

.tool-options__sw {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 0.12s ease;
}

.tool-options__sw:hover {
  transform: scale(1.1);
}

.tool-options__sw.is-active {
  border-color: #fff;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2);
}

/* ===== VIDEO ===== */
.video-stage {
  position: relative;
  background: #000;
  border-radius: 4px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  width: 100%;
  max-width: 1100px;
  aspect-ratio: 16/9;
  cursor: pointer;
}

.video-fake {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.4), transparent 30%, transparent 70%, rgba(0, 0, 0, 0.7)),
    linear-gradient(135deg, #1a1612 0%, #2a221a 40%, #1a1612 100%);
}

.video-fake__plate {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(0, 0, 0, 0.7);
  border: 1px solid rgba(220, 32, 21, 0.6);
  color: #DC2015;
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 4px;
  letter-spacing: 1px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.video-fake__plate .rec-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #DC2015;
  box-shadow: 0 0 8px rgba(220, 32, 21, 0.8);
  animation: rec-pulse 1.4s infinite;
}

@keyframes rec-pulse {
  50% {
    opacity: 0.4;
  }
}

.video-fake__time {
  position: absolute;
  bottom: 16px;
  left: 16px;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 14px;
  padding: 4px 10px;
  border-radius: 3px;
  letter-spacing: 0.5px;
}

.video-fake__chip {
  position: absolute;
  top: 16px;
  left: 16px;
  background: rgba(0, 0, 0, 0.7);
  color: rgba(255, 255, 255, 0.85);
  font-family: var(--font-mono);
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 3px;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.video-fake__bars {
  position: absolute;
  bottom: 60px;
  left: 16px;
  display: flex;
  gap: 3px;
}

.video-fake__bars span {
  display: block;
  width: 3px;
  height: 12px;
  background: rgba(255, 255, 255, 0.3);
}

.video-fake__bars span:nth-child(2) {
  background: rgba(255, 255, 255, 0.6);
}

.video-fake__bars span:nth-child(3) {
  background: rgba(255, 255, 255, 0.85);
}

/* the actual frame content (pretend) */
.video-fake__scene {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.08);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 68px;
  letter-spacing: 4px;
  text-transform: uppercase;
}

/* video controls */
.video-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 16px 20px 14px;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.4) 60%, transparent 100%);
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: #fff;
  z-index: 5;
}

.video-controls__row {
  display: flex;
  align-items: center;
  gap: 14px;
}

.video-play {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--victory-red);
  color: #fff;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.12s ease;
  box-shadow: 0 4px 14px rgba(220, 32, 21, 0.45);
  flex-shrink: 0;
}

.video-play:hover {
  background: var(--victory-red-hover);
  transform: scale(1.05);
}

.video-play:active {
  transform: scale(0.96);
}

.video-time {
  font-family: var(--font-mono);
  font-size: 14px;
  color: rgba(255, 255, 255, 0.85);
  letter-spacing: 0.3px;
  white-space: nowrap;
}

.video-time .sep {
  color: rgba(255, 255, 255, 0.4);
  margin: 0 4px;
}

.video-actions {
  display: flex;
  gap: 6px;
  margin-left: auto;
}

.video-iconbtn {
  width: 34px;
  height: 34px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 7px;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.1s ease;
  position: relative;
}

.video-iconbtn:hover {
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}

.video-iconbtn.is-active {
  background: var(--victory-red);
  border-color: var(--victory-red);
  color: #fff;
}

/* speed pop */
.speed-pop {
  position: absolute;
  bottom: 100%;
  margin-bottom: 8px;
  right: 0;
  background: rgba(10, 18, 25, 0.96);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  min-width: 90px;
  gap: 2px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
  z-index: 30;
  animation: pop-in 0.15s ease;
}

.speed-pop__item {
  padding: 6px 10px;
  font-family: var(--font-mono);
  font-size: 14px;
  color: rgba(255, 255, 255, 0.75);
  border: none;
  background: transparent;
  cursor: pointer;
  border-radius: 5px;
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.speed-pop__item:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.speed-pop__item.is-active {
  background: var(--victory-red);
  color: #fff;
}

.speed-pop__item .check {
  opacity: 0;
}

.speed-pop__item.is-active .check {
  opacity: 1;
}

/* timeline */
.video-timeline {
  position: relative;
  height: 32px;
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 0 2px;
}

.video-track {
  position: absolute;
  left: 2px;
  right: 2px;
  height: 4px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  overflow: visible;
}

.video-track__buffered {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.28);
  border-radius: 999px;
}

.video-track__progress {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: linear-gradient(90deg, var(--victory-red), #FF3D2C);
  border-radius: 999px;
}

.video-track__handle {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  background: #fff;
  border: 3px solid var(--victory-red);
  border-radius: 50%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.video-track__pin {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  pointer-events: auto;
  cursor: pointer;
  z-index: 2;
}

.video-track__pin .marker {
  width: 14px;
  height: 14px;
  background: var(--victory-red);
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: -0.5px;
}

.video-track__pin .label {
  position: absolute;
  bottom: 100%;
  margin-bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(10, 18, 25, 0.95);
  color: #fff;
  font-size: 11px;
  font-family: var(--font-mono);
  padding: 3px 7px;
  border-radius: 3px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.12s ease;
  pointer-events: none;
}

.video-track__pin:hover .label {
  opacity: 1;
}

.video-flash {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at center, rgba(220, 32, 21, 0.4), transparent 60%);
  opacity: 0;
  pointer-events: none;
}

.video-flash.is-flashing {
  animation: vid-flash 0.6s ease-out;
}

@keyframes vid-flash {
  0% {
    opacity: 0;
  }

  30% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

/* big center play button before playing */
.video-bigplay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80px;
  height: 80px;
  background: rgba(220, 32, 21, 0.9);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  box-shadow: 0 0 0 12px rgba(220, 32, 21, 0.15), 0 12px 40px rgba(220, 32, 21, 0.5);
  transition: all 0.2s ease;
  color: #fff;
}

.video-stage.is-playing .video-bigplay {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.6);
}

/* playback speed badge top-left of frame */
.video-speedbadge {
  position: absolute;
  top: 56px;
  left: 16px;
  background: rgba(220, 32, 21, 0.9);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 3px;
  letter-spacing: 0.5px;
  z-index: 4;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.video-speedbadge.is-shown {
  opacity: 1;
}

/* frame-pinned overlay */
.video-frame-pin-marker {
  position: absolute;
  pointer-events: none;
  width: 32px;
  height: 32px;
  margin-left: -16px;
  margin-top: -32px;
  z-index: 4;
}

/* keyboard shortcuts hint */
.kbd-hints {
  display: flex;
  gap: 14px;
  align-items: center;
  margin-left: auto;
  color: rgba(255, 255, 255, 0.45);
  font-size: 12px;
}

.kbd-hints .kbd {
  font-family: var(--font-mono);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  padding: 1px 5px;
  margin-right: 4px;
  font-size: 11px;
}

/* =============================================================================
   ADMIN INSIDE access.chirica.law (preview surface)
   ============================================================================= */

/* nothing extra — uses dashboard styles */

/* Hide scrollbars in dark surfaces gracefully */
.viewer__canvas::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.viewer__canvas::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.02);
}

.viewer__canvas::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 5px;
}

.viewer__canvas::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.18);
}

.side-list::-webkit-scrollbar {
  width: 8px;
}

.side-list::-webkit-scrollbar-thumb {
  background: #E2E8F0;
  border-radius: 4px;
}

.vault-page::-webkit-scrollbar {
  width: 10px;
}

.vault-page::-webkit-scrollbar-thumb {
  background: #E2E8F0;
  border-radius: 5px;
}

/* ===========================================================
   ADDITIONS: Topbar actions, view switch, tiles, collapse, activity drawer, tutorial
   =========================================================== */

/* topbar action buttons (Activity / Take the tour) */
.vault-topbar__action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  background: #fff;
  border: 1px solid var(--border);
  color: var(--fg-2);
  border-radius: 8px;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.2px;
  margin-right: 8px;
  white-space: nowrap;
  flex-shrink: 0;
  transition: all 0.15s var(--ease-standard);
}

.vault-topbar__action:hover {
  background: #F7F8FA;
  color: var(--fg-1);
  border-color: #CBD5E0;
}

.vault-topbar__action:disabled {
  opacity: 0.5;
  cursor: default;
}
.vault-topbar__action:disabled:hover {
  background: #fff;
  color: var(--fg-2);
  border-color: var(--border);
}

.vault-topbar__action.is-active {
  background: rgba(220, 32, 21, 0.08);
  border-color: rgba(220, 32, 21, 0.35);
  color: var(--victory-red);
}

.vault-topbar__action.is-active:hover {
  background: rgba(220, 32, 21, 0.12);
}

/* toolbar above file sections */
.vault-toolbar {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 8px 0 18px;
}

.vault-toolbar__title {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--fg-3);
}

.vault-toolbar__spacer {
  flex: 1;
}

.vault-toolbar__viewswitch {
  display: inline-flex;
  padding: 3px;
  background: #EDF2F7;
  border: 1px solid var(--border);
  border-radius: 9px;
}

.vault-vs {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 12px;
  border: none;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  color: var(--fg-3);
  border-radius: 6px;
  transition: all 0.15s var(--ease-standard);
}

.vault-vs:hover {
  color: var(--fg-1);
}

.vault-vs.is-on {
  background: #fff;
  color: var(--fg-1);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.04);
}

/* folder section collapse chevron */
.file-section__chev {
  margin-right: -2px;
  transition: transform 0.18s var(--ease-standard);
  flex-shrink: 0;
}

.file-section.is-collapsed .file-section__bar {
  border-radius: 10px;
}

.file-section__bar {
  cursor: pointer;
}

/* folder tiles grid */
.folder-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
  margin-bottom: 8px;
}

.folder-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  text-align: left;
  padding: 16px 18px 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.18s var(--ease-standard);
  overflow: hidden;
}

.folder-tile::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
}

.folder-tile--blue::before {
  background: linear-gradient(180deg, var(--knowledgeable-blue), #3B6B8A);
}

.folder-tile--red::before {
  background: linear-gradient(180deg, var(--victory-red), #A01810);
}

.folder-tile {
  /* Hover lift transition. Will-change keeps the compositor warm so the
     translate is smooth on first hover; ease-out feels snappier than the
     default ease for short distances. */
  transition: transform 0.18s ease-out, box-shadow 0.22s ease-out, border-color 0.18s ease-out;
  will-change: transform;
}
.folder-tile:hover {
  border-color: #CBD5E0;
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.10);
}
.folder-tile:active {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08);
}

.folder-tile__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.folder-tile__icon {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  color: #fff;
}

.folder-tile--blue .folder-tile__icon {
  background: linear-gradient(135deg, var(--knowledgeable-blue), #3B6B8A);
}

.folder-tile--red .folder-tile__icon {
  background: linear-gradient(135deg, var(--victory-red), #A01810);
}

.folder-tile__chev {
  color: var(--fg-4);
}

.folder-tile:hover .folder-tile__chev {
  color: var(--victory-red);
}

.folder-tile__name {
  font-family: var(--font-francy);
  font-weight: 400;
  font-size: 19px;
  color: var(--fg-1);
  margin-bottom: 6px;
}

.folder-tile__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--fg-3);
}

.folder-tile__sep {
  color: var(--fg-4);
}

.folder-tile__date {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed #E2E8F0;
  font-size: 12px;
  color: var(--fg-4);
  letter-spacing: 0.3px;
}

/* activity drawer */
.vault-activity-drawer {
  position: fixed;
  top: 60px;
  left: 4px;
  right: 0;
  max-height: 60vh;
  background: #fff;
  border-bottom: 1px solid var(--border);
  box-shadow: 0 18px 32px rgba(15, 23, 42, 0.08);
  z-index: 30;
  overflow-y: auto;
  animation: drawerIn 0.22s var(--ease-standard);
}

@keyframes drawerIn {
  from {
    transform: translateY(-12px);
    opacity: 0;
  }

  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.vault-activity-drawer__inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 22px 32px 28px;
}

/* activity feed */
.act-feed {
  font-family: var(--font-ui);
}

.act-feed__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.act-feed__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  color: var(--fg-1);
}

.act-feed__roleflag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
}

.act-feed__roleflag--client {
  background: rgba(43, 71, 96, 0.08);
  color: var(--knowledgeable-blue);
}

.act-feed__roleflag--firm {
  background: rgba(220, 32, 21, 0.08);
  color: var(--victory-red);
}

.act-empty {
  font-size: 15px;
  color: var(--fg-3);
  padding: 20px 0;
}

.act-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.act-item {
  position: relative;
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: 12px;
  align-items: flex-start;
  padding: 10px 0;
}

.act-item__rail {
  position: relative;
  width: 28px;
  display: flex;
  justify-content: center;
  padding-top: 2px;
}

.act-item__rail::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 22px;
  bottom: -10px;
  width: 1px;
  background: #E2E8F0;
  transform: translateX(-50%);
}

.act-item:last-child .act-item__rail::before {
  display: none;
}

.act-item__dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-2);
  z-index: 1;
}

.act-item--comment .act-item__dot,
.act-item--reply .act-item__dot {
  color: var(--victory-red);
  border-color: rgba(220, 32, 21, 0.4);
}

.act-item--upload .act-item__dot,
.act-item--create .act-item__dot {
  color: var(--knowledgeable-blue);
  border-color: rgba(43, 71, 96, 0.4);
}

.act-item--share .act-item__dot {
  color: #16a34a;
  border-color: rgba(22, 163, 74, 0.4);
}

.act-item--view .act-item__dot {
  color: var(--fg-3);
}

.act-item__line {
  font-size: 15px;
  color: var(--fg-1);
}

.act-item__role {
  color: var(--fg-3);
  font-weight: 500;
  margin-left: 4px;
}

.act-item__detail {
  font-size: 14px;
  color: var(--fg-2);
  margin-top: 2px;
  line-height: 1.5;
}

.act-item__file em {
  font-style: normal;
  color: var(--fg-1);
  font-weight: 500;
}

.act-item__when {
  font-size: 12px;
  color: var(--fg-4);
  margin-top: 4px;
  letter-spacing: 0.2px;
}

.act-item__abs {
  color: var(--fg-4);
}

.act-item__meta {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  color: var(--fg-4);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px;
  border: 1px solid var(--border);
  border-radius: 4px;
}

/* tutorial overlay */
.tour-scrim {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: tourIn 0.25s var(--ease-standard);
}

@keyframes tourIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.tour-card {
  width: min(720px, 100%);
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.4);
  overflow: hidden;
  display: grid;
  grid-template-columns: 280px 1fr;
  animation: tourCardIn 0.32s var(--ease-standard);
}

@keyframes tourCardIn {
  from {
    transform: translateY(8px) scale(0.98);
    opacity: 0;
  }

  to {
    transform: none;
    opacity: 1;
  }
}

.tour-card__art {
  background: linear-gradient(150deg, #1A2D3D 0%, var(--knowledgeable-blue) 60%, #3B6B8A 100%);
  color: #fff;
  padding: 28px 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.tour-card__art--red {
  background: linear-gradient(150deg, #6B1A14 0%, var(--victory-red) 60%, #A01810 100%);
}

.tour-card__art--green {
  background: linear-gradient(150deg, #14532D 0%, #16a34a 60%, #166534 100%);
}

.tour-card__art--gold {
  background: linear-gradient(150deg, #5A4216 0%, #C99A3D 60%, #8B6914 100%);
}

.tour-card__body {
  padding: 28px 30px 24px;
  display: flex;
  flex-direction: column;
  min-height: 320px;
}

.tour-step-pill {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--victory-red);
  margin-bottom: 10px;
}

.tour-card__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 25px;
  color: var(--fg-1);
  margin: 0 0 10px;
  line-height: 1.2;
  text-wrap: balance;
}

.tour-card__copy {
  font-size: 15px;
  color: var(--fg-2);
  line-height: 1.55;
  margin: 0 0 16px;
  text-wrap: pretty;
}

.tour-card__copy strong {
  color: var(--fg-1);
}

.tour-card__list {
  font-size: 14px;
  color: var(--fg-2);
  line-height: 1.65;
  padding-left: 18px;
  margin: 0 0 16px;
}

.tour-card__foot {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 16px;
  border-top: 1px solid #EDF2F7;
}

.tour-dots {
  display: inline-flex;
  gap: 6px;
}

.tour-dots__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #CBD5E0;
  transition: all 0.2s var(--ease-standard);
}

.tour-dots__dot.is-on {
  background: var(--victory-red);
  width: 18px;
  border-radius: 999px;
}

.tour-actions {
  display: inline-flex;
  gap: 8px;
  align-items: center;
}

.tour-btn {
  height: 32px;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--fg-2);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all 0.15s var(--ease-standard);
}

.tour-btn:hover {
  background: #F7F8FA;
  color: var(--fg-1);
}

.tour-btn--primary {
  background: var(--victory-red);
  color: #fff;
  border-color: var(--victory-red);
}

.tour-btn--primary:hover {
  background: #C41D13;
  color: #fff;
}

.tour-btn--ghost {
  border: none;
  background: transparent;
  color: var(--fg-3);
}

.tour-btn--ghost:hover {
  background: #F7F8FA;
}

.tour-card__close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  cursor: pointer;
  z-index: 2;
}

.tour-card__close:hover {
  background: rgba(255, 255, 255, 0.2);
}

/* tour SVG art tweaks (positioning) */
.tour-art-svg {
  width: 200px;
  height: 180px;
  display: block;
}

@media (max-width: 720px) {
  .tour-card {
    grid-template-columns: 1fr;
  }

  .tour-card__art {
    padding: 24px 16px;
    min-height: 160px;
  }
}

/* ===========================================================
   TUTORIAL — spotlight + tooltip walkthrough
   =========================================================== */
.tour {
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: auto;
  font-family: var(--font-ui);
}

.tour__mask {
  position: absolute;
  inset: 0;
  pointer-events: auto;
}

.tour__ring {
  position: absolute;
  z-index: 205;
  border-radius: 12px;
  box-shadow: 0 0 0 2px rgba(220, 32, 21, 0.9), 0 0 0 6px rgba(220, 32, 21, 0.18);
  pointer-events: none;
  transition: all 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

.tour__ring-pulse {
  position: absolute;
  inset: -4px;
  border-radius: 14px;
  border: 2px solid rgba(220, 32, 21, 0.5);
  animation: tourPulse 1.6s ease-out infinite;
}

@keyframes tourPulse {
  0% {
    transform: scale(1);
    opacity: 0.6;
  }

  100% {
    transform: scale(1.08);
    opacity: 0;
  }
}

.tour__chip {
  position: fixed;
  top: 80px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 210;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px 7px 14px;
  background: rgba(15, 23, 42, 0.92);
  color: #fff;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.2px;
}

.tour__chip-num {
  color: var(--victory-red);
}

.tour__chip-sep {
  color: rgba(255, 255, 255, 0.4);
}

.tour__chip-tot {
  color: rgba(255, 255, 255, 0.6);
}

.tour__chip-label {
  margin-left: 4px;
  padding-left: 10px;
  border-left: 1px solid rgba(255, 255, 255, 0.15);
  color: rgba(255, 255, 255, 0.85);
}

.tour__chip-skip {
  margin-left: 6px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  border: none;
  padding: 5px 12px;
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: background 0.15s;
}

.tour__chip-skip:hover {
  background: rgba(255, 255, 255, 0.18);
}

.tour__panel {
  position: fixed;
  z-index: 210;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 24px 56px rgba(15, 23, 42, 0.45), 0 2px 8px rgba(0, 0, 0, 0.2);
  padding: 22px 24px 18px;
  width: 360px;
  pointer-events: auto;
  opacity: 1;
  animation: tourPanelIn 0.32s var(--ease-standard);
}

@keyframes tourPanelIn {
  0% {
    transform: translateY(8px);
  }

  100% {
    transform: translateY(0);
  }
}

.tour__panel--center {
  left: 50%;
  top: 50%;
  width: 480px;
  padding: 28px 32px 24px;
  transform: translate(-50%, -50%);
  animation: tourPanelInCenter 0.32s var(--ease-standard);
}

@keyframes tourPanelInCenter {
  0% {
    transform: translate(-50%, -46%) scale(0.97);
  }

  100% {
    transform: translate(-50%, -50%) scale(1);
  }
}

.tour__panel--arrow-top::before {
  content: '';
  position: absolute;
  top: -7px;
  left: 32px;
  width: 14px;
  height: 14px;
  background: #fff;
  transform: rotate(45deg);
  box-shadow: -2px -2px 6px rgba(0, 0, 0, 0.04);
}

.tour__panel--arrow-left::before {
  content: '';
  position: absolute;
  left: -7px;
  top: 32px;
  width: 14px;
  height: 14px;
  background: #fff;
  transform: rotate(45deg);
  box-shadow: -2px 2px 6px rgba(0, 0, 0, 0.04);
}

.tour__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  color: var(--victory-red);
  margin-bottom: 10px;
}

.tour__eyebrow-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--victory-red);
  box-shadow: 0 0 0 3px rgba(220, 32, 21, 0.18);
}

.tour__title {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 700;
  color: var(--fg-1);
  line-height: 1.2;
  margin: 0 0 10px;
  text-wrap: balance;
}

.tour__panel--center .tour__title {
  font-size: 29px;
}

.tour__body {
  font-size: 15px;
  line-height: 1.55;
  color: var(--fg-2);
  margin: 0 0 16px;
  text-wrap: pretty;
}

.tour__panel--center .tour__body {
  font-size: 16px;
}

.tour__progress {
  display: flex;
  gap: 6px;
  margin: 18px 0 14px;
}

.tour__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #E2E8F0;
  transition: all 0.25s var(--ease-standard);
}

.tour__dot.is-on {
  background: var(--victory-red);
  width: 22px;
  border-radius: 999px;
}

.tour__dot.is-done {
  background: rgba(220, 32, 21, 0.5);
}

.tour__controls {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 14px;
  border-top: 1px solid #EDF2F7;
}

.tour__spacer {
  flex: 1;
}

.tour__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 16px;
  background: #fff;
  color: var(--fg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s var(--ease-standard);
}

.tour__btn:hover {
  background: #F7F8FA;
  color: var(--fg-1);
  border-color: #CBD5E0;
}

.tour__btn--ghost {
  border: none;
  background: transparent;
  color: var(--fg-3);
}

.tour__btn--ghost:hover {
  background: #F7F8FA;
}

.tour__btn--primary {
  background: var(--victory-red);
  color: #fff;
  border-color: var(--victory-red);
  box-shadow: 0 2px 4px rgba(220, 32, 21, 0.25);
}

.tour__btn--primary:hover {
  background: #C41D13;
  color: #fff;
  border-color: #C41D13;
}

.tour__kbd {
  display: flex;
  gap: 14px;
  margin-top: 12px;
  font-size: 12px;
  color: var(--fg-4);
  letter-spacing: 0.2px;
}

.tour__kbd .kbd {
  display: inline-block;
  padding: 1px 6px;
  margin-right: 3px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #FAFBFC;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--fg-2);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.04);
}

/* tour ART (used in center panels) */
.tour-art {
  position: relative;
  width: 100%;
  height: 130px;
  margin: -6px 0 18px;
  border-radius: 10px;
  background: linear-gradient(150deg, #1A2D3D 0%, var(--knowledgeable-blue) 60%, #3B6B8A 100%);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tour-art--vault {
  background: linear-gradient(150deg, #6B1A14 0%, var(--victory-red) 60%, #A01810 100%);
}

.tour-art--pin {
  background: linear-gradient(150deg, #1f2937 0%, #334155 60%, #475569 100%);
}

.tour-art--activity {
  background: linear-gradient(150deg, #14532D 0%, #16a34a 60%, #166534 100%);
}

.tour-art--lock {
  background: linear-gradient(150deg, #0f172a 0%, #1e293b 60%, #334155 100%);
}

.tour-art__door {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #2a3340 0%, #0f1419 100%);
  border: 4px solid rgba(255, 255, 255, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.6);
  position: relative;
  z-index: 1;
}

.tour-art__spoke {
  position: relative;
  width: 50px;
  height: 50px;
}

.tour-art__spoke i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 5px;
  height: 22px;
  background: rgba(255, 255, 255, 0.6);
  transform-origin: center 0;
  border-radius: 2px;
  margin-left: -2.5px;
  box-shadow: 0 0 4px rgba(255, 255, 255, 0.4);
}

.tour-art__spoke i:nth-child(1) {
  transform: rotate(0deg) translateY(2px);
}

.tour-art__spoke i:nth-child(2) {
  transform: rotate(72deg) translateY(2px);
}

.tour-art__spoke i:nth-child(3) {
  transform: rotate(144deg) translateY(2px);
}

.tour-art__spoke i:nth-child(4) {
  transform: rotate(216deg) translateY(2px);
}

.tour-art__spoke i:nth-child(5) {
  transform: rotate(288deg) translateY(2px);
}

.tour-art__rays {
  position: absolute;
  inset: 0;
  opacity: 0.18;
}

.tour-art__rays i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 3px;
  height: 200%;
  background: linear-gradient(to bottom, transparent, #fff, transparent);
  transform-origin: top center;
}

.tour-art__rays i:nth-child(1) {
  transform: rotate(20deg) translate(-50%, -50%);
}

.tour-art__rays i:nth-child(2) {
  transform: rotate(-30deg) translate(-50%, -50%);
}

.tour-art__rays i:nth-child(3) {
  transform: rotate(70deg) translate(-50%, -50%);
}

.tour-art__page {
  width: 78%;
  height: 96px;
  background: #fff;
  border-radius: 6px;
  position: relative;
  padding: 12px 14px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
}

.tour-art__line {
  height: 5px;
  background: #E2E8F0;
  border-radius: 3px;
  margin-bottom: 6px;
}

.tour-art__line:nth-child(1) {
  width: 60%;
  background: #94A3B8;
}

.tour-art__line--short {
  width: 40%;
}

.tour-art__pin {
  position: absolute;
  right: 22px;
  top: 28px;
  width: 24px;
  height: 24px;
  background: var(--victory-red);
  color: #fff;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 10px rgba(220, 32, 21, 0.5);
}

.tour-art__pin span {
  transform: rotate(45deg);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
}

.tour-art__bubble {
  position: absolute;
  right: -8px;
  bottom: -10px;
  background: var(--fg-1);
  color: #fff;
  font-size: 11px;
  padding: 6px 9px;
  border-radius: 6px;
  white-space: nowrap;
  font-style: italic;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.35);
}

.tour-art__feed {
  width: 78%;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tour-art__row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 12px;
  color: var(--fg-1);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
  animation: feedRowIn 0.5s var(--ease-standard) backwards;
}

.tour-art__row:nth-child(1) {
  animation-delay: 0.1s;
}

.tour-art__row:nth-child(2) {
  animation-delay: 0.25s;
}

.tour-art__row:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes feedRowIn {
  from {
    transform: translateX(-8px);
    opacity: 0;
  }

  to {
    transform: none;
    opacity: 1;
  }
}

.tour-art__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--victory-red);
  flex-shrink: 0;
}

.tour-art__txt em {
  font-style: normal;
  font-weight: 600;
  color: var(--knowledgeable-blue);
}

.tour-art__shield {
  width: 70px;
  height: 70px;
  border-radius: 18px;
  background: linear-gradient(135deg, var(--victory-red), #8B1410);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  box-shadow: 0 8px 20px rgba(220, 32, 21, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
  z-index: 1;
}

.tour-art__bars {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  opacity: 0.15;
  pointer-events: none;
}

.tour-art__bars i {
  width: 1px;
  height: 70%;
  background: linear-gradient(to bottom, transparent, #fff, transparent);
}

/* --- Refresh button on toolbar --- */
@keyframes vault-spin {
  to {
    transform: rotate(360deg);
  }
}

.vault-vs--refresh {
  gap: 4px;
}

.vault-vs--refresh:disabled {
  cursor: wait;
  opacity: 0.7;
}

/* --- Firm logo at top of vault ---
   Fetched verbatim from chirica.law/images/logo.svg. Do NOT modify the SVG.
   Sizing only here. Wordmark aspect ratio ~2.76:1 (1102.3 x 399.54).
   At 38px tall on a 64px topbar = ~59% of bar height — comfortable wordmark zone. */
.vault-topbar__logo {
  height: 38px;
  width: auto;
  display: block;
  flex-shrink: 0;
  margin-right: 4px;
  -webkit-user-drag: none;
  user-select: none;
  transform: translateZ(0);
  /* anti-aliasing nudge for SVG on transforms */
}

@media (max-width: 640px) {
  .vault-topbar__logo {
    height: 30px;
  }
}

/* --- Activity drawer (slides in from the right) --- */
.vault-drawer__scrim {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.32);
  z-index: 90;
  animation: scrimIn 0.18s var(--ease-standard);
}

@keyframes scrimIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.vault-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(440px, 92vw);
  background: #fff;
  border-left: 1px solid var(--border-1, #e2e8f0);
  box-shadow: -16px 0 48px rgba(15, 23, 42, 0.18);
  display: flex;
  flex-direction: column;
  z-index: 100;
  animation: drawerSlide 0.22s var(--ease-standard);
}

@keyframes drawerSlide {
  from {
    transform: translateX(24px);
    opacity: 0;
  }

  to {
    transform: none;
    opacity: 1;
  }
}

.vault-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border-1, #e2e8f0);
}

.vault-drawer__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--fg-1);
}

.vault-drawer__close {
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--fg-3);
  padding: 4px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.vault-drawer__close:hover {
  background: rgba(15, 23, 42, 0.06);
  color: var(--fg-1);
}

.vault-drawer .act-list {
  padding: 12px 16px 24px;
  overflow-y: auto;
  flex: 1;
}

.vault-drawer .act-empty {
  padding: 24px 20px;
}

/* --- Comment thread polish (replies, actions, reply state) --- */
.cmt-thread {
  margin-bottom: 4px;
}

.cmt--reply {
  margin-left: 22px;
  border-left: 2px solid var(--border-1, #e2e8f0);
  padding-left: 12px;
  background: rgba(15, 23, 42, 0.02);
}

.cmt--replying {
  outline: 2px solid var(--knowledgeable-blue, #2b4760);
  outline-offset: 2px;
}

.cmt__pin--reply {
  background: transparent;
  color: var(--fg-3);
  border: 1px dashed var(--border-1, #e2e8f0);
  width: 22px;
  height: 22px;
}

/* Markup note — surfaced in the Discussion from a saved drawing note. The
   badge shows the tool icon (pen / highlighter / shape) in an ink-toned
   circle so it reads as an annotation rather than a numbered pin. */
.cmt__pin--markup {
  background: #1f2d3d;
  color: #fff;
  box-shadow: 0 1px 2px rgba(31, 45, 61, 0.3);
}
.cmt--markup.is-active {
  background: rgba(31, 45, 61, 0.05);
  border-color: rgba(31, 45, 61, 0.22);
}

/* Actions stay visible at low emphasis (discoverable on touch, no hover
   needed) and gain contrast on hover / when the card is active. */
.cmt__actions {
  display: flex;
  gap: 6px;
  margin-top: 9px;
  opacity: 0.62;
  transition: opacity 0.15s var(--ease-standard, ease);
}

.cmt:hover .cmt__actions,
.cmt.is-active .cmt__actions {
  opacity: 1;
}

.cmt__act {
  background: none;
  border: 1px solid transparent;
  padding: 4px 8px;
  border-radius: 6px;
  font-family: var(--font-display, sans-serif);
  font-size: 12px;
  font-weight: 600;
  color: var(--fg-3);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}

.cmt__act:hover {
  background: rgba(15, 23, 42, 0.06);
  color: var(--fg-1);
}

.cmt__act--done:hover {
  background: rgba(16, 122, 68, 0.12);
  color: #0b7a44;
}
.cmt__act--reopen:hover {
  background: rgba(15, 23, 42, 0.06);
  color: var(--fg-1);
}
.cmt__act--danger:hover {
  background: #FEE2E2;
  color: #991B1B;
}

.cmt-compose__cancel {
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--victory-red, #dc2015);
  text-decoration: underline;
  font: inherit;
  padding: 0;
  margin-left: 4px;
}

/* =============================================================================
   iPHONE OPTIMIZATION — "Reading Room" mobile pass
   -----------------------------------------------------------------------------
   The desktop vault is a 6-column file table with hover-revealed action
   chips, a 64 px chromed topbar that ignores the notch, and a 520×520 px
   vault-door sculpture next to the login form. On a 390 px iPhone all of
   that is wrong: tables horizontal-scroll into oblivion, hover never
   triggers (so action buttons read as missing), inputs auto-zoom on
   focus when font-size < 16 px, and the door is wider than the viewport.
   This block reframes the page for phones without forking the markup.

   Strategy:
     • One 760 px breakpoint for tablets (light tweaks).
     • One 640 px breakpoint for phones (full restructure).
     • One 420 px breakpoint for compact phones (further compression).
     • A single @supports block scopes safe-area insets so the topbar
       respects the notch and the page bottom respects the home bar.
     • All inputs bumped to 16 px on mobile to defeat iOS auto-zoom.

   IMPORTANT: this file (client/public/styles/vault.css) is the canonical
   source. Vite copies it to httpdocs/public/styles/vault.css at build
   time. Edit here, never the served copy — the build will silently
   overwrite the served copy.
   ============================================================================= */

@media (max-width: 760px) {
  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    overscroll-behavior-y: none;
  }

  .vault-page {
    /* Tablet still uses the 64px desktop topbar + the -100px offset from
       the base rule; clear both before laying out content. */
    padding: calc(100px + 64px + env(safe-area-inset-top, 0px) + 16px) 20px 64px;
  }

  .case-header {
    padding: 22px 22px;
  }

  .case-header__title {
    font-size: 29px !important;
    line-height: 1.2;
  }

  .vault-toolbar {
    gap: 10px;
  }
}

@media (max-width: 640px) {

  /* Topbar — 56pt with notch padding, icon-only actions */
  .vault-topbar {
    height: 56px;
    padding: 0 12px;
    gap: 8px;
  }

  .vault-topbar__logo {
    height: 26px;
    margin-right: 0;
  }

  .vault-topbar__brand {
    gap: 8px;
    /* Size to content (logo + client name) and let the flex:1 spacer push the
       action buttons to the right, exactly like desktop. Previously flex:1
       here made the brand and the flex:1 spacer split the row 50/50, so the
       client name was truncated to roughly half-width while an equal slab of
       white space sat to its right before the buttons. */
    flex: 0 1 auto;
    min-width: 0;
  }

  .vault-topbar__crumbs {
    flex: 1;
    min-width: 0;
    overflow: hidden;
  }

  .vault-topbar__crumb {
    font-size: 15px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }

  .vault-topbar__product {
    display: none;
  }

  /* User identity pill — shown on phones as an avatar-only icon (the name,
     role, and chevron are dropped) so clients can still reach Change password
     and Sign out from its dropdown. Was display:none, which left no way to
     sign out or change a password in portrait on a phone. The round avatar
     mirrors the icon-only action buttons beside it. */
  .vault-topbar__user {
    display: inline-flex;
    max-width: none;
    margin-left: 0;
    padding: 3px;
    gap: 0;
    background: transparent;
    border: none;
  }
  .vault-topbar__user > div:not(.vault-topbar__avatar) {
    display: none;
  }
  .vault-topbar__user > svg {
    display: none;
  }

  .vault-topbar__action {
    width: 36px;
    height: 36px;
    padding: 0;
    border-radius: 50%;
    font-size: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
  }

  .vault-topbar__action svg {
    width: 16px;
    height: 16px;
  }

  /* Body becomes scroll container; vault-page flows normally */
  html,
  body,
  #root {
    height: auto;
  }

  body {
    overflow: visible;
  }

  /* Splash exception: the splash needs the locked-viewport behavior from
     the canonical body:has(.login-stage) rule at the top of this file
     (100lvh + overflow: hidden + navy bg). Don't override here — the
     old `background: #000` + `overflow-y: auto` made a black seam
     between the navy iOS chrome (theme-color) and the body, and let
     the body scroll. Explicit `revert: layer` keeps this block's other
     mobile rules from leaking into the splash. */

  /* Page frame */
  .vault-page {
    position: static;
    /* Fill the viewport, never exceed it. The previous min-height of
       100dvh + 200px forced the page 200px taller than the screen on every
       phone regardless of content, producing 200px of dead scroll below the
       matters. The dashboard has no scroll-nudge (the +200px overscan only
       makes sense on the splash, which retracts iOS chrome), so it is removed
       here. The bottom padding likewise drops its +100px overscan, keeping a
       comfortable safe-area-aware gap below the last card. */
    min-height: 100dvh;
    padding-top: calc(56px + env(safe-area-inset-top, 0px) + 18px);
    padding-right: 16px;
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 48px);
    padding-left: 16px;
    overflow: hidden;
  }

  .vault-shell {
    max-width: 100%;
  }

  /* Case header */
  .case-header {
    padding: 20px 18px;
    border-radius: 14px;
    margin-bottom: 18px;
  }

  .case-header__row {
    gap: 14px;
  }

  .case-header__main {
    min-width: 0;
    flex: 1 1 100%;
  }

  .case-header__eyebrow {
    font-size: 11px;
    letter-spacing: 1.2px;
    margin-bottom: 6px;
  }

  .case-header__eyebrow::before {
    width: 12px;
  }

  .case-header__title {
    font-size: 25px !important;
    line-height: 1.2;
    letter-spacing: -0.4px !important;
  }

  .case-header__sub {
    font-size: 16px !important;
    line-height: 1.5;
  }

  /* Toolbar */
  .vault-toolbar {
    flex-wrap: wrap;
    gap: 10px;
    padding: 0;
    margin-bottom: 14px;
  }

  .vault-toolbar__title {
    font-size: 17px;
  }

  .vault-toolbar__viewswitch {
    width: 100%;
  }

  .vault-vs {
    flex: 1;
    justify-content: center;
    min-height: 40px;
    font-size: 15px;
  }

  /* Breadcrumb chips */
  .dash-breadcrumb {
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 12px;
  }

  .dash-breadcrumb__chip {
    padding: 6px 12px;
    font-size: 14px;
    min-height: 32px;
  }

  /* Section bar */
  .file-section+.file-section {
    margin-top: 22px;
  }

  .file-section__bar {
    padding: 12px 14px;
    font-size: 16px;
    min-height: 48px;
  }

  .file-section__count {
    font-size: 11px;
    letter-spacing: 0.8px;
  }

  /* File rows: collapse 6-column grid to 2-row card */
  .file-list__head {
    display: none;
  }

  .file-row {
    grid-template-columns: 40px minmax(0, 1fr) 36px;
    grid-template-rows: auto;
    gap: 12px;
    padding: 12px 14px;
    min-height: 64px;
    align-items: center;
    -webkit-tap-highlight-color: rgba(220, 32, 21, 0.06);
    touch-action: manipulation;
  }

  .file-row__icon {
    width: 36px;
    height: 36px;
    border-radius: 8px;
  }

  .file-row__icon svg {
    width: 18px;
    height: 18px;
  }

  .file-row__name {
    font-size: 17px;
    line-height: 1.3;
  }

  .file-row__sub {
    font-size: 14px;
    margin-top: 3px;
  }

  .file-row__type,
  .file-row__size,
  .file-row__date {
    display: none;
  }

  .file-row__actions {
    opacity: 1 !important;
  }

  .file-row__action {
    width: 32px;
    height: 32px;
    border-radius: 8px;
  }

  .file-row::before {
    display: none;
  }

  .file-row:active {
    background: rgba(220, 32, 21, 0.05);
  }

  .file-row[style*="cursor: pointer"]:first-child {
    background: rgba(15, 23, 42, 0.02);
  }

  /* Folder tiles → single column */
  .folder-tiles {
    grid-template-columns: 1fr !important;
    gap: 12px;
  }

  .folder-tile {
    padding: 18px 18px;
    min-height: 92px;
  }

  .folder-tile__name {
    font-size: 19px;
  }

  .folder-tile__meta {
    font-size: 14px;
  }

  /* All of .login-stage / .login-shell / .login-form-side / .login-title /
     .login-sub geometry lives in the source-of-truth block at the END
     of this file ("LOGIN STAGE — magazine geometry"). Don't fight it
     here — keep this block to bottom-bar / corner-logo tweaks only. */

  .login-bottom-bar {
    /* Two stacked columns pinned to opposite edges: the security pair on
       the left (left-aligned), the firm pair on the right (right-aligned),
       justified apart. nowrap keeps them on opposite sides at every phone
       width instead of collapsing onto one another. */
    left: max(12px, env(safe-area-inset-left, 0px));
    right: max(12px, env(safe-area-inset-right, 0px));
    justify-content: space-between;
    flex-wrap: nowrap;
    column-gap: 12px;
    row-gap: 6px;
    /* Sit lower: pin to the screen bottom with only a small home-indicator
       clearance, instead of the base bottom:~42px + padding-bottom:~34px
       double-stack (it double-counted the safe-area inset and floated the
       text ~76px up). */
    bottom: 0;
    /* Lower still: pull ~24px into the safe-area inset (floored at 2px so it
       never sits flush against the very edge / home indicator). */
    padding: 6px 0 max(2px, calc(env(safe-area-inset-bottom, 0px) - 29px));
    font-size: 11px;
    line-height: 1.4;
  }

  /* Force each group into a vertical stack (overriding the wider-screen
     wrap-reverse rules) so the two lines sit one under the other. */
  .login-bottom-bar__group {
    flex-direction: column;
    flex-wrap: nowrap;
    row-gap: 4px;
  }
  /* TLS 1.3 · AES-256 at rest  →  Session expires…  (top to bottom, left-aligned) */
  .login-bottom-bar__group--tls {
    align-items: flex-start;
    text-align: left;
  }
  /* CHIRICA LAW OFFICE  →  CHICAGO · IL  (top to bottom, right-aligned) */
  .login-bottom-bar__group--firm {
    align-items: flex-end;
    text-align: right;
  }

  .login-corner-logo {
    /* No longer offset by the old +100 scroll-nudge — the stage is now
       position: fixed from y=0. Tuck the logo just under the system
       status bar / notch, leaving room for the CONFIDENTIAL stamp above. */
    top: calc(env(safe-area-inset-top, 0px) + 42px);
    left: max(16px, env(safe-area-inset-left, 0px) + 12px);
  }

  .login-corner-logo img {
    min-width: 0;
    max-width: 130px;
    height: auto;
  }

  .login-corner-slogan {
    display: none !important;
  }

  /* Inputs at 16px so iOS doesn't auto-zoom on focus */
  .login-field__input,
  .vault-topbar__search input,
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  textarea {
    font-size: 18px !important;
  }

  .login-submit {
    padding: 16px 18px;
    font-size: 16px;
    min-height: 52px;
  }

  /* Drawer / tour */
  .vault-drawer {
    width: 100vw;
    border-left: none;
  }

  .vault-drawer__head {
    padding-top: max(14px, env(safe-area-inset-top, 14px));
  }

  .tour__panel,
  .tour__panel--center {
    width: min(94vw, 360px) !important;
    padding: 18px 20px 16px !important;
  }

  .tour__title {
    font-size: 19px !important;
  }

  .tour__chip {
    top: max(20px, env(safe-area-inset-top, 20px));
  }

  .secure-note {
    margin: 24px auto max(20px, env(safe-area-inset-bottom, 20px));
    font-size: 11px;
    text-align: center;
    line-height: 1.5;
  }

  /* =========================================================================
     VIEWER (PDF / image / video / HTML) — mobile reflow
     -----------------------------------------------------------------------
     The desktop viewer is a 3-column grid: 64px tools | 1fr canvas | 360px
     sidebar. On a 390 px iPhone the tools + sidebar add up to 424 px,
     leaving the canvas grid cell with NO room — which is why the PDF
     iframe was rendering at 0 px wide and "never loaded".

     This block collapses the grid to a single column, repositions the
     tools palette as a floating pill above the home-indicator, and turns
     the comments sidebar into a slide-up drawer toggled by a Comments
     chip in the header. Header and footer rows extend by the safe-area
     insets so the Back button isn't hidden under the notch and the
     "Read-only · all access logged" footer isn't hidden under the home
     indicator.
     ========================================================================= */
  .viewer {
    grid-template-columns: 1fr !important;
    /* Header row = 56 pt + notch; canvas takes the rest; footer = 44 pt
       + home-indicator. The 0px row preserves the desktop grid-area
       template (head/tools/canvas + head2/footer/side) — the empty
       "tools" / "head2" cells collapse to nothing on mobile because we
       reposition them with position:fixed below. */
    grid-template-rows: calc(56px + env(safe-area-inset-top, 0px)) 1fr calc(44px + env(safe-area-inset-bottom, 0px)) !important;
    grid-template-areas:
      "head"
      "canvas"
      "footer" !important;
  }

  /* Tools rail becomes a floating capsule above the footer/home-indicator.
     This brings back pin / pen / highlight / arrow / text / eraser on
     phones — the previous pass hid them entirely, which made annotation
     impossible on mobile. The pill is centered horizontally, pads its
     content, and sits at z-index above the canvas but below the comments
     drawer scrim. */
  .viewer__tools {
    display: flex !important;
    flex-direction: row !important;
    position: fixed !important;
    left: 50%;
    bottom: calc(56px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    grid-area: unset !important;
    padding: 5px !important;
    gap: 2px !important;
    background: rgba(10, 18, 25, 0.92);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 999px;
    box-shadow:
      0 12px 28px rgba(0, 0, 0, 0.45),
      inset 0 1px 0 rgba(255, 255, 255, 0.06);
    z-index: 30;
    align-items: center !important;
    /* Cap the floating pill so an overlong tool list doesn't run off the
       sides on a 320 px screen. Horizontal scroll within the pill is fine. */
    max-width: calc(100vw - 24px);
    overflow-x: auto;
    overscroll-behavior: contain;
  }

  .viewer__tools::-webkit-scrollbar {
    display: none;
  }

  /* Swipe-to-hide: the pill animates off-screen with a single transform.
     The default centering transform (translateX(-50%)) is baked in; when
     hidden we add 110vw / -110vw to slide it past either edge. */
  .viewer__tools {
    transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
    touch-action: pan-x;
    will-change: transform;
  }
  .viewer__tools.is-hidden {
    pointer-events: none;
  }
  .viewer__tools.is-hidden-right {
    transform: translate(calc(-50% + 110vw), 0) !important;
  }
  .viewer__tools.is-hidden-left {
    transform: translate(calc(-50% - 110vw), 0) !important;
  }

  /* "Show tools" tab — surfaces at the edge where the pill was dismissed
     to. Small enough to not obscure the image; big enough for a thumb. */
  .viewer__tools-show {
    position: fixed;
    bottom: calc(56px + env(safe-area-inset-bottom, 0px));
    z-index: 30;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 12px 9px 10px;
    background: rgba(10, 18, 25, 0.92);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.92);
    font-family: var(--font-mono, 'Courier Prime'), monospace;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45);
    cursor: pointer;
    animation: tools-show-in 0.22s cubic-bezier(0.32, 0.72, 0, 1) both;
  }
  .viewer__tools-show--right {
    right: 0;
    border-radius: 999px 0 0 999px;
    border-right: none;
    padding-right: 14px;
  }
  .viewer__tools-show--left {
    left: 0;
    border-radius: 0 999px 999px 0;
    border-left: none;
    padding-left: 14px;
  }
  @keyframes tools-show-in {
    from { transform: translateX(var(--from, 100%)); opacity: 0; }
    to   { transform: translateX(0); opacity: 1; }
  }
  .viewer__tools-show--right { --from: 100%; }
  .viewer__tools-show--left  { --from: -100%; }

  /* Undo/Redo only appear inside the pill on mobile (desktop has them in
     the header). The global rule hides them by default; this turns them on. */
  .viewer__tools .viewer__tool--mobile-only {
    display: flex !important;
    width: 36px !important;
    height: 36px !important;
  }
  .viewer__tools .viewer__tool--mobile-only:disabled {
    opacity: 0.35;
    pointer-events: none;
  }
  .viewer__tools .viewer__tool-divider--mobile-only {
    display: block !important;
  }

  /* iOS native momentum, no chrome */

  /* Pill-tool sizing tightens slightly so 7 tools + dividers fit a 360 px iPhone Mini */
  .viewer__tools .viewer__tool {
    width: 38px !important;
    height: 38px !important;
    flex-shrink: 0;
  }

  .viewer__tools .viewer__tool-divider {
    width: 1px !important;
    height: 22px !important;
    margin: 0 3px !important;
    background: rgba(255, 255, 255, 0.12);
  }

  /* Tooltip placement flips below on mobile (no room above on 38 pt buttons) */
  .viewer__tools .viewer__tool-tip {
    left: 50% !important;
    top: auto !important;
    bottom: calc(100% + 8px) !important;
    transform: translateX(-50%) scale(0.9) !important;
    transform-origin: bottom center !important;
  }

  .viewer__tools .viewer__tool:hover .viewer__tool-tip,
  .viewer__tools .viewer__tool:focus-visible .viewer__tool-tip {
    transform: translateX(-50%) scale(1) !important;
  }

  /* On video files, the playback-tools strip uses the same `.viewer__tools`
     class — the floating-pill rules apply uniformly. Speed picker dropdown
     within it lifts above the pill. */
  .viewer__tools .viewer__tool>div[style*="absolute"] {
    bottom: calc(100% + 6px) !important;
    top: auto !important;
  }

  .viewer__head {
    grid-area: head !important;
    padding: env(safe-area-inset-top, 0px) 12px 0;
    gap: 10px;
    align-items: stretch;
  }

  .viewer__head>* {
    align-self: center;
  }

  .viewer__back {
    padding: 6px 10px 6px 8px;
    font-size: 14px;
    flex-shrink: 0;
  }

  .viewer__title-wrap {
    min-width: 0;
    flex: 1;
  }

  .viewer__title {
    font-size: 15px;
  }

  .viewer__sub {
    font-size: 11px;
  }

  .viewer__head-actions {
    gap: 4px;
    flex-shrink: 0;
  }

  .viewer__head-btn {
    width: 36px;
    height: 36px;
    -webkit-tap-highlight-color: transparent;
  }

  /* Header overflow fix on phones. The desktop header packs
     Back · Title · Nav · Undo/Zoom/Redo · Comments/Surround/Download into
     one row — there is no room for all of that at 360 px. We collapse to
     the essentials: Back as icon-only, the truncating title, the centered
     prev/next nav if siblings exist, the Download button, and the Comments
     toggle. Pinch-zoom replaces the zoom buttons; Undo/Redo move to the
     bottom tool pill (added separately in JS). Surround folds into the
     comments drawer's overflow on small screens; Download stays in the
     header — it's a primary action clients reach for constantly on phones. */
  .viewer__head .viewer__back-copy {
    display: none;
  }
  .viewer__head .viewer__back {
    padding: 8px;
    width: 36px;
    height: 36px;
    justify-content: center;
  }
  .viewer__head .viewer__head-markup {
    display: none !important;
  }
  .viewer__head-actions > .viewer__head-btn:not(.viewer__head-btn--mobile-comments):not(.viewer__head-btn--download) {
    display: none;
  }
  /* Download is a primary, always-visible action on phones: firm-red fill so
     it reads as the main call-to-action and is an easy 38px touch target. */
  .viewer__head-btn--download {
    width: 38px;
    height: 38px;
    background: var(--victory-red);
    border-color: var(--victory-red);
    color: #fff;
  }
  .viewer__head-btn--download:hover,
  .viewer__head-btn--download:active {
    background: var(--victory-red);
    border-color: var(--victory-red);
    color: #fff;
  }

  .viewer__head-btn--mobile-comments {
    position: relative;
  }

  .viewer__head-btn--mobile-comments.is-on {
    background: var(--victory-red);
    border-color: var(--victory-red);
    color: #fff;
  }

  .viewer__comment-count {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    background: var(--victory-red);
    color: #fff;
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(10, 18, 25, 0.85);
    line-height: 1;
  }

  .viewer__head-btn--mobile-comments.is-on .viewer__comment-count {
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 0 2px var(--victory-red);
    background: #fff;
    color: var(--victory-red);
  }

  /* Canvas takes the entire remaining viewport — no padding stealing
     space from the iframe. flex-start (instead of the desktop's
     align-items: center) is the iOS scroll fix: when content is taller
     than the canvas, centering anchors the overflow above and below the
     scroll origin and Safari refuses to scroll up to the hidden top
     half. flex-start makes the overflowed content reachable.
     touch-action: pan-x pan-y pinch-zoom (not just pan-y) so the user
     can horizontal-pan a wider-than-viewport email; the pan-y-only
     value used to block right-swipe inside the iframe entirely. */
  .viewer__canvas,
  .viewer__canvas-wrap {
    grid-area: canvas !important;
    padding: 0 !important;
    min-height: 0;
    min-width: 0;
    align-items: flex-start !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    touch-action: pan-x pan-y pinch-zoom;
  }

  /* The .image-stage's pixel size is computed in JS (see Viewer.jsx
     updateStage effect) so the box matches the displayed image exactly.
     We only need to make sure the stage itself can be centered and that
     no inherited rule re-imposes a max-height clamp. */
  .viewer__canvas-wrap > .image-stage {
    margin: 0 auto;
  }
  .viewer__canvas-wrap > .image-stage > img {
    max-height: none !important;
    max-width: none !important;
  }

  /* PDF/HTML iframe needs an explicit pixel-resolved height to render on
     iOS Safari (a percentage-only height inside a flex/grid parent often
     resolves to 0 there). The canvas-wrap is the closest sized ancestor;
     this fills it. */
  .viewer__canvas-wrap iframe {
    width: 100% !important;
    height: 100% !important;
    min-height: 0;
    display: block;
  }

  /* Footer trims down on mobile — read-only marker only, in tiny mono text.
     Padding-bottom carries the home-indicator inset so the pill toolbar
     above it has guaranteed clearance and the text never tucks under the
     home bar. */
  .viewer__footer {
    grid-area: footer !important;
    padding: 0 14px env(safe-area-inset-bottom, 0px);
    font-size: 11px;
    align-items: center;
  }

  /* ---- Comments sidebar → bottom slide-up drawer ---- */
  .viewer__side {
    position: fixed !important;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto !important;
    height: 70vh;
    height: 70dvh;
    grid-area: unset !important;
    grid-row: unset !important;
    border-left: none !important;
    border-top: 1px solid var(--border);
    border-top-left-radius: 18px;
    border-top-right-radius: 18px;
    box-shadow: 0 -16px 40px rgba(0, 0, 0, 0.32);
    transform: translateY(100%);
    transition: transform 0.32s var(--ease-standard);
    z-index: 50;
  }

  /* Drag-handle ornament — implies "swipeable" without wiring a real
     swipe gesture (the toggle button does the work). */
  .viewer__side::before {
    content: '';
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    width: 36px;
    height: 4px;
    background: var(--border-strong, #CBD5E0);
    border-radius: 999px;
    pointer-events: none;
  }

  .viewer.is-comments-open .viewer__side {
    transform: translateY(0);
  }

  .viewer__comments-scrim {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.42);
    z-index: 45;
    animation: viewerScrimIn 0.18s ease-out;
    -webkit-tap-highlight-color: transparent;
  }

  @keyframes viewerScrimIn {
    from {
      opacity: 0;
    }

    to {
      opacity: 1;
    }
  }

  /* Slightly larger top padding on the side-head so the drag handle has
     breathing room. */
  .side-head {
    padding-top: 22px;
  }
}

/* Hide the mobile-only Comments toggle on tablet and up. */
@media (min-width: 641px) {
  .viewer__head-btn--mobile-comments {
    display: none !important;
  }
}

@media (max-width: 420px) {
  .vault-topbar {
    padding: 0 10px;
    gap: 6px;
  }

  .vault-topbar__logo {
    height: 24px;
  }

  .vault-topbar__action {
    width: 34px;
    height: 34px;
  }

  .vault-page {
    padding-top: calc(56px + env(safe-area-inset-top, 0px) + 14px);
    padding-right: 12px;
    /* Drop the +100px overscan (see the 640px rule above) — pure dead space
       below the content on a page that never nudges. */
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 40px);
    padding-left: 12px;
  }

  .case-header {
    padding: 18px 16px;
    border-radius: 12px;
  }

  .case-header__title {
    font-size: 22px !important;
  }

  .file-row {
    padding: 11px 12px;
    gap: 10px;
  }

  .file-row__icon {
    width: 34px;
    height: 34px;
  }

  .login-title {
    font-size: 36px !important;
  }
}

@supports (padding: env(safe-area-inset-top)) {
  @media (max-width: 640px) {
    .vault-topbar {
      height: calc(56px + env(safe-area-inset-top));
      padding-top: env(safe-area-inset-top);
    }
  }
}

/* =============================================================================
   TABLET / NARROW DESKTOP — drop the modified-date column when the 6-column
   file table would overflow the available width. Below 640px the existing
   mobile pass collapses the row to a 3-column card; this zone is the
   in-between (641–1024) where we want to keep the table layout but lose the
   least-useful column. The "modified" date is already shown in .file-row__sub
   under the name, so dropping the dedicated date column doesn't lose data.
   Also: collapse Activity/Tour action buttons to icons-only below 760px so
   they fit alongside the user card without wrapping.
   ============================================================================= */
@media (min-width: 641px) and (max-width: 1024px) {
  .file-list__head,
  .file-row {
    grid-template-columns: 28px minmax(180px, 1fr) 80px 80px 56px;
  }

  .file-list__head .sortable--date,
  .file-row__date {
    display: none;
  }
}

@media (max-width: 760px) {
  /* Collapse Activity / Tour / Sign out labels to icons; keep the user card
     readable. Below 480px (handled in the mobile pass) the Tour button hides
     entirely — it's a re-openable nicety, not a primary action. */
  .vault-topbar__action {
    padding: 0 8px;
    gap: 0;
    font-size: 0;
  }

  .vault-topbar__action svg {
    width: 16px;
    height: 16px;
  }

  .vault-topbar__user {
    /* Let the pill use the available topbar width rather than a hard 200px
       cap. It's still flex: 0 1 auto with min-width: 0, so when the actions
       genuinely need the room it shrinks (and the name truncates) — but it
       no longer truncates early and leaves blank space on iPhone. */
    max-width: 66vw;
  }

  .vault-topbar__user-name {
    /* No fixed cap — the flex pill above constrains the width, so the name
       only truncates when it actually runs out of room (was hard-capped at
       120px, which over-truncated and left blank space). */
    max-width: none;
  }
}

@media (max-width: 480px) {
  .vault-topbar {
    padding: 0 12px;
    gap: 4px;
  }

  /* The Tour button is the most disposable on a phone — re-openable from
     the (existing) tour overlay state. Hide it; keep Activity + Sign out. */
  .vault-topbar__action[aria-label="Replay the tour"],
  .vault-topbar__action[title="Replay the tour"] {
    display: none;
  }

  .vault-topbar__user-role {
    display: none;
  }
}

/* =============================================================================
   LOGIN STAGE — magazine geometry (source-of-truth for centering + fit)
   -----------------------------------------------------------------------------
   Replaces every earlier portrait / max-height / "PRIORITY" / "FINAL
   OVERRIDE" block. One coherent system, designed like a magazine spread:

     • The form column is sacred. Logo, eyebrow, title, sub, fields, submit,
       and bottom-bar are GUARANTEED fully visible on every viewport from
       280×400 up to 4K and beyond.
     • The vault sculpture is the editorial hero. It scales fluidly, sits
       beside the form on wide spreads and above it on narrow ones, and is
       allowed to BLEED past the spread's edges — like a printed image that
       runs off the page — when the viewport doesn't have room for it whole.
     • The stage is a flex centering shell with explicit padding reserves
       for the fixed-position corner logo (top) and bottom info bar
       (bottom). No spacer divs, no flex-end hacks, no transform translates.

   Vertical reserves are tuned so the form sits well clear of both fixed
   chrome elements in every chrome state (iOS Safari translucent or solid,
   Android Chrome, desktop, PWA standalone). On mobile we add the
   (100lvh - 100svh) delta to absorb the iOS URL-bar shrink-on-scroll so
   the layout doesn't reflow when chrome appears or disappears.
   ============================================================================= */
.login-stage {
  /* Custom props — single place to tune the reserve math. */
  --stage-top-reserve: max(76px, env(safe-area-inset-top, 0px) + 60px);
  --stage-bot-reserve: max(108px, env(safe-area-inset-bottom, 0px) + 84px);
  --stage-side-pad: clamp(16px, 4vw, 56px);

  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  /* justify-content: flex-end + asymmetric pseudo-spacers — see below.
     The spacers are what choose between "center when content fits" and
     "anchor to bottom, overflow upward" when content doesn't. Pure
     justify-content: center fails the second case (it splits overflow
     symmetrically across top + bottom, pushing the submit button past
     the fixed footer on cramped viewports like 320×320). */
  justify-content: flex-end !important;

  padding-top: var(--stage-top-reserve) !important;
  padding-bottom: var(--stage-bot-reserve) !important;
  padding-left: var(--stage-side-pad) !important;
  padding-right: var(--stage-side-pad) !important;
  overflow: hidden !important;
}

/* Spacer divs (rendered by LoginScreen.jsx as the first and last children
   of .login-stage). Top spacer grows AND shrinks (collapses to 0 when
   the shell would otherwise overlap the corner logo). Bottom spacer
   grows but does NOT shrink, so the shell always keeps the full bottom
   reserve above the fixed footer. When the shell fits, both grow
   equally → shell centers. When it overflows, top spacer shrinks to 0,
   bottom spacer stays at 0, and the shell overflows UPWARD into the
   (hidden) corner-logo area instead of DOWNWARD into the footer. */
.login-stage__spacer--top {
  display: block !important;
  flex: 1 1 0 !important;
  width: 0;
  min-height: 0;
  pointer-events: none;
}
.login-stage__spacer--bottom {
  display: block !important;
  flex: 1 0 0 !important;
  width: 0;
  min-height: 0;
  pointer-events: none;
}

/* On mobile, the bottom reserve also has to clear the iOS home-indicator
   AND the bottom-bar's wrapped rows. The stage is 100lvh (covers under
   iOS chrome) but we anchor content within 100svh (always-visible
   area) by adding the chrome-delta to the bottom reserve. Without this
   the form can sit *below* the iOS URL bar when chrome is shown. */
@media (max-width: 820px) {
  .login-stage {
    --stage-bot-reserve: calc(max(108px, env(safe-area-inset-bottom, 0px) + 96px) + (100lvh - 100svh));
  }
}

/* On very narrow viewports (≤ 600 px) the bottom-bar wraps to 2–3 rows
   so it stands ~80–110 px tall. Bump the reserve to keep the submit
   button comfortably above. */
@media (max-width: 600px) {
  .login-stage {
    --stage-bot-reserve: calc(max(116px, env(safe-area-inset-bottom, 0px) + 100px) + (100lvh - 100svh));
  }
}
@media (max-width: 460px) {
  .login-stage {
    --stage-bot-reserve: calc(max(124px, env(safe-area-inset-bottom, 0px) + 108px) + (100lvh - 100svh));
  }
}

/* (Spacer rules live below near the shell — they're now load-bearing.) */

/* =========================================================================
   LOGIN SHELL — the magazine spread itself
   The form column is `minmax(0, 1fr)` so it shrinks to the column width
   instead of pushing past it (a plain 1fr resolves to min-content, which
   for the vault's 520-px box means 520 — pushing the spread off-screen).
   The vault column gets `minmax(0, auto)` so it claims only the space it
   actually needs and is allowed to clip via the stage's overflow:hidden.
   ========================================================================= */
.login-shell {
  display: grid !important;
  /* Form column: capped to a comfortable reading column (max 460px) so
     the line length stays around the editorial 60–70 ch sweet spot even
     on a 3440-px ultrawide. Vault column: claims only what it needs. */
  grid-template-columns: minmax(320px, 460px) minmax(0, auto) !important;
  grid-template-rows: auto !important;
  align-items: center !important;
  justify-items: stretch !important;
  /* Asymmetric gap — the form sits closer to the right column on wide
     spreads so the eye travels naturally from title → vault hero. */
  gap: clamp(40px, 6vw, 96px) !important;
  /* Spread width capped at a luxe magazine spread proportion. Centered
     in stage via the asymmetric spacer pseudo-divs on the parent. */
  width: min(1100px, 100%) !important;
  max-width: 100% !important;
  /* Deliberately no max-height: % resolves against the stage's tight
     content-box and would crush the shell on cramped viewports. Let
     the shell keep its intrinsic content height; flex-shrink: 0 below
     prevents the flex algorithm from squeezing it; the stage's
     overflow: hidden clips anything that exceeds the visible viewport,
     and the asymmetric spacers steer the overflow toward the top
     (behind the corner logo) instead of toward the bottom (where it
     would collide with the fixed footer). */
  /* Reset any transforms / flex-shrink baggage from prior rules.
     flex-shrink: 0 — shell never deforms; the spacer pseudo divs absorb
     all the flex algorithm's resizing instead. Without this, on cramped
     viewports the flex algo squishes the shell's auto-content height,
     overlapping form rows into each other. */
  transform: none !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
  position: relative;
  z-index: 1;
}

/* === SPREAD COLLAPSE ====================================================
   When the viewport is too narrow OR too short for a real two-column
   spread, collapse to a single column with the vault sitting above the
   form. We keep the 2-col layout in landscape down to ~480 px tall
   (short-wide windows still read as a spread); only collapse when the
   width genuinely can't host two columns or the orientation says so.
   ======================================================================== */
@media (max-width: 940px), (orientation: portrait), (max-height: 480px) {
  .login-shell {
    grid-template-columns: minmax(0, 540px) !important;
    justify-content: center !important;
    gap: clamp(8px, 2.5vh, 32px) !important;
  }
  .vault-side {
    order: -1;
    justify-self: center !important;
  }
  .login-form-side {
    justify-self: stretch !important;
    width: 100% !important;
    padding: 0 !important;
  }
}

/* === VAULT SCULPTURE — fluid scale + visual bleed ========================
   The vault is built from pixel-fixed absolutely-positioned children
   inside a 520×520 box. To fluidly resize it we transform: scale() the
   box, then absorb the post-scale empty layout-space with negative
   margins so the form column packs flush against the visible footprint.

   CRITICAL: scale() requires a UNITLESS number. `calc(length / 520)`
   yields a length and breaks silently in modern Chrome (renders no
   transform at all). The correct form is `calc(length / 520px)` —
   length÷length resolves to a unitless number per CSS Values 4. */
.vault-side {
  /* Desktop hero: sized well past the 520px native box (scale > 1) so the
     dial reads as a large editorial hero, bleeding past the spread edges
     when there isn't room for it whole. */
  --vs-fit: clamp(360px, min(50vw, 92vh), 780px);
  --vs-scale: calc(var(--vs-fit) / 520px);
  width: 520px !important;
  height: 520px !important;
  flex-shrink: 0 !important;
  transform: scale(var(--vs-scale)) !important;
  transform-origin: center !important;
  /* Negative margins on all four sides absorb the unscaled box's empty
     space so the visual sculpture sits in its own footprint, not in a
     520×520 layout cage. */
  margin: calc((var(--vs-scale) - 1) * 260px) calc((var(--vs-scale) - 1) * 260px) !important;
}

/* Two-column landscape that's short on height: vault gets a tighter cap
   so it doesn't crowd the form vertically, but stays large enough to
   read as a sculpture rather than a smudge. */
@media (min-width: 941px) and (max-height: 700px) {
  .vault-side {
    --vs-fit: clamp(280px, min(42vw, 92vh), 540px);
    --vs-scale: calc(var(--vs-fit) / 520px);
  }
}

/* Stacked layout (portrait / narrow / very short): the vault sits above
   the form and is sized off the smaller viewport dimension. Slightly
   bigger floor + ceiling than before so the dial details (rivets, brass
   nameplate, spoke handles) stay legible — at scale < 0.35 the sculpture
   degrades into an indistinct dark circle, which fights the brand. */
@media (max-width: 940px), (orientation: portrait), (max-height: 480px) {
  .vault-side {
    /* 36vw OR 26vh, whichever is smaller — capped at 280px. Scale lands
       in 0.35–0.54 range on every supported portrait viewport, so the
       dial's chrome detail stays visible. */
    --vs-fit: clamp(160px, min(36vw, 26vh), 280px);
    --vs-scale: calc(var(--vs-fit) / 520px);
    transform-origin: 50% 0 !important;
    /* Top: 0, sides absorb unscaled width, bottom pulls form up flush
       against the visible bottom of the scaled dial. */
    margin:
      0
      calc((var(--vs-scale) - 1) * 260px)
      calc((var(--vs-scale) - 1) * 520px)
      calc((var(--vs-scale) - 1) * 260px)
    !important;
  }
}

/* On cramped viewports the vault hides entirely so the form gets every
   available pixel. 560 px is the threshold below which even a 160-px
   vault would push the submit below the visible viewport on a stacked
   layout. (Two-col landscape at h<480 already collapses to stacked via
   the SPREAD COLLAPSE block above, so this also catches very short
   wide windows once they've collapsed.) */
@media (max-height: 560px) {
  .vault-side { display: none !important; }
}

/* === PHONE: oversized "hero dial" =======================================
   On phones the vault is deliberately blown up far past its 520px native
   box so it reads as a dramatic hero — it's fine for it to bleed off the
   top and sides (you see the lower portion of the dial). The big dial
   takes the upper half, which pushes the title + sub + Sign-in button down
   into the lower half. Sized off vw so it scales with the screen; the
   stage's anchor-to-bottom spacer logic then floats the form low while the
   dial overflows upward off the top edge. Placed AFTER the generic mobile
   vault block so it wins on phones (<= 640px). */
@media (max-width: 640px) {
  .login-shell {
    /* a touch more air between the giant dial and the form */
    gap: clamp(20px, 5vh, 52px) !important;
  }
  .login-stage {
    /* The 200px stage overscan (added for the chrome bleed) sits BELOW the
       visible viewport after the scroll-nudge, so the form — anchored to the
       stage bottom — ends up almost on top of the fixed footer. Clearance
       above the footer ≈ (this reserve − 100px overscan offset); ~145px lands
       the Sign-in button about 10px above the footer. Tune this one number. */
    --stage-bot-reserve: calc(145px + (100lvh - 100svh)) !important;
  }
  .vault-side {
    --vs-fit: clamp(420px, 120vw, 700px);
    --vs-scale: calc(var(--vs-fit) / 520px);
    transform-origin: 50% 0 !important;
    /* translateY(40px) (applied AFTER the scale, so it's a flat 40px in
       parent space) drops the dial a little lower on screen. Bottom margin
       keeps the form packed just under the dial; sides/top 0 (origin is
       top-center so it scales down from the top and bleeds off the sides). */
    transform: translateY(40px) scale(var(--vs-scale)) !important;
    margin: 0 0 calc((var(--vs-scale) - 1) * 520px) 0 !important;
  }
}

/* === FORM-SIDE TYPOGRAPHY — fluid clamps so text never disappears ======== */
/* The user's hard rule: title + sub + fields + submit MUST stay visible
   on every viewport. So instead of hiding them at short heights (the old
   approach), we scale them. min() against vh keeps the column from
   exceeding its available vertical room. */
.login-form-side,
.login-title,
.login-sub,
.login-eyebrow {
  max-width: 100%;
  overflow-wrap: break-word;
}
.login-title em {
  overflow-wrap: break-word;
  word-break: keep-all;
}

/* Wide spread / tall enough — full editorial typography. (Base rule lives
   earlier in this file at .login-title / .login-sub; we only override
   here for the fluid regime.) */

/* Narrower spread or shorter height — fluid scaling so nothing overflows.
   The eyebrow gets noticeably more clearance from the title (clamp floor
   raised to 10px) so they read as separate elements, not collided. */
@media (max-width: 1000px), (orientation: portrait), (max-height: 760px) {
  .login-eyebrow {
    font-size: clamp(9px, 1.3vh, 11px) !important;
    letter-spacing: clamp(1.6px, 0.3vw, 3px) !important;
    margin-bottom: clamp(10px, 1.8vh, 18px) !important;
  }
  .login-title {
    font-size: clamp(28px, min(6vw, 6.2vh), 56px) !important;
    line-height: 1.08 !important;
    letter-spacing: -0.6px !important;
    margin: 0 0 clamp(10px, 2vh, 20px) !important;
  }
  .login-sub {
    font-size: clamp(12px, min(1.6vw, 1.9vh), 15px) !important;
    line-height: 1.5 !important;
    margin: 0 0 clamp(14px, 2.8vh, 30px) !important;
    max-width: none !important;
  }
  .login-field { margin-bottom: clamp(8px, 1.4vh, 16px) !important; }
  .login-submit { margin-top: clamp(4px, 0.8vh, 10px) !important; }
}

/* Very short viewports (landscape phones, kiosks): tighten sub-paragraph
   so the form fits. Don't HIDE it — the user explicitly wants the text
   always present. We clamp sub to two lines max and tighten leading. */
@media (max-height: 560px) {
  .login-sub {
    font-size: 14px !important;
    line-height: 1.4 !important;
    margin: 0 0 10px !important;
    /* Constrain to 60ch so it never sprawls beyond the form column. */
    max-width: 60ch !important;
    display: -webkit-box !important;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .login-title {
    font-size: clamp(22px, 5.5vh, 32px) !important;
    margin: 0 0 6px !important;
  }
  .login-eyebrow { margin-bottom: 6px !important; }
  .login-field { margin-bottom: 8px !important; }
}

/* Tiniest landscape windows (≤ 420 px tall) — single-line sub-paragraph
   so the email + submit always clear the footer. */
@media (max-height: 420px) {
  .login-sub { -webkit-line-clamp: 1 !important; max-height: 1.4em; }
}

/* EXTREME cramped — 380 px or less tall, OR 380×380 square windows.
   Shrinks every form atom to its physical minimum so even an iPhone-SE-
   landscape-half (about 333×203) keeps every required element visible.
   We never hide text per the user's rule; we just compress it. */
@media (max-height: 380px), (max-width: 360px) and (max-height: 580px) {
  .login-eyebrow {
    font-size: 10px !important;
    letter-spacing: 1.4px !important;
    margin-bottom: 3px !important;
  }
  .login-title {
    font-size: 22px !important;
    line-height: 1.08 !important;
    margin: 0 0 4px !important;
    letter-spacing: -0.4px !important;
  }
  .login-title em { font-size: 25px !important; margin-top: 0 !important; }
  .login-sub {
    font-size: 12px !important;
    line-height: 1.35 !important;
    margin: 0 0 6px !important;
    -webkit-line-clamp: 1 !important;
    max-height: 1.35em !important;
  }
  .login-field__label {
    font-size: 10px !important;
    margin-bottom: 3px !important;
    letter-spacing: 1px !important;
  }
  .login-field__input {
    padding: 8px 12px !important;
    font-size: 15px !important;
  }
  .login-field { margin-bottom: 6px !important; }
  .login-submit {
    padding: 10px 14px !important;
    font-size: 14px !important;
    min-height: 36px !important;
    margin-top: 2px !important;
  }
}

/* === CORNER ORNAMENTS — sized per spread ================================= */
/* Portrait + narrow widths: shrink the logo and hide the slogan (it's
   three lines of bold type — too much for a phone corner). */
@media (max-width: 1000px), (orientation: portrait) {
  .login-corner-slogan { display: none !important; }
  .login-corner-logo {
    top: max(20px, env(safe-area-inset-top, 0px) + 12px) !important;
    left: max(12px, env(safe-area-inset-left, 0px) + 4px) !important;
  }
  .login-corner-logo img {
    min-width: clamp(140px, 32vw, 200px) !important;
    max-width: 220px !important;
  }
}

/* On extreme-cramped viewports the corner logo would paint over the form
   title (corner logo z-index > form, position: fixed). Hide it so the
   form's text stays readable — the user's "text must always be visible"
   rule outweighs the brand mark in this corner case. */
@media (max-height: 420px), (max-width: 380px) and (max-height: 580px) {
  .login-corner-logo { display: none !important; }
  /* Tighten stage top reserve once the logo's gone — reclaim its room
     for the form's headline. */
  .login-stage {
    --stage-top-reserve: max(28px, env(safe-area-inset-top, 0px) + 16px) !important;
  }
}

/* =============================================================================
   .vault-up — "back to {parent}" chip above the file table.
   Distinct from file rows by shape (asymmetric chevron-cut left edge),
   surface (navy on white), and motion (arrow + chip translate left on
   hover). Reads as a navigation action, not a file.
   ============================================================================ */

.vault-up {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 10px 22px 10px 18px;
  margin: 14px 0 12px;
  background: linear-gradient(180deg, #1A202C 0%, #0F1620 100%);
  color: #fff;
  border: 0;
  cursor: pointer;
  font-family: var(--font-display);
  position: relative;
  user-select: none;
  text-align: left;
  clip-path: polygon(
    12px 0%,
    100% 0%,
    calc(100% - 6px) 50%,
    100% 100%,
    12px 100%,
    0% 50%
  );
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
              filter 160ms ease,
              box-shadow 200ms ease;
  filter: drop-shadow(0 6px 10px rgba(15, 22, 32, 0.18))
          drop-shadow(0 1px 2px rgba(15, 22, 32, 0.22));
}

.vault-up:hover {
  transform: translateX(-3px);
  filter: drop-shadow(0 10px 16px rgba(15, 22, 32, 0.26))
          drop-shadow(0 2px 3px rgba(15, 22, 32, 0.30));
}

.vault-up:active {
  transform: translateX(-1px);
  filter: drop-shadow(0 2px 4px rgba(15, 22, 32, 0.30));
}

.vault-up:focus-visible {
  outline: 2px solid var(--victory-red);
  outline-offset: 3px;
}

.vault-up__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--victory-red);
  color: #fff;
  flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.12);
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
              background-color 160ms ease;
}
.vault-up__icon svg { transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1); }
.vault-up:hover .vault-up__icon  { background: var(--victory-red-hover); }
.vault-up:hover .vault-up__icon svg { transform: translateX(-2px); }

.vault-up__copy {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.15;
  min-width: 0;
}

.vault-up__eyebrow {
  /* Open Sans — pairs with the viewer back chip for a consistent
     back-button family across the vault. */
  font-family: var(--font-body, 'Open Sans'), sans-serif;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}

.vault-up__label {
  font-family: var(--font-body, 'Open Sans'), sans-serif;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0;
  color: #fff;
  max-width: 360px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .vault-up {
    padding: 9px 16px 9px 14px;
    gap: 10px;
    clip-path: polygon(
      8px 0%,
      100% 0%,
      calc(100% - 4px) 50%,
      100% 100%,
      8px 100%,
      0% 50%
    );
  }
  .vault-up__icon { width: 26px; height: 26px; }
  .vault-up__label { font-size: 15px; max-width: 200px; }
}

/* =============================================================================
   .viewer__back — twin of .vault-up, sized for the dark viewer header.
   Same chevron-cut silhouette + crimson icon disc family. Light surface
   here (instead of navy on white) for contrast against the dark chrome.
   Override of the legacy pill style above.
   ============================================================================ */

.viewer__back {
  /* Reset the legacy pill base — we're starting fresh. */
  all: unset;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 18px 7px 14px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F1F3F7 100%);
  color: var(--fg-1, #1A202C);
  cursor: pointer;
  user-select: none;
  font-family: var(--font-display, 'Montserrat'), sans-serif;
  text-align: left;
  /* Asymmetric chevron-cut silhouette — same shape language as .vault-up
     so the two read as a family. Slightly tighter for the header context. */
  clip-path: polygon(
    10px 0%,
    100% 0%,
    calc(100% - 5px) 50%,
    100% 100%,
    10px 100%,
    0% 50%
  );
  /* Box-shadow doesn't render outside the clip mask. Drop-shadow on the
     filter does — and stacking two gives the proper soft + sharp combo. */
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.28))
          drop-shadow(0 1px 2px rgba(0, 0, 0, 0.20));
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
              filter 160ms ease;
}
.viewer__back:hover {
  /* The LEGACY .viewer__back:hover above (line ~1637) sets a translucent
     white background that bleeds the dark header through — that's what was
     making the chip look "dark blue with blue text" on hover. Re-paint the
     light gradient and re-assert the dark text color so the chip keeps its
     readable surface during the hover transition. */
  background: linear-gradient(180deg, #FFFFFF 0%, #FAFBFD 100%) !important;
  color: var(--fg-1, #1A202C) !important;
  transform: translateX(-3px);
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.38))
          drop-shadow(0 2px 3px rgba(0, 0, 0, 0.26));
}
.viewer__back:active {
  transform: translateX(-1px);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.34));
}
.viewer__back:focus-visible {
  outline: 2px solid var(--victory-red, #DC2015);
  outline-offset: 3px;
}

.viewer__back-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--victory-red, #DC2015);
  color: #fff;
  flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
              background-color 160ms ease;
}
.viewer__back-icon svg {
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
}
.viewer__back:hover .viewer__back-icon {
  background: var(--victory-red-hover, #C41D13);
}
.viewer__back:hover .viewer__back-icon svg {
  transform: translateX(-2px);
}

.viewer__back-copy {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.1;
  min-width: 0;
}
.viewer__back-eyebrow {
  /* Open Sans — softer humanist sans, contrast against the Montserrat
     everywhere else. Acts as the chip's accent typeface. */
  font-family: var(--font-body, 'Open Sans'), sans-serif;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3, #718096);
}
.viewer__back-label {
  /* Open Sans — pairs with the eyebrow. Slightly looser tracking than
     Montserrat needs for the bold weight. */
  font-family: var(--font-body, 'Open Sans'), sans-serif;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0;
  color: var(--fg-1, #1A202C);
}

@media (max-width: 640px) {
  .viewer__back {
    padding: 6px 14px 6px 12px;
    gap: 8px;
  }
  .viewer__back-icon { width: 22px; height: 22px; }
  .viewer__back-label { font-size: 14px; }
  .viewer__back-eyebrow { font-size: 10px; }
}

/* =============================================================================
   iPhone polish — at iPhone-class widths the viewer chrome trims to the
   essentials so the email body gets nearly the full viewport. The back
   chip collapses to its icon, the case-name subtitle disappears, and the
   centered prev/next nav stays compact. The email's own subject (rendered
   inside the iframe by routes/files.js renderEml) is the primary title on
   this size class — the viewer__title becomes a quiet path hint instead.
   ============================================================================ */
@media (max-width: 480px) {
  .viewer__head {
    gap: 6px;
    padding-left: 8px;
    padding-right: 8px;
  }
  /* Back chip → arrow only. The "Back to" eyebrow and the folder-name
     label hide; the round icon shoulders the affordance alone. */
  .viewer__back {
    padding: 6px;
    gap: 0;
    border-radius: 50%;
    flex-shrink: 0;
  }
  .viewer__back-copy { display: none; }
  .viewer__back-icon {
    width: 24px; height: 24px;
    margin: 0;
  }
  /* Sub-line (case display name) is redundant with the email card's own
     crumbs and steals a row of vertical space the message needs. */
  .viewer__sub { display: none; }
  .viewer__title {
    font-size: 14px;
    font-weight: 500;
    color: rgba(255,255,255,0.55);
    /* Squeeze a touch on the right so the absolutely-positioned center
       nav has visible whitespace behind it. */
    padding-right: 110px;
  }
  .viewer.surround-light .viewer__title { color: rgba(15,23,42,0.55); }
  /* Center nav: keep absolute centering but shrink each control + gap so
     the cluster fits behind the title with room to spare on a 390px
     iPhone. The count text drops to a tiny tabular figure. */
  .viewer__head-nav {
    gap: 0;
    padding: 1px;
    border-radius: 999px;
  }
  .viewer__head-nav .viewer__head-btn {
    width: 28px; height: 28px;
  }
  .viewer__head-nav-count {
    min-width: 30px;
    font-size: 11px;
    padding: 0 4px;
  }
  /* Drop the Comments toggle's text/count badge on iPhone — it's
     surfaced inside the message anyway, and these mm of chrome are
     worth more to reading. The button itself stays as a single icon. */
  .viewer__head-actions { gap: 2px; }
  .viewer__head-btn { width: 32px; height: 32px; }
}

/* =============================================================================
   v2 VIEWER UPGRADES — ports from the design's vault.css additions.
   ============================================================================ */

/* Inline contrast-aware Text-tool overlay (drops at click point) */
.text-edit-overlay {
  /* Translate up so the click point is the baseline, not the top of the box */
  transform: translate(0, -100%);
  min-width: 16px;
  min-height: 1em;
  padding: 2px 4px;
  background: rgba(255,255,255,0.04);
  border: 1px dashed rgba(220,32,21,0.6);
  border-radius: 3px;
  font-family: var(--font-display, 'Montserrat'), sans-serif;
  font-weight: 600;
  font-size: 20px;
  line-height: 1.1;
  white-space: pre;
  caret-color: currentColor;
  z-index: 30;
  cursor: text;
  user-select: text;
}
.text-edit-overlay:empty::before {
  content: attr(data-placeholder);
  opacity: 0.55;
  pointer-events: none;
}
.text-edit-overlay:focus {
  border-color: var(--victory-red, #DC2015);
  background: rgba(255,255,255,0.06);
  outline: none;
}

/* Eraser hover state — strokes become hit-targetable, dim + red glow on hover */
.draw-layer.is-erasing { pointer-events: auto; }
.draw-layer.is-erasing svg { pointer-events: auto; }
.draw-layer.is-erasing svg path,
.draw-layer.is-erasing svg rect,
.draw-layer.is-erasing svg text,
.draw-layer.is-erasing svg g {
  cursor: cell;
}
.draw-layer.is-erasing svg path:hover,
.draw-layer.is-erasing svg rect:hover,
.draw-layer.is-erasing svg text:hover,
.draw-layer.is-erasing svg g:hover {
  opacity: 0.4;
  filter: drop-shadow(0 0 4px rgba(220,32,21,0.6));
}

/* =============================================================================
   .pin-compose — floating compose popup anchored next to a freshly dropped pin
   ============================================================================ */
.pin-compose {
  position: fixed;
  z-index: 60;
  background: #fff;
  border-radius: 12px;
  border: 1px solid var(--border, #E2E8F0);
  box-shadow: 0 18px 40px rgba(15,23,42,0.32), 0 4px 12px rgba(0,0,0,0.12);
  padding: 12px 12px 10px;
  animation: pinComposeIn 0.18s cubic-bezier(0.2, 0.6, 0.2, 1);
}
@keyframes pinComposeIn {
  0%   { transform: translateY(4px) scale(0.96); opacity: 0; }
  100% { transform: none; opacity: 1; }
}
/* Arrow-tail pointing left (toward the pin) */
.pin-compose::before {
  content: '';
  position: absolute;
  left: -7px; top: 22px;
  width: 12px; height: 12px;
  background: #fff;
  border-left: 1px solid var(--border, #E2E8F0);
  border-bottom: 1px solid var(--border, #E2E8F0);
  transform: rotate(45deg);
}
.pin-compose__head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 8px;
}
.pin-compose__pin {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--victory-red, #DC2015); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display, 'Montserrat'), sans-serif;
  font-weight: 800; font-size: 12px;
  flex-shrink: 0;
  box-shadow: 0 1px 2px rgba(220,32,21,0.35);
}
.pin-compose__loc {
  font-family: var(--font-mono, 'Courier Prime'), monospace;
  font-size: 12px; color: var(--fg-3, #718096);
  letter-spacing: 0.1px;
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pin-compose__x {
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; cursor: pointer;
  color: var(--fg-3, #718096);
  border-radius: 6px;
}
.pin-compose__x:hover { background: #F1F5F9; color: var(--fg-1, #1A202C); }
.pin-compose__ta {
  width: 100%;
  min-height: 68px;
  max-height: 200px;
  overflow-y: auto;
  padding: 9px 11px;
  border: 1px solid var(--border, #E2E8F0);
  border-radius: 8px;
  font-family: var(--font-ui, 'Open Sans'), sans-serif;
  font-size: 15px;
  line-height: 1.45;
  outline: none;
  color: var(--fg-1, #1A202C);
  background: #fff;
  transition: all 0.12s ease;
  white-space: pre-wrap;
  word-wrap: break-word;
  cursor: text;
  box-sizing: border-box;
}
.pin-compose__ta:empty::before {
  content: attr(data-placeholder);
  color: var(--fg-4, #A0AEC0);
  pointer-events: none;
}
.pin-compose__ta:focus {
  border-color: rgba(220,32,21,0.4);
  box-shadow: 0 0 0 3px rgba(220,32,21,0.08);
}
.pin-compose__row {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 8px;
  gap: 8px;
}
.pin-compose__kbd {
  font-size: 11px; color: var(--fg-4, #A0AEC0); letter-spacing: 0.2px;
}
.pin-compose__kbd kbd {
  font-family: var(--font-mono, 'Courier Prime'), monospace;
  font-size: 11px;
  padding: 1px 5px;
  background: #F1F5F9;
  border: 1px solid var(--border, #E2E8F0);
  border-radius: 3px;
  margin: 0 1px;
  color: var(--fg-2, #4A5568);
}

/* =============================================================================
   .cmt-help — sidebar instructional block (replaces compose footer when not
   replying). The new-comment flow lives in PinCompose now.
   ============================================================================ */
.cmt-help {
  display: flex; gap: 12px;
  padding: 14px 16px 16px;
  border-top: 1px solid var(--border, #E2E8F0);
  background: #FAFBFC;
  flex-shrink: 0;
}
.cmt-help__icon {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(220,32,21,0.08);
  color: var(--victory-red, #DC2015);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.cmt-help__title {
  font-family: var(--font-display, 'Montserrat'), sans-serif;
  font-weight: 700; font-size: 14px;
  color: var(--fg-1, #1A202C);
  margin-bottom: 4px;
  letter-spacing: 0.1px;
}
.cmt-help__text {
  font-size: 14px; color: var(--fg-2, #4A5568); line-height: 1.55;
}

/* =============================================================================
   PDF.js rendered document — stacks of <canvas> pages with per-page overlays.
   The canvas-wrap above owns vertical scroll; .pdf-doc just lays the pages out.
   ============================================================================ */
.pdf-doc {
  /* Top-align inside the (safe-centered) canvas-wrap so page 1 is always
     reachable. Constrain horizontal max so super-wide pages or wide zoom
     can't paint into the sidebar's grid column. */
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 100%;
  min-width: 0;
}
.pdf-page {
  /* Width/height come from inline styles on the element (scale * natural).
     This rule is purely for safety: don't let a single page exceed the
     visible canvas column width even at high zoom. */
  max-width: 100%;
}

/* =============================================================================
   .viewer__head-markup — Undo · Zoom · Redo cluster in the viewer header.
   Lives between the title and the right-side head-actions group. Undo and
   Redo flank a tightly-packed zoom group with its own subtle background.
   ============================================================================ */
.viewer__head-markup {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-right: 8px;
  flex-shrink: 0;
}
.viewer__head-zoomgroup {
  display: inline-flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 2px;
  gap: 2px;
}
/* Reset-zoom button shows percentage text instead of an icon — give it a
   mono face so the % digits don't jiggle as the number changes. */
.viewer__head-btn--zoomlabel {
  font-family: var(--font-mono, 'Courier Prime'), monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2px;
  min-width: 44px;
  padding: 0 6px;
}
/* Reuse the .viewer__head-btn base styles for the new buttons; just make
   sure disabled state communicates clearly even on the dark surface. */
.viewer__head-markup .viewer__head-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
@media (max-width: 720px) {
  /* Tighten on phones — keep the cluster but drop the gap. */
  .viewer__head-markup { gap: 2px; margin-right: 4px; }
  .viewer__head-btn--zoomlabel { min-width: 36px; font-size: 11px; }
}

/* =============================================================================
   .viewer__head-nav — Prev / [n of N] / Next cluster, centered in the viewer
   header. Absolutely positioned so the surrounding flex children (back,
   title, markup, actions) keep their existing claim on space and don't get
   pushed around — the title-wrap truncates with ellipsis if it would
   otherwise underlap the nav.
   ============================================================================ */
.viewer__head { position: relative; }
.viewer__head-nav {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 2px;
  z-index: 2;
  /* Sit visually flush with the bar's translucent surface. */
  backdrop-filter: blur(4px);
}
.viewer__head-nav .viewer__head-btn { width: 30px; height: 30px; }

/* PDF page nav — prev / [type-to-jump field] / next, in the viewer header. */
.viewer__head-pages {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 2px;
}
.viewer__head-pagefield {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0 4px 0 2px;
}
.viewer__head-pageinput {
  width: 34px;
  height: 26px;
  text-align: center;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 6px;
  color: #fff;
  font-family: var(--font-mono, monospace);
  font-size: 14px;
  font-weight: 700;
  outline: none;
  -moz-appearance: textfield;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.viewer__head-pageinput:focus {
  border-color: var(--victory-red, #dc2015);
  background: rgba(255, 255, 255, 0.14);
}
.viewer__head-pagetotal {
  font-family: var(--font-mono, monospace);
  font-size: 12px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.55);
  white-space: nowrap;
  user-select: none;
}
.viewer.surround-light .viewer__head-pages {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(15, 23, 42, 0.10);
}
.viewer.surround-light .viewer__head-pageinput {
  background: rgba(15, 23, 42, 0.05);
  border-color: rgba(15, 23, 42, 0.12);
  color: var(--fg-1, #1a202c);
}
.viewer.surround-light .viewer__head-pagetotal { color: var(--fg-3, #64748b); }
.viewer__head-nav-count {
  font-family: var(--font-mono, 'Courier Prime'), monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2px;
  color: rgba(255, 255, 255, 0.78);
  padding: 0 8px;
  min-width: 44px;
  text-align: center;
  user-select: none;
}
.viewer.surround-light .viewer__head-nav {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(15, 23, 42, 0.10);
}
.viewer.surround-light .viewer__head-nav-count {
  color: var(--fg-1, #1A202C);
}

@media (max-width: 720px) {
  /* On phones the title would underlap the centered nav. Drop the nav size
     a touch and ensure the title clips cleanly behind it. */
  .viewer__head-nav { gap: 0; padding: 1px; }
  .viewer__head-nav .viewer__head-btn { width: 26px; height: 26px; }
  .viewer__head-nav-count { min-width: 32px; font-size: 11px; padding: 0 4px; }
}

/* =============================================================================
   Light-surround visibility pass. The header flips to a white surface in
   light mode but its child buttons kept their rgba(255,255,255,*) palette,
   leaving icons invisible. Mirror them to dark-on-light here.
   ============================================================================ */
.viewer.surround-light .viewer__head-btn {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(15, 23, 42, 0.10);
  color: var(--fg-2, #4A5568);
}
.viewer.surround-light .viewer__head-btn:hover {
  background: rgba(15, 23, 42, 0.08);
  color: var(--fg-1, #1A202C);
}
.viewer.surround-light .viewer__head-btn:disabled {
  opacity: 0.35;
}
.viewer.surround-light .viewer__head-zoomgroup {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(15, 23, 42, 0.10);
}
.viewer.surround-light .viewer__head-btn--zoomlabel {
  color: var(--fg-1, #1A202C);
}
/* Comment-count badge sits over the message icon — needs contrast in light too */
.viewer.surround-light .viewer__comment-count {
  background: var(--victory-red, #DC2015);
  color: #fff;
}

/* =============================================================================
   ExplorerView — 2-pane Outlook/Microsoft 365-style browser. Self-contained
   theming via CSS custom properties scoped to .explorer, so swapping
   .explorer--surround-light ↔ --surround-dark on the root recolors the
   whole subtree without overrides bleeding past it.
   ============================================================================ */

.explorer {
  --ex-bg:           #f6f6f8;
  --ex-surface:      #ffffff;
  --ex-surface-2:    #f1f1f4;
  --ex-border:       #e9e9ee;
  --ex-border-strong:#d7d7de;
  --ex-text:         #1b1c20;
  --ex-text-2:       #585b64;
  --ex-text-3:       #8b8d97;
  --ex-accent:       #dc2015;
  --ex-accent-soft:  rgba(220, 32, 21, 0.10);
  --ex-selected-bg:  rgba(220, 32, 21, 0.07);
  --ex-selected-border:#dc2015;
  --ex-hover:        #f1f1f4;
  --ex-divider:      #e9e9ee;
  --ex-shadow:       0 6px 20px rgba(17, 18, 22, 0.06), 0 1px 3px rgba(17, 18, 22, 0.04);
  --ex-radius:       9px;

  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  background: var(--ex-bg); color: var(--ex-text);
  font-family: var(--font-ui, 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
  font-size: 15px; line-height: 1.45;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  z-index: 50;
}
.explorer--surround-dark {
  --ex-bg:           #191a1d;
  --ex-surface:      #232428;
  --ex-surface-2:    #2a2b30;
  --ex-border:       #313338;
  --ex-border-strong:#454750;
  --ex-text:         #f0f0f3;
  --ex-text-2:       #aeb0b9;
  --ex-text-3:       #7d808b;
  --ex-accent:       #ff6359;
  --ex-accent-soft:  rgba(255, 99, 89, 0.16);
  --ex-selected-bg:  rgba(255, 99, 89, 0.14);
  --ex-selected-border:#ff6359;
  --ex-hover:        #2c2e33;
  --ex-divider:      #313338;
  --ex-shadow:       0 8px 28px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* ── Topbar ─────────────────────────────────────────────────────────────── */
.explorer__topbar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  height: 44px;
  padding: 0 14px;
  background: var(--ex-surface);
  border-bottom: 1px solid var(--ex-border);
  box-shadow: var(--ex-shadow);
  z-index: 2;
}
.explorer__brand {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}
.explorer__logo {
  height: 22px; width: auto;
  filter: var(--ex-logo-filter, none);
}
.explorer--surround-dark .explorer__logo { filter: invert(1) brightness(1.1) contrast(1.1); }
.explorer__brand-text {
  display: flex; flex-direction: column; line-height: 1.15;
  min-width: 0;
}
.explorer__brand-name {
  font-size: 15px; font-weight: 600; color: var(--ex-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 260px;
}
.explorer__brand-product {
  font-size: 11px; font-weight: 600;
  color: var(--ex-text-3); letter-spacing: 0.12em;
  text-transform: uppercase;
}
.explorer__topbar-spacer { flex: 1 1 auto; }
.explorer__top-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--ex-text-2);
  font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer;
  transition: background 80ms ease, color 80ms ease, border-color 80ms ease;
}
.explorer__top-btn:hover {
  background: var(--ex-hover);
  color: var(--ex-text);
  border-color: var(--ex-border);
}
.explorer__top-btn:active { background: var(--ex-surface-2); }
.explorer__user {
  display: flex; align-items: center;
  padding-left: 4px;
  border-left: 1px solid var(--ex-border);
  margin-left: 4px;
  height: 28px;
}
.explorer__avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--ex-accent);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
}

/* ── Panes layout ───────────────────────────────────────────────────────── */
.explorer__panes {
  flex: 1 1 auto;
  display: flex; min-height: 0;
}
.explorer__pane {
  display: flex; flex-direction: column;
  min-height: 0;
}
.explorer__pane--tree {
  flex: 0 0 auto;
  background: var(--ex-surface);
  border-right: 1px solid var(--ex-border);
  min-width: 220px; max-width: 560px;
}
.explorer__pane--preview {
  flex: 1 1 auto; min-width: 0;
  background: var(--ex-bg);
  position: relative; /* containing block for the embedded viewer */
}

/* Host wrapper for the embedded single-pane viewer. Fills the preview pane
   and gives the absolutely-positioned `.viewer--embedded` a positioned,
   clipped box to live in. */
.explorer__viewer-host {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
  overflow: hidden;
}

/* Embedded viewer — same component as the full-screen viewer, but contained
   to its host instead of `position: fixed` over the viewport. The host owns
   navigation (the tree), so the back button is hidden and the header reads as
   a clean markup toolbar. */
.viewer--embedded {
  position: absolute;
  inset: 0;
}
.viewer--embedded .viewer__back {
  display: none;
}
.explorer__divider {
  flex: 0 0 5px;
  background: transparent;
  cursor: col-resize;
  position: relative;
}
.explorer__divider::before {
  content: '';
  position: absolute; left: 2px; top: 0; bottom: 0; width: 1px;
  background: var(--ex-border);
  transition: background 120ms ease;
}
.explorer__divider:hover::before { background: var(--ex-accent); }

/* ── Tree pane header + search ─────────────────────────────────────────── */
.explorer__pane-head {
  flex: 0 0 auto;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--ex-border);
}
.explorer__pane-title {
  font-family: var(--font-display, 'Montserrat', sans-serif);
  font-size: 15px; font-weight: 700;
  color: var(--ex-text);
  letter-spacing: 0.01em;
}
.explorer__pane-sub {
  font-size: 12px; color: var(--ex-text-3);
  margin-top: 2px;
  letter-spacing: 0.01em;
}
.explorer__search-wrap {
  position: relative;
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--ex-border);
}
.explorer__search {
  width: 100%;
  height: 34px;
  background: var(--ex-surface-2);
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 0 30px 0 32px;
  font: inherit; font-size: 14px;
  color: var(--ex-text);
  outline: none;
  transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.explorer__search::placeholder { color: var(--ex-text-3); }
.explorer__search:focus {
  border-color: var(--ex-accent);
  background: var(--ex-surface);
  box-shadow: 0 0 0 3px var(--ex-accent-soft);
}
.explorer__search-icon {
  position: absolute; left: 22px; top: 50%;
  transform: translateY(-50%);
  color: var(--ex-text-3); pointer-events: none;
}
.explorer__search-clear {
  position: absolute; right: 19px; top: 50%;
  transform: translateY(-50%);
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 0; border-radius: 50%;
  color: var(--ex-text-3); cursor: pointer;
  transition: background 80ms ease, color 80ms ease;
}
.explorer__search-clear:hover {
  background: var(--ex-hover);
  color: var(--ex-text);
}

/* ── Tree rows ──────────────────────────────────────────────────────────── */
.extree {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto;
  padding: 4px 0 16px;
  /* Microsoft 365-style narrow scrollbar */
  scrollbar-width: thin;
  scrollbar-color: var(--ex-border-strong) transparent;
}
.extree::-webkit-scrollbar { width: 10px; }
.extree::-webkit-scrollbar-thumb {
  background: var(--ex-border-strong); border-radius: 5px;
  border: 2px solid var(--ex-surface);
}
.extree::-webkit-scrollbar-track { background: transparent; }

/* ── Bookmarks panel — pinned below the tree in Explorer's left pane ──────────
   Splits the tree pane vertically: drag the divider to re-balance, click the
   header to collapse into just the bar. Themes off --ex-* so it follows the
   Explorer's light/dark surround automatically. */
.exbm {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--ex-surface);
  border-top: 1px solid var(--ex-border);
}
.exbm__divider {
  flex: 0 0 auto;
  height: 7px;
  cursor: row-resize;
  position: relative;
  margin-top: -1px;
}
.exbm__divider::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 2px;
  height: 2px;
  background: transparent;
  transition: background 0.12s ease;
}
.exbm__divider:hover::before { background: var(--ex-accent); }
.exbm__head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--ex-text-2);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background 0.1s ease, color 0.1s ease;
}
.exbm__head:hover { background: var(--ex-hover); color: var(--ex-text); }
.exbm__chev {
  display: inline-flex;
  color: var(--ex-text-3);
  transition: transform 0.16s ease;
}
.exbm__chev.is-collapsed { transform: rotate(-90deg); }
.exbm__label { flex: 0 0 auto; }
.exbm__count {
  margin-left: auto;
  min-width: 18px; height: 16px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--ex-surface-2);
  border: 1px solid var(--ex-border);
  border-radius: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ex-text-2);
}
.exbm__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 2px 6px 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--ex-border-strong) transparent;
}
.exbm__body::-webkit-scrollbar { width: 10px; }
.exbm__body::-webkit-scrollbar-thumb {
  background: var(--ex-border-strong); border-radius: 5px;
  border: 2px solid var(--ex-surface);
}
.exbm__body::-webkit-scrollbar-track { background: transparent; }
/* Theme the shared .bm-* rows for the Explorer palette. */
.exbm .bm-row { color: var(--ex-text-2); font-family: inherit; font-size: 14px; }
.exbm .bm-row:hover { background: var(--ex-hover); color: var(--ex-text); }
.exbm .bm-page { color: var(--ex-text-3); }
.exbm .bm-node .bm-node { border-left-color: var(--ex-border); }

/* In-document search panel (shares the .exbm collapsible chrome). */
.exsearch__body {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 320px;
  padding: 8px 10px 10px;
}
.exsearch__field {
  position: relative;
  flex: 0 0 auto;
  margin-bottom: 8px;
}
.exsearch__icon {
  position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  color: var(--ex-text-3); pointer-events: none;
}
.exsearch__input {
  width: 100%;
  height: 32px;
  background: var(--ex-surface-2);
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 0 28px 0 28px;
  font: inherit; font-size: 14px;
  color: var(--ex-text);
  outline: none;
  transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.exsearch__input::placeholder { color: var(--ex-text-3); }
.exsearch__input:focus {
  border-color: var(--ex-accent);
  background: var(--ex-surface);
  box-shadow: 0 0 0 3px var(--ex-accent-soft);
}
.exsearch__clear {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: 50%;
  color: var(--ex-text-3); cursor: pointer;
}
.exsearch__clear:hover { background: var(--ex-hover); color: var(--ex-text); }
.exsearch__results {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--ex-border-strong) transparent;
}
.exsearch__hint {
  padding: 8px 6px;
  font-size: 13px;
  color: var(--ex-text-3);
}
.exsearch__result {
  display: flex;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 7px 8px;
  background: transparent;
  border: 0;
  border-radius: 7px;
  color: var(--ex-text-2);
  cursor: pointer;
  font: inherit; font-size: 14px; line-height: 1.4;
  transition: background 0.1s ease;
}
.exsearch__result:hover { background: var(--ex-hover); }
.exsearch__result-page {
  flex: 0 0 auto;
  font-family: var(--font-mono, monospace);
  font-size: 11px;
  font-weight: 700;
  color: var(--ex-text-3);
  padding-top: 1px;
}
.exsearch__result-snippet {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.exsearch__result-snippet mark {
  background: rgba(220, 32, 21, 0.18);
  color: var(--ex-text);
  border-radius: 2px;
  padding: 0 1px;
  font-weight: 700;
}
.explorer--surround-dark .exsearch__result-snippet mark {
  background: rgba(255, 99, 89, 0.28);
}

.extree__row {
  display: flex; align-items: center; gap: 6px;
  height: 30px;
  margin: 1px 8px;
  padding-right: 10px;
  border-radius: 8px;
  font-size: 14px;
  color: var(--ex-text);
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: background 0.1s ease, color 0.1s ease;
}
.extree__row:hover { background: var(--ex-hover); }
.extree__row.is-selected {
  background: var(--ex-selected-bg);
  color: var(--ex-text);
  font-weight: 600;
}
.extree__row.is-selected::before {
  content: '';
  position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--ex-selected-border);
}
.extree__row.is-folder { font-family: var(--font-francy); font-weight: 400; }
.extree__row.is-file { font-family: 'Montserrat', 'Helvetica Neue', Arial, sans-serif; font-weight: 400; }

/* MultiCam folder — a specialty player, not a normal folder. Always
   highlighted so it reads as an action row: faint purple wash, a persistent
   left accent bar, and bolder text. Layers cleanly on top of is-selected. */
.extree__row.is-multicam {
  background: rgba(126, 34, 206, 0.08);
  font-weight: 600;
}
.extree__row.is-multicam:hover { background: rgba(126, 34, 206, 0.14); }
.extree__row.is-multicam::before {
  content: '';
  position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: #7e22ce;
}
.extree__row.is-multicam.is-selected { background: rgba(126, 34, 206, 0.18); }
.explorer--surround-dark .extree__row.is-multicam { background: rgba(168, 85, 247, 0.16); }
.explorer--surround-dark .extree__row.is-multicam:hover { background: rgba(168, 85, 247, 0.24); }
.explorer--surround-dark .extree__row.is-multicam::before { background: #c084fc; }

.extree__chevron {
  flex: 0 0 12px;
  width: 12px; height: 12px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ex-text-3);
}
.extree__icon {
  flex: 0 0 16px;
  width: 16px; height: 16px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ex-text-2);
}
.extree__icon--folder    { color: #c19a3f; }
.extree__icon--pdf       { color: #b91c1c; }
.extree__icon--image     { color: #1e7c44; }
.extree__icon--video     { color: #7e22ce; }
.extree__icon--audio     { color: #c2410c; }
.extree__icon--sheet     { color: #047857; }
.extree__icon--doc,
.extree__icon--html      { color: var(--ex-accent); }
.extree__icon--multicam  { color: #7e22ce; }
.explorer--surround-dark .extree__icon--multicam { color: #c084fc; }
.explorer--surround-dark .extree__icon--folder { color: #e6c879; }
.explorer--surround-dark .extree__icon--pdf    { color: #f87171; }
.explorer--surround-dark .extree__icon--image  { color: #6bcf94; }

.extree__name {
  flex: 1 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.extree__spin {
  flex: 0 0 10px;
  width: 10px; height: 10px;
  border: 1.5px solid var(--ex-border-strong);
  border-top-color: var(--ex-accent);
  border-radius: 50%;
  animation: ex-spin 0.7s linear infinite;
}
.extree__count {
  flex: 0 0 auto;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ex-surface-2);
  color: var(--ex-text-3);
  border-radius: 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.extree__row.is-selected .extree__count {
  background: rgba(255,255,255,0.5);
  color: var(--ex-text);
}
.explorer--surround-dark .extree__row.is-selected .extree__count {
  background: rgba(255,255,255,0.18);
  color: #fff;
}
.extree__chevron-btn {
  flex: 0 0 14px;
  width: 14px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--ex-text-3);
  cursor: pointer;
  border-radius: 2px;
}
.extree__chevron-btn:hover {
  background: rgba(0,0,0,0.08);
  color: var(--ex-text);
}
.explorer--surround-dark .extree__chevron-btn:hover { background: rgba(255,255,255,0.10); }
@keyframes ex-spin { to { transform: rotate(360deg); } }

.extree__empty,
.extree__err {
  font-size: 12px;
  color: var(--ex-text-3);
  padding: 4px 10px;
  font-style: italic;
}
.extree__err { color: #b91c1c; }
.explorer--surround-dark .extree__err { color: #f87171; }

/* ── Right pane: preview header ─────────────────────────────────────────── */
.expreview {
  display: flex; flex-direction: column;
  height: 100%; min-height: 0;
  background: var(--ex-bg);
}
.expreview__head {
  flex: 0 0 auto;
  background: var(--ex-surface);
  border-bottom: 1px solid var(--ex-border);
  padding: 10px 18px 12px;
  box-shadow: var(--ex-shadow);
  z-index: 1;
}
.expreview__crumbs {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--ex-text-3);
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.expreview__crumb {
  font-weight: 500;
  letter-spacing: 0.01em;
}
.expreview__crumb--case { color: var(--ex-text-2); font-weight: 600; }
.expreview__crumb-sep { color: var(--ex-text-3); font-size: 12px; }

.expreview__title-row {
  display: flex; align-items: center; gap: 14px;
  flex-wrap: wrap;
}
.expreview__title {
  flex: 1 1 auto; min-width: 0;
  font-family: 'Segoe UI', sans-serif;
  font-size: 19px; font-weight: 600;
  color: var(--ex-text);
  letter-spacing: -0.005em;
  line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.expreview__meta {
  display: inline-flex; gap: 6px; align-items: center;
  font-size: 12px; color: var(--ex-text-3);
  white-space: nowrap;
}
.expreview__meta-dot { color: var(--ex-text-3); }

.expreview__head-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px;
  background: var(--ex-accent);
  border: 1px solid var(--ex-accent);
  color: #fff;
  border-radius: 4px;
  font: inherit; font-size: 14px; font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease, transform 80ms ease;
}
.expreview__head-btn:hover {
  background: #106ebe;
  border-color: #106ebe;
}
.expreview__head-btn:active { transform: translateY(0.5px); }

/* ── Right pane: body ──────────────────────────────────────────────────── */
.expreview__body {
  flex: 1 1 auto; min-height: 0;
  overflow: auto;
  background: var(--ex-bg);
  display: flex; flex-direction: column;
}
.expreview__iframe {
  width: 100%; height: 100%;
  border: 0;
  background: #fff;
  flex: 1 1 auto;
}
.expreview__image-wrap {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: var(--ex-bg);
}
.expreview__image {
  max-width: 100%; max-height: 100%;
  box-shadow: var(--ex-shadow);
  border: 1px solid var(--ex-border);
}
.expreview__video {
  width: 100%; height: 100%;
  max-height: calc(100vh - 120px);
  background: #000;
  outline: none;
}
.expreview__audio-wrap {
  display: flex; align-items: center; justify-content: center;
  padding: 40px;
  flex: 1 1 auto;
}
.expreview__audio { width: 100%; max-width: 520px; }

.expreview__loading,
.expreview__error,
.expreview__nonpreview {
  padding: 40px 24px;
  text-align: center;
  color: var(--ex-text-2);
  font-size: 15px;
}
.expreview__error { color: #b91c1c; }
.expreview__nonpreview { max-width: 460px; margin: 60px auto; }
.expreview__nonpreview-h {
  font-size: 18px; font-weight: 600;
  color: var(--ex-text);
  margin: 0 0 10px;
}
.expreview__nonpreview p {
  margin: 0 0 20px;
  color: var(--ex-text-2);
  line-height: 1.55;
}

/* ── Right pane: empty state ───────────────────────────────────────────── */
.expreview--empty {
  align-items: center; justify-content: center;
  display: flex;
}
.expreview__empty-card {
  text-align: center;
  max-width: 420px;
  padding: 40px 24px;
}
.expreview__empty-icon {
  width: 84px; height: 84px;
  border-radius: 22px;
  background: var(--ex-accent-soft);
  color: var(--ex-accent);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 20px;
  box-shadow: 0 10px 30px -12px var(--ex-accent-soft);
}
.expreview__empty-h {
  font-family: 'Montserrat', 'Helvetica Neue', Arial, sans-serif;
  font-size: 20px; font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ex-text);
  margin-bottom: 8px;
}
.expreview__empty-sub {
  font-family: 'Montserrat', 'Helvetica Neue', Arial, sans-serif;
  font-size: 15px; color: var(--ex-text-2);
  line-height: 1.55; margin: 0;
}

/* ── Folder list (right pane when a folder is selected) ─────────────────── */
.exlist {
  display: flex; flex-direction: column;
  height: 100%; min-height: 0;
  background: var(--ex-bg);
}
.exlist__head {
  flex: 0 0 auto;
  background: var(--ex-surface);
  border-bottom: 1px solid var(--ex-border);
  padding: 10px 18px 14px;
  box-shadow: var(--ex-shadow);
  z-index: 1;
}
.exlist__title-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.exlist__title {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display, 'Montserrat', sans-serif);
  font-size: 19px; font-weight: 700;
  color: var(--ex-text);
  letter-spacing: -0.01em;
  line-height: 1.25;
  min-width: 0;
}
.exlist__title-icon {
  display: inline-flex; align-items: center; justify-content: center;
  color: #c19a3f;
}
.explorer--surround-dark .exlist__title-icon { color: #e6c879; }
.exlist__count {
  font-size: 14px;
  color: var(--ex-text-2);
  font-variant-numeric: tabular-nums;
}
.exlist__count strong {
  color: var(--ex-text);
  font-weight: 700;
}
.exlist__count-label { color: var(--ex-text-2); }
.exlist__count-sub { color: var(--ex-text-3); }

.exlist__body {
  flex: 1 1 auto; min-height: 0;
  overflow: auto;
  background: var(--ex-bg);
}
.exlist__loading,
.exlist__empty,
.exlist__error {
  padding: 32px 24px;
  text-align: center;
  font-size: 15px;
  color: var(--ex-text-2);
}
.exlist__error { color: #b91c1c; }

.exlist__table {
  display: grid;
  grid-template-columns: minmax(260px, 1fr) 110px 110px 170px;
  /* Force the implicit grid to use the same template so each row's cells
     land in the same columns as the header. */
  grid-auto-rows: 32px;
  align-items: stretch;
}
.exlist__head-row {
  display: contents;
}
.exlist__th {
  display: inline-flex; align-items: center; gap: 4px;
  height: 34px; padding: 0 12px;
  background: var(--ex-surface);
  border-bottom: 1px solid var(--ex-border);
  font-family: var(--font-display, 'Montserrat', sans-serif);
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ex-text-3);
  cursor: pointer;
  border-left: 0; border-right: 0; border-top: 0;
  text-align: left;
  position: sticky; top: 0; z-index: 1;
}
.exlist__th.is-active { color: var(--ex-accent); }
.exlist__th.is-right {
  justify-content: flex-end; padding-right: 16px;
}
.exlist__th:hover { background: var(--ex-hover); color: var(--ex-text); }
.exlist__th-arrow { font-size: 11px; opacity: 0.7; }

.exlist__row {
  display: contents;
  cursor: pointer;
}
.exlist__cell {
  display: flex; align-items: center;
  padding: 0 12px;
  font-size: 15px;
  color: var(--ex-text);
  border-bottom: 1px solid var(--ex-border);
  background: var(--ex-bg);
  overflow: hidden;
  transition: background 80ms ease;
  min-width: 0;
}
.exlist__row:hover .exlist__cell { background: var(--ex-hover); }
.exlist__cell--name {
  gap: 10px;
  font-weight: 500;
}
.exlist__cell-icon {
  flex: 0 0 16px;
  width: 16px; height: 16px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ex-text-2);
}
.exlist__cell-icon--folder { color: #c19a3f; }
.exlist__cell-icon--pdf    { color: #b91c1c; }
.exlist__cell-icon--image  { color: #1e7c44; }
.exlist__cell-icon--video  { color: #7e22ce; }
.exlist__cell-icon--audio  { color: #c2410c; }
.exlist__cell-icon--sheet  { color: #047857; }
.exlist__cell-icon--doc,
.exlist__cell-icon--html   { color: var(--ex-accent); }
.exlist__cell-icon--multicam { color: #7e22ce; }
.explorer--surround-dark .exlist__cell-icon--multicam { color: #c084fc; }
/* MultiCam row in a folder listing — same purple wash as the tree row. */
.exlist__row.is-multicam .exlist__cell { background: rgba(126, 34, 206, 0.08); }
.exlist__row.is-multicam:hover .exlist__cell { background: rgba(126, 34, 206, 0.14); }
.explorer--surround-dark .exlist__row.is-multicam .exlist__cell { background: rgba(168, 85, 247, 0.16); }
.explorer--surround-dark .exlist__row.is-multicam:hover .exlist__cell { background: rgba(168, 85, 247, 0.24); }
.explorer--surround-dark .exlist__cell-icon--folder { color: #e6c879; }
.explorer--surround-dark .exlist__cell-icon--pdf    { color: #f87171; }
.explorer--surround-dark .exlist__cell-icon--image  { color: #6bcf94; }
.exlist__cell-name {
  flex: 1 1 auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.exlist__cell--type {
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ex-text-3);
  text-transform: uppercase;
}
.exlist__cell--size {
  justify-content: flex-end;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  color: var(--ex-text-2);
  padding-right: 16px;
}
.exlist__cell--mod {
  font-size: 14px;
  color: var(--ex-text-2);
  font-variant-numeric: tabular-nums;
}

/* ── Mobile ─────────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .explorer__panes { flex-direction: column; }
  .explorer__pane--tree {
    width: 100% !important;
    max-width: none; min-width: 0;
    max-height: 40vh;
    border-right: 0;
    border-bottom: 1px solid var(--ex-border);
  }
  .explorer__divider { display: none; }
  .explorer__brand-name { max-width: 140px; }
  .explorer__top-btn span { display: none; }
  .expreview__head { padding: 8px 12px 10px; }
  .expreview__title { font-size: 17px; }
  .exlist__table {
    grid-template-columns: 1fr 80px 90px;
  }
  .exlist__th--modified, .exlist__cell--mod { display: none; }
}

/* =============================================================================
   Client picker (firm staff) — dark vault aesthetic.

   The picker is the *continuation* of the login splash, not a separate room.
   It uses the same `.background` deep-navy panel and the same firm-standard
   mobile-fullscreen-splash positioning (position: absolute, top: 100px) so
   the gradient bleeds under iOS Safari's chrome edge-to-edge on every
   device. The body is frozen by useIosChromeFreeze; the picker LIST scrolls
   inside `.picker-stage` (overflow-y: auto + touch-action: pan-y), and the
   freeze hook's touchmove handler walks up from the touch target so any
   touch landing inside this stage is allowed to scroll.

   Visual language:
     • Deep navy backdrop with radial blooms (inherits .background).
     • Brass-tinted top-right firm pill (mirrors the login identity plaque).
     • Editorial title + sub.
     • "Registry drawer" of dark slabs — docket-style index, brass-engraved
       client name (#F1E1BC, engraved text-shadow), victory-red left accent on
       hover/focus.
   ============================================================================= */

.picker-stage {
  /* position: absolute (NOT fixed) per the firm-standard
     mobile-fullscreen-splash skill — iOS 26 clips position: fixed at the
     chrome boundary (memory 4847684e). The theme-color approach in
     index.html paints iOS chrome the same navy as this stage, so the
     stage visually fills the device edge-to-edge with no offset.
     height: 100lvh + overflow-y: auto keeps the client list scrollable
     INSIDE the stage; touch-action: pan-y + -webkit-overflow-scrolling:
     touch deliver native momentum on iOS. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100lvh;
  z-index: 5000;
  overflow-y: auto;
  overflow-x: hidden;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
  outline: none;
  display: block;
  padding:
    calc(env(safe-area-inset-top, 0px)    + clamp(72px, 9vh, 128px))
    env(safe-area-inset-right, 0px)
    calc(env(safe-area-inset-bottom, 0px) + 96px)
    env(safe-area-inset-left, 0px);
}

/* Firm identity pill — top-right, brass-engraved edge to match the login
   identity plaque so the firm member feels they're inside the same vault. */
.picker-firm {
  position: fixed;
  top: max(28px, env(safe-area-inset-top, 0px) + 16px);
  right: max(32px, env(safe-area-inset-right, 0px) + 16px);
  z-index: 5001;
  display: flex; align-items: center;
  gap: 12px;
  padding: 8px 8px 8px 12px;
  border-radius: 999px;
  background: rgba(18, 28, 38, 0.62);
  -webkit-backdrop-filter: saturate(160%) blur(20px);
  backdrop-filter:         saturate(160%) blur(20px);
  border: 1px solid rgba(208, 168, 96, 0.22);
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 160, 0.10),
    0 8px 32px rgba(0, 0, 0, 0.42);
}
.picker-firm__avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.18);
  object-fit: cover;
  background: #1a2632;
}
.picker-firm__avatar--initials {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-weight: 700; font-size: 14px;
  color: #F1E1BC;
  letter-spacing: 1px;
}
.picker-firm__body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.picker-firm__label {
  font-size: 9px; font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: rgba(232, 200, 132, 0.55);
  font-family: var(--font-display);
}
.picker-firm__name {
  font-size: 15px; font-weight: 600;
  color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 220px;
}
.picker-firm__out {
  border: 0;
  background: rgba(0, 0, 0, 0.28);
  color: rgba(255, 255, 255, 0.55);
  width: 30px; height: 30px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: all 0.15s var(--ease-standard);
  margin-left: 4px;
  flex-shrink: 0;
}
.picker-firm__out:hover {
  background: rgba(220, 32, 21, 0.32);
  color: #fff;
}

.picker-shell {
  width: min(1200px, 100%);
  margin: 0 auto;
  position: relative;
  z-index: 1;
  color: #fff;
}

.picker-head { margin-bottom: 32px; }
.picker-eyebrow {
  font-family: var(--font-display);
  font-size: 12px; font-weight: 700;
  letter-spacing: 3px;
  color: var(--victory-red);
  text-transform: uppercase;
  margin-bottom: 18px;
  display: flex; align-items: center; gap: 12px;
}
.picker-eyebrow__dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--victory-red);
  box-shadow: 0 0 14px rgba(220, 32, 21, 0.8);
  animation: secure-pulse 2.4s ease-out infinite;
}
.picker-title {
  font-family: var(--font-display);
  font-size: clamp(40px, 6vw, 64px);
  font-weight: 800;
  letter-spacing: -2px;
  line-height: 1;
  margin: 0 0 16px;
  /* Explicit white so "Open a client's" reads against the dark splash;
     the <em> still picks up victory red via .picker-title em below. */
  color: #FFFFFF;
}
.picker-title em {
  font-style: normal;
  color: var(--victory-red);
}
.picker-sub {
  font-size: 17px;
  color: rgba(255, 255, 255, 0.62);
  line-height: 1.6;
  margin: 0 0 28px;
  max-width: 560px;
}

.picker-search {
  display: flex; align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  color: rgba(255, 255, 255, 0.45);
  transition: all 0.15s var(--ease-standard);
}
.picker-search:focus-within {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(220, 32, 21, 0.55);
  color: rgba(255, 255, 255, 0.8);
  box-shadow: 0 0 0 4px rgba(220, 32, 21, 0.10);
}
.picker-search input {
  flex: 1;
  background: none; border: 0; outline: 0;
  color: #fff;
  font-family: var(--font-ui);
  font-size: 16px;
  padding: 2px 0;
  min-width: 0;
}
.picker-search input::placeholder { color: rgba(255, 255, 255, 0.32); }
.picker-search input:disabled { color: rgba(255, 255, 255, 0.3); }
.picker-search__clear {
  border: 0;
  background: rgba(255, 255, 255, 0.06);
  width: 22px; height: 22px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: rgba(255, 255, 255, 0.6);
  transition: all 0.12s var(--ease-standard);
  flex-shrink: 0;
}
.picker-search__clear:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }

.picker-error {
  margin: 16px 0 20px;
  padding: 10px 14px;
  background: rgba(220, 32, 21, 0.10);
  border: 1px solid rgba(220, 32, 21, 0.35);
  border-radius: 8px;
  color: #FCA5A5;
  font-size: 15px;
  display: flex; align-items: center; gap: 8px;
}

.picker-list { display: flex; flex-direction: column; gap: 8px; }

.picker-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 18px 24px 18px 28px;
  /* Solid-ish dark steel surface — was rgba(255,255,255,0.025) which
     left the brushed-metal background bleeding straight through. At
     ~80% opacity over the navy base the texture reads at ~20% behind
     each card, so cards have their own surface but still feel of-a-
     piece with the splash. */
  background: rgba(15, 24, 35, 0.80);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  text-align: left;
  color: #fff;
  cursor: pointer;
  font-family: var(--font-ui);
  transition: all 0.18s var(--ease-standard);
  overflow: hidden;
  animation: picker-card-in 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.picker-card:nth-child(1) { animation-delay: 0.05s; }
.picker-card:nth-child(2) { animation-delay: 0.10s; }
.picker-card:nth-child(3) { animation-delay: 0.15s; }
.picker-card:nth-child(4) { animation-delay: 0.20s; }
.picker-card:nth-child(5) { animation-delay: 0.25s; }
.picker-card:nth-child(6) { animation-delay: 0.30s; }
.picker-card:nth-child(7) { animation-delay: 0.35s; }
.picker-card:nth-child(n+8) { animation-delay: 0.40s; }
@keyframes picker-card-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.picker-card::before {
  content: '';
  position: absolute;
  left: 0; top: 14px; bottom: 14px;
  width: 3px;
  /* Neutral white tick at rest; the hover/focused state takes over with
     victory red. Gold/champagne accents removed — brand palette only. */
  background: rgba(255, 255, 255, 0.16);
  border-radius: 0 2px 2px 0;
  transition: all 0.18s var(--ease-standard);
}
.picker-card:hover,
.picker-card.is-focused {
  /* Slightly lighter steel on hover so the card lifts toward the eye
     without exposing more of the metal texture behind it. */
  background: rgba(28, 42, 58, 0.86);
  border-color: rgba(220, 32, 21, 0.40);
  transform: translateX(2px);
}
.picker-card:hover::before,
.picker-card.is-focused::before {
  background: var(--victory-red);
  top: 0; bottom: 0;
  box-shadow: 0 0 18px rgba(220, 32, 21, 0.6);
}
.picker-card:disabled { cursor: not-allowed; opacity: 0.55; }
.picker-card.is-busy {
  background: rgba(220, 32, 21, 0.10);
  border-color: rgba(220, 32, 21, 0.4);
  opacity: 1;
}
.picker-card.is-busy::before { background: var(--victory-red); top: 0; bottom: 0; }

.picker-card__index {
  font-family: var(--font-mono);
  font-size: 25px;
  font-weight: 600;
  /* Muted white at rest, full white on hover/focus — gold removed. */
  color: rgba(255, 255, 255, 0.45);
  letter-spacing: -0.5px;
  font-variant-numeric: tabular-nums;
  width: 36px;
  flex-shrink: 0;
}
.picker-card:hover .picker-card__index,
.picker-card.is-focused .picker-card__index {
  color: rgba(255, 255, 255, 0.92);
}

.picker-card__body {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.picker-card__name {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 1px;
  /* White on dark — champagne tint dropped to stay on brand palette. */
  color: #FFFFFF;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.15;
}
.picker-card__meta {
  display: flex; align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 12px;
}
.picker-card__pill {
  display: inline-flex; align-items: center;
  padding: 3px 8px;
  border-radius: 3px;
  background: rgba(220, 32, 21, 0.15);
  color: #FCA5A5;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.picker-card__slug {
  font-family: var(--font-mono);
  color: rgba(255, 255, 255, 0.45);
  font-size: 12px;
}
.picker-card__last {
  color: rgba(255, 255, 255, 0.35);
  font-size: 12px;
}
.picker-card__cases { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.picker-card__case {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 3px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
  font-family: var(--font-mono);
  max-width: 240px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.picker-card__case--more {
  color: rgba(208, 168, 96, 0.72);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.5px;
}

.picker-card__action {
  display: flex; align-items: center; gap: 6px;
  color: rgba(255, 255, 255, 0.35);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  flex-shrink: 0;
  transition: all 0.18s var(--ease-standard);
}
.picker-card:hover .picker-card__action,
.picker-card.is-focused .picker-card__action {
  color: var(--victory-red);
  gap: 8px;
}

.picker-card__spin {
  width: 16px; height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--victory-red);
  border-radius: 50%;
  animation: picker-spin 0.6s linear infinite;
}
@keyframes picker-spin { to { transform: rotate(360deg); } }

.picker-card--skeleton {
  pointer-events: none;
  border-color: rgba(255, 255, 255, 0.05);
  animation: none;
  opacity: 1;
}
.picker-card--skeleton::before { background: rgba(255, 255, 255, 0.05); }
.picker-card--skeleton .picker-card__bar {
  display: block;
  height: 12px;
  background: linear-gradient(90deg,
    rgba(255, 255, 255, 0.04) 0%,
    rgba(255, 255, 255, 0.10) 50%,
    rgba(255, 255, 255, 0.04) 100%);
  background-size: 200% 100%;
  animation: picker-shimmer 1.4s ease-in-out infinite;
  border-radius: 4px;
}
.picker-card--skeleton .picker-card__bar--name { width: 220px; height: 18px; margin-bottom: 10px; }
.picker-card--skeleton .picker-card__bar--meta { width: 140px; height: 11px; }
@keyframes picker-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.picker-empty {
  padding: 60px 24px;
  text-align: center;
  color: rgba(255, 255, 255, 0.4);
  font-size: 16px;
  border: 1px dashed rgba(255, 255, 255, 0.10);
  border-radius: 8px;
  font-family: var(--font-ui);
  line-height: 1.6;
}

.picker-foot {
  margin-top: 22px;
  font-size: 12px;
  font-family: var(--font-mono);
  color: rgba(255, 255, 255, 0.4);
  display: flex; align-items: center; gap: 10px;
}

@media (max-width: 720px) {
  .picker-firm { padding: 6px; gap: 8px; }
  .picker-firm__body { display: none; }
  .picker-firm__avatar { width: 28px; height: 28px; }
  .picker-firm__out { width: 28px; height: 28px; }
  .picker-card { padding: 14px 16px 14px 22px; gap: 12px; }
  .picker-card__index { font-size: 18px; width: 22px; }
  .picker-card__name { font-size: 18px; }
  .picker-card__action span { display: none; }
  .picker-card__action { gap: 0; }
}

/* ──────────────────────────────────────────────────────────────────────
   Health-records export — the always-highlighted row ("liquid glass")
   The .zip that opens the medical-record viewer (file-row type "health")
   is pinned as a cool, sophisticated glass card: a blue-tinted translucent
   frosted material with a hairline specular rim, a single diffuse float
   shadow, and one light reflection that sweeps across it on mount. Cool
   blue, drawn from the firm navy family; dark row text stays fully legible.
   Transform/opacity only; the sweep and lift are suppressed under
   prefers-reduced-motion. End of file so it wins the cascade.
   ────────────────────────────────────────────────────────────────────── */
.file-row.is-medical {
  position: relative;
  z-index: 1;
  overflow: hidden;
  isolation: isolate;
  /* Full-bleed: the whole row in its natural shape (no inset pill). Same box,
     padding and bottom divider as every other row — just rendered as glass. */
  border-bottom: 1px solid rgba(150, 182, 214, 0.30);
  /* Frosted glass: a cool blue-tinted translucent fill over a backdrop blur. */
  background:
    linear-gradient(157deg, rgba(238, 245, 252, 0.60) 0%, rgba(202, 222, 242, 0.32) 100%),
    rgba(88, 132, 176, 0.15);
  -webkit-backdrop-filter: blur(16px) saturate(175%);
  backdrop-filter: blur(16px) saturate(175%);
  /* Specular top highlight + hairline side rims, no heavy float (it's a row,
     not a floating card). */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.75),
    inset 1px 0 0 rgba(255, 255, 255, 0.30),
    inset -1px 0 0 rgba(150, 182, 214, 0.30);
  transition: background 240ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 240ms cubic-bezier(0.22, 1, 0.36, 1);
}
.file-row.is-medical:hover {
  background:
    linear-gradient(157deg, rgba(242, 248, 253, 0.72) 0%, rgba(208, 226, 244, 0.42) 100%),
    rgba(88, 132, 176, 0.20);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.90),
    inset 1px 0 0 rgba(255, 255, 255, 0.40),
    inset -1px 0 0 rgba(150, 182, 214, 0.45);
}
/* The medical row owns the full width, so suppress the generic red hover bar. */
.file-row.is-medical::before { content: none; }
/* The health icon takes the cool accent so the card reads as one material. */
.file-row.is-medical .file-row__icon--health { color: #2F5E7E; }

/* One-time specular sweep — a soft light reflection crosses the glass once
   on mount. translateX only (compositor). */
.file-row.is-medical::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-130%);
  background: linear-gradient(105deg,
              transparent 36%,
              rgba(255, 255, 255, 0.55) 49%,
              rgba(196, 220, 244, 0.35) 55%,
              transparent 68%);
  animation: medrec-glisten 1300ms cubic-bezier(0.22, 1, 0.36, 1) 360ms 1 both;
  pointer-events: none;
}

@keyframes medrec-glisten {
  to { transform: translateX(130%); }
}

@media (prefers-reduced-motion: reduce) {
  .file-row.is-medical { transition: none; }
  .file-row.is-medical::after { animation: none; opacity: 0; }
}
/* Web equivalents of iOS Reduce Transparency / Increase Contrast: drop the
   blur to a solid cool fill and strengthen the rim so legibility never
   depends on the translucency. */
@media (prefers-reduced-transparency: reduce) {
  .file-row.is-medical {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: #E7EFF7;
  }
}
@media (prefers-contrast: more) {
  .file-row.is-medical {
    box-shadow:
      inset 0 0 0 1px rgba(47, 94, 126, 0.9),
      0 10px 26px -14px rgba(29, 50, 66, 0.45);
  }
}

/* ══════════════════════════════════════════════════════════════════════
   Liquid Glass — site-wide iOS 26 glass pass (2026-06-18)
   Glass lives on the navigation / chrome layer (top bar, menus, sheets,
   controls, cards), never on body text. Every surface = a translucent
   tinted fill over a backdrop blur + saturate, a hairline specular top
   edge, and a soft float. Light glass for the in-app chrome (it floats over
   light content); dark glass for the splash picker (it floats over the dark
   brushed-metal hero). Accessibility fallbacks at the end honor Reduce
   Transparency and Increase Contrast. Appended last so it wins the cascade.
   ══════════════════════════════════════════════════════════════════════ */

/* Top bar — deeper, cooler glass with a specular top edge. */
.vault-topbar {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0.60));
  -webkit-backdrop-filter: blur(24px) saturate(185%);
  backdrop-filter: blur(24px) saturate(185%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    0 1px 0 rgba(29, 50, 66, 0.06);
}

/* User-menu dropdown — a floating glass panel. */
.vault-topbar__menu {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(255, 255, 255, 0.70));
  -webkit-backdrop-filter: blur(26px) saturate(185%);
  backdrop-filter: blur(26px) saturate(185%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 18px 40px -18px rgba(15, 23, 42, 0.4);
}

/* Modal — deeper, blurred scrim; the panel becomes a glass sheet. */
.vault-modal {
  background: rgba(10, 18, 25, 0.46);
  -webkit-backdrop-filter: blur(10px) saturate(125%);
  backdrop-filter: blur(10px) saturate(125%);
}
.vault-modal__panel {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0.78));
  -webkit-backdrop-filter: blur(34px) saturate(185%);
  backdrop-filter: blur(34px) saturate(185%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 30px 70px -24px rgba(15, 23, 42, 0.5);
}

/* Sticky list header — glass so rows scroll beneath it. */
.file-list__head {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.78), rgba(255, 255, 255, 0.60));
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
}

/* Controls — glass buttons. Ghost becomes clear glass; the primaries stay
   tinted (legible white labels) but gain a specular top edge + glass sheen. */
.btn--ghost {
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  backdrop-filter: blur(16px) saturate(180%);
  border-color: rgba(255, 255, 255, 0.6);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
.btn--ghost:hover {
  background: rgba(255, 255, 255, 0.72);
  border-color: rgba(255, 255, 255, 0.85);
}
.btn--red {
  background: linear-gradient(180deg, rgba(229, 52, 42, 0.95), rgba(220, 32, 21, 0.96));
  -webkit-backdrop-filter: blur(8px) saturate(160%);
  backdrop-filter: blur(8px) saturate(160%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 6px 16px -8px rgba(220, 32, 21, 0.5);
}
.btn--blue {
  background: linear-gradient(180deg, rgba(38, 64, 84, 0.95), rgba(29, 50, 66, 0.96));
  -webkit-backdrop-filter: blur(8px) saturate(160%);
  backdrop-filter: blur(8px) saturate(160%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 6px 16px -8px rgba(29, 50, 66, 0.5);
}

/* Splash picker cards — dark glass on the brushed-metal hero. */
.picker-card {
  background: linear-gradient(180deg, rgba(28, 40, 54, 0.62), rgba(15, 24, 35, 0.72));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    0 20px 44px -22px rgba(0, 0, 0, 0.6);
}

/* ── Accessibility: Reduce Transparency / Increase Contrast ───────────── */
@media (prefers-reduced-transparency: reduce) {
  .vault-topbar,
  .file-list__head,
  .vault-topbar__menu,
  .vault-modal__panel,
  .btn--ghost {
    background: #FFFFFF;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .btn--red { background: var(--victory-red); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .btn--blue { background: var(--knowledgeable-blue); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .vault-modal { background: rgba(10, 18, 25, 0.7); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .picker-card { background: rgba(15, 24, 35, 0.92); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  .vault-topbar { border-bottom-color: rgba(29, 50, 66, 0.5); }
  .vault-topbar__menu,
  .vault-modal__panel { border-color: rgba(29, 50, 66, 0.4); }
}

/* ══════════════════════════════════════════════════════════════════════
   Specialty rows — highlight + one-shot glisten (2026-06-18)
   The rows that open a bespoke viewer (medical-records zip, MultiCam folder,
   iMessage folder) each carry a persistent highlight and sweep a single
   light reflection ~1s after the list paints, so the client's eye is drawn
   to them. Compositor-only (translateX); suppressed under reduced motion.
   Appended last so it wins the cascade.
   ══════════════════════════════════════════════════════════════════════ */

/* iMessage folder row — subtle blue highlight + persistent accent bar. */
.file-row.is-imessage { background: rgba(10, 132, 255, 0.06); }
.file-row.is-imessage:hover { background: rgba(10, 132, 255, 0.10); }
.file-row.is-imessage::before { background: #0A84FF; opacity: 1; }

/* Shared one-shot glisten across every specialty row. */
.file-row.is-medical,
.file-row.is-multicam,
.file-row.is-imessage { overflow: hidden; }

.file-row.is-medical::after,
.file-row.is-multicam::after,
.file-row.is-imessage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: translateX(-130%);
  background: linear-gradient(105deg,
    transparent 36%,
    rgba(255, 255, 255, 0.55) 49%,
    rgba(255, 255, 255, 0.30) 55%,
    transparent 68%);
  animation: vault-glisten 1100ms cubic-bezier(0.22, 1, 0.36, 1) 1000ms 1 both;
}
@keyframes vault-glisten {
  to { transform: translateX(130%); }
}
@media (prefers-reduced-motion: reduce) {
  .file-row.is-medical::after,
  .file-row.is-multicam::after,
  .file-row.is-imessage::after { animation: none; opacity: 0; }
}
