/* AYA CoVault design layer.
   Workspace register: focused teal and cool neutrals.
   Trust register: scoped rust and warm cream for auth/public sharing.
   Loaded after Bootstrap/Materio; semantic tokens are the public contract. */

/* ------------------------------------------------------------------ scale */
/* The number the whole product is drawn from. Almost every size below, and in
   the sibling stylesheets, is in rem — so this sets type, padding, gaps, radii
   and control sizes together.

   Until now nothing set it at all: the design inherited the browser's default
   16px and stayed there from 768px to 2560px. That is what made the UI read as
   zoomed in on a scaled display. Windows at 125% hands the browser a viewport a
   quarter narrower than the panel, so a layout tuned on a wide monitor arrives
   with everything a quarter too large — and no rule existed to notice.

   Tracking the viewport keeps the app the same proportion of the screen at any
   resolution or OS scaling. Bounded at both ends: a floor where body text stops
   being comfortable, and a ceiling past which a very wide monitor would just
   get bigger furniture. Media-query breakpoints stay in px, so layout still
   changes where it always did — only the scale moves. */
/* Set through Bootstrap's own hook, not by restyling `html`. core.css carries
   `:root { font-size: var(--bs-root-font-size) }`, and `:root` outranks a bare
   `html` selector on specificity — so overriding the element loses silently
   however late it is loaded. The variable is the supported seam. */
:root {
  /* The app is laid out against a fixed logical canvas and painted down to
     fit — see Views/Shared/_ViewportScale.cshtml, which sets `zoom` on this
     element before the first paint. Type therefore stays at its DESIGN size in
     logical px and does not need a viewport curve of its own; zoom already
     scales it along with everything else. A second curve here would shrink
     text twice.

     16px is the no-JS value too: with script off there is no zoom, the page
     lays out at the real viewport, and the design baseline is the right
     answer. */
  --bs-root-font-size: 16px; /* AFV-SCALE */

  /* Published by the same script. vh/dvh resolve against the UNZOOMED
     viewport, so anything that wants to span the real screen height has to
     divide by this — see --vault-screen-h below. Defaults to 1 so the
     stylesheet is correct on its own with no script. */
  --vault-zoom: 1;

  /* "One screen tall" and "one screen wide", corrected for zoom. Use these
     instead of the raw viewport units.

     vw and vh resolve against the RAW viewport, not the zoomed canvas, so
     under z=0.665 a full-viewport-width overlay is 1366 logical px on a canvas
     that is 2054 wide - it paints across two thirds of the screen and
     leaves the rest uncovered. That is what the modal backdrop was doing,
     and what left the footer floating with dead space under it. */
  --vault-screen-h: calc(100dvh / var(--vault-zoom));
  --vault-screen-w: calc(100vw / var(--vault-zoom));

  /* One seam for the whole product's typeface. It used to be the literal word
     "Inter" written out at 22 call sites, which meant changing the face was 22
     edits and a search that had to catch three different shorthand spellings.
     Everything now reads this token, so a swap is this line.

     The fallbacks matter more than they look: the webfont is fetched over the
     network and `display=swap` paints the fallback first, so this stack is what
     a real person sees for the first few hundred milliseconds of every cold
     load. Keep a system UI face at the front of it.

     Dropbox's own face is Atlas Grotesk (Commercial Type) with Sharp Grotesk
     for display — both commercial licences they self-host under their own
     agreement, so neither can be used here. Hanken Grotesk is the closest free
     (OFL) stand-in: humanist grotesque, tall x-height, single-storey 'g', a
     little warmer than Inter. Inter is kept immediately behind it — it is still
     loaded from the same stylesheet link, so if the first face fails the app
     lands on the typography it was originally drawn in rather than on Arial.
     To go back to Inter entirely, delete the first entry. */
  --vault-font: "Hanken Grotesk", Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; /* AFV-FONT */

  /* Bootstrap's own hook, aliased to the same token. `body` inheritance covers
     most of the app, but Materio components that name --bs-font-sans-serif
     directly would otherwise keep the vendor's hardcoded "Inter" and quietly
     render in a different face than everything around them. */
  --bs-font-sans-serif: var(--vault-font);

  /* The minimum size of anything you click. This was the literal 44px, written
     out at 36 sites, and it is the single biggest reason the app read as
     oversized on a small screen: at a 12.5px root, 44px is three and a half
     rem of furniture around a line of 12.5px text. Scaling the type down could
     never fix that, because a px literal does not listen to the root font size
     — which is why two rounds of density work moved the file table (rem) and
     left the sidebar and topbar exactly where they were (px).

     So the floor scales too. min() keeps 44px as the ceiling, so a large
     display gets precisely the metrics the app was drawn with and nothing
     grows past them; a 1366x768 laptop gets ~34px instead. */
  --vault-tap: min(2.75rem, 44px);
}

/* Touch is the reason the 44px floor exists, and there it is not negotiable:
   a thumb has no hover, no pointer precision, and a mis-tap costs a wrong
   file. Coarse pointers keep the full target regardless of how small the type
   has been scaled. */
@media (pointer: coarse) {
  /* Divided by the canvas zoom so the floor is 44 PHYSICAL px. A coarse
     tablet still gets the zoomed-down canvas (the room is the point),
     but a finger does not shrink with it: at z=0.62 a plain 44px rule
     would paint ~27px. Phones never zoom (pinned to 1 by
     _ViewportScale.cshtml), so there this is just 44px. */
  :root { --vault-tap: calc(44px / var(--vault-zoom, 1)); }
}

:root,
[data-bs-theme="light"] {
  --vault-workspace-deep: #082f28;
  --vault-workspace-frame: #f7f9f8;
  --vault-workspace-surface-inset: #f3f7f5;
  --vault-workspace-ink: #1d2522;
  --vault-workspace-muted: #68746f;
  --vault-workspace-line: #d9e1de;
  --vault-workspace-accent: #006b5a;
  --vault-workspace-accent-rgb: 0, 107, 90;
  --vault-workspace-accent-hover: #075247;
  --vault-workspace-tint: #dff1eb;
  --vault-deep: #082f28;
  --vault-frame: #f7f9f8;
  --vault-surface: #ffffff;
  --vault-surface-inset: #f3f7f5;
  --vault-ink: #1d2522;
  --vault-ink-2: #68746f;
  --vault-line: #d9e1de;
  --vault-line-strong: #b7c8c2;
  --vault-accent: #006b5a;
  --vault-accent-rgb: 0, 107, 90;
  --vault-accent-hover: #075247;
  --vault-accent-ink: #ffffff;
  --vault-tint: #dff1eb;
  --vault-pulse: #49d5b2;
  --vault-folder: #5b96f2;
  --vault-depth-blue: #8fb8f7;
  --vault-depth-blue-soft: #f5f8fe;
  --vault-depth-lavender: #b6a5e8;
  --vault-depth-lavender-soft: #faf8fe;
  --vault-depth-blush: #eba7a2;
  --vault-depth-blush-soft: #fff8f7;
  --vault-depth-champagne: #ddbf72;
  --vault-depth-champagne-soft: #fffbf2;
  --vault-wordmark-co: #dc7f37;
  --vault-warning: #8a6815;
  --vault-warning-soft: #fff6dd;
  --vault-danger: #b52f38;
  --vault-danger-soft: #fae6e7;
  --vault-hover: rgba(8, 47, 40, 0.06);
  --vault-hover-strong: rgba(0, 107, 90, 0.11);
  --vault-rail-bg: var(--vault-deep);
  --vault-rail-ink: #aac5be;
  --vault-rail-ink-active: #ffffff;
  --vault-trust-accent: #c4421a;
  --vault-trust-accent-hover: #a93817;
  --vault-trust-frame: #f6f3ef;
  --vault-trust-ink: #25211f;
  --vault-trust-muted: #6f6862;
  --vault-trust-on-accent: rgba(255, 255, 255, 0.92);
  --vault-trust-accent-deep: #873014;
  --vault-trust-surface: #ffffff;
  --vault-trust-line: #d8cec7;
  --vault-trust-success: #006b5a;
  --vault-trust-success-soft: #dff1eb;
  --vault-trust-warning: #8a4b08;
  --vault-trust-warning-soft: #fff0d4;
  --vault-trust-danger: #a93817;
  --vault-trust-danger-soft: #f8e2da;
  --vault-dark: var(--vault-deep);
  --vault-dark-hover: #0b3c33;
  --vault-dark-ink: #ffffff;
  --vault-snackbar-bg: var(--vault-deep);
  --vault-snackbar-ink: #ffffff;
  /* Accent hues for tiles and chips. The workspace register stays teal —
     these are for distinguishing one figure from the next, so a dashboard row
     reads as five different things rather than five shades of the brand.
     Each hue is a readable ink plus a soft chip background. */
  --vault-hue-indigo: #4c56c0;
  --vault-hue-indigo-soft: #e8eaf9;
  --vault-hue-cyan: #0e7490;
  --vault-hue-cyan-soft: #ddf1f6;
  --vault-hue-violet: #7c3aed;
  --vault-hue-violet-soft: #f0e9fd;
  --vault-hue-amber: #a16207;
  --vault-hue-amber-soft: #fdf1d7;
  --vault-hue-rose: #b32d4e;
  --vault-hue-rose-soft: #fce7ec;
  /* Five more, so the notice wall can deal a colour per note without the same
     one turning up twice on a screen. Same construction as the originals: a
     saturated ink dark enough for text, and a very pale paper wash. */
  --vault-hue-teal: #0e7a55;
  --vault-hue-teal-soft: #d7f0e5;
  --vault-hue-lime: #4d7c0f;
  --vault-hue-lime-soft: #e8f4d6;
  --vault-hue-orange: #c2410c;
  --vault-hue-orange-soft: #fdead9;
  --vault-hue-sky: #0369a1;
  --vault-hue-sky-soft: #dcecfa;
  --vault-hue-plum: #86198f;
  --vault-hue-plum-soft: #f7e4f8;
  /* The second half of the pinboard palette. These are chosen to sit in the
     gaps the first ten leave AND to differ in lightness and saturation, not
     only in hue — ten more jewel tones at the same weight read as one muddy
     family, which is exactly what the first attempt at this looked like.
     Deliberately no near-neighbours: no coral (orange), no purple (violet),
     no magenta (plum), no olive (lime).

     Note which hues above may NOT be retuned to make room: indigo, cyan,
     violet, amber and rose are used as TEXT colour by the project tiles
     (.vault-project-tile.hue-*), so shifting them for the notice wall's sake
     would quietly change contrast on another page. The crowded pairs were
     pulled apart by moving the notice-only side instead — teal away from cyan,
     sienna away from amber, blue away from indigo, red away from rose. */
  --vault-hue-red: #9b1c1c;
  --vault-hue-red-soft: #f7dede;
  --vault-hue-pink: #e0489a;
  --vault-hue-pink-soft: #fce6f1;
  --vault-hue-sienna: #7a4420;
  --vault-hue-sienna-soft: #f0e4d9;
  --vault-hue-green: #2e8b3d;
  --vault-hue-green-soft: #e0f2e2;
  --vault-hue-emerald: #00a389;
  --vault-hue-emerald-soft: #d5f4ec;
  --vault-hue-mint: #5fbf9b;
  --vault-hue-mint-soft: #e2f6ef;
  --vault-hue-blue: #1e3fa8;
  --vault-hue-blue-soft: #dfe4f7;
  --vault-hue-slate: #5b7183;
  --vault-hue-slate-soft: #e8ecf0;
  --vault-shadow-sm: 0 1px 2px rgba(8, 47, 40, 0.05), 0 4px 12px rgba(8, 47, 40, 0.05);
  --vault-shadow-pop: 0 1px 3px rgba(8, 47, 40, 0.08), 0 12px 30px rgba(8, 47, 40, 0.14);
  /* Sticky-note paper. Warmer than --vault-surface on purpose: the notice wall
     tints this with its urgency ink, and mixing into flat white gives a washed
     grey. Matches --paper-base in the notice-board playground. */
  --vault-paper: #fffdf4;
  --vault-text-meta: 0.875rem;
  --vault-title-page: clamp(1.75rem, calc(var(--vault-screen-w) * 0.024), 2.25rem);
  --vault-title-section: clamp(1.25rem, calc(var(--vault-screen-w) * 0.015), 1.5rem);
  --project-surface: var(--vault-surface);
  --project-surface-inset: var(--vault-surface-inset);
  --project-border: var(--vault-line);
  --project-muted: var(--vault-ink-2);
  --project-accent: var(--vault-accent);
  --project-health-on-track: var(--vault-accent);
  --project-health-at-risk: var(--vault-warning);
  --project-health-off-track: var(--vault-danger);
  --project-blocker: var(--vault-warning);
  --project-overdue: var(--vault-danger);
  --project-chart-grid: var(--vault-line);
  --project-presence-rust: #9a4f33;
  --project-presence-sage: #47705d;
  --project-presence-amber: #8a6400;
  --project-presence-ocean: #226a78;
  --project-presence-plum: #72506f;
  --project-presence-slate: #53636b;
  --project-presence-on-color: #ffffff;
  --project-focus: #006b5a;
  --project-panel-width: 32.5rem;
  --project-column-width: 19rem;
  --project-target-size: 2.75rem;
  --project-shadow-drawer: -1rem 0 2rem rgba(8, 47, 40, 0.14);

  --bs-body-bg: var(--vault-frame);
  --bs-body-color: var(--vault-ink);
  --bs-border-color: var(--vault-line);
  --bs-primary: var(--vault-accent);
  --bs-primary-rgb: var(--vault-accent-rgb);
  --bs-link-color: var(--vault-accent);
  --bs-link-hover-color: var(--vault-accent-hover);
  --bs-heading-color: var(--vault-ink);
  --bs-secondary-color: var(--vault-ink-2);
}

[data-bs-theme="dark"] {
  --vault-deep: #061c18;
  --vault-frame: #0b1512;
  --vault-surface: #111e1a;
  --vault-surface-inset: #162520;
  --vault-ink: #f3f7f5;
  --vault-ink-2: #b0c1bb;
  --vault-line: rgba(225, 241, 235, 0.14);
  --vault-line-strong: rgba(225, 241, 235, 0.28);
  --vault-accent: #65d9bb;
  --vault-accent-rgb: 101, 217, 187;
  --vault-accent-hover: #84e5ca;
  --vault-accent-ink: #041a15;
  --vault-tint: #123b31;
  --vault-pulse: #65d9bb;
  --vault-folder: #79a9f5;
  --vault-depth-blue: #9fc2fa;
  --vault-depth-blue-soft: rgba(159, 194, 250, 0.1);
  --vault-depth-lavender: #c4b5f0;
  --vault-depth-lavender-soft: rgba(196, 181, 240, 0.1);
  --vault-depth-blush: #f2b7b1;
  --vault-depth-blush-soft: rgba(242, 183, 177, 0.1);
  --vault-depth-champagne: #e8ce88;
  --vault-depth-champagne-soft: rgba(232, 206, 136, 0.1);
  --vault-wordmark-co: #f0a850;
  --vault-warning: #e8c979;
  --vault-warning-soft: #2f2a17;
  --vault-danger: #f2a3aa;
  --vault-danger-soft: #34191c;
  --vault-hover: rgba(255, 255, 255, 0.07);
  --vault-hover-strong: rgba(101, 217, 187, 0.14);
  --vault-rail-bg: #041713;
  --vault-rail-ink: #9ebbb3;
  --vault-rail-ink-active: #ffffff;
  --vault-dark: #65d9bb;
  --vault-dark-hover: #84e5ca;
  --vault-dark-ink: #041a15;
  --vault-snackbar-bg: #eef8f5;
  --vault-snackbar-ink: #0b211b;
  /* Dark theme: lift the inks so they carry on a near-black surface, and make
     the chips translucent rather than pale so they sit in the surface. */
  --vault-hue-indigo: #9aa4f2;
  --vault-hue-indigo-soft: rgba(122, 133, 232, 0.16);
  --vault-hue-cyan: #5ec7de;
  --vault-hue-cyan-soft: rgba(94, 199, 222, 0.15);
  --vault-hue-violet: #bda0f7;
  --vault-hue-violet-soft: rgba(160, 130, 240, 0.16);
  --vault-hue-amber: #e8bd6d;
  --vault-hue-amber-soft: rgba(232, 189, 109, 0.15);
  --vault-hue-rose: #f094ab;
  --vault-hue-rose-soft: rgba(240, 148, 171, 0.16);
  --vault-hue-teal: #4fd2a6;
  --vault-hue-teal-soft: rgba(79, 210, 166, 0.15);
  --vault-hue-lime: #a8d16a;
  --vault-hue-lime-soft: rgba(168, 209, 106, 0.15);
  --vault-hue-orange: #f0a072;
  --vault-hue-orange-soft: rgba(240, 160, 114, 0.16);
  --vault-hue-sky: #7cbdea;
  --vault-hue-sky-soft: rgba(124, 189, 234, 0.16);
  --vault-hue-plum: #dda0e0;
  --vault-hue-plum-soft: rgba(221, 160, 224, 0.16);
  --vault-hue-red: #e06c6c;
  --vault-hue-red-soft: rgba(224, 108, 108, 0.16);
  --vault-hue-pink: #f49ac6;
  --vault-hue-pink-soft: rgba(244, 154, 198, 0.16);
  --vault-hue-sienna: #c08f63;
  --vault-hue-sienna-soft: rgba(192, 143, 99, 0.15);
  --vault-hue-green: #74cc84;
  --vault-hue-green-soft: rgba(116, 204, 132, 0.15);
  --vault-hue-emerald: #3fd3b4;
  --vault-hue-emerald-soft: rgba(63, 211, 180, 0.15);
  --vault-hue-mint: #9fe0c8;
  --vault-hue-mint-soft: rgba(159, 224, 200, 0.15);
  --vault-hue-blue: #5b8def;
  --vault-hue-blue-soft: rgba(91, 141, 239, 0.16);
  --vault-hue-slate: #a8b6c6;
  --vault-hue-slate-soft: rgba(168, 182, 198, 0.16);
  --vault-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.28);
  --vault-shadow-pop: 0 1px 3px rgba(0, 0, 0, 0.4), 0 12px 30px rgba(0, 0, 0, 0.5);
  --vault-paper: #17231f;
  --project-surface: var(--vault-surface);
  --project-surface-inset: var(--vault-surface-inset);
  --project-border: var(--vault-line);
  --project-muted: var(--vault-ink-2);
  --project-accent: var(--vault-accent);
  --project-health-on-track: var(--vault-accent);
  --project-health-at-risk: var(--vault-warning);
  --project-health-off-track: var(--vault-danger);
  --project-blocker: #f0c66f;
  --project-overdue: #f2a3aa;
  --project-chart-grid: rgba(225, 241, 235, 0.18);
  --project-presence-rust: #e7a084;
  --project-presence-sage: #91c6ad;
  --project-presence-amber: #e8c979;
  --project-presence-ocean: #80c7d5;
  --project-presence-plum: #c8a5c5;
  --project-presence-slate: #b0c1bb;
  --project-presence-on-color: #061c18;
  --project-focus: #84e5ca;
  --project-panel-width: 32.5rem;
  --project-column-width: 19rem;
  --project-target-size: 2.75rem;
  --project-shadow-drawer: -1rem 0 2rem rgba(0, 0, 0, 0.5);

  --bs-body-bg: var(--vault-frame);
  --bs-body-color: var(--vault-ink);
  --bs-border-color: var(--vault-line);
  --bs-primary: var(--vault-accent);
  --bs-primary-rgb: var(--vault-accent-rgb);
  --bs-link-color: var(--vault-accent);
  --bs-link-hover-color: var(--vault-accent-hover);
  --bs-heading-color: var(--vault-ink);
  --bs-secondary-color: var(--vault-ink-2);
}

.vault-auth,
.vault-sharepage {
  --vault-frame: var(--vault-trust-frame);
  --vault-ink: var(--vault-trust-ink);
  --vault-ink-2: var(--vault-trust-muted);
  --vault-accent: var(--vault-trust-accent);
  --vault-accent-rgb: 196, 66, 26;
  --vault-accent-hover: var(--vault-trust-accent-hover);
  --vault-accent-ink: #ffffff;
  --vault-tint: #f4ddd4;
  --vault-dark: #2e2218;
  --vault-dark-hover: #3d2f22;
  --vault-dark-ink: #f6f3ef;
}

:root {
  --vault-ease: cubic-bezier(0.2, 0, 0, 1);
  --vault-fast: 150ms;
  --vault-med: 220ms;
}

body {
  /* Always at least one screen tall. Under canvas zoom a short page ends
     partway down and the bare canvas shows through below the footer -
     which reads as "the footer is pushed up". 100dvh would not do it:
     vh resolves against the raw viewport, so it would stop at z of the
     screen and cause the very thing it is meant to prevent. */
  min-height: var(--vault-screen-h);
  background: var(--vault-frame) !important;
  color: var(--vault-ink);
  font-family: var(--vault-font);
  /*font-size: 1rem;*/
  line-height: 1.5;
  letter-spacing: 0;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  color: var(--vault-ink);
  font-weight: 650;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

h1 { font-size: var(--vault-title-page); line-height: 1.1; }
h2 { font-size: var(--vault-title-section); line-height: 1.2; }
h3 { font-size: 1.125rem; line-height: 1.3; }
b, strong { font-weight: 650; }
.fw-bold { font-weight: 700 !important; }
.text-body-secondary, .text-muted { color: var(--vault-ink-2) !important; }
.text-primary { color: var(--vault-accent) !important; }
.bg-primary { background-color: var(--vault-accent) !important; }
a { transition: color var(--vault-fast) var(--vault-ease); }
:focus-visible { outline: 2px solid var(--vault-accent); outline-offset: 2px; }

.vault-skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 2000;
  padding: 0.7rem 0.9rem;
  border-radius: 0.625rem;
  background: var(--vault-surface);
  color: var(--vault-ink);
  box-shadow: var(--vault-shadow-pop);
  transform: translateY(-160%);
}

.vault-skip-link:focus { transform: translateY(0); }

@media (min-width: 1200px) {
  html.vault-panel-collapsed { --vault-menu-width: var(--vault-rail-width); }
  html.vault-panel-collapsed .vault-panel { display: none; }
  html.vault-panel-collapsed .vault-panel-reopen { display: inline-grid; }
  .vault-panel-collapse.d-none { display: inline-grid !important; }
}

/* ----------------------------------------------------------------- frame */
/* Sidebar: two-tier icon rail + folder panel, flat on the frame. */
/* Icon rail + folder panel. The panel was a flat 280px at every size,
   which is a quarter of a 1366-wide laptop spent on navigation and was part of
   why the file table ran off the side of the screen there. It now gives a
   little back as the window narrows and reaches its designed 358px from 1600px
   up, so the layout it was drawn for is unchanged on a large display. */
/* Expressed in rem, so the frame shrinks with the type instead of staying a
   fixed slab. This was the known gap in the scale work: with a px width, the
   sidebar was 317px of a 1366-wide laptop — 23% of the window on navigation —
   no matter how small the text got. 4.75rem rail + 17.5rem panel reaches the
   designed 358px at the top of the scale and gives real width back at the
   bottom. Capped in px so a large monitor gets the layout it was drawn for
   rather than an ever-wider one. */
:root {
  /* The rail and the collapsed menu width are the same measurement; they
     were two separate 78px literals that had to be kept equal by hand. */
  --vault-rail-width: 4.75rem;
  --vault-menu-width: min(calc(var(--vault-rail-width) + 17.5rem), 358px);
}

#layout-menu.layout-menu.vault-sidebar {
  width: var(--vault-menu-width) !important;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  border: 0 !important;
  background: var(--vault-frame) !important;
  box-shadow: none !important;
}

@media (max-width: 1199.98px) {
  :root { --vault-menu-width: min(358px, var(--vault-screen-w)); }

  #layout-menu.layout-menu.vault-sidebar {
    max-width: var(--vault-screen-w) !important;
  }
}

/* ---- the sidebar follows the LOGICAL width, not the physical one ----
   Materio turns the menu into an off-canvas drawer under
   `@media (max-width: 1199.98px)`. Media queries see the physical viewport, so
   on a 768px tablet that fires — even though the zoomed canvas is ~1239 logical
   px and has room for the sidebar inline. The result was a drawer overlapping
   the content on a layout that was still laid out as desktop.

   The media queries stay: they are the correct answer at zoom 1 and the only
   answer with no script. This corrects the one case they get wrong — physical
   below the breakpoint, logical above it. The reverse cannot happen, because
   zoom is never greater than 1, so logical width is never less than physical. */
/* Only the transform. The drawer rules already position the menu fixed at the
   inline start, which is exactly what desktop does too — the sole thing making
   it a drawer is being translated -100% off-screen. Undoing more than that was
   a bug: `position: relative` put the sidebar back INTO the flow while
   .layout-page kept the padding-left sized for an out-of-flow sidebar, so the
   width was counted twice and the content sat in a column with a dead gap
   beside it. */
:root[data-bp-xl="1"] .layout-menu {
  transform: none !important;
}
:root[data-bp-xl="1"] .layout-overlay { display: none !important; }
:root[data-bp-xl="1"].layout-menu-fixed .layout-page {
  padding-left: var(--vault-menu-width) !important;
}
/* The hamburger is for the drawer; with the sidebar inline it is noise. */
:root[data-bp-xl="1"] .layout-menu-toggle,
:root[data-bp-xl="1"] .menu-mobile-toggler { display: none !important; }
/* And the collapse/reopen affordance belongs back on screen. */
:root[data-bp-xl="1"].vault-panel-collapsed { --vault-menu-width: var(--vault-rail-width); }
:root[data-bp-xl="1"].vault-panel-collapsed .vault-panel { display: none; }
:root[data-bp-xl="1"].vault-panel-collapsed .vault-panel-reopen { display: inline-grid; }
:root[data-bp-xl="1"] .vault-panel-collapse.d-none { display: inline-grid !important; }

@media (min-width: 1200px) {
  html.layout-menu-fixed .layout-page { padding-left: var(--vault-menu-width) !important; }
}

/* icon rail */
.vault-rail {
  width: var(--vault-rail-width);
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 1.125rem 0.5rem 1rem;
  background: var(--vault-rail-bg);
}

.vault-rail-brand {
  display: grid;
  place-items: center;
  width: var(--vault-tap);
  height: var(--vault-tap);
  margin-bottom: 1rem;
  border-radius: 13px;
  background: var(--vault-pulse);
  color: var(--vault-deep);
}

.vault-rail .dropdown {
  width: 100%;
}

.vault-rail-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  width: 3.875rem;
  min-height: 3.625rem;
  padding: 0.45rem 0.2rem;
  border: 0;
  border-radius: 13px;
  background: transparent;
  color: var(--vault-rail-ink);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
}

.vault-rail-item:hover,
.vault-rail-item:focus-visible {
  background: rgba(73, 213, 178, 0.1);
  color: var(--vault-rail-ink-active);
}

.vault-rail-brand:focus-visible,
.vault-rail-item:focus-visible,
.vault-panel-reopen:focus-visible {
  outline: 2px solid var(--vault-pulse);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.28);
}

/* Dropbox rail: the active item just goes full-ink — no colored pill */
.vault-rail-item.active {
  background: rgba(73, 213, 178, 0.15);
  color: var(--vault-rail-ink-active);
}

.vault-rail-item.active::before {
  content: "";
  position: absolute;
  left: -8px;
  width: 4px;
  height: 31px;
  border-radius: 0 4px 4px 0;
  background: var(--vault-pulse);
}

.vault-rail-item.active i { color: var(--vault-pulse); }

.vault-rail-soon {
  opacity: 0.55;
  cursor: default;
}

.vault-rail-soon:hover {
  background: transparent;
  color: var(--vault-rail-ink);
}

/* folder panel */
.vault-panel {
  width: 17.5rem;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--vault-line);
  background: var(--vault-frame);
}

.vault-panel-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: 4.5rem;
  padding: 0 1.125rem 0 1.375rem;
  border-bottom: 1px solid var(--vault-line);
}

.vault-panel-title {
  margin-right: auto;
  color: var(--vault-ink);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

.vault-panel-collapse,
.vault-panel-reopen {
  place-items: center;
  width: var(--vault-tap);
  height: var(--vault-tap);
  border: 1px solid var(--vault-line);
  border-radius: 10px;
  background: var(--vault-surface);
  color: var(--vault-ink-2);
}

.vault-panel-reopen { display: none; }

.vault-panel-close {
  display: inline-grid;
  place-items: center;
  min-width: var(--vault-tap);
  min-height: var(--vault-tap);
  border-radius: 10px;
  color: var(--vault-ink-2);
}

/* neutralize Materio .menu-inner flex styling on the scroll area */
#layout-menu .vault-panel-scroll.menu-inner {
  flex: 1 1 auto;
  display: block;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 0.75rem 1.5rem;
}

/* "All files" root item */
.vault-tree-all {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: var(--vault-tap);
  padding: 0.42rem 0.65rem;
  margin-bottom: 0.5rem;
  border-radius: 11px;
  color: var(--vault-ink);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color var(--vault-fast) var(--vault-ease);
}

.vault-tree-all:hover {
  background: var(--vault-hover);
  color: var(--vault-ink);
}

/* Dropbox nav selection is a warm state overlay, not a blue tint */
.vault-tree-all.active {
  background: var(--vault-hover-strong);
  color: var(--vault-ink);
}

/* Administration context panel (spec 5.2): swaps in for the folder tree on
   admin routes inside the same panel shell, so rail/panel widths are unchanged. */
.vault-panel-admin .vault-panel-scroll {
  padding-top: 0.15rem;
}

.vault-admin-nav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.vault-admin-nav-link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: var(--vault-tap);
  padding: 0.42rem 0.65rem;
  border-radius: 11px;
  color: var(--vault-ink);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color var(--vault-fast) var(--vault-ease);
}

.vault-admin-nav-link i {
  color: var(--vault-ink-2);
}

.vault-admin-nav-link:hover {
  background: var(--vault-hover);
  color: var(--vault-ink);
}

.vault-admin-nav-link.active {
  background: var(--vault-hover-strong);
  color: var(--vault-ink);
}

.vault-admin-nav-link.active i {
  color: var(--vault-accent);
}

.vault-admin-nav-link:focus-visible {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
}

/* Administrator-only eyebrow label, shared across admin pages (audit log first) */
.vault-admin-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 0.35rem;
  color: var(--vault-ink-2);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Audit log filter card + event-icon container (Task 7: hierarchy/spacing only) */
.vault-audit-filters {
  padding: 1rem 1.1rem;
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  border-radius: 12px;
}

.vault-audit-icon {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--vault-surface-inset);
}

/* "ADMINISTRATOR ONLY" chip, top-right of admin-only page heads (mockup: activity-notifications-fullscale) */
.vault-admin-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.55rem;
  border-radius: 999px;
  background: var(--vault-surface-inset);
  color: var(--vault-ink-2);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Three-stat summary strip atop Groups (mockup: groups-administration-fullscale §01) */
.vault-admin-summary-strip {
  display: flex;
  align-items: stretch;
  margin-bottom: 1.25rem;
  overflow: hidden;
  border: 1px solid var(--vault-line);
  border-radius: 10px;
  background: var(--vault-surface);
}

.vault-admin-summary-item {
  flex: 1;
  padding: 0.9rem 1.1rem;
}

.vault-admin-summary-item + .vault-admin-summary-item {
  border-left: 1px solid var(--vault-line);
}

.vault-admin-summary-item b {
  display: block;
  font-size: 1.1rem;
}

.vault-admin-summary-item span {
  display: block;
  color: var(--vault-ink-2);
  font-size: 0.72rem;
}

/* Calm informational callout — teal, safe/effective state (design rule: teal = safe, amber = broad-impact warning, red = destructive) */
.vault-note-info {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  margin-top: 1rem;
  padding: 0.7rem 0.85rem;
  border-left: 3px solid var(--vault-accent);
  border-radius: 6px;
  background: var(--vault-tint);
  color: var(--vault-ink);
  font-size: 0.8rem;
  line-height: 1.5;
}

.vault-note-info i {
  color: var(--vault-accent);
  flex-shrink: 0;
}

/* Danger zone — irreversible/destructive actions get their own quiet, red-bordered section rather than living only in a modal */
.vault-danger-zone {
  margin-top: 1.5rem;
  padding: 1rem 1.1rem;
  border: 1px solid rgba(220, 53, 69, 0.28);
  border-radius: 10px;
  background: rgba(220, 53, 69, 0.045);
}

.vault-danger-zone-title {
  display: block;
  margin-bottom: 0.2rem;
  color: #c83f42;
  font-size: 0.8rem;
  font-weight: 700;
}

.vault-danger-zone p {
  margin: 0.2rem 0 0.85rem;
  color: var(--vault-ink-2);
  font-size: 0.78rem;
}

/* Search/role/status filter row above the Users table (mockup: groups-administration-fullscale §03) */
.vault-user-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
}

.vault-user-toolbar .form-control,
.vault-user-toolbar .form-select {
  max-width: 220px;
}

/* Category breakdown chips on a template card (mockup: permissions-settings-fullscale §03) */
.vault-template-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.6rem 0;
}

.vault-template-chips span {
  padding: 0.22rem 0.45rem;
  border-radius: 6px;
  background: var(--vault-surface-inset);
  color: var(--vault-ink-2);
  font-size: 0.68rem;
}

/* Exact-set behavior note under the template grid */
.vault-template-note {
  margin-top: 0.5rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--vault-line);
  border-radius: 10px;
  background: var(--vault-surface);
  color: var(--vault-ink-2);
  font-size: 0.8rem;
}

/* Details/Versions/Activity tabs in the file details offcanvas */
.vault-details-tabs .nav-link {
  color: var(--vault-ink-2);
  font-weight: 500;
}

.vault-details-tabs .nav-link.active {
  color: var(--vault-accent);
}

/* folder tree */
.vault-tree,
.vault-tree-children {
  list-style: none;
  margin: 0;
  padding: 0;
}

.vault-tree-children {
  display: none;
}

.vault-tree-item.expanded > .vault-tree-children {
  display: block;
}

.vault-tree-row {
  display: flex;
  align-items: center;
  min-height: 40px;
  border-radius: 9px;
  padding-left: calc(var(--tree-depth, 0) * 14px);
  font-size: 0.875rem;
  transition: background-color var(--vault-fast) var(--vault-ease);
}

.vault-tree-row:hover {
  background: var(--vault-hover);
}

.vault-tree-row.active {
  background: var(--vault-tint);
  color: var(--vault-accent);
}

.vault-tree-row.active .vault-tree-link {
  color: var(--vault-accent);
  font-weight: 500;
}

.vault-tree-chevron {
  flex: none;
  width: var(--vault-tap);
  min-height: var(--vault-tap);
  margin-inline: -6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--vault-ink-2);
  padding: 0;
  border-radius: 6px;
}

.vault-tree-chevron i {
  transition: transform var(--vault-fast) var(--vault-ease);
}

.vault-tree-item.expanded > .vault-tree-row .vault-tree-chevron i {
  transform: rotate(90deg);
}

.vault-tree-link {
  flex: 1;
  min-width: 0;
  min-height: var(--vault-tap);
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.5rem 0.3rem 0;
  color: var(--vault-ink);
  font-size: 0.875rem;
  text-decoration: none;
}

.vault-tree-link i {
  color: var(--vault-folder);
  flex: none;
}

/* Dropbox signature: every folder glyph is flat content-icon blue.
   (Wins over Bootstrap's .text-warning by loading later at equal specificity.) */
.ri-folder-3-fill,
.ri-folder-2-fill {
  color: var(--vault-folder) !important;
}

/* ---------------------------------------------------------------------------
   Discovery (folders.browse_all): folders a viewer can see listed but not
   open. Quieter than an ordinary row and stripped of every affordance —
   nothing here is actionable except following the link, which the server
   turns into the request-access page.
--------------------------------------------------------------------------- */

.vault-tree-item.locked > .vault-tree-row .vault-tree-link {
  color: var(--vault-ink-2);
}

.vault-tree-item.locked > .vault-tree-row .vault-tree-link i,
.vault-locked-glyph {
  color: var(--vault-ink-2);
}

.vault-tree-item.locked > .vault-tree-row:hover .vault-tree-link {
  color: var(--vault-ink);
}

/* "Mine only". One root class governs the tree and the listing together. */
.vault-hide-locked .vault-tree-item.locked,
.vault-hide-locked .library-row.is-locked,
.vault-hide-locked .item-card.is-locked {
  display: none;
}

.vault-locked-toggle {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--vault-ink-2);
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.vault-locked-toggle:hover {
  background: var(--vault-tint);
  color: var(--vault-accent);
}

.vault-locked-toggle[aria-pressed="true"] {
  border-color: var(--vault-line);
  background: var(--vault-tint);
  color: var(--vault-accent);
}

/* Listing: readable, plainly inert. Not so faint it reads as a loading state
   — the name is the whole point of showing the row. */
.library-row.is-locked {
  color: var(--vault-ink-2);
}

.library-row.is-locked .item-name-link {
  color: var(--vault-ink-2) !important;
}

.library-row.is-locked:hover .item-name-link {
  color: var(--vault-ink) !important;
}

.vault-request-access-btn {
  font-size: 0.8125rem;
  white-space: nowrap;
}

.item-card.is-locked {
  border-style: dashed;
}

.item-card.is-locked .item-card-name {
  color: var(--vault-ink-2);
}

/* Folder-template preview tree (admin). Read-only, so it carries none of the
   sidebar tree's interaction affordances — just structure and who gets what. */

.vault-template-tree,
.vault-template-children {
  list-style: none;
  margin: 0;
  padding: 0;
}

.vault-template-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding: 0.35rem 0;
  padding-left: calc(var(--tree-depth, 0) * 1.25rem);
}

.vault-template-row > i {
  color: var(--vault-folder);
  flex: none;
}

/* Starred nav section (Phase 6 §3.6): a collapsible group under the folder
   tree. Entries reuse the .vault-tree-* classes; only the header + collapse
   need their own rules. */
.vault-starred {
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--vault-line);
}

.vault-starred-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  min-height: 40px;
  padding: 0.35rem 0.65rem;
  border: 0;
  background: transparent;
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  border-radius: 9px;
}

.vault-starred-head:hover {
  background: var(--vault-hover);
  color: var(--vault-ink);
}

.vault-starred-caret {
  transition: transform var(--vault-fast) var(--vault-ease);
}

.vault-starred-collapsed .vault-starred-caret {
  transform: rotate(-90deg);
}

.vault-starred-collapsed #vault-starred-list {
  display: none;
}

/* The tree forces every .vault-tree-link glyph to folder-blue; keep folder
   entries blue (folder glyph wins via !important) but mute file glyphs so a
   file isn't shown in folder colours. */
.vault-starred .vault-tree-link i {
  color: var(--vault-ink-2);
}

/* storage meter pinned at the panel bottom */
.vault-panel .storage-meter {
  border-top: 1px solid var(--vault-line);
  margin-top: 0 !important;
}

.vault-brand-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: var(--vault-accent);
  color: var(--vault-accent-ink);
  flex: none;
}

.app-brand-text {
  font-size: 2.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: none !important;
  color: var(--vault-ink) !important;
}

/* Split-color CoVault wordmark (brand lockups next to the product mark). */
.vault-wordmark {
  display: inline-flex;
  align-items: baseline;
  white-space: nowrap;
  color: var(--vault-ink);
}
.vault-wordmark-aya {
  margin-right: 0.32em;
  color: var(--vault-accent);
  font-family: var(--vault-font);
  font-weight: 800;
  letter-spacing: 0.06em;
}
.vault-wordmark-co { color: var(--vault-wordmark-co); }
.vault-wordmark-vault { color: var(--vault-ink-2); }

.vault-auth .vault-wordmark-aya { color: var(--vault-login-accent, var(--vault-accent)); }
.vault-auth .vault-wordmark-co { color: var(--vault-wordmark-co); }
.vault-auth .vault-wordmark-vault { color: var(--vault-login-muted, var(--vault-ink-2)); }

/* Each character rolls up into place like a type wheel, left to right.
   No longer scoped to the sign-in page: the same mark now sits at the top
   right of the app header, and it should arrive the same way there. */
.vault-wm-c { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .vault-wordmark-rollout .vault-wm-c {
    animation: vault-wordmark-unseal 300ms cubic-bezier(0.22, 1, 0.36, 1) both;
    animation-delay: calc(var(--i, 0) * 45ms);
    transform-origin: 50% 100%;
  }
}
@keyframes vault-wordmark-unseal {
  from { opacity: 0; transform: perspective(480px) translateY(0.55em) rotateX(-90deg); }
  to { opacity: 1; transform: perspective(480px) translateY(0) rotateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .vault-wordmark-rollout .vault-wm-c { animation: none; opacity: 1; transform: none; }
}

/* owner avatars (Drive-style; hue is a deterministic hash of the name) */
.vault-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: hsl(var(--avatar-h, 210) 45% 45%);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  flex: none;
}

[data-bs-theme="dark"] .vault-avatar {
  background: hsl(var(--avatar-h, 210) 42% 60%);
  color: oklch(0.2 0.01 260);
}

/* Dropbox-style global search: wide bordered field on the surface */
.vault-search {
  position: relative;
  width: min(540px, calc(var(--vault-screen-w) * 0.49));
}

.vault-search .vault-search-icon {
  position: absolute;
  left: 1.05rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--vault-ink-2);
  pointer-events: none;
}

.vault-search .form-control {
  min-height: var(--vault-tap);
  padding: 0.65rem 4.8rem 0.65rem 2.7rem;
  border: 1px solid var(--vault-line-strong);
  border-radius: 11px;
  background: var(--vault-surface);
  color: var(--vault-ink);
  font-size: 0.9375rem;
}

.vault-search .form-control:hover {
  border-color: var(--vault-ink-2);
}

.vault-search .form-control:focus {
  border-color: var(--vault-accent);
  box-shadow: 0 0 0 3px rgba(var(--vault-accent-rgb), 0.1);
}

.vault-search .form-control:focus-visible {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(var(--vault-accent-rgb), 0.12);
}

/* Top bar: white like the canvas below it — Dropbox draws no divider,
   the warm sidebar is the only color break. */
#layout-navbar.layout-navbar {
  min-height: 72px;
  background: var(--vault-surface) !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  border-bottom: 1px solid var(--vault-line);
  margin: 0 !important;
  width: 100% !important;
  max-width: none !important;
  padding: 0 1.75rem;
}

.vault-search-shortcut {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--vault-line);
  border-radius: 6px;
  background: var(--vault-surface-inset);
  color: var(--vault-ink-2);
  font-size: 0.75rem;
}

/* The navbar "New" button is Dropbox's dark charcoal primary
   (flips to warm white in dark mode); blue stays for in-canvas CTAs. */
#layout-navbar .btn-primary {
  --bs-btn-bg: var(--vault-dark);
  --bs-btn-border-color: var(--vault-dark);
  --bs-btn-color: var(--vault-dark-ink);
  --bs-btn-hover-bg: var(--vault-dark-hover);
  --bs-btn-hover-border-color: var(--vault-dark-hover);
  --bs-btn-hover-color: var(--vault-dark-ink);
  --bs-btn-active-bg: var(--vault-dark-hover);
  --bs-btn-active-border-color: var(--vault-dark-hover);
  --bs-btn-active-color: var(--vault-dark-ink);
}

.layout-navbar-fixed .layout-page {
  padding-top: 0 !important;
}

.layout-navbar-fixed #layout-navbar.layout-navbar {
  position: sticky;
  top: 0;
  z-index: 1075;
}

.layout-overlay { display: none; }

/* Dropbox canvas: everything right of the sidebar is one flat white
   surface — no border, no rounded corner; the sidebar color is the seam. */
.layout-page .content-wrapper {
  background: var(--vault-surface);
  border: 0;
  border-radius: 0;
}

.content-wrapper > .container-xxl {
  max-width: none !important;
  padding: 0.5rem 1.75rem 1rem !important;
}

/* The file browser sits directly on the canvas — no card shell. */
#fileBrowser.card {
  border: 0;
  background: transparent;
  border-radius: 0;
}

/* Drive-style page head: breadcrumb-as-title + actions */
.vault-canvas-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
}

.vault-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.1rem;
  /* Left on the raw viewport on purpose: the ceiling is below the floor,
     so clamp collapses to the floor and the vw term never contributes.
     Author confirmed the 0.5rem ceiling is deliberate. */
  font-size: clamp(1.0625rem, 0.9rem + 0.5vw, 0.5rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  margin: 0;
  min-width: 0;
}

.vault-title a {
  color: var(--vault-ink);
  text-decoration: none;
}

.vault-title [data-vault-depth="0"] {
  --vault-depth-accent: var(--vault-depth-blue);
  --vault-depth-wash: var(--vault-depth-blue-soft);
}

.vault-title [data-vault-depth="1"] {
  --vault-depth-accent: var(--vault-depth-lavender);
  --vault-depth-wash: var(--vault-depth-lavender-soft);
}

.vault-title [data-vault-depth="2"] {
  --vault-depth-accent: var(--vault-depth-blush);
  --vault-depth-wash: var(--vault-depth-blush-soft);
}

.vault-title [data-vault-depth="3"] {
  --vault-depth-accent: var(--vault-depth-champagne);
  --vault-depth-wash: var(--vault-depth-champagne-soft);
}

.vault-title [data-vault-depth] {
  position: relative;
  display: inline-flex;
  min-width: 0;
  min-height: 46px;
  max-width: 100%;
  align-items: center;
  gap: 0.5rem;
  padding: 0 0.625rem 0.25rem;
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  color: var(--vault-ink);
  transition:
    border-color var(--vault-fast) var(--vault-ease),
    background-color var(--vault-fast) var(--vault-ease);
}

.vault-title [data-vault-depth]::after {
  content: "";
  position: absolute;
  right: 8px;
  bottom: 2px;
  left: 8px;
  height: 3px;
  border-radius: 999px;
  background: var(--vault-depth-accent);
  pointer-events: none;
}

.vault-title [data-vault-depth]:hover,
.vault-title a[data-vault-depth]:focus-visible {
  border-color: color-mix(in srgb, var(--vault-depth-accent) 45%, var(--vault-line));
  background: var(--vault-depth-wash);
}

.vault-title .vault-title-current[data-vault-depth]::after {
  right: 5px;
  left: 5px;
  height: 4px;
}

.vault-title-depth {
  display: inline-grid;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  place-items: center;
  border-radius: 8px;
  background: var(--vault-surface-inset);
  color: var(--vault-ink-2);
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0;
}

.vault-title-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vault-title .vault-title-sep {
  color: var(--vault-ink-2);
  display: inline-flex;
}

/* The chevrons carry a fixed .icon-18px from the markup, so without this they
   stay 18px while the title shrinks around them and start to outweigh it. */
.vault-title .vault-title-sep .icon-base {
  font-size: 0.85em;
}

.vault-title .vault-title-current {
  cursor: default;
}

/* chips + selection rows live on the canvas above the list */
#cmdDefault {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

#cmdSelection {
  margin-bottom: 0.5rem;
}

.content-footer {
  background: transparent !important;
}

.content-footer .footer-container {
  padding-top: 0.75rem !important;
  padding-bottom: 1rem !important;
  font-size: 0.875rem;
  color: var(--vault-ink-2);
}

/* ----------------------------------------------------------------- cards */
.card {
  --bs-card-bg: var(--vault-surface);
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  border-radius: 12px; /* DIG radius/large */
  box-shadow: none !important;
  color: var(--vault-ink);
}

.card .card-header {
  background: transparent;
  border-color: var(--vault-line);
}

.card .card-title {
  color: var(--vault-ink);
  font-weight: 600;
}

/* -------------------------------------------------------- shared controls */
.btn,
.form-control,
.form-select {
  min-height: var(--vault-tap);
  border-radius: 10px;
  font-size: 0.9375rem;
}

.btn {
  --bs-btn-border-radius: 10px;
  --bs-btn-font-weight: 650;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding-inline: 1rem;
  font-weight: 650;
  /* Materio ships `.btn { text-transform: capitalize }`, which rewrote every
     label the markup had already written in sentence case — "New folder" was
     rendering as "New Folder" regardless of what the view said. Six places in
     this file were already overriding it one surface at a time, two of them
     with !important; this is the same fix once, at equal specificity but a
     later stylesheet, so the button says what the Razor says. */
  text-transform: none;
  transition: background-color var(--vault-fast) var(--vault-ease),
              color var(--vault-fast) var(--vault-ease),
              border-color var(--vault-fast) var(--vault-ease);
}

.btn-primary {
  --bs-btn-bg: var(--vault-accent);
  --bs-btn-border-color: var(--vault-accent);
  --bs-btn-color: var(--vault-accent-ink);
  --bs-btn-hover-bg: var(--vault-accent-hover);
  --bs-btn-hover-border-color: var(--vault-accent-hover);
  --bs-btn-hover-color: var(--vault-accent-ink);
  --bs-btn-active-bg: var(--vault-accent-hover);
  --bs-btn-active-border-color: var(--vault-accent-hover);
  --bs-btn-active-color: var(--vault-accent-ink);
  --bs-btn-disabled-bg: var(--vault-accent);
  --bs-btn-disabled-border-color: var(--vault-accent);
  --bs-btn-disabled-color: var(--vault-accent-ink);
  border-color: var(--vault-accent);
  background: var(--vault-accent);
  color: var(--vault-accent-ink);
}

.btn-primary:hover,
.btn-primary:focus-visible {
  border-color: var(--vault-accent-hover);
  background: var(--vault-accent-hover);
  color: var(--vault-accent-ink);
}

/* Materio's core.css ends with `a:not([href]) { color: inherit }`, which at
   (0,1,1) outranks every .btn and .btn-primary colour rule above — those are
   (0,1,0). So an anchor styled as a button loses its label colour the moment
   it stops being a link, and drops to body ink on whatever fill it is sitting
   on. The details panel's Open does exactly that for a PDF: it drops the href
   because the file opens in place rather than navigating, and its white label
   on teal turned near-black. Hand the button back its own colour, at a
   specificity that clears the rule taking it away. */
a.btn:not([href]) { color: var(--bs-btn-color); }
a.btn:not([href]):hover { color: var(--bs-btn-hover-color); }

/* Dropbox's secondary ("opacity") button: transparent, 1px border/base,
   ink text, warm overlay on hover — see "Get more storage". */
.btn-outline-primary,
.btn-outline-secondary {
  --bs-btn-color: var(--vault-ink);
  --bs-btn-bg: transparent;
  --bs-btn-border-color: var(--vault-line-strong);
  --bs-btn-hover-bg: var(--vault-hover);
  --bs-btn-hover-color: var(--vault-ink);
  --bs-btn-hover-border-color: var(--vault-line-strong);
  --bs-btn-active-bg: var(--vault-hover-strong);
  --bs-btn-active-color: var(--vault-ink);
  --bs-btn-active-border-color: var(--vault-line-strong);
}

.btn-outline-primary {
  --bs-btn-color: var(--vault-accent);
  --bs-btn-active-color: var(--vault-accent);
}

/* filter chips stay outlined (Drive's chip row) */
.filter-chip .btn {
  --bs-btn-bg: transparent;
  --bs-btn-border-color: var(--vault-line);
  --bs-btn-hover-bg: var(--vault-hover);
  --bs-btn-hover-border-color: var(--vault-line);
}

.btn-text-secondary,
.btn-text-primary {
  --bs-btn-color: var(--vault-ink-2);
  --bs-btn-hover-bg: var(--vault-hover);
  --bs-btn-hover-color: var(--vault-ink);
  --bs-btn-active-bg: var(--vault-hover-strong);
  --bs-btn-active-color: var(--vault-ink);
}

.btn-text-danger {
  --bs-btn-hover-bg: rgba(var(--bs-danger-rgb), 0.08);
}

.btn-icon {
  width: var(--vault-tap);
  padding: 0;
}

.btn-close {
  width: var(--vault-tap);
  height: var(--vault-tap);
  padding: 0;
}

/* ----------------------------------------------------------------- forms */
.form-control,
.form-select {
  background-color: var(--vault-surface);
  border-color: var(--vault-line-strong);
  color: var(--vault-ink);
  transition: border-color var(--vault-fast) var(--vault-ease),
              box-shadow var(--vault-fast) var(--vault-ease);
}

.form-control:focus,
.form-select:focus {
  border-color: var(--vault-accent);
  box-shadow: 0 0 0 1px var(--vault-accent);
}

.form-control::placeholder {
  color: var(--vault-ink-2);
  opacity: 1;
}

.form-check-input {
  border-color: oklch(0.62 0.01 260);
}

.form-check-input:checked {
  background-color: var(--vault-accent);
  border-color: var(--vault-accent);
}

.form-check-input:focus {
  border-color: var(--vault-accent);
  box-shadow: 0 0 0 2px var(--vault-tint);
}

/* Pill search (file browser toolbar) */
#librarySearch {
  max-width: 320px;
  flex: 1 1 220px;
}

#librarySearch .input-group-text {
  background: var(--vault-hover);
  border: 0;
  border-radius: 50rem 0 0 50rem;
  color: var(--vault-ink-2);
  padding-left: 0.9rem;
}

#librarySearch .form-control {
  background: var(--vault-hover);
  border: 0;
  border-radius: 0 50rem 50rem 0;
  padding-top: 0.55rem;
  padding-bottom: 0.55rem;
}

#librarySearch:focus-within .input-group-text,
#librarySearch:focus-within .form-control {
  background: var(--vault-surface);
  clip-path: none;
}

#librarySearch:focus-within {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(var(--vault-accent-rgb), 0.12);
  border-radius: 50rem;
}

/* ---------------------------------------------------------------- badges */
.badge {
  font-weight: 500;
  letter-spacing: 0;
}

.bg-label-primary {
  background: var(--vault-tint) !important;
  color: var(--vault-accent) !important;
}

.bg-label-secondary {
  background: var(--vault-hover) !important;
  color: var(--vault-ink-2) !important;
}

/* Access column reads as plain subtle text ("Only you"), like Dropbox's
   table — the badge chrome only appears for shared items. */
.access-chip .badge.bg-label-secondary {
  background: transparent !important;
  padding: 0;
  font-size: 0.875rem;
  font-weight: 400;
}

.access-chip:hover .badge.bg-label-secondary {
  color: var(--vault-ink) !important;
  text-decoration: underline;
}

.access-chip .badge.bg-label-info {
  background: var(--vault-tint) !important;
  color: var(--vault-accent) !important;
}

.vault-workspace .access-chip {
  min-width: var(--vault-tap);
  min-height: var(--vault-tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

/* ----------------------------------------------------------------- table */
.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--vault-ink);
  --bs-table-hover-bg: var(--vault-hover);
  --bs-table-hover-color: var(--vault-ink);
  border-color: var(--vault-line);
}

.table thead th {
  text-transform: none !important;
  font-size: 0.875rem !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important;
  color: var(--vault-ink-2) !important;
  border-bottom: 1px solid var(--vault-line);
  padding-top: 0.55rem;
  padding-bottom: 0.55rem;
}

/* Dropbox list rows: ~48px tall, hairline separators */
.table > tbody > tr > td {
  border-color: var(--vault-line);
  padding-top: 0.7rem;
  padding-bottom: 0.7rem;
  vertical-align: middle;
}

.table-hover > tbody > tr {
  transition: background-color var(--vault-fast) var(--vault-ease);
}

.table-hover > tbody > tr.table-active,
.table-hover > tbody > tr.table-active > td {
  --bs-table-active-bg: var(--vault-tint);
  background: var(--vault-tint) !important;
  color: var(--vault-ink);
}

/* Recycle bin: mutes a row mid permanent-delete so it reads as inert (Phase 6 §1) */
.bin-row-busy {
  opacity: .5;
  pointer-events: none;
}

/* Recycle bin: flags rows whose purge countdown is under a week (Phase 6 §2b) */
.bin-purge-soon {
  color: var(--vault-trust-accent);
}

/* ----------------------------------------------------------- breadcrumbs */
.breadcrumb-style1 {
  --bs-breadcrumb-divider-color: var(--vault-ink-2);
  margin-bottom: 1rem !important;
}

.breadcrumb-style1 .breadcrumb-item,
.breadcrumb-style1 .breadcrumb-item a {
  font-size: 0.9375rem;
  color: var(--vault-ink-2);
}

.breadcrumb-style1 .breadcrumb-item a {
  border-radius: 50rem;
  padding: 0.2rem 0.55rem;
  margin-left: -0.55rem;
  transition: background-color var(--vault-fast) var(--vault-ease);
}

.breadcrumb-style1 .breadcrumb-item a:hover {
  background: var(--vault-hover);
  color: var(--vault-ink);
}

.breadcrumb-style1 .breadcrumb-item.active {
  color: var(--vault-ink);
  font-weight: 500;
}

/* ------------------------------------------------------ dropdowns/menus */
.dropdown-menu {
  --bs-dropdown-bg: var(--vault-surface);
  --bs-dropdown-color: var(--vault-ink);
  --bs-dropdown-link-color: var(--vault-ink);
  --bs-dropdown-link-hover-bg: var(--vault-hover);
  --bs-dropdown-link-hover-color: var(--vault-ink);
  --bs-dropdown-link-active-bg: var(--vault-tint);
  --bs-dropdown-link-active-color: var(--vault-accent);
  --bs-dropdown-border-color: var(--vault-line);
  padding: 0.45rem;
  border: 1px solid var(--vault-line);
  border-radius: 12px;
  background: var(--vault-surface);
  box-shadow: var(--vault-shadow-pop);
}

.dropdown-menu .dropdown-item {
  min-height: var(--vault-tap);
  display: flex;
  align-items: center;
  border-radius: 8px;
  color: var(--vault-ink);
  font-size: 0.9375rem;
  padding: 0.45rem 0.75rem;
}

.dropdown-menu .dropdown-item:hover,
.dropdown-menu .dropdown-item:focus-visible {
  background: var(--vault-hover);
  color: var(--vault-ink);
}

.navbar-nav .nav-link:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.dropdown-item:focus-visible,
.vault-tree-chevron:focus-visible,
.vault-workspace .access-chip:focus-visible,
.btn-close:focus,
.btn-close:focus-visible {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(var(--vault-accent-rgb), 0.12);
}

.vault-password-toggle:focus-visible {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(var(--vault-accent-rgb), 0.12);
}

#librarySearch:focus-within .form-control {
  outline: 0;
  box-shadow: none;
}

.dropdown-menu .dropdown-divider {
  border-color: var(--vault-line);
  margin: 0.375rem 0.25rem;
}

@media (prefers-reduced-motion: no-preference) {
  .dropdown-menu.show {
    animation: vault-pop var(--vault-fast) var(--vault-ease);
  }
}

/* ---------------------------------------------------------------- modals
   Dialog shell (Phase 3+4, A1): every dialog in the app — markup modals and
   the programmatic Dialog.confirm/open API in dialog.js — shares this look:
   16px radius, no border, soft large-radius shadow, 24px padding,
   fade + 0.96→1 scale over ~150ms. Backdrop (sharing-trust-fullscale §01,
   2026-07-19): one glass veil for every modal AND offcanvas — deep-teal
   tint + backdrop blur, so the workspace stays visible but recedes. */
.modal-content {
  background: var(--vault-surface);
  border: 0;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  color: var(--vault-ink);
}

.modal-header,
.modal-footer {
  border-color: var(--vault-line);
  padding: 1.25rem 1.5rem;
}

.modal-body {
  padding: 1.25rem 1.5rem;
}

.modal-backdrop,
.offcanvas-backdrop {
  background-color: rgba(8, 23, 19, 0.36);
  -webkit-backdrop-filter: blur(6px) saturate(1.2);
  backdrop-filter: blur(6px) saturate(1.2);
}

[data-bs-theme="dark"] .modal-backdrop,
[data-bs-theme="dark"] .offcanvas-backdrop {
  background-color: rgba(2, 12, 10, 0.5);
}

.modal-backdrop.show,
.offcanvas-backdrop.show {
  opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
  .modal.fade .modal-dialog {
    transform: scale(0.96);
    opacity: 0;
    transition: transform 150ms var(--vault-ease), opacity 150ms var(--vault-ease);
  }

  .modal.show .modal-dialog {
    transform: none;
    opacity: 1;
  }
}

/* ------------------------------------------------------------- offcanvas */
.offcanvas {
  background: var(--vault-surface);
  color: var(--vault-ink);
  border-left: 1px solid var(--vault-line) !important;
  box-shadow: var(--vault-shadow-pop);
}

.offcanvas-header {
  border-color: var(--vault-line) !important;
}

/* ---------------------------------------------------------------- avatar */
.avatar .avatar-initial.bg-label-primary {
  background: var(--vault-accent) !important;
  color: var(--vault-accent-ink) !important;
  font-weight: 500;
}

/* -------------------------------------------------------------- progress */
.progress {
  background-color: var(--vault-hover);
}

.progress .progress-bar.bg-primary {
  background-color: var(--vault-accent) !important;
}

/* -------------------------------------------------------------- snackbar */
.vault-snackbar {
  position: fixed;
  left: 1.25rem;
  bottom: 1.25rem;
  z-index: 1095;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  max-width: min(420px, calc(var(--vault-screen-w) - 2.5rem));
  padding: 0.8rem 1rem;
  border-radius: 8px;
  background: var(--vault-snackbar-bg);
  color: var(--vault-snackbar-ink);
  box-shadow: var(--vault-shadow-pop);
  font-size: 0.9375rem;
}

.vault-snackbar .btn-close {
  filter: none;
  margin-left: 0.25rem;
}

[data-bs-theme="light"] .vault-snackbar .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }
[data-bs-theme="dark"] .vault-snackbar .btn-close { filter: none; }

@media (prefers-reduced-motion: no-preference) {
  .vault-snackbar {
    animation: vault-snack-in var(--vault-med) var(--vault-ease);
  }
  .vault-snackbar.hiding {
    transition: opacity var(--vault-fast) var(--vault-ease), transform var(--vault-fast) var(--vault-ease);
    opacity: 0;
    transform: translateY(6px);
  }
}

/* ------------------------------------------------------------ auth page */
.vault-auth-page {
  min-height: var(--vault-screen-h);
  display: grid;
  grid-template-rows: 1fr auto;
  overflow-x: hidden;
  padding: clamp(1rem, calc(var(--vault-screen-w) * 0.03), 2.5rem);
  background: var(--vault-trust-frame) !important;
  color: var(--vault-trust-ink);
}

.vault-auth-stage {
  width: 100%;
  display: grid;
  place-items: center;
}

.vault-auth-legal {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  padding-top: 1.25rem;
  color: var(--vault-trust-muted);
  font-size: 0.875rem;
}

.vault-auth-card {
  width: 100%;
  max-width: 408px;
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  border-radius: 12px;
  padding: 2.5rem 2.25rem 2rem;
}

@media (prefers-reduced-motion: no-preference) {
  .vault-auth-card {
    animation: vault-rise 260ms var(--vault-ease);
  }
}

.vault-auth-brand {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-bottom: 1.75rem;
}

.vault-auth h1 {
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
  letter-spacing: -0.01em;
}

.vault-auth .vault-auth-sub {
  color: var(--vault-ink-2);
  font-size: 1rem;
  margin-bottom: 1.75rem;
}

.vault-auth-foot {
  margin-top: 1.25rem;
  font-size: 0.875rem;
  color: var(--vault-ink-2);
  text-align: center;
}

/* welcome flow: nav is visible but inert until the profile has a name —
   the RequireProfileCompletionFilter enforces this server-side too */
.vault-nav-locked .vault-rail,
.vault-nav-locked .vault-panel-scroll,
.vault-nav-locked .vault-panel-title,
.vault-nav-locked .vault-panel-collapse,
.vault-nav-locked .storage-meter,
.vault-nav-locked.vault-search,
.vault-nav-locked > .btn {
  pointer-events: none;
  opacity: 0.45;
  user-select: none;
}

#layout-navbar [data-vault-mobile-menu-trigger],
.menu-mobile-toggler [data-vault-mobile-menu-trigger] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--vault-tap);
  min-height: var(--vault-tap);
}

.vault-auth-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
  text-transform: lowercase;
}

.vault-auth-divider::before,
.vault-auth-divider::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--vault-line);
}

/* 6-digit sign-in code entry (Claude-style boxes) */
.vault-code-boxes {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
}

.vault-code-digit {
  width: 48px;
  height: 56px;
  padding: 0;
  text-align: center;
  font-size: 1.5rem;
  font-weight: 500;
  border-radius: 8px;
  border: 1px solid var(--vault-line-strong);
  caret-color: var(--vault-accent);
}

.vault-code-digit:focus {
  border-color: var(--vault-accent);
  box-shadow: 0 0 0 1px var(--vault-accent);
}

/* avatar as an uploaded photo — same footprint as the initials circle */
img.vault-avatar {
  object-fit: cover;
  background: var(--vault-hover);
}

.vault-avatar-lg {
  width: 40px;
  height: 40px;
  font-size: 0.9375rem;
}

/* profile page photo block */
.vault-profile-photo {
  position: relative;
  width: 132px;
  height: 132px;
  flex: none;
}

.vault-profile-photo > img,
.vault-profile-photo > .vault-profile-initials {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--vault-surface);
  box-shadow: 0 0 0 1px var(--vault-line);
}

.vault-profile-initials {
  display: flex;
  align-items: center;
  justify-content: center;
  background: hsl(var(--avatar-h, 210) 45% 45%);
  color: #fff;
  font-size: 2.5rem;
  font-weight: 600;
}

[data-bs-theme="dark"] .vault-profile-initials {
  background: hsl(var(--avatar-h, 210) 42% 60%);
  color: oklch(0.2 0.01 260);
}

.vault-profile-photo .vault-photo-edit {
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 2px solid var(--vault-surface);
  background: var(--vault-dark);
  color: var(--vault-dark-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform var(--vault-fast) var(--vault-ease);
}

.vault-profile-photo .vault-photo-edit:hover {
  transform: scale(1.06);
}

/* --------------------------------------------------------- dashboard bits */
.vault-page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.vault-page-head h4 {
  font-size: 1.5rem;
  letter-spacing: -0.01em;
  margin-bottom: 0.125rem;
}

.vault-page-head p {
  margin: 0;
  color: var(--vault-ink-2);
  font-size: 0.9375rem;
}

/* Task-oriented Home (spec 6.1): Continue working, Team changes, support strip.
   Flat one-pixel boundaries, no gradient, no heavy shadow. */
.vault-home-section {
  margin-bottom: 1.75rem;
  min-width: 0;
}

/* Continue working (wider) beside Team changes (narrower), stacking below 992px. */
.vault-home-columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.75rem;
  margin-bottom: 0;
}

.vault-home-columns .vault-home-section {
  margin-bottom: 0;
}

@media (min-width: 992px) {
  .vault-home-columns {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    margin-bottom: 1.75rem;
  }
}

.vault-home-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.vault-home-section-head .vault-home-title {
  margin-bottom: 0;
}

.vault-home-section-link {
  flex-shrink: 0;
  color: var(--vault-accent);
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: none;
}

.vault-home-section-link:hover {
  text-decoration: underline;
}

.vault-home-section-link-static {
  color: var(--vault-ink-2);
  cursor: default;
}

.vault-home-section-link-static:hover {
  text-decoration: none;
}

.vault-home-title {
  font-size: var(--vault-title-section);
  font-weight: 600;
  color: var(--vault-ink);
  margin-bottom: 0.75rem;
}

.vault-home-empty {
  margin: 0;
  color: var(--vault-ink-2);
  font-size: 0.9375rem;
}

.vault-home-work-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--vault-line);
}

.vault-home-work-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: var(--vault-tap);
  padding: 0.85rem 0.25rem;
  border-bottom: 1px solid var(--vault-line);
  color: var(--vault-ink);
  text-decoration: none;
  transition: background-color var(--vault-fast) var(--vault-ease);
}

.vault-home-work-row:hover {
  background: var(--vault-hover);
}

.vault-home-work-row > .vault-ficon {
  flex-shrink: 0;
}

.vault-home-work-copy {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  gap: 0.1rem;
}

.vault-home-work-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.9375rem;
  font-weight: 600;
}

.vault-home-work-caption {
  color: var(--vault-ink-2);
  font-size: 0.75rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vault-home-work-location {
  display: none;
  flex: 0 0 auto;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
  text-align: right;
}

.vault-home-work-time {
  flex: 0 0 auto;
  color: var(--vault-ink-2);
  font-size: 0.75rem;
  text-align: right;
}

@media (min-width: 700px) {
  .vault-home-work-location {
    display: block;
  }
}

.vault-home-team-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
}

.vault-home-team-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0.15rem;
  border-bottom: 1px solid var(--vault-line);
}

.vault-home-team-item:last-child {
  border-bottom: 0;
}

/* The actor's face carries the row; the action icon shrinks to a corner badge. */
.vault-home-team-face {
  position: relative;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  line-height: 0;
}

.vault-home-team-avatar {
  width: 32px;
  height: 32px;
  font-size: 0.8125rem;
}

.vault-home-team-icon {
  position: absolute;
  right: -3px;
  bottom: -3px;
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--vault-tint);
  box-shadow: 0 0 0 1.5px var(--vault-surface);
  color: var(--vault-accent);
  line-height: 1;
}

.vault-home-team-item > div {
  flex: 1 1 auto;
  min-width: 0;
}

.vault-home-team-text {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--vault-ink-2);
}

.vault-home-team-text strong {
  color: var(--vault-ink);
  font-weight: 600;
}

.vault-home-team-item time {
  flex-shrink: 0;
  color: var(--vault-ink-2);
  font-size: var(--vault-text-meta);
}

/* ======================================================================
   Home overview band (modern redesign): KPI tiles + storage donut.
   Refined restraint (hairline tiles on the flat canvas, teal-family only)
   with richer visuals (the donut, count-up, hover lift).
   ====================================================================== */
/* Single column since the storage panel moved out. It used to sit in a 300px
   track with align-items: stretch, which forced every KPI tile to grow to the
   donut's height — tall tiles carrying one number each. */
.vault-overview {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  margin-bottom: 1.25rem;
}

.vault-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.75rem;
}

.vault-kpi {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.8rem 0.85rem;
  border: 1px solid var(--vault-line);
  border-radius: 14px;
  background: var(--vault-surface);
  color: var(--vault-ink);
  text-decoration: none;
  transition: border-color var(--vault-fast) var(--vault-ease),
    transform var(--vault-fast) var(--vault-ease),
    box-shadow var(--vault-fast) var(--vault-ease);
}

/* One-time staggered entrance (DESIGN.md: cards get a fade-rise, <=240ms
   total stagger). backwards fill keeps the pre-delay frame; if the animation
   is disabled (reduced motion) the tiles render in their normal visible state. */
@media (prefers-reduced-motion: no-preference) {
  .vault-overview .vault-kpi,
  .vault-overview .vault-storage-card {
    /* `backwards`, never `both`. The forwards half of `both` holds the final
       keyframe (transform: none) after the animation ends, and a filled
       animation outranks a normal declaration — which silently killed the
       hover lift on these tiles. `backwards` still supplies the pre-delay
       frame, which is all the stagger needs. */
    animation: vault-rise 260ms var(--vault-ease) backwards;
  }
  .vault-overview .vault-kpi:nth-child(1) { animation-delay: 0ms; }
  .vault-overview .vault-kpi:nth-child(2) { animation-delay: 40ms; }
  .vault-overview .vault-kpi:nth-child(3) { animation-delay: 80ms; }
  .vault-overview .vault-kpi:nth-child(4) { animation-delay: 120ms; }
  .vault-overview .vault-kpi:nth-child(5) { animation-delay: 160ms; }
  .vault-overview .vault-storage-card { animation-delay: 120ms; }
}

.vault-kpi-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--vault-tint);
  color: var(--vault-accent);
  transition: transform var(--vault-fast) var(--vault-ease);
}

.vault-kpi-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.vault-kpi-value {
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--vault-ink);
  font-variant-numeric: tabular-nums;
}

.vault-kpi-label {
  margin-top: 0.15rem;
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
  font-weight: 500;
}

/* Lift AND scale, with the icon growing in sympathy — the card reads as
   floating off the page rather than merely nudging. z-index keeps the raised
   card's shadow above its neighbours instead of under the next tile. */
a.vault-kpi:hover {
  border-color: var(--vault-accent);
  transform: translateY(-5px) scale(1.02);
  box-shadow: var(--vault-shadow-pop);
  z-index: 2;
}

a.vault-kpi:hover .vault-kpi-icon {
  transform: scale(1.12);
}

a.vault-kpi:active {
  transform: translateY(-1px);
}

/* ---- Storage donut panel ---- */
.vault-storage-card {
  display: flex;
  flex-direction: column;
  padding: 1.15rem 1.2rem 1.3rem;
  border: 1px solid var(--vault-line);
  border-radius: 16px;
  background: var(--vault-surface);
}

.vault-storage-head {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 0.35rem;
}

.vault-storage-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--vault-tint);
  color: var(--vault-accent);
}

.vault-storage-title {
  font-size: 1rem;
  margin-bottom: 0;
}

.vault-storage-sub {
  margin: 0;
  font-size: 0.75rem;
  color: var(--vault-ink-2);
}

.vault-storage-body {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-top: 0.6rem;
}

@media (min-width: 992px) {
  .vault-storage-body {
    flex-direction: column;
    gap: 0.9rem;
    margin-top: auto;
    padding-top: 0.6rem;
  }
}

.vault-donut {
  position: relative;
  flex-shrink: 0;
  width: 140px;
  height: 140px;
}

.vault-donut svg {
  transform: rotate(-90deg);
}

.vault-donut-track {
  stroke: var(--vault-surface-inset);
}

:root[data-bs-theme="dark"] .vault-donut-track {
  stroke: rgba(255, 255, 255, 0.08);
}

.vault-donut-seg {
  transition: stroke-dashoffset 700ms var(--vault-ease), stroke-dasharray 700ms var(--vault-ease);
}

.vault-donut-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
}

.vault-donut-center strong {
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--vault-ink);
}

.vault-donut-center span {
  font-size: 0.7rem;
  color: var(--vault-ink-2);
}

.vault-storage-legend {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin: 0;
  width: 100%;
  min-width: 0;
}

.vault-storage-legend li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.8125rem;
}

.vault-storage-swatch {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 3px;
}

.vault-storage-legend-label {
  color: var(--vault-ink-2);
}

.vault-storage-legend-size {
  margin-left: auto;
  font-weight: 600;
  color: var(--vault-ink);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .vault-kpi,
  .vault-kpi-icon,
  .vault-donut-seg {
    transition: none;
  }
}

.vault-home-group-list {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin: 0;
}

.vault-home-group-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem;
  padding: 0.5rem 0.15rem;
}

/* ---- Home pulse band: live presence board + vault legends ---- */
.vault-home-pulse {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}
@media (max-width: 991px) {
  .vault-home-pulse { grid-template-columns: 1fr; }
}

.vault-live-beacon {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--vault-pulse);
  animation: vault-beacon 1.6s ease-in-out infinite;
}
@keyframes vault-beacon {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.75); }
}

.vault-live-board { display: grid; gap: 0.4rem; margin: 0; }
.vault-live-board:empty { display: none; }
.vault-live-row {
  display: grid;
  grid-template-columns: 1.75rem 32px 1fr auto auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--vault-line);
  border-radius: 0.5rem;
  transition: transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.35s ease, box-shadow 0.35s ease;
}
.vault-live-row.is-entering { opacity: 0; transform: translateX(-14px); }
.vault-live-row.is-leaving { opacity: 0; transform: translateX(14px); pointer-events: none; }
.vault-live-row.is-first { border-color: #d4a72c; box-shadow: inset 3px 0 0 #d4a72c; }
.vault-live-row.is-first .vault-live-rank { color: #d4a72c; }
.vault-live-row.is-top3:not(.is-first) { box-shadow: inset 3px 0 0 var(--vault-line); }
.vault-live-row.moved-up { box-shadow: 0 0 0 1px var(--vault-pulse), inset 3px 0 0 var(--vault-pulse); }
.vault-live-row .vault-live-delta { min-width: 0.9rem; font-size: 0.6875rem; }
.vault-live-row.moved-up .vault-live-delta { color: var(--vault-pulse); animation: vault-delta-pop 0.5s ease; }
.vault-live-row.moved-down .vault-live-delta { color: #d4a72c; animation: vault-delta-pop 0.5s ease; }
@keyframes vault-delta-pop {
  from { transform: translateY(6px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.vault-live-rank { font-weight: 700; font-size: 0.8125rem; color: var(--vault-ink-2); text-align: center; }
.vault-live-board-avatar { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; font-size: 0.8125rem; }
.vault-live-name { font-weight: 600; font-size: 0.875rem; color: var(--vault-ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vault-live-you {
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: var(--vault-pulse);
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  vertical-align: 1px;
}
.vault-live-clock { font-variant-numeric: tabular-nums; font-size: 0.8125rem; color: var(--vault-ink-2); }

.vault-legend-list { display: grid; gap: 0.4rem; margin: 0; }
.vault-legend-row {
  display: grid;
  grid-template-columns: 1.75rem 32px 1fr auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.6rem;
  border-radius: 0.5rem;
}
.vault-legend-row.vault-legend-top { border: 1px solid var(--vault-line); }
.vault-legend-1 { background: linear-gradient(90deg, rgba(212, 167, 44, 0.14), transparent 65%); }
.vault-legend-1 .vault-legend-rank { color: #d4a72c; }
.vault-legend-2 { background: linear-gradient(90deg, rgba(148, 163, 184, 0.16), transparent 65%); }
.vault-legend-2 .vault-legend-rank { color: #94a3b8; }
.vault-legend-3 { background: linear-gradient(90deg, rgba(196, 124, 60, 0.14), transparent 65%); }
.vault-legend-3 .vault-legend-rank { color: #c47c3c; }
.vault-legend-rank { font-weight: 700; font-size: 0.8125rem; color: var(--vault-ink-2); text-align: center; }
.vault-legend-avatar { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; font-size: 0.8125rem; }
.vault-legend-copy { min-width: 0; }
.vault-legend-name { display: block; font-weight: 600; font-size: 0.875rem; color: var(--vault-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vault-legend-meter { display: block; height: 4px; margin-top: 0.25rem; border-radius: 999px; background: var(--vault-line); overflow: hidden; }
.vault-legend-meter > span { display: block; height: 100%; border-radius: inherit; background: var(--vault-pulse); }
.vault-legend-count { display: grid; text-align: right; font-size: 0.75rem; color: var(--vault-ink-2); }
.vault-legend-count strong { font-size: 0.9375rem; color: var(--vault-ink); font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .vault-live-row { transition: none; }
  .vault-live-beacon,
  .vault-live-row.moved-up .vault-live-delta,
  .vault-live-row.moved-down .vault-live-delta { animation: none; }
}

.vault-stats-strip {
  display: flex;
  flex-direction: row; /* .card defaults to column — must be reset */
  flex-wrap: wrap;
}

.vault-stat {
  flex: 1 1 150px;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.95rem 1.35rem;
  min-width: 0;
}

.vault-stat + .vault-stat {
  border-left: 1px solid var(--vault-line);
}

.vault-stat .vault-stat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--vault-tint);
  color: var(--vault-accent);
  flex: none;
}

.vault-stat .vault-stat-num {
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--vault-ink);
}

.vault-stat .vault-stat-label {
  font-size: 0.875rem;
  color: var(--vault-ink-2);
}

@media (max-width: 767.98px) {
  .vault-stat + .vault-stat { border-left: 0; border-top: 1px solid var(--vault-line); }
  .vault-stat { flex-basis: 100%; }
}

.vault-activity li {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.7rem 0;
}

.vault-activity li + li {
  border-top: 1px solid var(--vault-line);
}

.vault-activity .vault-activity-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--vault-hover);
  flex: none;
}

@keyframes vault-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

@keyframes vault-pop {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

@keyframes vault-snack-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html:focus-within {
    scroll-behavior: auto !important;
  }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------- misc chrome */
/* kill the Materio waves ripple tint mismatch on primary buttons */
.waves-effect .waves-ripple { background: rgba(255, 255, 255, 0.35); }

/* storage meter (sidebar) — Dropbox meters stay in one blue family */
.storage-meter .progress { background: var(--vault-hover-strong); }
.storage-meter .bg-primary { background-color: var(--vault-accent) !important; }
.storage-meter .bg-info    { background-color: #85b8ff !important; }
.storage-meter .bg-warning { background-color: #c9ddff !important; }
[data-bs-theme="dark"] .storage-meter .bg-info    { background-color: #2d71d9 !important; }
[data-bs-theme="dark"] .storage-meter .bg-warning { background-color: #164a9e !important; }

/* upload progress panel — same inverse surface family as the snackbar */
.vault-upload-panel .card {
  background: var(--vault-snackbar-bg) !important;
  border: 0;
  border-radius: 12px;
  box-shadow: var(--vault-shadow-pop) !important;
}

.vault-upload-panel .text-white { color: var(--vault-snackbar-ink) !important; }
.vault-upload-panel .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }
[data-bs-theme="dark"] .vault-upload-panel .btn-close { filter: none; }

/* "Announce to People" — the one thing you can DO in a panel that otherwise
   just reports progress, and it lives for a few seconds on a surface nobody
   is looking at. An outlined .btn lost that fight twice over: outline-primary
   on the inverse snackbar ground reads as disabled, and the global 44px .btn
   touch floor stretched it into the panel's own furniture. So it is its own
   control (no .btn class, nothing to lose a specificity fight with), solid,
   pill-shaped, on its own line — and it breathes until someone deals with it. */
.vault-announce-cta {
  /* Warm amber, NOT the brand accent. The panel is --vault-deep, the accent is
     the same green family, and an accent-coloured button on it was green on
     green — the one control in the panel reading as part of the panel. #dc7f37
     is the wordmark's amber deepened until white ink clears AA on it, so the
     contrast colour still belongs to the product rather than being a note
     struck from outside the palette.
     The fill is pinned by two constraints pulling opposite ways: white text
     needs 4.5:1 against the button (#dc7f37 straight from the wordmark gives
     only 2.9:1 -- far too pale to carry white), while the button needs 3:1
     against the deep-green panel, which anything darker starts to fail.
     #c94d16 is the band that satisfies both: 4.61:1 ink, 3.15:1 edge. */
  --cta-bg: #c94d16;
  --cta-ink: #ffffff;
  --cta-glow: 201, 77, 22;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.75rem;
  padding: 0.5rem 1rem;
  border: 0;
  border-radius: 999px;
  background: var(--cta-bg);
  color: var(--cta-ink);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition: filter var(--vault-fast, 150ms) ease, transform var(--vault-fast, 150ms) ease;
}

/* Dark theme flips the snackbar to a pale mint ground, so the button flips with
   it: the deep rust reads on light exactly as the amber reads on dark. Same
   warm family, opposite weight — inheriting the light-theme amber here would
   put pale on pale. */
[data-bs-theme="dark"] .vault-announce-cta {
  --cta-bg: var(--vault-trust-accent);
  --cta-ink: #ffffff;
  --cta-glow: 196, 66, 26;
}

.vault-announce-cta:hover { filter: brightness(1.08); }
.vault-announce-cta:active { transform: scale(0.98); }
.vault-announce-cta:focus-visible {
  outline: 2px solid var(--vault-snackbar-ink);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: no-preference) {
  .vault-announce-cta { animation: vault-announce-pulse 1.9s ease-in-out infinite; }
  /* Once it has been noticed, the pulse has done its job and only distracts. */
  .vault-announce-cta:hover,
  .vault-announce-cta:focus-visible { animation: none; }
}

@keyframes vault-announce-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(var(--cta-glow), 0.55);
    transform: scale(1);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(var(--cta-glow), 0);
    transform: scale(1.035);
  }
}

/* drag-and-drop upload overlay */
#dropOverlay {
  background: rgba(var(--vault-accent-rgb), 0.07) !important;
  border: 2px dashed var(--vault-accent) !important;
  border-radius: 16px;
}


/* ============================================================================
   Public-page redesign (sign-in / verify / shared-link) + glass pass.
   These pages force light mode and share one visual system: warm gradient
   canvas, soft drifting color fields, and a glass card. Glass is applied to
   overlays app-wide (modals, offcanvas panels, storage widget) but never to
   dense data tables (readability).
   ========================================================================== */

.vault-auth::before,
.vault-auth::after {
  content: "";
  position: fixed;
  border-radius: 50%;
  filter: blur(64px);
  opacity: 0.55;
  z-index: 0;
  pointer-events: none;
}

.vault-auth::before {
  width: 420px;
  height: 420px;
  background: rgba(196, 66, 26, 0.14);
  top: -130px;
  right: -110px;
}

.vault-auth::after {
  width: 360px;
  height: 360px;
  background: rgba(224, 138, 100, 0.16);
  bottom: -130px;
  left: -90px;
}

@media (prefers-reduced-motion: no-preference) {
  .vault-auth::before { animation: vault-drift 16s ease-in-out infinite alternate; }
  .vault-auth::after { animation: vault-drift 20s ease-in-out infinite alternate-reverse; }
}

@keyframes vault-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(34px, 22px, 0) scale(1.08); }
}

.vault-auth-card {
  position: relative;
  z-index: 1;
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: 0 8px 40px rgba(26, 25, 24, 0.10);
  border-radius: 16px;
}

.vault-auth-card-compact {
  width: min(440px, 100%);
  max-width: 440px;
  padding: 2.75rem 2.5rem 2.25rem;
}

.vault-auth-card-compact.text-center .vault-auth-brand {
  justify-content: center;
}

.vault-auth-card-compact.text-center .vault-auth-sub {
  margin-inline: auto;
}

.vault-auth-state-icon {
  width: 52px;
  height: 52px;
  display: inline-grid;
  place-items: center;
  margin-bottom: 1.25rem;
  border-radius: 14px;
  background: color-mix(in srgb, var(--vault-trust-accent) 12%, white);
  color: var(--vault-trust-accent);
  font-size: 1.5rem;
}

.vault-auth-actions .btn,
.vault-auth-actions .form-control {
  min-height: var(--vault-tap);
}

.vault-code-boxes {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.5rem;
}

.vault-code-digit {
  width: 100%;
  min-width: 0;
  height: 56px;
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
}

.vault-auth-foot { position: relative; z-index: 1; }

/* split layout: form beside an illustration (login page, large screens) */
.vault-auth-card.vault-auth-split {
  width: min(920px, 100%);
  max-width: 920px;
  display: grid;
  grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
  padding: 0;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--vault-trust-ink) 10%, transparent);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 8px 40px rgba(26, 25, 24, 0.10);
}

.vault-auth-form {
  min-width: 0;
  padding: 3rem 2.75rem 2.5rem;
  font-size: 1rem;
}

.vault-auth-form .vault-auth-brand {
  margin-bottom: 2rem;
}

.vault-auth-form .app-brand-text {
  font-size: 1.25rem;
}

.vault-auth-form h1 {
  margin: 0 0 0.75rem;
  color: var(--vault-trust-ink);
  font-size: 2rem;
  line-height: 1.15;
  letter-spacing: -0.025em;
}

.vault-auth-sub {
  max-width: 38ch;
  margin: 0 0 1.75rem;
  color: var(--vault-trust-muted);
  font-size: 1rem;
  line-height: 1.55;
}

.vault-auth-alert {
  margin-bottom: 1.25rem;
  padding: 0.75rem 1rem;
  font-size: 0.9375rem;
}

.vault-auth .validation-summary-valid {
  display: none;
}

.vault-auth-field {
  margin-bottom: 1.25rem;
}

.vault-auth-field .form-label {
  margin-bottom: 0.5rem;
  color: var(--vault-trust-ink);
  font-size: 0.9375rem;
  font-weight: 600;
}

.vault-auth-input-wrap {
  position: relative;
}

.vault-auth-input-wrap > i {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 1rem;
  color: var(--vault-trust-muted);
  font-size: 1.125rem;
  pointer-events: none;
  transform: translateY(-50%);
}

.vault-auth-input-wrap .form-control {
  min-height: 48px;
  padding-left: 2.75rem;
  font-size: 1rem;
}

.vault-auth-input-wrap:has(.vault-password-toggle) .form-control {
  padding-right: 3rem;
}

.vault-field-error {
  display: block;
  margin-top: 0.375rem;
  font-size: 0.9375rem;
}

.vault-auth-primary,
.vault-auth-password-trigger {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-size: 1rem;
}

.vault-password-form {
  padding-top: 1.25rem;
}

.vault-password-form > .btn {
  min-height: 48px;
  font-size: 1rem;
}

.vault-password-toggle {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  min-height: 48px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--vault-trust-muted);
}

.vault-password-toggle:hover {
  color: var(--vault-trust-ink);
}

.vault-auth-recovery {
  min-height: var(--vault-tap);
  display: inline-flex;
  align-items: center;
  font-size: 0.9375rem;
  font-weight: 500;
}

.vault-auth-onboarding {
  margin: 1.5rem 0 0;
  color: var(--vault-trust-muted);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.vault-trust-visual {
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 2.5rem;
  overflow: hidden;
  color: #fff;
  background: var(--vault-trust-accent);
}

.vault-trust-copy {
  position: relative;
  z-index: 2;
  max-width: 32rem;
}

.vault-trust-kicker {
  color: var(--vault-trust-on-accent);
  font-size: 0.8125rem;
  font-weight: 600;
}

.vault-trust-copy h2 {
  margin: 0.5rem 0 0.75rem;
  color: #fff;
  font-size: 1.75rem;
  line-height: 1.18;
  letter-spacing: -0.025em;
}

.vault-trust-copy p {
  max-width: 36ch;
  margin: 0;
  color: var(--vault-trust-on-accent);
  line-height: 1.55;
}

.vault-trust-scene {
  position: relative;
  min-height: 280px;
}

.vault-storage-stack,
.vault-collaborator,
.vault-transfer-file,
.vault-access-check {
  position: absolute;
}

.vault-collaborator {
  z-index: 3;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.42);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.18);
  box-shadow: 0 6px 8px rgba(64, 23, 12, 0.14);
  font-size: 1.25rem;
}

.vault-collaborator-a {
  left: 4%;
  top: 18%;
}

.vault-collaborator-b {
  right: 2%;
  top: 6%;
}

.vault-collaborator-c {
  right: 8%;
  bottom: 10%;
}

.vault-scene-path {
  position: absolute;
  z-index: 1;
  height: 1px;
  transform-origin: left center;
  background: rgba(255, 255, 255, 0.34);
}

.vault-scene-path-a {
  width: 64%;
  left: 12%;
  top: 36%;
  transform: rotate(-12deg);
}

.vault-scene-path-b {
  width: 58%;
  left: 28%;
  top: 63%;
  transform: rotate(14deg);
}

.vault-storage-stack {
  z-index: 2;
  left: 50%;
  top: 50%;
  width: 112px;
  height: 124px;
  display: grid;
  place-items: center;
  transform: translate(-50%, -46%);
  border: 1px solid rgba(255, 255, 255, 0.46);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.2);
  box-shadow: 0 8px 8px rgba(64, 23, 12, 0.16);
  font-size: 2rem;
}

.vault-storage-layer {
  position: absolute;
  width: 84px;
  height: 70px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 12px;
}

.vault-storage-layer:nth-child(1) {
  transform: translateY(14px) scale(0.9);
  opacity: 0.38;
}

.vault-storage-layer:nth-child(2) {
  transform: translateY(7px) scale(0.95);
  opacity: 0.6;
}

.vault-storage-layer:nth-child(3) {
  transform: translateY(0);
  background: rgba(255, 255, 255, 0.12);
}

.vault-version-ring {
  position: absolute;
  right: -12px;
  top: -12px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fff;
  color: var(--vault-trust-accent);
  font-size: 0.75rem;
  font-weight: 700;
}

.vault-transfer-file {
  z-index: 4;
  left: calc(50% - 20px);
  top: calc(50% - 18px);
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: #fff;
  color: var(--vault-trust-accent);
  box-shadow: 0 6px 8px rgba(64, 23, 12, 0.18);
}

.vault-access-check {
  z-index: 4;
  right: 4%;
  bottom: 2%;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.55rem 0.7rem;
  border-radius: 8px;
  background: #fff;
  color: var(--vault-trust-accent);
  font-size: 0.8125rem;
  font-weight: 700;
}

.vault-trust-signals {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  color: var(--vault-trust-on-accent);
  font-size: 0.8125rem;
}

.vault-trust-signals span {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

@media (prefers-reduced-motion: no-preference) {
  .vault-transfer-file {
    animation: vault-file-transfer 5.4s var(--vault-ease) infinite;
  }

  .vault-version-ring {
    animation: vault-version-pulse 5.4s var(--vault-ease) infinite;
  }

  .vault-access-check {
    animation: vault-access-confirm 5.4s var(--vault-ease) infinite;
  }
}

@keyframes vault-file-transfer {
  0%, 12% {
    opacity: 0;
    transform: translate3d(-88px, 42px, 0) scale(0.82);
  }
  24%, 58% {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
  72%, 100% {
    opacity: 0;
    transform: translate3d(88px, -38px, 0) scale(0.88);
  }
}

@keyframes vault-version-pulse {
  0%, 38%, 100% {
    opacity: 0.55;
    transform: scale(0.94);
  }
  48%, 64% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes vault-access-confirm {
  0%, 58% {
    opacity: 0;
    transform: translateY(8px);
  }
  70%, 92% {
    opacity: 1;
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateY(-4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .vault-transfer-file,
  .vault-version-ring,
  .vault-access-check {
    animation: none !important;
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 991.98px) {
  .vault-auth-card.vault-auth-split {
    max-width: 520px;
    grid-template-columns: minmax(0, 1fr);
  }

  .vault-auth-form {
    padding: 2.5rem 2.25rem 2rem;
  }

  .vault-trust-visual {
    display: none;
  }
}

@media (max-width: 575.98px) {
  .vault-auth-form {
    padding: 2rem 1.25rem 1.5rem;
  }
}

@media (max-width: 479.98px) {
  .vault-auth-card-compact { padding: 2rem 1.25rem 1.5rem; }
  .vault-code-boxes { gap: 0.35rem; }
  .vault-code-digit { height: 52px; font-size: 1.25rem; }
}

/* illustration motion: floating cards, pulsing nodes, flowing share lines */
.vault-illus { width: 100%; max-width: 360px; height: auto; }
.vault-illus .dash {
  stroke-dasharray: 5 7;
}

@media (prefers-reduced-motion: no-preference) {
  .vault-illus .float-1 { animation: vault-float 6s ease-in-out infinite; }
  .vault-illus .float-2 { animation: vault-float 8s ease-in-out 0.8s infinite; }
  .vault-illus .float-3 { animation: vault-float 7s ease-in-out 1.6s infinite; }
  .vault-illus .pulse   { animation: vault-node 3.2s ease-in-out infinite; }
  .vault-illus .pulse-2 { animation: vault-node 3.2s ease-in-out 1.1s infinite; }
  .vault-illus .dash { animation: vault-dash 24s linear infinite; }
}

@keyframes vault-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

@keyframes vault-node {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 1; }
}

@keyframes vault-dash { to { stroke-dashoffset: -288; } }

/* code boxes: pop as each digit lands */
.vault-code-digit.filled {
  border-color: var(--vault-accent);
}

@media (prefers-reduced-motion: no-preference) {
  .vault-code-digit.filled { animation: vault-code-pop 160ms var(--vault-ease); }
}

@keyframes vault-code-pop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.1); }
  100% { transform: scale(1); }
}

/* circular resend-cooldown ring (JS drives --p from 100 -> 0) */
.vault-timer-ring {
  --p: 100;
  display: inline-block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  vertical-align: -3px;
  margin-right: 6px;
  background: conic-gradient(var(--vault-accent) calc(var(--p) * 1%), var(--vault-line) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3.5px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3.5px), #000 calc(100% - 3px));
}

/* shared-link public page bits */
.vault-share-hero {
  width: 76px;
  height: 76px;
  border-radius: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--vault-tint);
  color: var(--vault-accent);
  margin-bottom: 1rem;
}

.vault-share-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 1rem;
  justify-content: center;
  color: var(--vault-ink-2);
  font-size: 0.875rem;
  margin-bottom: 1.5rem;
}

.vault-share-meta span { display: inline-flex; align-items: center; gap: 0.375rem; }

/* ------------------------------------------------ glass pass (app chrome)
   Floating/overlay surfaces get glass; dense data tables and cards never do
   (readability). Extends beyond modals/offcanvas to dropdown menus, the
   notification drawer, and the search typeahead — every panel that floats
   above the canvas rather than living in it. */
.modal-content,
.offcanvas,
.dropdown-menu,
.vault-search-results {
  --bs-dropdown-bg: rgba(255, 255, 255, 0.78); 
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.45);
}

[data-bs-theme="dark"] .modal-content,
[data-bs-theme="dark"] .offcanvas,
[data-bs-theme="dark"] .dropdown-menu,
[data-bs-theme="dark"] .vault-search-results {
  --bs-dropdown-bg: rgba(26, 25, 24, 0.84);
  background: rgba(26, 25, 24, 0.84);
  border-color: rgba(255, 255, 255, 0.08);
}

.storage-meter {
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid var(--vault-line);
  border-radius: 12px;
  margin: 0 0.75rem 0.75rem;
}

[data-bs-theme="dark"] .storage-meter {
  background: rgba(255, 255, 255, 0.05);
}

/* ---- Global search typeahead ------------------------------------------ */

.vault-search-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  min-width: 320px;
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  border-radius: 12px;
  box-shadow: var(--vault-shadow-pop);
  max-height: min(430px, calc(var(--vault-screen-h) * 0.60));
  overflow-y: auto;
  z-index: 1091;
}

.vault-mobile-search .modal-dialog { margin: 0; }
.vault-mobile-search .modal-content { min-height: 100%; background: var(--vault-surface); }
.vault-search-mobile { width: 100%; }
.vault-search-mobile .vault-search-results {
  position: static;
  width: 100%;
  margin-top: 0.75rem;
  border: 1px solid var(--vault-line);
  box-shadow: none;
}

.vault-search-item,
.vault-search-all {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0.875rem;
  min-height: 52px;
  color: inherit;
  text-decoration: none;
}

.vault-search-item:hover,
.vault-search-item.active,
.vault-search-all:hover,
.vault-search-all.active {
  background: var(--vault-tint);
}

.vault-search-item-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.vault-search-item-name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vault-search-item-name mark { background: transparent; color: var(--vault-accent); padding: 0; font-weight: 600; }
.vault-search-item-path { font-size: 0.8125rem; color: var(--vault-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Content matches carry a line of the document; one line, clipped, so a
   long paragraph cannot stretch the row. */
.vault-search-item-snippet { font-size: 0.8125rem; color: var(--vault-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vault-search-item-snippet mark { background: transparent; color: var(--vault-accent); padding: 0; font-weight: 600; }
.vault-search-item-kind { font-size: 0.75rem; color: var(--vault-ink-2); text-transform: uppercase; letter-spacing: 0.04em; }
.vault-search-all { justify-content: center; font-weight: 500; color: var(--vault-accent); border-top: 1px solid var(--vault-line); }

@media (max-width: 767.98px) {
  #layout-navbar.layout-navbar { padding: 0 1rem; }
  .vault-mobile-search .modal-header,
  .vault-mobile-search .modal-body { padding: 1rem; }
}

.vault-link-card { background: var(--vault-surface); }

/* ---- Move picker tree (modal) ----------------------------------------- */
.vault-picker-tree {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid var(--vault-line);
  border-radius: 8px;
  padding: 0.375rem;
}
.vault-picker-tree .vault-tree-link { background: none; border: 0; width: 100%; text-align: left; }
.vault-picker-tree .vault-tree-link.active { background: var(--vault-tint); color: var(--vault-accent); border-radius: 6px; }
.vault-picker-tree .vault-tree-link:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---- Icon scale bump (2026-07-14) --------------------------------------
   +2px on every utility tier the app uses at UI scale. core.css defines
   these with !important; this file loads later, so equal specificity wins
   by source order. Decorative sizes (30px+) keep their core.css values. */
.icon-12px, .icon-12px::before { block-size: 14px !important; font-size: 14px !important; inline-size: 14px !important; }
.icon-14px, .icon-14px::before { block-size: 16px !important; font-size: 16px !important; inline-size: 16px !important; }
.icon-16px, .icon-16px::before { block-size: 18px !important; font-size: 18px !important; inline-size: 18px !important; }
.icon-18px, .icon-18px::before { block-size: 20px !important; font-size: 20px !important; inline-size: 20px !important; }
.icon-20px, .icon-20px::before { block-size: 22px !important; font-size: 22px !important; inline-size: 22px !important; }
.icon-22px, .icon-22px::before { block-size: 24px !important; font-size: 24px !important; inline-size: 24px !important; }
.icon-24px, .icon-24px::before { block-size: 26px !important; font-size: 26px !important; inline-size: 26px !important; }

/* ============================================================ v2.1 live collaboration
   Presence chips, join toasts, and the editor presence pill. Everything here
   is self-contained (no Bootstrap utility dependencies) because the ONLYOFFICE
   editor page links this stylesheet standalone. */

.vault-live-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: 0.625rem;
  padding: 0.125rem 0.6rem 0.125rem 0.45rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--vault-accent);
  background: var(--vault-tint);
  border: 1px solid rgba(var(--vault-accent-rgb), 0.25);
  white-space: nowrap;
  animation: vault-live-enter 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.vault-live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--vault-pulse);
  position: relative;
  flex-shrink: 0;
}

.vault-live-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid var(--vault-pulse);
  opacity: 0.8;
  animation: vault-live-ping 1.6s ease-out infinite;
}

.vault-live-avatars { display: inline-flex; }

.vault-live-avatars .vault-avatar {
  width: 20px;
  height: 20px;
  font-size: 0.58rem;
  border: 2px solid var(--vault-surface);
}

.vault-live-avatars .vault-avatar + .vault-avatar { margin-left: -7px; }

/* Row shimmer when someone joins a session on that file. */
.library-row.live-flash > td { animation: vault-live-row-flash 1.2s ease-out; }

/* Grid-card mirror of the row chip: a pulsing dot in the card corner. */
.item-card .card-live-dot {
  position: absolute;
  top: 0.75rem;
  right: 2.6rem;
}

/* Slide-in notification stack (bottom-right). */
.vault-live-stack {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 2147483000;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  pointer-events: none;
}

.vault-live-toast {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  max-width: 360px;
  padding: 0.7rem 0.9rem;
  border-radius: 0.75rem;
  background: var(--vault-snackbar-bg);
  color: var(--vault-snackbar-ink);
  box-shadow: var(--vault-shadow-pop);
  font-family: var(--vault-font);
  pointer-events: auto;
  transform: translateX(120%);
  opacity: 0;
  transition: transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.15), opacity 0.35s ease;
}

.vault-live-toast.show { transform: none; opacity: 1; }

.vault-live-toast .vault-avatar {
  flex-shrink: 0;
  animation: vault-live-halo 1.8s ease-out 2;
}

.vault-live-toast-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.vault-live-toast-text strong { font-size: 0.85rem; font-weight: 600; }

.vault-live-toast-text small {
  opacity: 0.75;
  font-size: 0.75rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vault-live-toast-action {
  margin-left: auto;
  flex-shrink: 0;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  background: var(--vault-pulse);
  color: var(--vault-deep);
  font-size: 0.75rem;
  font-weight: 600;
  text-decoration: none;
}

.vault-live-toast-action:hover { filter: brightness(1.08); color: var(--vault-deep); }

.vault-live-toast-close {
  background: none;
  border: 0;
  padding: 0 0.1rem;
  color: inherit;
  opacity: 0.6;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.vault-live-toast-close:hover { opacity: 1; }

/* Editor page: floating "who's here" pill over the ONLYOFFICE canvas. */
.vault-editor-presence {
  position: fixed;
  left: 1rem;
  bottom: 1rem;
  z-index: 2147483000;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.35rem 0.95rem 0.35rem 0.45rem;
  border-radius: 999px;
  background: var(--vault-deep);
  color: #ffffff;
  box-shadow: var(--vault-shadow-pop);
  font-family: var(--vault-font);
  font-size: 0.8rem;
}

.vault-editor-presence[hidden] { display: none; }

.vault-editor-presence .vault-avatar {
  width: 26px;
  height: 26px;
  font-size: 0.65rem;
  border: 2px solid var(--vault-deep);
}

.vault-editor-presence .vault-avatar + .vault-avatar { margin-left: -8px; }

.vault-editor-presence.bump { animation: vault-live-enter 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2); }

/* ------------------------------------------------------------ leave-session
   Deliberate exit pill, stacked above the presence pill (bottom-left; the
   chat fab owns bottom-right). Two-step: first click arms, second confirms. */

.vault-editor-leave {
  position: fixed;
  left: 1rem;
  bottom: 3.75rem;
  z-index: 2147483000;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1.05rem 0.5rem 0.85rem;
  border: none;
  border-radius: 999px;
  background: var(--vault-trust-accent);
  color: var(--vault-trust-on-accent);
  font: 600 0.8rem var(--vault-font);
  letter-spacing: 0.01em;
  box-shadow: var(--vault-shadow-pop);
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.15s ease;
}

.vault-editor-leave svg { width: 17px; height: 17px; flex-shrink: 0; }

.vault-editor-leave:hover {
  background: var(--vault-trust-accent-hover);
  transform: translateY(-1px);
}

.vault-editor-leave:focus-visible {
  outline: 2px solid var(--vault-trust-accent-deep);
  outline-offset: 2px;
}

.vault-editor-leave.armed {
  background: var(--vault-trust-accent-deep);
  animation: vault-leave-pulse 1.2s ease-in-out infinite;
}

@keyframes vault-leave-pulse {
  0%, 100% { box-shadow: var(--vault-shadow-pop), 0 0 0 0 rgba(196, 66, 26, 0.45); }
  50% { box-shadow: var(--vault-shadow-pop), 0 0 0 7px rgba(196, 66, 26, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .vault-editor-leave.armed { animation: none; }
  .vault-editor-leave:hover { transform: none; }
}

/* ------------------------------------------------------------ session-ended
   Full-viewport interstitial shown when a restored tab points at a dead
   co-editing session (editor-session.js). Sits above the presence pill and
   chat fab; the editor iframe is destroyed before it appears. */

.vault-session-ended {
  position: fixed;
  inset: 0;
  z-index: 2147483200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--vault-frame);
  font-family: var(--vault-font);
  color: var(--vault-ink);
}

.vault-session-ended[hidden] { display: none; }

.vault-session-ended-card {
  max-width: 27rem;
  width: 100%;
  padding: 2.5rem 2.5rem 2rem;
  border-radius: 16px;
  background: var(--vault-surface);
  box-shadow: var(--vault-shadow-pop);
  text-align: center;
  animation: vault-live-enter 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.vault-session-ended-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto 1.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--vault-tint);
  color: var(--vault-accent);
}

.vault-session-ended-icon svg { width: 28px; height: 28px; }

.vault-session-ended-card h1 {
  margin: 0 0 0.35rem;
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.vault-session-ended-file {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--vault-accent);
  overflow-wrap: anywhere;
}

.vault-session-ended-sub {
  margin: 0 0 1.5rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--vault-ink-2);
}

.vault-session-ended-actions {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.vault-session-ended-primary,
.vault-session-ended-secondary {
  width: 100%;
  padding: 0.65rem 1rem;
  border-radius: 999px;
  font: 600 0.875rem var(--vault-font);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.vault-session-ended-primary {
  border: none;
  background: var(--vault-accent);
  color: var(--vault-accent-ink);
}

.vault-session-ended-primary:hover { background: var(--vault-accent-hover); transform: translateY(-1px); }

.vault-session-ended-secondary {
  border: 1px solid var(--vault-line-strong);
  background: transparent;
  color: var(--vault-ink);
}

.vault-session-ended-secondary:hover { background: var(--vault-hover); }

.vault-session-ended-primary:focus-visible,
.vault-session-ended-secondary:focus-visible {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
}

.vault-session-ended-count {
  margin: 1.1rem 0 0;
  font-size: 0.78rem;
  color: var(--vault-ink-2);
}

.vault-session-ended-count[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .vault-session-ended-card { animation: none; }
  .vault-session-ended-primary:hover { transform: none; }
}

/* ------------------------------------------------------------ idle warning
   Countdown overlay before auto-logout (idle-watcher.js). Bespoke — it must
   render on both the bootstrap layout and the bootstrap-less editor page.
   Sits above everything, including the session-ended interstitial. */

.vault-idle-overlay {
  position: fixed;
  inset: 0;
  z-index: 2147483300;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(8, 47, 40, 0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-family: var(--vault-font);
}

.vault-idle-overlay.show { display: flex; }

.vault-idle-card {
  max-width: 25rem;
  width: 100%;
  padding: 2.25rem 2.25rem 2rem;
  border-radius: 16px;
  background: var(--vault-surface);
  color: var(--vault-ink);
  box-shadow: var(--vault-shadow-pop);
  text-align: center;
  animation: vault-live-enter 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.vault-idle-icon {
  width: 52px;
  height: 52px;
  margin: 0 auto 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--vault-warning-soft);
  color: var(--vault-warning);
}

.vault-idle-icon svg { width: 26px; height: 26px; }

.vault-idle-card h2 {
  margin: 0 0 0.4rem;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.vault-idle-card p {
  margin: 0 0 1.4rem;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--vault-ink-2);
}

.vault-idle-card p strong {
  color: var(--vault-ink);
  font-variant-numeric: tabular-nums;
}

.vault-idle-actions {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.vault-idle-stay,
.vault-idle-out {
  width: 100%;
  padding: 0.62rem 1rem;
  border-radius: 999px;
  font: 600 0.875rem var(--vault-font);
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.15s ease;
}

.vault-idle-stay {
  border: none;
  background: var(--vault-accent);
  color: var(--vault-accent-ink);
}

.vault-idle-stay:hover { background: var(--vault-accent-hover); transform: translateY(-1px); }

.vault-idle-out {
  border: 1px solid var(--vault-line-strong);
  background: transparent;
  color: var(--vault-ink);
}

.vault-idle-out:hover { background: var(--vault-hover); }

.vault-idle-stay:focus-visible,
.vault-idle-out:focus-visible {
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .vault-idle-card { animation: none; }
  .vault-idle-stay:hover { transform: none; }
}

@keyframes vault-live-ping {
  0% { transform: scale(0.4); opacity: 0.8; }
  80%, 100% { transform: scale(1.3); opacity: 0; }
}

@keyframes vault-live-enter {
  from { transform: scale(0.6); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

@keyframes vault-live-row-flash {
  0% { background-color: rgba(73, 213, 178, 0.28); }
  100% { background-color: transparent; }
}

@keyframes vault-live-halo {
  0% { box-shadow: 0 0 0 0 rgba(73, 213, 178, 0.7); }
  100% { box-shadow: 0 0 0 12px rgba(73, 213, 178, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .vault-live-chip,
  .vault-editor-presence.bump { animation: none; }
  .vault-live-dot::after { animation: none; opacity: 0; }
  .vault-live-toast .vault-avatar { animation: none; }
  .library-row.live-flash > td { animation: none; }
  .vault-live-toast { transition: opacity 0.2s ease; transform: none; }
}

/* ============================================================ v2.2 file-type icons
   Windows-style branded SVG sprite (img/file-type-icons.svg). Sizes only —
   colors live inside the sprite because they are app brands, not theme. */

.vault-ficon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  vertical-align: -0.32em;
}

.vault-ficon-16 { width: 16px; height: 16px; vertical-align: -0.22em; }
.vault-ficon-18 { width: 18px; height: 18px; vertical-align: -0.26em; }
.vault-ficon-28 { width: 28px; height: 28px; }
.vault-ficon-42 { width: 42px; height: 42px; }

/* Grid thumbnails. The slot holds a fixed height whether it contains the
   file-type icon or a rendered preview, so tiles keep a single baseline and
   a preview arriving late never shifts the grid. */
.vault-thumb-slot {
    align-items: center;
    height: 84px;
}

.vault-thumb {
    max-width: 100%;
    max-height: 84px;
    border-radius: var(--vault-radius-sm, 6px);
    /* Contain, not cover: a document preview cropped to fill would cut off the
       very header text that makes it recognisable. */
    object-fit: contain;
    box-shadow: 0 1px 3px rgb(0 0 0 / 12%);
}

/* ============================================================================
   Public authentication: Living Vault arrival experience.
   ========================================================================== */

.vault-auth::before,
.vault-auth::after {
  content: "";
  position: fixed;
  z-index: 0;
  border-radius: 50%;
  pointer-events: none;
  filter: blur(72px);
}

.vault-auth::before {
  width: 420px;
  height: 420px;
  top: -180px;
  right: -100px;
  background: color-mix(in srgb, var(--vault-trust-accent) 10%, transparent);
}

.vault-auth::after {
  width: 340px;
  height: 340px;
  bottom: -170px;
  left: -100px;
  background: color-mix(in srgb, var(--vault-trust-success) 7%, transparent);
}

.vault-auth-card {
  position: relative;
  z-index: 1;
  background: var(--vault-trust-surface);
  border: 0;
  border-radius: 16px;
  box-shadow: 0 12px 32px rgba(37, 33, 31, 0.10);
  animation: none;
}

.vault-auth .btn { text-transform: none; }

.vault-auth-card.vault-auth-split {
  width: min(1040px, 100%);
  max-width: 1040px;
  display: grid;
  grid-template-areas: "visual form";
  grid-template-columns: minmax(0, 1.3fr) minmax(400px, 0.95fr);
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 16px;
  background: var(--vault-trust-surface);
  box-shadow: 0 12px 32px rgba(37, 33, 31, 0.10);
}

.vault-auth-form {
  grid-area: form;
  min-width: 0;
  align-self: center;
  padding: 3rem 3rem 2.5rem;
  color: var(--vault-trust-ink);
  font-size: 1rem;
}

.vault-auth-form .vault-auth-brand { margin-bottom: 2rem; }
.vault-auth-form .app-brand-text { font-size: 1.25rem; letter-spacing: -0.015em; }
.vault-auth-form h1 {
  margin: 0 0 0.625rem;
  color: var(--vault-trust-ink);
  font-size: 2rem;
  line-height: 1.15;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.vault-auth-sub {
  max-width: 38ch;
  margin: 0 0 1.75rem;
  color: var(--vault-trust-muted);
  font-size: 1rem;
  line-height: 1.55;
  text-wrap: pretty;
}

.vault-auth-alert {
  margin-bottom: 1.25rem;
  padding: 0.75rem 1rem;
  border: 0;
  border-radius: 10px;
  font-size: 0.9375rem;
}

.vault-auth .validation-summary-valid { display: none; }
.vault-auth-method-intro,
.vault-auth-method-note {
  color: var(--vault-trust-muted);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.vault-auth-method-intro { margin: 0 0 1.25rem; }
.vault-auth-method-note {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0.75rem 0 0;
}
.vault-auth-method-note i { margin-top: 0.2rem; color: var(--vault-trust-accent); }

.vault-auth-field { margin-bottom: 1.25rem; }
.vault-auth-field .form-label {
  margin-bottom: 0.5rem;
  color: var(--vault-trust-ink);
  font-size: 0.9375rem;
  font-weight: 600;
}
.vault-auth-label-row {
  min-height: var(--vault-tap);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.vault-auth-label-row .form-label { margin-bottom: 0; }
.vault-auth-input-wrap { position: relative; }
.vault-auth-input-wrap > i {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 1rem;
  color: var(--vault-trust-muted);
  font-size: 1.125rem;
  pointer-events: none;
  transform: translateY(-50%);
}
.vault-auth-input-wrap .form-control {
  min-height: 50px;
  padding-left: 2.75rem;
  border: 1px solid var(--vault-trust-line);
  border-radius: 10px;
  background: var(--vault-trust-surface);
  color: var(--vault-trust-ink);
  font-size: 1rem;
  box-shadow: none;
}
.vault-auth-input-wrap .form-control:focus-visible {
  border-color: var(--vault-trust-accent);
  outline: 2px solid color-mix(in srgb, var(--vault-trust-accent) 52%, transparent);
  outline-offset: 2px;
  box-shadow: none;
}
.vault-auth-input-wrap:has(.vault-password-toggle) .form-control { padding-right: 3rem; }
.vault-field-error { display: block; margin-top: 0.375rem; font-size: 0.9375rem; }

.vault-auth-primary {
  min-height: 50px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 1px solid var(--vault-trust-accent);
  border-radius: 10px;
  background: var(--vault-trust-accent);
  color: var(--vault-trust-surface);
  font-size: 1rem;
  font-weight: 650;
  text-transform: none;
  box-shadow: none;
  transition: background-color var(--vault-fast) var(--vault-ease), border-color var(--vault-fast) var(--vault-ease), transform var(--vault-fast) var(--vault-ease);
}
.vault-auth-primary:hover { border-color: var(--vault-trust-accent-hover); background: var(--vault-trust-accent-hover); color: var(--vault-trust-surface); transform: translateY(-1px); }
.vault-auth-primary:active { transform: translateY(0); }
.vault-auth-primary:focus-visible,
.vault-auth-mode-switch:focus-visible,
.vault-password-toggle:focus-visible,
.vault-auth-recovery:focus-visible {
  outline: 2px solid var(--vault-trust-accent);
  outline-offset: 3px;
  box-shadow: none;
}

.vault-auth-mode-switch {
  width: 100%;
  min-height: var(--vault-tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  padding: 0.5rem 0.75rem;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--vault-trust-ink);
  font-size: 0.9375rem;
  font-weight: 550;
  text-transform: none;
}
.vault-auth-mode-switch:hover { background: color-mix(in srgb, var(--vault-trust-accent) 7%, transparent); color: var(--vault-trust-accent-deep); }
.vault-password-form { padding-top: 0; }
.vault-password-toggle {
  position: absolute;
  z-index: 2;
  top: 1px;
  right: 1px;
  width: 48px;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--vault-trust-muted);
}
.vault-password-toggle:hover { color: var(--vault-trust-ink); }
.vault-auth-recovery { min-height: var(--vault-tap); display: inline-flex; align-items: center; color: var(--vault-trust-success); font-size: 0.9375rem; font-weight: 550; }
.vault-auth-onboarding { display: flex; align-items: flex-start; gap: 0.5rem; margin: 1.5rem 0 0; color: var(--vault-trust-muted); font-size: 0.9375rem; line-height: 1.5; }
.vault-auth-onboarding i { margin-top: 0.2rem; color: var(--vault-trust-success); }

.vault-trust-visual {
  position: relative;
  grid-area: visual;
  min-width: 0;
  min-height: 650px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 3rem;
  overflow: hidden;
  color: var(--vault-trust-surface);
  background: var(--vault-trust-accent);
}
.vault-trust-visual::before { content: ""; position: absolute; width: 420px; height: 420px; right: -220px; bottom: -170px; border-radius: 50%; background: color-mix(in srgb, var(--vault-trust-surface) 10%, transparent); pointer-events: none; }
.vault-trust-copy { position: relative; z-index: 2; max-width: 34rem; }
.vault-trust-context { color: var(--vault-trust-on-accent); font-size: 0.875rem; font-weight: 600; }
.vault-trust-copy h2 { max-width: 15ch; margin: 0.625rem 0 0.875rem; color: var(--vault-trust-surface); font-size: 2.25rem; line-height: 1.12; letter-spacing: -0.03em; text-wrap: balance; }
.vault-trust-copy p { max-width: 42ch; margin: 0; color: var(--vault-trust-on-accent); font-size: 1rem; line-height: 1.55; text-wrap: pretty; }

.vault-living-scene { position: relative; z-index: 2; min-height: 330px; margin: 1.75rem 0; }
.vault-living-path { position: absolute; top: 0; left: 0; display: flex; align-items: center; gap: 0.4rem; color: var(--vault-trust-on-accent); font-size: 0.8125rem; }
.vault-living-file { position: absolute; top: 56px; left: 50%; width: min(390px, 88%); min-height: 184px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0.875rem; padding: 1.25rem; border: 1px solid color-mix(in srgb, var(--vault-trust-surface) 36%, transparent); border-radius: 14px; background: color-mix(in srgb, var(--vault-trust-surface) 14%, transparent); transform: translateX(-50%); }
.vault-living-file-icon { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 12px; background: var(--vault-trust-surface); color: var(--vault-trust-accent); font-size: 1.35rem; }
.vault-living-file-copy { min-width: 0; display: grid; gap: 0.25rem; }
.vault-living-file-copy strong { overflow: hidden; color: var(--vault-trust-surface); font-size: 0.9375rem; text-overflow: ellipsis; white-space: nowrap; }
.vault-living-file-copy span { color: var(--vault-trust-on-accent); font-size: 0.8125rem; }
.vault-living-version { align-self: start; padding: 0.3rem 0.5rem; border-radius: 999px; background: var(--vault-trust-surface); color: var(--vault-trust-accent-deep); font-size: 0.75rem; font-weight: 700; }
.vault-living-share-row { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-top: 1rem; border-top: 1px solid color-mix(in srgb, var(--vault-trust-surface) 28%, transparent); color: var(--vault-trust-on-accent); font-size: 0.8125rem; }
.vault-living-avatars { display: flex; align-items: center; }
.vault-living-avatars span { width: 30px; height: 30px; display: grid; place-items: center; margin-left: -6px; border: 2px solid var(--vault-trust-accent); border-radius: 50%; background: var(--vault-trust-surface); color: var(--vault-trust-accent-deep); font-size: 0.625rem; font-weight: 700; }
.vault-living-avatars span:first-child { margin-left: 0; }
.vault-living-history { position: absolute; left: 4%; right: 4%; bottom: 8px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; }
.vault-living-history span { min-width: 0; display: flex; align-items: center; gap: 0.35rem; color: var(--vault-trust-on-accent); font-size: 0.75rem; }
.vault-living-history .is-current { color: var(--vault-trust-surface); font-weight: 650; }
.vault-living-access { position: absolute; z-index: 3; right: 0; bottom: 50px; min-height: var(--vault-tap); display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.625rem 0.75rem; border-radius: 10px; background: var(--vault-trust-surface); color: var(--vault-trust-success); font-size: 0.8125rem; font-weight: 700; }
.vault-living-trust-note { position: relative; z-index: 2; display: flex; align-items: center; gap: 0.45rem; margin: 0; color: var(--vault-trust-on-accent); font-size: 0.8125rem; }

@media (prefers-reduced-motion: no-preference) {
  .vault-living-file { animation: vault-living-settle 6.4s var(--vault-ease) infinite; }
  .vault-living-version { animation: vault-living-version-step 6.4s var(--vault-ease) infinite; }
  .vault-living-access { animation: vault-living-access-confirm 6.4s var(--vault-ease) infinite; }
}
@keyframes vault-living-settle { 0%, 8% { transform: translate3d(calc(-50% - 18px), 10px, 0); opacity: 0.82; } 11%, 100% { transform: translate3d(-50%, 0, 0); opacity: 1; } }
@keyframes vault-living-version-step { 0%, 28% { transform: scale(0.92); opacity: 0.58; } 31%, 100% { transform: scale(1); opacity: 1; } }
@keyframes vault-living-access-confirm { 0%, 48% { transform: translateY(8px); opacity: 0.72; } 51%, 100% { transform: translateY(0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .vault-auth *, .vault-auth *::before, .vault-auth *::after { scroll-behavior: auto !important; animation: none !important; transition-duration: 0.01ms !important; }
  .vault-living-file, .vault-living-version, .vault-living-access { opacity: 1; }
}

.vault-auth-card-compact { width: min(456px, 100%); max-width: 456px; padding: 2.75rem 2.5rem 2.25rem; border: 0; background: var(--vault-trust-surface); box-shadow: 0 12px 32px rgba(37, 33, 31, 0.10); }
.vault-auth-card-compact.text-center .vault-auth-brand { justify-content: center; }
.vault-auth-card-compact.text-center .vault-auth-sub { margin-inline: auto; }
.vault-auth-state-icon { width: 52px; height: 52px; display: inline-grid; place-items: center; margin-bottom: 1.25rem; border-radius: 14px; background: var(--vault-trust-danger-soft); color: var(--vault-trust-accent); font-size: 1.5rem; }
.vault-auth-state-icon.is-success { background: var(--vault-trust-success-soft); color: var(--vault-trust-success); }
.vault-auth-state-icon.is-warning { background: var(--vault-trust-warning-soft); color: var(--vault-trust-warning); }
.vault-auth-state-icon.is-error { background: var(--vault-trust-danger-soft); color: var(--vault-trust-danger); }
.vault-auth-actions .btn, .vault-auth-actions .form-control { min-height: var(--vault-tap); text-transform: none; }
.vault-code-boxes { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0.5rem; }
.vault-code-digit { width: 100%; min-width: 0; height: 56px; font-size: 1.5rem; font-variant-numeric: tabular-nums; }

@media (max-height: 800px) and (min-width: 992px) {
  .vault-auth-form { padding-block: 2.25rem; }
  .vault-trust-visual { min-height: 590px; padding-block: 2.25rem; }
  .vault-living-scene { min-height: 285px; margin-block: 1rem; }
  .vault-living-file { top: 40px; }
}
@media (max-width: 991.98px) {
  .vault-auth-card.vault-auth-split { width: min(560px, 100%); max-width: 560px; grid-template-areas: "visual" "form"; grid-template-columns: minmax(0, 1fr); }
  .vault-trust-visual { min-height: 156px; padding: 2rem 2.25rem; }
  .vault-trust-copy h2 { max-width: 22ch; margin-bottom: 0.625rem; font-size: 1.75rem; }
  .vault-trust-copy p { max-width: 46ch; font-size: 0.9375rem; }
  .vault-living-scene { display: none; }
  .vault-living-trust-note { margin-top: 1rem; }
  .vault-auth-form { padding: 2.5rem 2.25rem 2rem; }
}
@media (max-width: 575.98px) {
  .vault-auth-page { padding: 0.75rem; }
  .vault-auth-card.vault-auth-split { border-radius: 14px; }
  .vault-trust-visual { min-height: 136px; padding: 1.5rem 1.25rem; }
  .vault-trust-copy h2 { font-size: 1.5rem; }
  .vault-trust-copy p, .vault-living-trust-note { display: none; }
  .vault-auth-form { padding: 2rem 1.25rem 1.5rem; }
}
@media (max-width: 479.98px) {
  .vault-auth-card-compact { padding: 2rem 1.25rem 1.5rem; }
  .vault-code-boxes { gap: 0.35rem; }
  .vault-code-digit { height: 52px; font-size: 1.25rem; }
}

/* ============================================================================
   Collaboration motion login: readable type and a product-shaped system map.
   This is intentionally flat and warm; the visual earns its space by explaining
   how collaboration, storage, and access relate to one another.
   ========================================================================== */

.vault-auth-page.vault-auth-page {
  overflow: hidden;
  background: var(--vault-workspace-frame) !important;
}
.vault-auth:has(.vault-living-login)::before {
  background: color-mix(in srgb, var(--vault-workspace-accent) 10%, transparent);
}
.vault-auth:has(.vault-living-login)::after {
  background: color-mix(in srgb, var(--vault-pulse) 9%, transparent);
}

/* Every other auth step (code entry, password sign-in fallback, password
   reset, lockout, access-denied) matches the teal workspace accent instead of
   the rust trust-register default; the Living Vault login above keeps its own
   explicit teal override and is otherwise untouched. */
.vault-auth-page:not(:has(.vault-living-login)) {
  --vault-trust-accent: var(--vault-workspace-accent);
  --vault-trust-accent-hover: var(--vault-workspace-accent-hover);
  --vault-trust-accent-deep: var(--vault-workspace-accent-hover);
  --vault-accent-rgb: var(--vault-workspace-accent-rgb);
  --vault-tint: var(--vault-workspace-tint);
}
.vault-auth-page:not(:has(.vault-living-login)) .vault-auth-state-icon:not(.is-success):not(.is-warning):not(.is-error) {
  background: var(--vault-workspace-tint);
}

.vault-auth-card.vault-auth-split.vault-living-login {
  --vault-login-deep: var(--vault-workspace-deep);
  --vault-login-ink: var(--vault-workspace-ink);
  --vault-login-muted: var(--vault-workspace-muted);
  --vault-login-line: var(--vault-workspace-line);
  --vault-login-accent: var(--vault-workspace-accent);
  --vault-login-accent-rgb: var(--vault-workspace-accent-rgb);
  --vault-login-accent-hover: var(--vault-workspace-accent-hover);
  --vault-login-soft: var(--vault-workspace-tint);
  grid-template-areas: "form visual";
  grid-template-columns: 440px minmax(0, 1fr);
  width: min(1060px, 100%);
  max-width: 1060px;
  min-height: 650px;
  border: 1px solid rgba(255, 255, 255, 0.94);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 24px 64px rgba(8, 47, 40, 0.14);
}

.vault-living-login .vault-auth-form {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  min-height: 0;
  padding: 42px 40px 34px;
  background: rgba(255, 255, 255, 0.96);
}

.vault-living-login .vault-auth-brand { margin-bottom: 34px; }
.vault-living-login .vault-brand-glyph {
  width: 41px;
  height: 41px;
  border-radius: 12px;
  background: var(--vault-login-accent);
  box-shadow: 0 6px 14px rgba(var(--vault-login-accent-rgb), 0.2);
}
.vault-living-login .app-brand-text {
  color: var(--vault-login-deep);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -0.02em;
}
.vault-living-login .vault-auth-heading h1 {
  margin-bottom: 9px;
  font-size: 31px;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.14;
  color: var(--vault-login-ink);
}
.vault-living-login .vault-auth-sub {
  max-width: 345px;
  margin-bottom: 29px;
  font-size: 0.90625rem;
  line-height: 1.6;
  color: var(--vault-login-muted);
}

.vault-living-login .vault-auth-field {
  position: relative;
  margin-bottom: 17px;
}
.vault-living-login .vault-auth-field > .form-label {
  position: absolute;
  z-index: 3;
  top: 8px;
  left: 14px;
  margin: 0;
  color: var(--vault-login-muted);
  font-size: 10.5px;
  font-weight: 750;
  pointer-events: none;
}
.vault-living-login .vault-auth-label-row {
  min-height: var(--vault-tap);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.vault-living-login .vault-auth-label-row .form-label {
  margin: 0;
  color: var(--vault-login-ink);
}
.vault-living-login .vault-auth-label-row + .vault-auth-input-wrap .form-control {
  padding: 0 48px 0 14px;
}
.vault-living-login .vault-auth-input-wrap > i { display: none; }
.vault-living-login .vault-auth-input-wrap .form-control {
  width: 100%;
  min-height: 54px;
  height: 54px;
  padding: 20px 14px 6px;
  border: 1px solid var(--vault-login-line);
  border-radius: 11px;
  background: #fff;
  color: var(--vault-login-ink);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  outline: none;
}
.vault-living-login .vault-auth-input-wrap .form-control:focus-visible {
  border-color: var(--vault-login-accent);
  box-shadow: 0 0 0 3px rgba(var(--vault-login-accent-rgb), 0.12);
  outline: none;
}
.vault-living-login .vault-field-error { margin-top: 0.4rem; }
.vault-living-login .vault-auth-primary {
  width: 100%;
  min-height: 49px;
  height: 49px;
  border: 0;
  border-radius: 11px;
  background: var(--vault-login-accent);
  box-shadow: 0 6px 14px rgba(var(--vault-login-accent-rgb), 0.18);
  font-size: 0.84375rem;
  font-weight: 800;
  text-transform: none;
}
.vault-living-login .vault-auth-primary:hover { background: var(--vault-login-accent-hover); }

.vault-reference-divider {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 22px 0 12px;
  color: var(--vault-login-muted);
  font-size: 0.71875rem;
}
.vault-reference-divider::before,
.vault-reference-divider::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--vault-login-line);
}
.vault-reference-divider span { flex: 0 0 auto; }
.vault-living-login .vault-auth-password-trigger {
  width: 100%;
  min-height: 48px;
  margin-top: 0;
  border: 1px solid var(--vault-login-line);
  border-radius: 10px;
  background: var(--vault-trust-surface);
  color: var(--vault-login-accent);
  font-size: 1rem;
  font-weight: 700;
}
.vault-living-login .vault-auth-password-trigger:hover { background: var(--vault-login-soft); color: var(--vault-login-accent-hover); }
.vault-living-login .vault-auth-mode-switch { color: var(--vault-login-ink); }
.vault-living-login .vault-auth-mode-switch:hover { background: var(--vault-login-soft); color: var(--vault-login-accent-hover); }
.vault-living-login .vault-auth-primary:focus-visible,
.vault-living-login .vault-auth-mode-switch:focus-visible,
.vault-living-login .vault-password-toggle:focus-visible,
.vault-living-login .vault-auth-recovery:focus-visible {
  outline-color: var(--vault-login-accent);
  box-shadow: none;
}
.vault-living-login .vault-password-toggle { color: var(--vault-login-muted); }
.vault-living-login .vault-password-toggle:hover,
.vault-living-login .vault-auth-recovery { color: var(--vault-login-accent); }
.vault-reference-key {
  position: relative;
  width: 14px;
  height: 14px;
  border: 1.8px solid currentColor;
  border-radius: 50%;
}
.vault-reference-key::after {
  content: "";
  position: absolute;
  top: 9px;
  left: 11px;
  width: 7px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: rotate(44deg);
  transform-origin: left center;
}
.vault-living-login .vault-auth-onboarding {
  display: block;
  margin: auto 0 0;
  padding-top: 24px;
  border-top: 1px solid var(--vault-login-line);
  color: var(--vault-login-muted);
  font-size: 0.875rem;
  line-height: 1.58;
  text-align: left;
}
.vault-living-login .vault-auth-onboarding strong { color: var(--vault-login-ink); font-weight: 800; }

.vault-living-login .vault-trust-visual.visual {
  position: relative;
  grid-area: visual;
  min-width: 0;
  min-height: 650px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 29px 25px 24px;
  border-left: 1px solid var(--vault-login-line);
  border-radius: 0;
  background: var(--vault-workspace-surface-inset);
  color: var(--vault-login-ink);
}
.vault-living-login .vault-trust-visual::before { display: none; }
.vault-living-login .visual-head {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 3px;
}
.vault-living-login .visual-title { color: var(--vault-login-ink); font-size: 0.8125rem; font-weight: 800; letter-spacing: -0.01em; }
.vault-living-login .visual-badge { display: flex; align-items: center; gap: 7px; padding: 7px 9px; border: 1px solid rgba(var(--vault-login-accent-rgb), 0.18); border-radius: 9px; background: rgba(255, 255, 255, 0.82); color: var(--vault-login-muted); font-size: 0.625rem; font-weight: 750; }
.vault-living-login .badge-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--vault-login-accent); box-shadow: 0 0 0 4px rgba(var(--vault-login-accent-rgb), 0.1); }
.vault-living-login .system { position: relative; z-index: 2; width: 100%; height: 455px; margin: auto 0 5px; }
.vault-living-login .paths { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; }
.vault-living-login .connector { fill: none; stroke-width: 1.5; stroke-dasharray: 4 7; }
.vault-living-login .rust-path { stroke: var(--vault-login-accent); stroke-opacity: 0.38; }
.vault-living-login .blue-path { stroke: var(--vault-folder); stroke-opacity: 0.42; }
.vault-living-login .teal-path { stroke: var(--vault-login-accent); stroke-opacity: 0.42; }
.vault-living-login .return-path { stroke: var(--vault-login-line); stroke-opacity: 0.9; }
.vault-living-login .orbit { fill: none; stroke: rgba(var(--vault-login-accent-rgb), 0.13); }
.vault-living-login .node { position: absolute; z-index: 2; width: 174px; min-height: 122px; padding: 15px; border: 1px solid var(--vault-login-line); border-radius: 15px; background: rgba(255, 255, 255, 0.96); box-shadow: 0 10px 23px rgba(8, 47, 40, 0.08); }
.vault-living-login .node h3 { margin: 11px 0 4px; color: var(--vault-login-ink); font-size: 0.8125rem; line-height: 1.2; letter-spacing: -0.015em; }
.vault-living-login .node p { margin: 0; color: var(--vault-login-muted); font-size: 0.6875rem; line-height: 1.4; }
.vault-living-login .collab { top: 67px; left: 0; }
.vault-living-login .storage { top: 55px; right: 0; }
.vault-living-login .access { right: 0; bottom: 12px; min-height: 118px; }
.vault-living-login .avatars { display: flex; }
.vault-living-login .avatar { display: grid; place-items: center; width: 30px; height: 30px; margin-right: -5px; border: 2px solid #fff; border-radius: 9px; font-size: 0.5rem; font-weight: 850; }
.vault-living-login .avatar.r { background: var(--vault-login-soft); color: var(--vault-login-accent); }
.vault-living-login .avatar.b { background: var(--vault-folder-soft, #deebff); color: #3f76cf; }
.vault-living-login .avatar.t { background: var(--vault-login-soft); color: var(--vault-login-accent); }
.vault-living-login .avatar.p { background: #eee5f7; color: #74598f; }
.vault-living-login .comment { position: absolute; top: 15px; right: 13px; display: grid; place-items: center; width: 28px; height: 24px; border-radius: 8px 8px 8px 3px; background: var(--vault-login-soft); color: var(--vault-login-accent); font-size: 0.9375rem; font-weight: 800; }
.vault-living-login .progress, .vault-living-login .storage-meter { height: 7px; margin-top: 11px; overflow: hidden; border-radius: 6px; background: #eee9e5; }
.vault-living-login .progress::after { content: ""; display: block; width: 62%; height: 100%; border-radius: inherit; background: color-mix(in srgb, var(--vault-login-accent) 42%, white); }
.vault-living-login .file-stack { position: relative; width: 82px; height: 43px; }
.vault-living-login .sheet { position: absolute; display: grid; place-items: center; width: 36px; height: 43px; border-radius: 7px; font-size: 0.5rem; font-weight: 850; }
.vault-living-login .sheet.one { top: 3px; left: 0; background: var(--vault-folder-soft, #deebff); color: #3973cc; transform: rotate(-4deg); }
.vault-living-login .sheet.two { top: 0; left: 28px; border: 1px solid var(--vault-login-line); background: #fff; color: var(--vault-login-accent); transform: rotate(3deg); }
.vault-living-login .upload { position: absolute; top: 3px; left: 73px; color: var(--vault-login-accent); font-size: 1.375rem; font-weight: 700; }
.vault-living-login .storage-meter { background: #e8efec; }
.vault-living-login .storage-meter::after { content: ""; display: block; width: 68%; height: 100%; border-radius: inherit; background: var(--vault-login-accent); }
.vault-living-login .shield-row { display: flex; align-items: center; gap: 10px; }
.vault-living-login .shield { display: grid; place-items: center; width: 34px; height: 37px; border-radius: 14px 14px 17px 17px; background: var(--vault-login-soft); color: var(--vault-login-accent); font-size: 1.0625rem; font-weight: 900; }
.vault-living-login .access-copy strong { display: block; color: var(--vault-login-ink); font-size: 0.6875rem; }
.vault-living-login .access-copy span { color: var(--vault-login-muted); font-size: 0.625rem; }
.vault-living-login .roles { display: flex; gap: 6px; margin-top: 12px; }
.vault-living-login .role { padding: 5px 8px; border-radius: 6px; font-size: 0.53125rem; font-weight: 800; }
.vault-living-login .role.edit { background: var(--vault-login-soft); color: var(--vault-login-accent-hover); }
.vault-living-login .role.view { background: var(--vault-folder-soft, #deebff); color: #386fc5; }
.vault-living-login .hub { position: absolute; top: 51%; left: 50%; z-index: 3; width: 178px; height: 158px; padding: 18px; border-radius: 22px; background: var(--vault-login-accent); box-shadow: 0 18px 30px rgba(var(--vault-login-accent-rgb), 0.22); color: #fff; transform: translate(-50%, -50%); }
.vault-living-login .hub-kicker { color: rgba(255, 255, 255, 0.78); font-size: 0.5625rem; font-weight: 850; letter-spacing: 0.07em; text-transform: uppercase; }
.vault-living-login .folder { position: relative; width: 71px; height: 47px; margin: 14px 0 13px; border-radius: 9px; background: #fff; }
.vault-living-login .folder::before { content: ""; position: absolute; top: -8px; left: 6px; width: 29px; height: 10px; border-radius: 5px 5px 0 0; background: #fff; }
.vault-living-login .folder-lines { position: absolute; top: 17px; left: 14px; width: 42px; }
.vault-living-login .folder-lines i { display: block; height: 4px; margin-bottom: 6px; border-radius: 3px; background: color-mix(in srgb, var(--vault-login-accent) 48%, white); }
.vault-living-login .folder-lines i:last-child { width: 70%; background: color-mix(in srgb, var(--vault-login-accent) 28%, white); }
.vault-living-login .hub h3 { margin: 0 0 3px; color: #fff; font-size: 0.875rem; letter-spacing: -0.015em; }
.vault-living-login .hub p { margin: 0; color: rgba(255, 255, 255, 0.82); font-size: 0.625rem; }
.vault-living-login .hub-check { position: absolute; top: 55px; right: 17px; display: grid; place-items: center; width: 46px; height: 46px; border: 3px solid color-mix(in srgb, var(--vault-login-accent) 26%, white); border-radius: 50%; background: #fff; color: var(--vault-login-accent); font-size: 1.4375rem; font-weight: 900; }
.vault-living-login .status-line { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.vault-living-login .status { display: flex; align-items: center; gap: 8px; padding: 10px 9px; border: 1px solid var(--vault-login-line); border-radius: 9px; background: rgba(255, 255, 255, 0.78); color: var(--vault-login-muted); font-size: 0.625rem; font-weight: 750; }
.vault-living-login .status i { width: 7px; height: 7px; flex: 0 0 7px; border-radius: 50%; background: var(--vault-login-line); }
.vault-living-login .caption { margin: 11px 0 0; color: var(--vault-login-muted); font-size: 0.6875rem; line-height: 1.48; text-align: center; }

@media (prefers-reduced-motion: no-preference) {
  .vault-living-login { animation: vault-collab-rise 260ms cubic-bezier(0.2, 0, 0, 1); }
  .vault-living-login .connector { animation: vault-collab-flow 18s linear infinite; }
  .vault-living-login .packet { filter: drop-shadow(0 2px 4px rgba(30, 35, 33, 0.22)); }
  .vault-living-login .hub-check { animation: vault-collab-verified 8s ease-in-out infinite; }
  .vault-living-login .comment { animation: vault-collab-comment 6s ease-in-out infinite; }
  .vault-living-login .sheet.two { animation: vault-collab-file 7s ease-in-out infinite; }
  .vault-living-login .s1 i { animation: vault-collab-step 8s 0s ease-in-out infinite; }
  .vault-living-login .s2 i { animation: vault-collab-step 8s 2.65s ease-in-out infinite; }
  .vault-living-login .s3 i { animation: vault-collab-step 8s 5.3s ease-in-out infinite; }
}
@keyframes vault-collab-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes vault-collab-flow { to { stroke-dashoffset: -190; } }
@keyframes vault-collab-verified { 0%, 48%, 100% { opacity: 0.45; transform: scale(0.88); } 58%, 78% { opacity: 1; transform: scale(1); } }
@keyframes vault-collab-comment { 0%, 100% { transform: translateY(0); } 45%, 60% { transform: translateY(-4px); } }
@keyframes vault-collab-file { 0%, 100% { transform: translateY(0) rotate(3deg); } 50% { transform: translateY(-4px) rotate(3deg); } }
@keyframes vault-collab-step { 0%, 20%, 100% { background: var(--vault-login-line); box-shadow: none; } 4%, 14% { background: var(--vault-login-accent); box-shadow: 0 0 0 4px rgba(var(--vault-login-accent-rgb), 0.1); } }
@media (prefers-reduced-motion: reduce) {
  .vault-living-login, .vault-living-login *, .vault-living-login *::before, .vault-living-login *::after { animation: none !important; transition: none !important; }
  .vault-living-login .moving-packet { display: none; }
}
@media (max-width: 1120px) {
  .vault-auth-page.vault-auth-page { overflow: auto; padding: 20px; }
  .vault-auth-card.vault-auth-split.vault-living-login { grid-template-areas: "form"; grid-template-columns: 1fr; width: min(460px, 100%); max-width: 460px; min-height: 0; }
  .vault-living-login .vault-trust-visual.visual { display: none; }
  .vault-living-login .vault-auth-form { min-height: 620px; }
}
@media (max-width: 575.98px) {
  .vault-auth-page.vault-auth-page { padding: 12px; }
  .vault-living-login .vault-auth-form { padding: 34px 24px 28px; }
}

/* Short screens, full width. The generic max-height:800px tier cannot reach the
   living-login skin - every measurement it wants to change is set at
   .vault-living-login specificity - and it was drawn for a ~900px window
   besides. On a 1366x768 laptop the browser leaves roughly 630px of page while
   the card stood at 707px, so the sign-in button fell below the fold and the
   whole page scrolled. The 780px cut-off is just above the height at which the
   full-size layout stops fitting (~762px), so there is no gap between the two.

   This is vertical rhythm only: nothing moves horizontally, no type drops below
   its readable size, and the illustration keeps its place. The 650px floor on
   the visual is the single biggest offender - it held the card tall even when
   the form beside it was short. */
@media (max-height: 780px) and (min-width: 1121px) {
  .vault-auth-page.vault-auth-page { padding: 8px; }

  /* The floor that actually pinned the card. Everything below is wasted effort
     while this stands: the card holds 650px however short its contents are. */
  .vault-auth-card.vault-auth-split.vault-living-login { min-height: 0; }
  .vault-auth-legal { padding-top: 8px; font-size: 0.75rem; }

  .vault-living-login .vault-auth-form { padding: 18px 40px 16px; }
  .vault-living-login .vault-auth-brand { margin-bottom: 12px; }
  .vault-living-login .vault-brand-glyph { width: 36px; height: 36px; }
  .vault-living-login .vault-auth-heading h1 { margin-bottom: 4px; font-size: 24px; }
  .vault-living-login .vault-auth-sub { margin-bottom: 12px; }

  /* Fields carry the rest: four gaps of 17px is a lot of air on a short screen. */
  .vault-living-login .vault-auth-field { margin-bottom: 10px; }
  .vault-living-login .vault-auth-mode-switch { margin-top: 8px; padding-block: 8px; }
  .vault-living-login .vault-auth-onboarding { margin-top: 10px; padding-top: 10px; }
  .vault-living-login .vault-auth-divider { margin-block: 8px; }

  .vault-living-login .vault-trust-visual.visual { min-height: 0; padding: 16px 25px 14px; }
  .vault-living-scene { min-height: 190px; margin-block: 0.375rem; }
}

/* ============================================================ v2.2 session chat
   Overlay on the ONLYOFFICE editor page (standalone: no Bootstrap, no icon
   font — inline SVG + these rules only). Messenger-grade: bubbles, day chips,
   replies, reactions, receipts, typing, voice notes, huddle strip. */

.vault-chat-fab {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 2147483000;
  width: 58px;
  height: 58px;
  border: 0;
  border-radius: 50%;
  background: var(--vault-deep);
  color: #fff;
  box-shadow: var(--vault-shadow-pop);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1), background-color 160ms ease;
}

.vault-chat-fab svg { width: 24px; height: 24px; }
.vault-chat-fab:hover { background: var(--vault-dark-hover); }
.vault-chat-fab[aria-expanded="true"] { background: var(--vault-accent); color: var(--vault-accent-ink); }
.vault-chat-fab:active, .vault-chat-send:active { transform: scale(0.97); }

.vault-chat-fab-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 21px;
  height: 21px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--vault-danger);
  color: #fff;
  font: 700 0.7rem/21px var(--vault-font);
  text-align: center;
  animation: vault-chat-badge-in 180ms ease;
}

@keyframes vault-chat-badge-in {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: none; }
}

.vault-chat-fab-live {
  position: absolute;
  bottom: 1px;
  right: 1px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--vault-pulse);
  border: 2px solid var(--vault-deep);
}

/* The join/leave toast stack shares the bottom-right corner with the FAB. */
.vault-has-chat .vault-live-stack { bottom: 6.25rem; }

.vault-chat-panel {
  position: fixed;
  top: 0.9rem;
  right: 0.9rem;
  bottom: 0.9rem;
  z-index: 2147483000;
  width: min(420px, calc(var(--vault-screen-w) - 1.8rem));
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  background: var(--vault-frame);
  box-shadow: 0 6px 40px rgba(8, 47, 40, 0.28);
  font-family: var(--vault-font);
  overflow: hidden;
  opacity: 1;
  transform: none;
  transition: none;
}

.vault-chat-panel.open { opacity: 1; }

.vault-chat-panel.vault-chat-animating {
  will-change: transform, clip-path, opacity, box-shadow;
  backface-visibility: hidden;
}

.vault-chat-panel.vault-chat-closing { pointer-events: none; }
.vault-chat-panel.vault-chat-fade { transition: opacity 150ms ease; }
.vault-chat-panel[hidden] { display: none; }

.vault-chat-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 64px;
  padding: 0.75rem 0.85rem 0.75rem 1rem;
  background: var(--vault-deep);
  color: #fff;
}

.vault-chat-head-id { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.vault-chat-head-id strong { font-size: 1.0625rem; line-height: 1.25; }
.vault-chat-subtitle {
  margin-top: 0.15rem;
  font-size: 0.8125rem;
  opacity: 0.72;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vault-chat-iconbtn {
  flex-shrink: 0;
  width: var(--vault-tap);
  height: var(--vault-tap);
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 150ms ease, transform 120ms ease;
}

.vault-chat-iconbtn svg { width: 20px; height: 20px; }
.vault-chat-iconbtn:hover { background: rgba(255, 255, 255, 0.14); }
.vault-chat-iconbtn:active { transform: scale(0.97); }

/* ------------------------------------------------------------- huddle strip */
.vault-huddle-strip {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "status actions" "peers peers";
  gap: 0.55rem 0.75rem;
  padding: 0.65rem 0.85rem;
  background: var(--vault-tint);
  color: var(--vault-ink);
  border-bottom: 1px solid var(--vault-line);
}

.vault-huddle-strip[hidden] { display: none; }
.vault-huddle-status { grid-area: status; display: flex; align-items: center; min-width: 0; gap: 0.5rem; }
.vault-huddle-actions { grid-area: actions; display: flex; align-items: center; gap: 0.3rem; }
.vault-huddle-peers { grid-area: peers; min-height: 32px; display: flex; align-items: center; gap: 0.3rem; flex-wrap: wrap; }

.vault-huddle-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--vault-pulse); box-shadow: 0 0 0 4px rgba(var(--vault-accent-rgb), .10); }
.vault-huddle-live-copy { display: flex; min-width: 66px; flex-direction: column; line-height: 1.15; }
.vault-huddle-live-copy strong { font-size: 0.8125rem; }
.vault-huddle-live-copy span { margin-top: 0.15rem; color: var(--vault-ink-2); font-size: 0.75rem; }
.vault-huddle-meter { display: inline-flex; align-items: center; gap: 3px; width: 58px; height: 28px; }
.vault-huddle-meter[hidden] { display: none; } /* explicit display would otherwise defeat the hidden attribute */
.vault-huddle-meter-bar { width: 4px; height: 24px; border-radius: 999px; background: var(--vault-accent); transform: scaleY(.08); transform-origin: center; transition: transform 70ms linear; }
@media (prefers-reduced-motion: reduce) {
  .vault-huddle-meter-bar { transition: none; transform: scaleY(.28) !important; }
}

.vault-huddle-peer { position: relative; display: inline-flex; }
.vault-huddle-peer .vault-avatar { width: 30px; height: 30px; font-size: 0.7rem; border: 2px solid var(--vault-tint); }
.vault-huddle-peer.speaking .vault-avatar { box-shadow: 0 0 0 3px var(--vault-pulse); }

.vault-huddle-peer.muted::after {
  content: "";
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--vault-trust-accent) center / 8px 8px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m4 4 16 16M12 3a3 3 0 0 1 3 3v5a3 3 0 0 1-.4 1.5M9 6v5a3 3 0 0 0 4.7 2.5' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");
  border: 2px solid var(--vault-tint);
}

.vault-huddle-strip .vault-chat-iconbtn { color: var(--vault-ink); }
.vault-huddle-strip .vault-chat-iconbtn:hover { background: var(--vault-hover-strong); }
.vault-huddle-strip .vault-chat-iconbtn[aria-pressed="true"] { background: var(--vault-trust-accent); color: #fff; }

.vault-huddle-leave {
  border: 0;
  border-radius: 999px;
  padding: 0.32rem 0.8rem;
  background: var(--vault-trust-accent);
  color: #fff;
  font: 600 0.75rem var(--vault-font);
  cursor: pointer;
}

.vault-huddle-leave:hover { background: var(--vault-trust-accent-hover); }

/* ---------------------------------------------------------------- messages */
.vault-chat-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1rem 1rem 0.6rem;
  scroll-behavior: smooth;
  /* Quieter document-like canvas: one low-contrast glow over a faint,
     wider dot field, all derived from theme tokens for light and dark. */
  background-color: var(--vault-frame);
  background-image:
    radial-gradient(circle at 14% 8%, rgba(var(--vault-accent-rgb), 0.08), transparent 40%),
    radial-gradient(rgba(var(--vault-accent-rgb), 0.10) 0.8px, transparent 1px);
  background-size: 100% 100%, 28px 28px;
}

.vault-chat-older {
  display: block;
  margin: 0 auto 0.7rem;
  border: 1px solid var(--vault-line);
  border-radius: 999px;
  background: var(--vault-surface);
  color: var(--vault-ink-2);
  font: 600 0.72rem var(--vault-font);
  padding: 0.3rem 0.9rem;
  cursor: pointer;
}

.vault-chat-empty { text-align: center; color: var(--vault-ink-2); padding: 2.2rem 1rem; font-size: 0.85rem; }
.vault-chat-empty strong { color: var(--vault-ink); }

.vault-chat-day {
  display: flex;
  justify-content: center;
  margin: 0.8rem 0 0.5rem;
}

.vault-chat-day span {
  background: var(--vault-surface-inset);
  color: var(--vault-ink-2);
  border-radius: 999px;
  padding: 0.18rem 0.7rem;
  font: 600 0.68rem var(--vault-font);
  letter-spacing: 0.02em;
}

.vault-chat-new {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.7rem 0 0.4rem;
  color: var(--vault-trust-accent);
  font: 700 0.66rem var(--vault-font);
  letter-spacing: 0.08em;
}

.vault-chat-new::before,
.vault-chat-new::after { content: ""; flex: 1; height: 1px; background: currentColor; opacity: 0.4; }

.vault-msg { display: flex; gap: 0.55rem; margin: 0.5rem 0; position: relative; }
.vault-msg.cont { margin-top: 0.1rem; } /* tighter within a same-author run */
.vault-msg.mine { flex-direction: row-reverse; }
.vault-msg .vault-avatar { width: 26px; height: 26px; font-size: 0.62rem; align-self: flex-end; flex-shrink: 0; }
.vault-msg.cont .vault-avatar { visibility: hidden; }

.vault-msg-bubble {
  position: relative;
  max-width: 82%;
  border-radius: 16px;
  padding: 0.62rem 0.78rem 0.48rem;
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  box-shadow: 0 1px 1px rgba(8, 47, 40, 0.05);
  font-size: 0.9375rem;
  line-height: 1.46;
  color: var(--vault-ink);
  word-break: break-word;
}

.vault-msg:not(.cont) .vault-msg-bubble { border-bottom-left-radius: 5px; }
.vault-msg.mine .vault-msg-bubble {
  background: var(--vault-tint);
  border-color: rgba(var(--vault-accent-rgb), 0.25);
  border-bottom-left-radius: 14px;
}
.vault-msg.mine:not(.cont) .vault-msg-bubble { border-bottom-right-radius: 5px; }

.vault-msg-author { display: block; font-size: 0.8125rem; line-height: 1.2; font-weight: 700; color: var(--vault-accent); margin-bottom: 0.2rem; }
.vault-msg.mine .vault-msg-author, .vault-msg.cont .vault-msg-author { display: none; }

.vault-msg-meta {
  display: flex;
  justify-content: flex-end;
  gap: 0.3rem;
  font-size: 0.75rem;
  color: var(--vault-ink-2);
  margin-top: 0.22rem;
}

.vault-msg-deleted { font-style: italic; color: var(--vault-ink-2); }

.vault-msg-quote {
  border-left: 3px solid var(--vault-accent);
  background: var(--vault-surface-inset);
  border-radius: 7px;
  padding: 0.28rem 0.5rem;
  margin-bottom: 0.28rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  overflow: hidden;
}

.vault-msg-quote strong { display: block; color: var(--vault-accent); font-size: 0.75rem; }
.vault-msg-quote span {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--vault-ink-2);
}

/* Reactions ride the bubble's bottom edge, WhatsApp style. The bubble is
   appended after the pills in the DOM, so without an explicit z-index it
   paints over them — lift the pills above the bubble. */
.vault-msg-reactions {
  position: absolute;
  bottom: -11px;
  left: 8px;
  z-index: 2;
  display: flex;
  gap: 3px;
}

.vault-msg.mine .vault-msg-reactions { left: auto; right: 8px; }

.vault-msg-reaction {
  min-height: 28px;
  border: 1px solid var(--vault-line);
  border-radius: 999px;
  background: var(--vault-surface);
  box-shadow: 0 1px 2px rgba(8, 47, 40, 0.12);
  font-size: 1rem;
  line-height: 1;
  padding: 3px 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.vault-msg-reaction.mine { border-color: var(--vault-accent); background: var(--vault-tint); }
.vault-msg.has-reactions { margin-bottom: 1.45rem; } /* clear the overhanging reaction pill */

/* Dedicated origin-aware reaction tray (opens above the bubble edge). */
.vault-msg-reaction-picker {
  position: absolute;
  top: -52px;
  left: 38px;
  z-index: 5;
  display: flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid var(--vault-line);
  border-radius: 999px;
  background: var(--vault-surface);
  box-shadow: var(--vault-shadow-pop);
  transform-origin: bottom left;
  max-width: calc(var(--vault-screen-w) - 1.5rem);
  overflow-x: auto;
}
.vault-msg.mine .vault-msg-reaction-picker { left: auto; right: 38px; transform-origin: bottom right; }
.vault-msg-reaction-picker[hidden] { display: none; }
.vault-msg-reaction-picker button {
  min-width: var(--vault-tap);
  min-height: var(--vault-tap);
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 1.35rem;
  cursor: pointer;
}
.vault-msg-reaction-picker button:hover,
.vault-msg-reaction-picker button:focus-visible { background: var(--vault-hover-strong); }
.vault-msg-reaction-picker button:active,
.vault-msg-voice-play:active,
.vault-msg-actions button:active { transform: scale(0.97); }

/* Hover quick-actions (react / reply / delete). */
.vault-msg-actions {
  position: absolute;
  top: -14px;
  right: 6px;
  display: flex;
  gap: 2px;
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  border-radius: 999px;
  box-shadow: var(--vault-shadow-pop);
  padding: 2px;
  z-index: 4; /* always above bubbles and reaction pills */
  opacity: 0;
  pointer-events: none;
  transform: translateY(2px);
  transform-origin: bottom center;
  transition: opacity 0.12s ease, transform 0.12s ease;
}

.vault-msg.mine .vault-msg-actions { right: auto; left: 6px; }
.vault-msg:hover .vault-msg-actions,
.vault-msg:focus-within .vault-msg-actions { opacity: 1; pointer-events: auto; transform: none; }

.vault-msg-actions button {
  border: 0;
  background: transparent;
  border-radius: 999px;
  width: 26px;
  height: 26px;
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  color: var(--vault-ink-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.vault-msg-actions button:hover { background: var(--vault-hover-strong); }
.vault-msg-actions button svg { width: 15px; height: 15px; }
.vault-msg-actions button.confirm-delete { color: #fff; background: var(--vault-trust-accent); }

/* Voice bubbles. */
.vault-msg-voice { display: flex; align-items: center; gap: 0.5rem; min-width: 208px; }

.vault-msg-voice-play {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: var(--vault-accent);
  color: var(--vault-accent-ink);
  cursor: pointer;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.vault-msg-voice-play svg { width: 16px; height: 16px; }
.vault-msg-voice canvas { width: 118px; height: 26px; display: block; }
.vault-msg-voice-time { font-size: 0.66rem; color: var(--vault-ink-2); min-width: 30px; }

.vault-msg-voice-speed {
  border: 1px solid var(--vault-line);
  border-radius: 999px;
  background: var(--vault-surface);
  color: var(--vault-ink-2);
  font: 700 0.62rem var(--vault-font);
  padding: 2px 6px;
  cursor: pointer;
}

/* Seen receipts under my newest message. */
.vault-chat-seen {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.3rem;
  margin: 0.15rem 0 0.3rem;
  font-size: 0.62rem;
  color: var(--vault-ink-2);
}

.vault-chat-seen .vault-avatar { width: 15px; height: 15px; font-size: 0.42rem; }

/* Typing indicator. */
.vault-chat-typing {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.25rem 1rem 0.35rem;
  font-size: 0.72rem;
  color: var(--vault-ink-2);
}

.vault-chat-typing[hidden] { display: none; }
.vault-chat-typing-dots { display: inline-flex; gap: 3px; }

.vault-chat-typing-dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--vault-accent);
  opacity: 0.35;
  animation: vault-chat-typing 1.1s ease-in-out infinite;
}

.vault-chat-typing-dots i:nth-child(2) { animation-delay: 0.18s; }
.vault-chat-typing-dots i:nth-child(3) { animation-delay: 0.36s; }

@keyframes vault-chat-typing {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* Jump-to-new pill. */
.vault-chat-jump {
  position: absolute;
  right: 1rem;
  bottom: 4.6rem;
  border: 0;
  border-radius: 999px;
  padding: 0.34rem 0.8rem;
  background: var(--vault-deep);
  color: #fff;
  font: 600 0.72rem var(--vault-font);
  box-shadow: var(--vault-shadow-pop);
  cursor: pointer;
}

/* Reply bar above the composer. */
.vault-chat-reply {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.9rem;
  background: var(--vault-surface-inset);
  border-top: 1px solid var(--vault-line);
}

.vault-chat-reply[hidden] { display: none; }
.vault-chat-reply-quote { flex: 1; min-width: 0; border-left: 3px solid var(--vault-accent); padding-left: 0.5rem; font-size: 0.74rem; }
.vault-chat-reply-quote strong { display: block; color: var(--vault-accent); font-size: 0.68rem; }
.vault-chat-reply-quote span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--vault-ink-2); }
.vault-chat-reply .vault-chat-iconbtn { color: var(--vault-ink-2); }
.vault-chat-reply .vault-chat-iconbtn:hover { background: var(--vault-hover); }

/* Recording strip (replaces the composer while recording). */
.vault-chat-record {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.9rem;
  background: var(--vault-surface);
  border-top: 1px solid var(--vault-line);
}

.vault-chat-record[hidden] { display: none; }

.vault-chat-record-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--vault-trust-accent);
  animation: vault-chat-blink 1.1s ease-in-out infinite;
}

@keyframes vault-chat-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

.vault-chat-record-timer { font: 700 0.8rem var(--vault-font); color: var(--vault-ink); min-width: 38px; }
.vault-chat-record-wave { flex: 1; height: 24px; }

.vault-chat-record-cancel,
.vault-chat-record-send {
  border: 0;
  border-radius: 999px;
  padding: 0.35rem 0.85rem;
  font: 600 0.75rem var(--vault-font);
  cursor: pointer;
}

.vault-chat-record-cancel { background: transparent; color: var(--vault-ink-2); }
.vault-chat-record-cancel:hover { background: var(--vault-hover); }
.vault-chat-record-send { background: var(--vault-accent); color: var(--vault-accent-ink); }
.vault-chat-record-send:hover { background: var(--vault-accent-hover); }

/* Composer. */
.vault-chat-mentions {
  list-style: none;
  margin: 0;
  padding: 0.3rem;
  max-height: 220px;
  overflow-y: auto;
  border-top: 1px solid var(--vault-line);
  background: var(--vault-surface);
}

.vault-chat-mentions[hidden] { display: none; }

.vault-chat-mentions li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.55rem;
  border-radius: 8px;
  font-size: 0.82rem;
  color: var(--vault-ink);
  cursor: pointer;
}

.vault-chat-mentions li:hover,
.vault-chat-mentions li.active { background: var(--vault-tint); }

.vault-chat-mentions li .vault-avatar { width: 22px; height: 22px; font-size: 0.625rem; }
.vault-chat-mention-name { font-weight: 600; }
.vault-chat-mention-email { color: var(--vault-ink-2); font-size: 0.72rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.vault-chat-composer {
  display: flex;
  align-items: flex-end;
  gap: 0.3rem;
  padding: 0.5rem 0.6rem;
  background: var(--vault-surface);
  border-top: 1px solid var(--vault-line);
}

.vault-chat-composer[hidden] { display: none; }

.vault-chat-composer textarea {
  flex: 1;
  resize: none;
  box-sizing: border-box; /* min-height is the TOTAL height; also stops the autosize padding-feedback */
  min-height: 40px;
  border: 1px solid var(--vault-line);
  border-radius: 12px;
  background: var(--vault-frame);
  color: var(--vault-ink);
  font: 400 1rem/1.3 var(--vault-font);
  padding: 0.4rem 0.7rem;
  max-height: 96px;
  outline: none;
}

.vault-chat-composer textarea:focus { border-color: var(--vault-accent); }

.vault-chat-composer .vault-chat-iconbtn { width: 40px; height: 40px; color: var(--vault-ink-2); }
.vault-chat-composer .vault-chat-iconbtn:hover { background: var(--vault-hover); }
.vault-chat-mic.recording { color: var(--vault-trust-accent); }

.vault-chat-send {
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: var(--vault-accent);
  color: var(--vault-accent-ink);
  cursor: pointer;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, transform 0.15s ease;
}

.vault-chat-send svg { width: 17px; height: 17px; }
.vault-chat-send:hover:not(:disabled) { background: var(--vault-accent-hover); }
.vault-chat-send:disabled { background: var(--vault-line-strong); cursor: default; }

.vault-chat-emoji-btn.active { color: var(--vault-accent); background: var(--vault-hover-strong); }

/* Emoji picker — WhatsApp-style popover above the composer. */
.vault-chat-emoji-pop {
  position: absolute;
  left: 0.6rem;
  right: 0.6rem;
  bottom: 3.3rem;
  z-index: 6;
  display: flex;
  flex-direction: column;
  max-height: 248px;
  border-radius: 14px;
  background: var(--vault-surface);
  border: 1px solid var(--vault-line);
  box-shadow: var(--vault-shadow-pop);
  overflow: hidden;
  transform-origin: bottom center;
  animation: vault-emoji-pop 0.14s cubic-bezier(0.2, 0.9, 0.3, 1.1);
}

.vault-chat-emoji-pop[hidden] { display: none; }

@keyframes vault-emoji-pop {
  from { opacity: 0; transform: translateY(6px) scale(0.97); }
  to { opacity: 1; transform: none; }
}

.vault-chat-emoji-scroll { overflow-y: auto; padding: 0.3rem 0.5rem 0.6rem; }

.vault-chat-emoji-cat {
  position: sticky;
  top: 0;
  background: var(--vault-surface);
  padding: 0.4rem 0.1rem 0.2rem;
  font: 700 0.62rem var(--vault-font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--vault-ink-2);
}

.vault-chat-emoji-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 1px;
}

.vault-chat-emoji-grid button {
  border: 0;
  background: transparent;
  border-radius: 8px;
  padding: 3px 0;
  font-size: 1.28rem;
  line-height: 1.25;
  cursor: pointer;
  transition: background 0.1s ease, transform 0.1s ease;
}

.vault-chat-emoji-grid button:hover {
  background: var(--vault-hover-strong);
  transform: scale(1.15);
}

/* Hover growth is pointer-only so touch devices never stick in a hover state. */
@media (hover: hover) and (pointer: fine) {
  .vault-chat-fab:hover { transform: scale(1.06); }
  .vault-chat-send:hover:not(:disabled) { transform: scale(1.05); }
}

/* Small screens: the panel takes the whole viewport. */
@media (max-width: 520px) {
  .vault-chat-panel { inset: 0; width: auto; border-radius: 0; }
  .vault-chat-scroll { padding-inline: 0.75rem; }
  .vault-msg-bubble { max-width: 86%; }
}

@media (prefers-reduced-motion: reduce) {
  .vault-chat-panel,
  .vault-chat-panel.vault-chat-animating {
    transform: none;
    clip-path: none;
    transition: none;
    will-change: opacity;
  }
  .vault-chat-panel.vault-chat-fade { transition: opacity 150ms ease; }
  .vault-chat-fab, .vault-chat-send, .vault-chat-iconbtn { transition: none; }
  /* No travel or scale — state stays legible through color/opacity only. */
  .vault-chat-fab:hover, .vault-chat-send:hover:not(:disabled),
  .vault-chat-fab:active, .vault-chat-send:active, .vault-chat-iconbtn:active,
  .vault-msg-reaction-picker button:active, .vault-msg-voice-play:active,
  .vault-msg-actions button:active { transform: none; }
  .vault-msg-actions { transition: opacity 0.12s ease; transform: none; }
  .vault-chat-fab-badge { animation: none; }
  .vault-chat-typing-dots i, .vault-chat-record-dot { animation: none; opacity: 1; }
  .vault-chat-scroll { scroll-behavior: auto; }
}

/* ============================================================================
   Shared page-state primitive (loading / empty / filtered / error / terminal).
   ========================================================================== */

.vault-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  padding: 3.5rem 1.5rem;
  text-align: center;
  color: var(--vault-ink-2);
}

.vault-state-icon {
  width: 52px;
  height: 52px;
  display: inline-grid;
  place-items: center;
  margin-bottom: 0.75rem;
  border-radius: 14px;
  background: var(--vault-tint);
  color: var(--vault-accent);
  font-size: 1.5rem;
}

.vault-state-loading { gap: 0; }

.vault-state-empty .vault-state-icon,
.vault-state-filtered .vault-state-icon {
  background: var(--vault-tint);
  color: var(--vault-accent);
}

.vault-state-error .vault-state-icon {
  background: var(--vault-danger-soft);
  color: var(--vault-danger);
}

.vault-state-terminal .vault-state-icon {
  background: var(--vault-warning-soft);
  color: var(--vault-warning);
}

.vault-state-heading {
  margin: 0;
  color: var(--vault-ink);
  font-size: 1.0625rem;
  font-weight: 600;
}

.vault-state-message {
  margin: 0;
  max-width: 42ch;
  font-size: 0.9375rem;
}

.vault-state-action {
  margin-top: 0.75rem;
}

.vault-state-action + .vault-state-action {
  margin-left: 0.5rem;
}

/* Loading: static skeleton blocks; shimmer only when motion is allowed. */
.vault-state-skeleton {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: min(320px, 100%);
  margin-bottom: 0.75rem;
}

.vault-state-skeleton-block {
  display: block;
  width: 100%;
  height: 14px;
  border-radius: 7px;
  background: var(--vault-line);
}

.vault-state-skeleton-block:nth-child(2) { width: 80%; }
.vault-state-skeleton-block:nth-child(3) { width: 60%; }

@media (prefers-reduced-motion: no-preference) {
  .vault-state-skeleton-block {
    background: linear-gradient(90deg, var(--vault-line) 25%, var(--vault-hover-strong) 37%, var(--vault-line) 63%);
    background-size: 400% 100%;
    animation: vault-state-shimmer 1.4s ease infinite;
  }
}

@keyframes vault-state-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}


/* ---- Sidebar presence rail: "In the vault" roster (every page but Home) ---- */
.vault-panel-presence {
  margin: 0.5rem 0.75rem 0;
  padding: 0.85rem 0.65rem 0.35rem;
  border-top: 1px solid var(--vault-line);
}

.vault-panel-presence-head {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  margin-bottom: 0.55rem;
}

.vault-panel-presence-title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--vault-ink);
}

.vault-panel-presence-count {
  margin-left: auto;
  padding: 0.05rem 0.5rem;
  border-radius: 999px;
  background: var(--vault-hover);
  color: var(--vault-ink-2);
  font-size: 0.6875rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.vault-panel-presence-list {
  display: grid;
  gap: 0.35rem;
  margin: 0;
}

.vault-presence-row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 0.5rem;
}

.vault-presence-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
  font-size: 0.625rem;
}

.vault-presence-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--vault-ink);
}

.vault-presence-clock {
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--vault-ink-2);
}

.vault-panel-presence-more {
  margin: 0.45rem 0 0;
  font-size: 0.75rem;
  color: var(--vault-ink-2);
}

/* ===================================================================
   Guided first-run profile (2026-07-27)
   A wizard drawn over the real profile page. The veil is one fixed
   element with a rounded hole, so travelling it between fields reflows
   nothing in the document. Tint only, no blur: the modal backdrop
   blurs deliberately, but a spotlight has to leave the field beneath it
   crisp and typable.
   =================================================================== */
.vault-guide {
  position: fixed;
  inset: 0;
  z-index: 1092;
  pointer-events: none;
}

/* The hole. Everything outside it is covered by the shadow spread. */
.vault-guide-veil {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border-radius: 10px;
  box-shadow: 0 0 0 100vmax rgba(8, 23, 19, 0.52);
  outline: 2px solid var(--vault-accent);
  outline-offset: 2px;
  transition:
    transform 260ms cubic-bezier(0.2, 0, 0, 1),
    width 260ms cubic-bezier(0.2, 0, 0, 1),
    height 260ms cubic-bezier(0.2, 0, 0, 1);
}

[data-bs-theme="dark"] .vault-guide-veil {
  box-shadow: 0 0 0 100vmax rgba(2, 12, 10, 0.62);
}

/* Two beats on arrival, then out of the way. A permanent pulse would be
   decoration rather than a state cue. */
.vault-guide-veil.is-arriving {
  animation: vault-guide-halo 900ms cubic-bezier(0.2, 0, 0, 1) 2;
}

@keyframes vault-guide-halo {
  0% { box-shadow: 0 0 0 100vmax rgba(8, 23, 19, 0.52), 0 0 0 0 rgba(73, 213, 178, 0.55); }
  100% { box-shadow: 0 0 0 100vmax rgba(8, 23, 19, 0.52), 0 0 0 14px rgba(73, 213, 178, 0); }
}

/* Pushing at a disabled Next flashes the ring warning and back. No shake:
   a nudge reads as an error the user caused, a flash as a field not yet done. */
.vault-guide-veil.is-nudged {
  animation: vault-guide-nudge 300ms cubic-bezier(0.2, 0, 0, 1);
}

@keyframes vault-guide-nudge {
  0%, 100% { outline-color: var(--vault-accent); }
  40% { outline-color: var(--vault-warning); }
}

.vault-guide-tip {
  position: absolute;
  z-index: 1094;
  width: min(21rem, calc(var(--vault-screen-w) - 2rem));
  padding: 1.25rem;
  border-radius: 16px;
  background: var(--vault-surface);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  pointer-events: auto;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 180ms cubic-bezier(0.2, 0, 0, 1),
    transform 180ms cubic-bezier(0.2, 0, 0, 1),
    top 260ms cubic-bezier(0.2, 0, 0, 1),
    left 260ms cubic-bezier(0.2, 0, 0, 1);
}

.vault-guide-tip.is-shown {
  opacity: 1;
  transform: none;
}

.vault-guide-progress {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.875rem;
}

.vault-guide-progress span {
  height: 3px;
  flex: 1;
  border-radius: 2px;
  background: var(--vault-line);
  transition: background 220ms cubic-bezier(0.2, 0, 0, 1);
}

.vault-guide-progress span.is-done {
  background: var(--vault-accent);
}

.vault-guide-step-count {
  margin: 0 0 0.25rem;
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
}

.vault-guide-title {
  margin: 0 0 0.375rem;
  color: var(--vault-ink);
  font-size: 1.0625rem;
  font-weight: 600;
}

.vault-guide-body {
  margin: 0;
  color: var(--vault-ink-2);
  font-size: 0.875rem;
  line-height: 1.5;
}

.vault-guide-hint {
  margin: 0.625rem 0 0;
  color: var(--vault-warning);
  font-size: 0.8125rem;
}

.vault-guide-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.125rem;
}

.vault-guide-actions #guideNext {
  margin-left: auto;
}

.vault-guide-actions .btn {
  min-height: var(--vault-tap);
}

/* Reads as unavailable but stays clickable, so pressing it can answer with the
   hint and the ring flash below. Bootstrap's :disabled would set
   pointer-events: none and swallow the press in silence. */
.vault-guide-actions .btn.is-blocked {
  opacity: 0.45;
}

/* The preview card: the artifact they are building, not an illustration. */
.vault-guide-card {
  position: absolute;
  right: 1.5rem;
  bottom: 1.5rem;
  /* Below the tip deliberately. Even with the yielding below, the tip is the
     thing being acted on and must never be painted over by the preview. */
  z-index: 1093;
  width: 17rem;
  padding: 1rem;
  border-radius: 16px;
  background: var(--vault-surface);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  pointer-events: none;
  transition: bottom 220ms cubic-bezier(0.2, 0, 0, 1);
}

/* Set by profile-guide.js together with an inline `bottom` that lifts the card
   clear of the tip. It is pointer-events:none, so parking it over the tip does
   not block the click — it blocks the user's view of the field they are being
   asked to fill and of the Next button, which is what actually stalls them.
   The class carries no offset of its own: the distance depends on where the tip
   landed, so JS owns it and this only marks the state for styling. */
.vault-guide-card.is-yielding {
  z-index: 1095;
}

.vault-guide-card-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.vault-guide-card-avatar {
  position: relative;
  display: grid;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--vault-tint);
  color: var(--vault-accent);
  font-size: 1.125rem;
  font-weight: 600;
  place-items: center;
  overflow: hidden;
}

.vault-guide-card-avatar::after {
  content: attr(data-initial);
}

.vault-guide-card-avatar.has-photo::after {
  content: none;
}

.vault-guide-card-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The photo lands: ring draws out from the avatar edge. Same 320ms and the
   same stroke-free technique the storage donut uses for its draw-on. */
.vault-guide-card-avatar.has-photo {
  animation: vault-guide-photo-in 320ms cubic-bezier(0.2, 0, 0, 1);
}

@keyframes vault-guide-photo-in {
  0% { box-shadow: 0 0 0 0 var(--vault-accent); transform: scale(0.94); }
  100% { box-shadow: 0 0 0 3px transparent; transform: none; }
}

/* On the finish panel the card stops being a corner preview and becomes the
   payoff, so it sits in flow at the top of the panel. */
.vault-guide-card.is-hero {
  position: static;
  width: 100%;
  margin-bottom: 1.25rem;
  box-shadow: none;
  background: var(--vault-surface-inset);
  animation: vault-guide-rise 260ms cubic-bezier(0.2, 0, 0, 1);
}

.vault-guide-card-lines {
  display: flex;
  flex-direction: column;
  gap: 0.3125rem;
  min-width: 0;
  flex: 1;
}

.vault-guide-card-name,
.vault-guide-card-meta {
  overflow: hidden;
  color: var(--vault-ink);
  font-size: 0.9375rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vault-guide-card-meta {
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
}

/* Skeleton until answered. */
.vault-guide-card-name[data-empty="true"],
.vault-guide-card-meta[data-empty="true"] {
  border-radius: 4px;
  background: var(--vault-surface-inset);
  color: transparent;
}

.vault-guide-card-name[data-empty="true"] { height: 14px; width: 70%; }

.vault-guide-card-meta[data-empty="true"] { height: 11px; width: 90%; }

.vault-guide-card-name.just-filled,
.vault-guide-card-meta.just-filled {
  animation: vault-guide-rise 180ms cubic-bezier(0.2, 0, 0, 1);
}

@keyframes vault-guide-rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.vault-guide-card-foot {
  margin: 0.875rem 0 0;
  color: var(--vault-ink-2);
  font-size: 0.75rem;
}

.vault-guide-finish {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1094;
  width: min(24rem, calc(var(--vault-screen-w) - 2rem));
  padding: 1.75rem;
  border-radius: 16px;
  background: var(--vault-surface);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  pointer-events: auto;
  text-align: center;
  transform: translate(-50%, -50%);
}

.vault-guide-check {
  width: 40px;
  height: 40px;
  margin-bottom: 0.75rem;
  color: var(--vault-accent);
}

.vault-guide-check path {
  stroke-dasharray: 32;
  stroke-dashoffset: 32;
  animation: vault-guide-draw 260ms cubic-bezier(0.2, 0, 0, 1) forwards;
}

@keyframes vault-guide-draw {
  to { stroke-dashoffset: 0; }
}

.vault-guide-finish-title {
  margin: 0 0 0.375rem;
  color: var(--vault-ink);
}

.vault-guide-finish-body {
  margin: 0 0 1.25rem;
  color: var(--vault-ink-2);
  font-size: 0.875rem;
}

.vault-guide-finish .btn {
  min-height: var(--vault-tap);
}

/* Below sm the tooltip is a bottom sheet and the card rides in its header. */
@media (max-width: 575.98px) {
  .vault-guide-tip {
    top: auto !important;
    bottom: 0;
    left: 0 !important;
    width: 100%;
    border-radius: 16px 16px 0 0;
  }

  .vault-guide-card {
    right: 0.75rem;
    bottom: auto;
    top: 0.75rem;
    width: calc(100% - 1.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .vault-guide-veil,
  .vault-guide-tip,
  .vault-guide-card,
  .vault-guide-progress span {
    transition: none;
  }

  .vault-guide-veil.is-arriving,
  .vault-guide-veil.is-nudged,
  .vault-guide-card-avatar.has-photo,
  .vault-guide-card.is-hero,
  .vault-guide-card-name.just-filled,
  .vault-guide-card-meta.just-filled {
    animation: none;
  }

  /* The nudge is the only cue that Next was refused, so keep it as a static
     colour rather than dropping it entirely. */
  .vault-guide-veil.is-nudged {
    outline-color: var(--vault-warning);
  }

  .vault-guide-check path {
    stroke-dashoffset: 0;
    animation: none;
  }
}

/* Review status beside a filename. Sits in the same slot as the live chip and
   borrows its restraint: no new accent, text always present, never colour
   alone. Hidden entirely when a file has never been reviewed. */
.vault-review-pill {
  margin-left: 0.5rem;
  font-weight: 500;
  vertical-align: middle;
  white-space: nowrap;
}

/* A review decision on the version timeline. Deliberately quieter than a
   version row — it annotates the history rather than competing with it. */
.vault-review-marker {
  border-left: 2px solid var(--bs-border-color);
  padding-left: 0.75rem !important;
  color: var(--bs-secondary-color);
}

/* An overdue review on the /reviews list. The text already says "N days
   overdue" — this only makes it findable while scanning, so it never carries
   the meaning on its own. */
.vault-review-overdue {
  color: var(--bs-danger);
  font-weight: 500;
}

/* "Send back" sits between Approve and doing nothing: it is not the primary
   act and it is not destructive, so it borrows the same amber the
   "Changes requested" pill uses rather than inventing a colour. Sized to sit
   beside Approve without wrapping — the destination is in the tooltip and the
   confirm dialog, never in the label. */
.vault-btn-send-back {
  background: var(--vault-warning-soft);
  border: 1px solid color-mix(in srgb, var(--vault-warning) 35%, transparent);
  color: var(--vault-warning);
  font-weight: 500;
  white-space: nowrap;
}

.vault-btn-send-back:hover,
.vault-btn-send-back:focus-visible {
  background: color-mix(in srgb, var(--vault-warning) 16%, var(--vault-warning-soft));
  border-color: var(--vault-warning);
  color: var(--vault-warning);
}

/* ---------------------------------------------------------------------------
   Dashboard — Projects corner

   Floating tiles: they lift and scale on hover with the icon growing in
   sympathy, matching the KPI tiles above them so the dashboard reads as one
   surface rather than two. Motion is 250ms and is dropped entirely under
   prefers-reduced-motion.
--------------------------------------------------------------------------- */

.vault-home-projects .vault-project-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.vault-project-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1rem 1.05rem;
  border: 1px solid var(--vault-line);
  border-radius: 16px;
  background: var(--vault-surface);
  color: var(--vault-ink);
  text-decoration: none;
  transition:
    transform 250ms var(--vault-ease),
    box-shadow 250ms var(--vault-ease),
    border-color 250ms var(--vault-ease);
}

.vault-project-tile:hover,
.vault-project-tile:focus-visible {
  transform: translateY(-5px) scale(1.02);
  box-shadow: var(--vault-shadow-pop);
  border-color: var(--vault-accent);
  color: var(--vault-ink);
  z-index: 2;
}

.vault-project-tile-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  margin-bottom: 0.4rem;
  border-radius: 11px;
  background: var(--vault-tint);
  color: var(--vault-accent);
  transition: transform 250ms var(--vault-ease);
}

.vault-project-tile:hover .vault-project-tile-icon {
  transform: scale(1.12);
}

.vault-project-tile-value {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.vault-project-tile-label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--vault-ink-2);
}

.vault-project-tile-note {
  font-size: 0.75rem;
  color: var(--vault-ink-2);
}

/* A count that means something is wrong colours its own figure and icon,
   so the tile carries the signal without a second badge. */
.vault-project-tile.is-alert .vault-project-tile-value,
.vault-project-tile.is-alert .vault-project-tile-icon { color: var(--vault-danger-ink); }
.vault-project-tile.is-alert .vault-project-tile-icon { background: var(--vault-danger-tint, var(--vault-tint)); }
.vault-project-tile.is-warn .vault-project-tile-value,
.vault-project-tile.is-warn .vault-project-tile-icon { color: var(--vault-warning-ink); }
.vault-project-tile.is-warn .vault-project-tile-icon { background: var(--vault-warning-tint, var(--vault-tint)); }

.vault-home-subtitle {
  margin: 0 0 0.5rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--vault-ink-2);
}

.vault-project-next {
  margin: 0;
  padding: 0;
  list-style: none;
}

.vault-project-next a {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.55rem 0.7rem;
  border-radius: 10px;
  color: var(--vault-ink);
  text-decoration: none;
  transition: background 150ms var(--vault-ease), transform 150ms var(--vault-ease);
}

.vault-project-next a:hover,
.vault-project-next a:focus-visible {
  background: var(--vault-surface-inset);
  transform: translateX(3px);
}

.vault-project-next-title { font-size: 0.875rem; font-weight: 500; }
.vault-project-next-meta { font-size: 0.75rem; color: var(--vault-ink-2); }
.vault-project-next-meta .is-overdue { color: var(--vault-danger-ink); font-weight: 600; }
.vault-project-next-meta .is-blocked { color: var(--vault-warning-ink); font-weight: 600; }

.vault-home-empty {
  margin: 0;
  color: var(--vault-ink-2);
  font-size: 0.8125rem;
}

/* Staggered entrance, matching the KPI tiles above. */
@media (prefers-reduced-motion: no-preference) {
  /* See the KPI tiles above: `backwards`, so the finished entrance does not
     hold `transform` and block the hover lift. */
  .vault-project-tile { animation: vault-rise 260ms var(--vault-ease) backwards; }
  .vault-project-tile:nth-child(1) { animation-delay: 0ms; }
  .vault-project-tile:nth-child(2) { animation-delay: 40ms; }
  .vault-project-tile:nth-child(3) { animation-delay: 80ms; }
  .vault-project-tile:nth-child(4) { animation-delay: 120ms; }
}

@media (prefers-reduced-motion: reduce) {
  .vault-project-tile,
  .vault-project-tile-icon,
  .vault-project-next a { transition: none; }
  .vault-project-tile:hover,
  .vault-project-next a:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   Dashboard — panel elevation

   The page sits on a recessed surface and every region on it is a card lifted
   off that surface, so the dashboard reads as a set of distinct panels rather
   than one long scroll of headings. Scoped to .vault-home: the rest of the
   vault keeps the flat body it was designed against.
--------------------------------------------------------------------------- */

.vault-home {
  /* The "little dark background" the cards are projected off. Reuses the inset
     token the app already uses for recessed areas, so both themes and the
     brand register come along rather than being re-picked here.
     Deliberately not bled to the viewport edge with negative margins: the
     layout container owns the page gutter, and fighting it is how a page ends
     up scrolling sideways. */
  padding: 1.25rem;
  border-radius: 20px;
  background: var(--vault-surface-inset);
}

/* Every dashboard region becomes a panel. The KPI and project tiles are
   already cards in their own right, so their containers stay transparent —
   a card inside a card is just a border nobody asked for. */
.vault-home .vault-home-section {
  padding: 1.15rem 1.25rem;
  border: 1px solid var(--vault-line);
  border-radius: 16px;
  background: var(--vault-surface);
  box-shadow: var(--vault-shadow-sm);
}

.vault-home .vault-overview,
.vault-home .vault-home-projects .vault-project-tiles {
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
}

/* The tiles are cards in their own right, so they carry the same resting
   elevation as the panels around them — otherwise they read as flat patches
   on the recessed surface while everything beside them floats. */
.vault-home .vault-kpi,
.vault-home .vault-project-tile {
  box-shadow: var(--vault-shadow-sm);
}

/* The greeting is a panel too, so the page opens on the same vocabulary. */
.vault-home .vault-page-head {
  padding: 1.15rem 1.25rem;
  margin-bottom: 1.25rem;
  border: 1px solid var(--vault-line);
  border-radius: 16px;
  background: var(--vault-surface);
  box-shadow: var(--vault-shadow-sm);
}

/* The columns keep their gap; each child is its own panel. */
.vault-home .vault-home-columns { gap: 1.25rem; }
.vault-home .vault-home-section { margin-bottom: 1.25rem; }
.vault-home .vault-home-columns .vault-home-section { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   Tile hues

   A dashboard row where every icon is brand teal reads as one repeated thing.
   Each tile takes a hue for its icon chip and its figure, so the eye can tell
   "files" from "shares" from "overdue" before reading a word. The hue is a
   modifier on the tile; everything else about it is unchanged.
--------------------------------------------------------------------------- */

.vault-kpi.hue-indigo .vault-kpi-icon,
.vault-project-tile.hue-indigo .vault-project-tile-icon {
  background: var(--vault-hue-indigo-soft);
  color: var(--vault-hue-indigo);
}
.vault-kpi.hue-indigo .vault-kpi-value,
.vault-project-tile.hue-indigo .vault-project-tile-value { color: var(--vault-hue-indigo); }
a.vault-kpi.hue-indigo:hover,
.vault-project-tile.hue-indigo:hover { border-color: var(--vault-hue-indigo); }

.vault-kpi.hue-cyan .vault-kpi-icon,
.vault-project-tile.hue-cyan .vault-project-tile-icon {
  background: var(--vault-hue-cyan-soft);
  color: var(--vault-hue-cyan);
}
.vault-kpi.hue-cyan .vault-kpi-value,
.vault-project-tile.hue-cyan .vault-project-tile-value { color: var(--vault-hue-cyan); }
a.vault-kpi.hue-cyan:hover,
.vault-project-tile.hue-cyan:hover { border-color: var(--vault-hue-cyan); }

.vault-kpi.hue-violet .vault-kpi-icon,
.vault-project-tile.hue-violet .vault-project-tile-icon {
  background: var(--vault-hue-violet-soft);
  color: var(--vault-hue-violet);
}
.vault-kpi.hue-violet .vault-kpi-value,
.vault-project-tile.hue-violet .vault-project-tile-value { color: var(--vault-hue-violet); }
a.vault-kpi.hue-violet:hover,
.vault-project-tile.hue-violet:hover { border-color: var(--vault-hue-violet); }

.vault-kpi.hue-amber .vault-kpi-icon,
.vault-project-tile.hue-amber .vault-project-tile-icon {
  background: var(--vault-hue-amber-soft);
  color: var(--vault-hue-amber);
}
.vault-kpi.hue-amber .vault-kpi-value,
.vault-project-tile.hue-amber .vault-project-tile-value { color: var(--vault-hue-amber); }
a.vault-kpi.hue-amber:hover,
.vault-project-tile.hue-amber:hover { border-color: var(--vault-hue-amber); }

.vault-kpi.hue-rose .vault-kpi-icon,
.vault-project-tile.hue-rose .vault-project-tile-icon {
  background: var(--vault-hue-rose-soft);
  color: var(--vault-hue-rose);
}
.vault-kpi.hue-rose .vault-kpi-value,
.vault-project-tile.hue-rose .vault-project-tile-value { color: var(--vault-hue-rose); }
a.vault-kpi.hue-rose:hover,
.vault-project-tile.hue-rose:hover { border-color: var(--vault-hue-rose); }

/* A live alert outranks the tile's decorative hue: an overdue count must not
   be indigo just because it is the first tile in the row. */
.vault-project-tile.is-alert .vault-project-tile-icon {
  background: var(--vault-hue-rose-soft);
  color: var(--vault-hue-rose);
}
.vault-project-tile.is-alert .vault-project-tile-value { color: var(--vault-hue-rose); }
.vault-project-tile.is-warn .vault-project-tile-icon {
  background: var(--vault-hue-amber-soft);
  color: var(--vault-hue-amber);
}
.vault-project-tile.is-warn .vault-project-tile-value { color: var(--vault-hue-amber); }

/* Awaiting-scan badge. Deferred scanning can leave a file unopenable for
   minutes, so the row says so in amber and breathes to read as "in progress"
   rather than a static state the user has to interpret. The pulse is opacity
   only — animating the badge's box would nudge the row's other pills. */
.vault-scan-pulse {
  background: var(--vault-hue-amber-soft) !important;
  color: var(--vault-hue-amber) !important;
}
@media (prefers-reduced-motion: no-preference) {
  .vault-scan-pulse,
  .library-row.is-awaiting-scan .item-name-link {
    animation: vault-scan-pulse 1.6s ease-in-out infinite;
  }
}
/* The filename fades with its badge so the whole row reads as pending, not
   just a pill someone has to notice. Kept to the link so the icon, star and
   other pills stay legible while it breathes. */
/* !important because .text-heading on the same anchor is a utility class
   that already carries one — without this the name pulses but stays dark. */
.library-row.is-awaiting-scan .item-name-link { color: var(--vault-hue-amber) !important; }
@keyframes vault-scan-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* ============================================================ viewport units
   under canvas zoom

   vw/vh resolve against the RAW viewport, not the zoomed canvas, so anything
   sized 100vw/100vh paints across only `zoom` of the screen. Measured with a
   dialog open at z=0.67: the Bootstrap backdrop computed 2048x991 (correct
   for the raw viewport) and painted 1372x664 on a 2048x991 screen, leaving a
   third of the screen undimmed and clickable.

   These are the vendor rules that do it. Overridden here rather than edited
   in core.css so a Materio update does not silently drop the correction.
   Percentage-based full-bleed (`.modal` is width/height:100%) is already
   correct, because percentages resolve inside the zoomed coordinate space.
   ========================================================================= */
.modal-backdrop,
.offcanvas-backdrop,
[data-bs-theme="dark"] .offcanvas-backdrop {
  width: var(--vault-screen-w);
  height: var(--vault-screen-h);
}

/* Bootstrap ships these with !important, so the correction needs it too. */
.vw-100 { width: var(--vault-screen-w) !important; }
.min-vw-100 { min-width: var(--vault-screen-w) !important; }
.vh-100 { height: var(--vault-screen-h) !important; }
.min-vh-100 { min-height: var(--vault-screen-h) !important; }

.modal-transparent .modal-dialog { min-block-size: var(--vault-screen-h); }
.navbar-nav-scroll { max-height: var(--bs-scroll-height, calc(var(--vault-screen-h) * 0.75)); }
.offcanvas { --bs-offcanvas-height: calc(var(--vault-screen-h) * 0.3); }

/* Materio's own layout overlay - found by sweeping every page with a zoomed
   canvas and looking for fixed elements narrower than the screen, not by
   reading the stylesheet. It is the one behind the mobile menu and the
   content dim, and it was painting 1372x664 on a 2048x991 screen. */
.content-backdrop { width: var(--vault-screen-w); height: var(--vault-screen-h); }

/* Fullscreen modal variants: all six size their dialog off 100vw. */
.modal-fullscreen,
.modal-fullscreen-sm-down,
.modal-fullscreen-md-down,
.modal-fullscreen-lg-down,
.modal-fullscreen-xl-down,
.modal-fullscreen-xxl-down { width: var(--vault-screen-w); }

/* The app shell itself. `.layout-container { min-block-size: 100vh }` is the
   one that mattered most and the one I missed twice: the first sweep grepped
   for `height`/`width` and this is written with the LOGICAL property, so it
   never showed up. Measured at z=0.63 on an empty folder: body was correct at
   963 logical px, but .layout-container stopped at 607 - the raw viewport -
   and painted 382 on a 607px screen, leaving 225px of bare canvas under the
   footer. It is the shell every page renders inside, which is why the footer
   rode up on all of them. */
.layout-container { min-block-size: var(--vault-screen-h); }
/* The menu is one screen tall, in every mode. `block-size: 100%` on a FIXED
   element resolves against the RAW viewport under canvas zoom - exactly like
   vh does - so the drawer rule left it 1024 logical px on a canvas 1651 tall,
   painting 635 of a 1024px screen. The rail and panel stretch to the menu, so
   the whole sidebar stopped two thirds of the way down with the storage card
   stranded above the gap.

   The id gives this enough specificity to beat both the drawer rule and
   Materio's own .layout-menu-100vh pair, which are !important. At zoom 1 it
   resolves to plain 100dvh, so this is also correct with no script. */
#layout-menu.layout-menu { block-size: var(--vault-screen-h) !important; }
.layout-menu-100vh .layout-menu,
.layout-menu-100vh .layout-overlay { block-size: var(--vault-screen-h) !important; }
.aa-DetachedOverlay { block-size: var(--vault-screen-h); }
.divider .divider-text::before,
.divider .divider-text::after { inline-size: var(--vault-screen-w); }

/* ---- brand mark in the app header (top right) ----
   Quieter than the sign-in lockup: the page subject is the file list, not the
   product name, so it reads as a mark rather than a title. Hidden below md,
   where the header has to hold the hamburger, search and avatar and there is
   no room for a wordmark. */
/* Anchored in .layout-page's top padding — the empty band above the sticky
   navbar. Absolute, so it fills space that was already blank and can never
   push the navbar or the content around. */
.layout-page { position: relative; }

.vault-page-brand {
  position: absolute;
  top: 0;
  right: 1.5rem;
  z-index: 2;
  height: 4rem;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 1.5rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1;
  user-select: none;
  pointer-events: none;
}

/* Below md the band is used by the mobile chrome; there is no room for a
   wordmark next to a hamburger, a search field and an avatar. */
@media (max-width: 767.98px) {
  .vault-page-brand { display: none; }
}

.vault-page-brand .vault-brand-glyph {
  display: inline-grid;
  place-items: center;
  /* 0.85 of the wordmark's 1.5rem -- the tile-to-letters ratio the
     sign-in lockup established; at 1.4rem it read heavy next to the
     smaller type. */
  width: 1.275rem;
  height: 1.275rem;
  border-radius: 5px;
  background: var(--vault-accent);
  color: #fff;
}

/* The wordmark span carries .app-brand-text, which this stylesheet sizes
   globally at 2.05rem for the sign-in lockups. That (0,1,0) rule beat the
   font-size inherited from .vault-page-brand, so shrinking the container
   moved the glyph and left the letters at 32.8px. Inheriting here makes
   the container the single knob for this mark. */
.vault-page-brand .app-brand-text { font-size: inherit; }
.vault-page-brand .vault-wordmark-aya { color: var(--vault-accent); }
.vault-page-brand .vault-wordmark-vault { color: var(--vault-ink-2); }

/* ---------------------------------------------- read-only document viewer bar
   The only chrome the read-only page owns. Deliberately quiet: it says what
   the page is (a fixed, unwritable copy) and how to leave it, and nothing more. */
:root { --vault-viewer-bar-h: 44px; }

.vault-viewer-bar {
  display: flex;
  align-items: center;
  gap: .5rem;
  height: var(--vault-viewer-bar-h);
  padding: 0 .75rem;
  background: var(--vault-surface, #fff);
  border-bottom: 1px solid var(--vault-line, #e3ded6);
  font-size: .875rem;
}

.vault-viewer-back,
.vault-viewer-edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 32px;
  padding: 0 .625rem;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.vault-viewer-back svg { width: 18px; height: 18px; }
.vault-viewer-back:hover,
.vault-viewer-edit:hover { background: var(--vault-surface-inset, #f4f1ec); }

.vault-viewer-name {
  font-weight: 600;
  max-width: 46vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vault-viewer-badge {
  padding: .125rem .5rem;
  border-radius: 999px;
  background: var(--vault-surface-inset, #f4f1ec);
  color: var(--vault-ink-2, #736c64);
  font-size: .75rem;
  font-weight: 600;
}

.vault-viewer-spacer { flex: 1 1 auto; }

.vault-viewer-edit {
  border: 1px solid var(--vault-line, #e3ded6);
  font-weight: 600;
}

/* The PDF page asks the shell to go dark (ViewData["ViewerDark"]), so its bar
   sits with the dark reading surface below it instead of capping it in cream. */
/* !important because the base `body` rule in this file is itself !important,
   which otherwise beats this on the cascade regardless of specificity. Without
   it the dark shell is dead code: invisible today only because the PDF mount
   covers the viewport, and light would show the moment it did not. */
.vault-viewer-dark { background: #202124 !important; }
.vault-viewer-dark .vault-viewer-bar { background: #202124; color: #e8eaed; border-bottom-color: #3c4043; }
.vault-viewer-dark .vault-viewer-badge { background: #3c4043; color: #bdc1c6; }
.vault-viewer-dark .vault-viewer-back:hover,
.vault-viewer-dark .vault-viewer-edit:hover { background: #3c4043; }
.vault-viewer-dark .vault-viewer-edit { border-color: #3c4043; }

/* -------------------------------------------------------------- PDF viewer
   The overlay is a lightbox, not a new screen: the scrim stays translucent so
   the folder you opened the document from is still visible underneath, and it
   is obvious that closing puts you back exactly where you were. That costs
   contrast, so the chrome carries its own weight — a blur behind the scrim and
   solid pill backgrounds under the controls, rather than bare white-on-page. */
.vault-pdf-overlay {
  --vault-pdf-bar-h: 60px;
  position: fixed;
  inset: 0;
  z-index: 1090;
  display: flex;
  flex-direction: column;
  background: rgba(18, 20, 24, .78);
  -webkit-backdrop-filter: blur(3px) saturate(.9);
  backdrop-filter: blur(3px) saturate(.9);
  color: #e8eaed;
}

/* No backdrop-filter (Firefox with it disabled, older Safari): the blur was
   doing part of the separating, so darken the scrim to make up for it. */
@supports not (backdrop-filter: blur(3px)) {
  .vault-pdf-overlay { background: rgba(18, 20, 24, .88); }
}

body.vault-pdf-open { overflow: hidden; }

/* Three tracks, not a flex row with a spacer: equal outer columns are what
   keep the title centred on the SCREEN rather than centred on whatever space
   the controls happened to leave. */
.vault-pdf-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: .75rem;
  flex: 0 0 auto;
  min-height: var(--vault-pdf-bar-h);
  padding: .5rem .875rem;
  font-size: .875rem;
}

.vault-pdf-lead {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-width: 0;
}

.vault-pdf-heading {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  line-height: 1.25;
}

.vault-pdf-tools {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: .25rem;
  min-width: 0;
}

.vault-pdf-title {
  font-weight: 600;
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vault-pdf-chip {
  padding: .125rem .5rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  color: #e8eaed;
  font-size: .75rem;
  font-weight: 600;
}

/* Transient confirmations ("Link copied"). Sits beside the chip so it never
   displaces the centred title when it appears. */
.vault-pdf-flash {
  padding: .125rem .5rem;
  border-radius: 999px;
  background: rgba(129, 201, 149, .22);
  color: #cbead6;
  font-size: .75rem;
  font-weight: 600;
  white-space: nowrap;
}

.vault-pdf-pages,
.vault-pdf-zoom {
  color: #bdc1c6;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.vault-pdf-pages { font-size: .75rem; }
.vault-pdf-zoom { min-width: 3.25rem; text-align: center; font-size: .8125rem; }

.vault-pdf-divider {
  width: 1px;
  height: 20px;
  margin: 0 .25rem;
  background: rgba(255, 255, 255, .2);
}

.vault-pdf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #e8eaed;
  font-size: 1rem;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}

.vault-pdf-btn:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.vault-pdf-btn:focus-visible { outline: 2px solid #8ab4f8; outline-offset: 2px; }
.vault-pdf-btn svg { width: 19px; height: 19px; }

/* Close is the one control that ends the task, so it gets a resting shape of
   its own instead of relying on hover to be findable. */
.vault-pdf-btn-round {
  margin-left: .25rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16);
}

.vault-pdf-btn-round:hover { background: rgba(255, 255, 255, .3); }

.vault-pdf-scroll {
  flex: 1 1 auto;
  overflow: auto;
  padding: 8px 0 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  background: #202124;
}

/* Inside the overlay the scrim IS the background; an opaque one here would
   undo the whole translucent effect. The backdrop is also the click target
   that dismisses the viewer, so say so. */
.vault-pdf-overlay .vault-pdf-scroll {
  background: transparent;
  cursor: zoom-out;
}

.vault-pdf-overlay .vault-pdf-page { cursor: auto; }

.vault-pdf-scroll:focus-visible { outline: 2px solid #8ab4f8; outline-offset: -2px; }

.vault-pdf-page {
  position: relative;
  flex: 0 0 auto;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .5), 0 6px 20px rgba(0, 0, 0, .35);
}

/* Deeper than the inline mount's: on a see-through scrim the drop shadow is
   what separates the page from whatever is showing through behind it. */
.vault-pdf-overlay .vault-pdf-page {
  border-radius: 2px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .45), 0 18px 48px rgba(0, 0, 0, .55);
}

.vault-pdf-page canvas { display: block; }

/* Off-screen, not display:none — a hidden frame is never laid out, and a
   frame that was never laid out has nothing for print() to paginate. */
.vault-pdf-printframe {
  position: fixed;
  left: -10000px;
  top: 0;
  width: 1px;
  height: 1px;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* pdf.js paints invisible, absolutely-positioned glyphs over the canvas and
   scales them through --total-scale-factor, which the renderer sets per page. */
.vault-pdf-textlayer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  line-height: 1;
  text-align: initial;
  forced-color-adjust: none;
  transform-origin: 0 0;
}

.vault-pdf-textlayer span,
.vault-pdf-textlayer br {
  position: absolute;
  color: transparent;
  white-space: pre;
  cursor: text;
  transform-origin: 0 0;
}

.vault-pdf-textlayer ::selection { background: rgba(138, 180, 248, .45); }

.vault-pdf-status {
  position: absolute;
  inset: var(--vault-pdf-bar-h, 48px) 0 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  color: #bdc1c6;
  pointer-events: none;
}

.vault-pdf-status-error { color: #f28b82; }

/* Narrow screens: the centred title and the control cluster cannot both have
   the width they want, so the title stands down to a single line above them. */
@media (max-width: 767.98px) {
  .vault-pdf-bar {
    grid-template-columns: 1fr auto;
    row-gap: .375rem;
  }

  .vault-pdf-heading {
    grid-row: 2;
    grid-column: 1 / -1;
    align-items: flex-start;
  }

  .vault-pdf-title { max-width: 100%; }
  .vault-pdf-divider { display: none; }
}

/* Inline mount (the share-link page): the renderer without the overlay. */
.vault-pdf-inline {
  /* Positioned, not static: .vault-pdf-status is absolutely positioned, and
     without a positioned ancestor here its error message resolves against the
     initial containing block — 48px from the top of the document, over the
     host page's header. The overlay gets this from .vault-pdf-overlay. */
  position: relative;
  height: min(72vh, 900px);
  border-radius: 12px;
}
