/* Pagejo - "Pop Glass": one calm canvas, a faint blue/cyan aurora, and a single
   diagonal gradient reserved for the things you *do* (FAB, primary button,
   active tool, selected chip). The shared token/base/component layer is the
   same across the hub's apps; only the hue block below is Pagejo's own. */

/* Metric-adjusted fallback so the web font swapping in does not shift layout. */
@font-face {
  font-family: "PJS Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Roboto");
  size-adjust: 104%; ascent-override: 97%; descent-override: 25%; line-gap-override: 0%;
}

:root {
  /* Without this, a browser that hasn't been told the page has its own dark
     palette renders native form controls (password fields especially) with
     ITS guess at light-mode colors - typically black text - regardless of
     the `color: inherit` these inputs already have. Declaring it explicitly
     makes the browser's own control chrome (text color, caret, autofill
     background) match the theme instead of guessing. */
  color-scheme: light dark;

  /* ---- Pagejo hue: blue to cyan-teal ---- */
  --a1: #2f4ff0;           /* gradient start; white on it >= 4.5:1 */
  --a2: #0b78a6;           /* gradient end;   white on it >= 4.5:1 */
  --a1-vivid: #5b8cff;     /* decorative only: glows, rings, tints */
  --a2-vivid: #22d3ee;
  --a-ink: #1d4ed8;        /* accent as text/icon colour on --surface / --bg */

  --grad: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
  --grad-soft: linear-gradient(135deg, color-mix(in srgb, var(--a1) 13%, transparent), color-mix(in srgb, var(--a2) 13%, transparent));
  --on-grad: #fff;

  /* ---- neutrals (light) ---- */
  --bg: #f6f5fb;
  --surface: #ffffff;
  --surface-2: #efedf7;
  --surface-3: #e5e2f1;
  --text: #15131f;
  --muted: #5d5a72;
  --border: rgba(30, 20, 70, .10);
  --border-strong: #8a86a0;
  --glass: rgba(255, 255, 255, .72);
  --glass-strong: rgba(255, 255, 255, .88);
  --glass-border: rgba(30, 20, 70, .08);
  --scrim: rgba(14, 10, 30, .48);
  --toast-bg: rgba(21, 19, 31, .94); --toast-fg: #fff;
  --focus: var(--a1);

  /* ---- semantic ---- */
  --success: #047857; --success-soft: color-mix(in srgb, #10b981 16%, transparent);
  --warn: #b45309;    --warn-soft: color-mix(in srgb, #f59e0b 20%, transparent);
  --danger: #dc2626;  --danger-soft: color-mix(in srgb, #ef4444 12%, transparent);

  /* ---- radii / spacing ---- */
  --r-xs: 8px; --r-sm: 12px; --r-md: 16px; --r-lg: 22px; --r-xl: 28px; --r-pill: 999px;
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-7: 32px; --s-8: 48px;

  /* ---- elevation ---- */
  --sh-1: 0 1px 2px rgba(30, 20, 70, .05), 0 4px 12px rgba(30, 20, 70, .06);
  --sh-2: 0 2px 4px rgba(30, 20, 70, .06), 0 12px 28px rgba(30, 20, 70, .12);
  --sh-3: 0 4px 8px rgba(30, 20, 70, .08), 0 20px 44px rgba(30, 20, 70, .18);
  --glow: 0 6px 18px color-mix(in srgb, var(--a1) 38%, transparent);
  --glow-lg: 0 10px 28px color-mix(in srgb, var(--a1) 45%, transparent), 0 2px 6px color-mix(in srgb, var(--a2) 30%, transparent);
  --blur: saturate(180%) blur(18px);

  /* ---- type ---- */
  --font: "Plus Jakarta Sans", "PJS Fallback", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --fs-xs: 12px; --fs-sm: 13.5px; --fs-base: 16px; --fs-md: 17px; --fs-lg: 20px; --fs-xl: 26px;

  /* ---- motion ---- */
  --dur-1: 120ms; --dur-2: 220ms; --dur-3: 360ms;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);

  /* ---- z-index: busy < scrim < sheet < toast < progress ---- */
  --z-bar: 20; --z-dock: 30; --z-fab: 40; --z-busy: 80; --z-scrim: 85; --z-sheet: 86; --z-toast: 90; --z-progress: 99;

  /* ---- safe areas ---- */
  --safe-t: env(safe-area-inset-top, 0px); --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px); --safe-r: env(safe-area-inset-right, 0px);
  --appbar-h: 60px;
  --dock-clear: 96px;
  /* The hub's ✦ assistant widget (myapps-hub.com/agent.js, 48px circle) reads
     --hub-agent-bottom / --hub-agent-right. It stacks 12px above the FAB and is
     centred over it; the dock views override the bottom below. Inherited by
     the widget through body, so body.picking / body.viewing can set it too. */
  --fab-size: 62px; --fab-bottom: 20px;
  --hub-agent-right: calc(max(16px, var(--safe-r)) + (var(--fab-size) - 48px) / 2);
  --hub-agent-bottom: calc(var(--fab-bottom) + var(--fab-size) + 12px);

  /* ---- legacy names (older rules and JS-built markup still use these) ---- */
  --card: var(--surface); --line: var(--border); --accent: var(--a-ink); --ok: var(--success);
  --err: var(--danger); --sunk: var(--surface-2); --sheet: var(--sh-3); --shadow: var(--sh-1);
  --bar: var(--appbar-h);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --a-ink: #93c5fd;
    --bg: #0c0b12; --surface: #16151f; --surface-2: #211f2e; --surface-3: #2c2a3c;
    --text: #f3f2fa; --muted: #a4a1ba;
    --border: rgba(255, 255, 255, .09); --border-strong: #77748f;
    --glass: rgba(22, 21, 31, .66); --glass-strong: rgba(22, 21, 31, .88); --glass-border: rgba(255, 255, 255, .09);
    --scrim: rgba(0, 0, 0, .6);
    --toast-bg: rgba(243, 242, 250, .96); --toast-fg: #15131f;
    --success: #34d399; --warn: #fbbf24; --danger: #f87171;
    --sh-1: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .3);
    --sh-2: 0 2px 4px rgba(0, 0, 0, .45), 0 12px 28px rgba(0, 0, 0, .45);
    --sh-3: 0 4px 8px rgba(0, 0, 0, .5), 0 20px 44px rgba(0, 0, 0, .6);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --a-ink: #93c5fd;
  --bg: #0c0b12; --surface: #16151f; --surface-2: #211f2e; --surface-3: #2c2a3c;
  --text: #f3f2fa; --muted: #a4a1ba;
  --border: rgba(255, 255, 255, .09); --border-strong: #77748f;
  --glass: rgba(22, 21, 31, .66); --glass-strong: rgba(22, 21, 31, .88); --glass-border: rgba(255, 255, 255, .09);
  --scrim: rgba(0, 0, 0, .6);
  --toast-bg: rgba(243, 242, 250, .96); --toast-fg: #15131f;
  --success: #34d399; --warn: #fbbf24; --danger: #f87171;
  --sh-1: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .3);
  --sh-2: 0 2px 4px rgba(0, 0, 0, .45), 0 12px 28px rgba(0, 0, 0, .45);
  --sh-3: 0 4px 8px rgba(0, 0, 0, .5), 0 20px 44px rgba(0, 0, 0, .6);
}
:root[data-theme="light"] { color-scheme: light; }

/* -------------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: var(--fs-base); line-height: 1.5; font-weight: 500;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overscroll-behavior-y: none;
}
h1, h2, h3, h4 { font-family: var(--font); font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; touch-action: manipulation; }
a { color: var(--a-ink); }
.hidden, [hidden] { display: none !important; }
.muted { color: var(--muted); }

/* Aurora: a faint two-colour glow behind the top of the screen. Pure gradients. */
body::before {
  content: ""; position: fixed; inset: 0 0 auto 0; height: min(60vh, 460px); z-index: -1; pointer-events: none;
  background:
    radial-gradient(60% 70% at 15% 0%, color-mix(in srgb, var(--a1-vivid) 20%, transparent), transparent 70%),
    radial-gradient(55% 65% at 90% 0%, color-mix(in srgb, var(--a2-vivid) 16%, transparent), transparent 70%);
}

:focus { outline: none; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
:root[data-theme="dark"] :focus-visible { outline-color: var(--a-ink); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) :focus-visible { outline-color: var(--a-ink); } }

/* Icons: an inline-sprite <svg class="i">. (`.ic` here is the older name for a
   glyph *slot*, so the SVG itself is `.i`.) */
.i { width: 22px; height: 22px; flex: none; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.i.sm { width: 18px; height: 18px; }
.i.lg { width: 28px; height: 28px; }

.grad-text { background: var(--grad); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent; }
:root[data-theme="dark"] .grad-text { background: linear-gradient(135deg, var(--a1-vivid), var(--a2-vivid)); -webkit-background-clip: text; background-clip: text; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .grad-text { background: linear-gradient(135deg, var(--a1-vivid), var(--a2-vivid)); -webkit-background-clip: text; background-clip: text; }
}

/* No backdrop-filter? Fall back to solid so text stays legible. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root { --glass: var(--surface); --glass-strong: var(--surface); }
}

@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes pop-in { from { opacity: 0; transform: scale(.92) translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes pop-center { from { opacity: 0; transform: translateY(-46%) scale(.95); } to { opacity: 1; transform: translateY(-50%) scale(1); } }
@keyframes rise { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes float { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-6px) rotate(2deg); } }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes toast-in {
  0% { opacity: 0; transform: translateX(-50%) translateY(18px) scale(.9); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

/* ------------------------------------------------------------------ chrome */

.topbar {
  position: sticky; top: 0; z-index: var(--z-bar);
  display: flex; align-items: center; gap: var(--s-2);
  min-height: calc(var(--appbar-h) + var(--safe-t));
  padding: var(--safe-t) max(var(--s-3), var(--safe-r)) 0 max(var(--s-3), var(--safe-l));
  background: var(--glass); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border-bottom: 1px solid var(--glass-border);
}
.topbar h1 { font-size: var(--fs-lg); margin: 0; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 2px 0; }

.iconbtn {
  position: relative; width: 44px; height: 44px; border: 0; border-radius: 14px; padding: 0;
  display: grid; place-items: center; background: transparent; color: var(--text); flex: none;
  transition: transform var(--dur-1) var(--ease-out), background-color var(--dur-2);
}
@media (hover: hover) { .iconbtn:hover { background: var(--surface-2); } }
.iconbtn:active { transform: scale(.9); background: var(--surface-3); }
.iconbtn[aria-pressed="true"] { background: var(--grad); color: #fff; box-shadow: var(--glow); }
.iconbtn:disabled { opacity: .4; cursor: default; }

main { padding: 14px 14px calc(var(--dock-clear) + var(--safe-b)); max-width: 1100px; margin: 0 auto; }

/* ----------------------------------------------------------------- library */

.searchrow { display: flex; gap: var(--s-2); margin-bottom: var(--s-3); }
.search {
  flex: 1; display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 8px 0 16px;
  background: var(--surface-2); border: 1.5px solid transparent; border-radius: var(--r-pill);
  transition: border-color var(--dur-2), box-shadow var(--dur-2), background-color var(--dur-2);
}
.search:focus-within { background: var(--surface); border-color: var(--a1-vivid);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--a1-vivid) 24%, transparent); }
.search > .i { color: var(--muted); }
.search input { flex: 1; border: 0; background: none; outline: none; padding: 10px 0; min-width: 0; font-size: 16px; }
.search input:focus-visible { outline: none; }
.search input::placeholder { color: var(--muted); opacity: .85; }
/* type=search brings its own clear button; the row already has one. */
.search input::-webkit-search-cancel-button, .search input::-webkit-search-decoration { display: none; }
.search .clear { flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%; padding: 0;
  display: grid; place-items: center; background: var(--surface-3); color: var(--muted); position: relative; }
.search .clear::after { content: ""; position: absolute; inset: -6px; }
.search .clear .i { width: 16px; height: 16px; stroke-width: 2.6; }

/* Edge to edge (negative margin) with padding to match, so the active chip's
   glow is not sliced off by the scroller and the row scrolls under the gutters. */
.chips { display: flex; gap: var(--s-2); overflow-x: auto; margin: -6px -14px -6px; padding: 8px 14px 16px; scrollbar-width: none;
  -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
.chips::-webkit-scrollbar { display: none; }
.chips > * { scroll-snap-align: start; scroll-margin-left: 14px; }
.chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 8px 16px;
  border: 1.5px solid var(--border); border-radius: var(--r-pill); background: var(--surface); color: var(--muted);
  font-size: 14px; font-weight: 700; white-space: nowrap;
  transition: transform var(--dur-1) var(--ease-out), background-color var(--dur-2), color var(--dur-2), border-color var(--dur-2);
}
.chip:active { transform: scale(.94); }
.chip[aria-pressed="true"] { background: var(--grad); border-color: transparent; color: #fff; box-shadow: var(--glow); }
.chip .i { width: 16px; height: 16px; }
.chip.dashed { border-style: dashed; border-color: var(--a1-vivid); color: var(--a-ink); background: transparent; }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }

/* List: a row per document, small thumbnail, easy to scan a long library. */
.list { display: flex; flex-direction: column; gap: 8px; }
.list .doc { flex-direction: row; align-items: center; gap: 12px; border-radius: var(--r-md); min-height: 62px; }
.list .doc:hover { transform: none; }
.list .doc .thumb { aspect-ratio: 1; width: 46px; flex: none; margin: 8px 0 8px 8px; border: 1px solid var(--border);
  border-radius: 12px; }
.list .doc .thumb::after { display: none; } /* no PDF ribbon on a 46px thumb */
.list .doc .thumb .ph .i { width: 22px; height: 22px; }
.list .doc .meta { padding: 8px 52px 8px 0; min-width: 0; flex: 1; }
.list .doc .name { -webkit-line-clamp: 1; }
.list .doc .snip { display: none; } /* content-search snippets stay in the grid, where there's room */
.list .doc.folder .thumb { aspect-ratio: 1; }
.list .doc .more { top: 50%; transform: translateY(-50%); }
.list .doc .pick { top: 50%; left: 18px; margin-top: -13px; }

/* Wrapping (not scrolling) so a button that doesn't fit drops to its own line
   on any screen instead of vanishing off an edge. */
.listbar {
  display: flex; align-items: center; justify-content: flex-start; gap: 8px;
  row-gap: 8px; flex-wrap: wrap; margin: 2px 0 12px;
}
.listbar-btn {
  display: inline-flex; align-items: center; gap: 6px; flex: none; white-space: nowrap;
  min-height: 40px; padding: 6px 14px; border: 0; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--text); font-weight: 700; font-size: 13px; position: relative;
  transition: transform var(--dur-1) var(--ease-out), background-color var(--dur-2);
}
.listbar-btn::after { content: ""; position: absolute; inset: -2px 0; }
.listbar-btn:active { transform: scale(.95); background: var(--surface-3); }
.listbar-btn .i { width: 17px; height: 17px; color: var(--a-ink); }
.listbar-btn.iconbtn { width: 40px; height: 40px; padding: 0; justify-content: center; border-radius: 14px; }

.doc {
  position: relative; display: flex; flex-direction: column; padding: 0; overflow: hidden; text-align: left; color: inherit;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1);
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2), border-color var(--dur-2);
}
@media (hover: hover) { .doc:hover { transform: translateY(-3px); box-shadow: var(--sh-2); } }
.doc:active { transform: scale(.975); transition-duration: var(--dur-1); }
.doc .thumb {
  position: relative; aspect-ratio: 3 / 4; display: grid; place-items: center; overflow: hidden;
  background: var(--grad-soft); border-bottom: 1px solid var(--border);
}
.doc .thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top; background: #fff; }
.doc .thumb .ph { color: var(--a-ink); opacity: .8; display: grid; place-items: center; }
.doc .thumb .ph .i { width: 34px; height: 34px; stroke-width: 1.75; }
/* File-type ribbon lives on .thumb (not .ph): thumbnails replace the .ph. */
.doc:not(.folder) .thumb::after {
  content: attr(data-ext); position: absolute; left: 8px; bottom: 8px; padding: 4px 7px; border-radius: 7px;
  background: var(--grad); color: #fff; font: 800 10px/1 var(--font); letter-spacing: .07em; box-shadow: var(--sh-1);
}
.doc .meta { padding: 10px 12px 12px; }
.doc .name { font-size: 14px; font-weight: 700; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.doc .sub { font-size: 12px; color: var(--muted); margin-top: 3px; }
.doc .snip { font-size: 11.5px; color: var(--muted); margin-top: 6px; border-top: 1px dashed var(--border);
  padding-top: 6px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.doc .snip mark { background: color-mix(in srgb, var(--a1-vivid) 30%, transparent); color: inherit; border-radius: 3px; }
.doc .more {
  position: absolute; top: 8px; right: 8px; width: 34px; height: 34px; border-radius: 12px; border: 0;
  display: grid; place-items: center; color: var(--text);
  background: var(--glass-strong); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.doc .more, .doc .pick { z-index: 2; }
.doc .more::after { content: ""; position: absolute; inset: -6px; }
.doc .more .i { width: 20px; height: 20px; }
.doc .pick {
  position: absolute; top: 8px; left: 8px; width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid #fff; background: rgba(0, 0, 0, .32); display: none; place-items: center; color: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}
.doc .pick .i { width: 15px; height: 15px; stroke-width: 3.2; opacity: 0; transform: scale(.5);
  transition: opacity var(--dur-1), transform var(--dur-2) var(--ease-spring); }
body.picking .doc .pick { display: grid; }
body.picking .doc .more { display: none; }
.doc[aria-selected="true"] { outline: 3px solid var(--a1-vivid); outline-offset: -2px; transform: scale(.97); }
.doc[aria-selected="true"] .pick { background: var(--grad); }
.doc[aria-selected="true"] .pick .i { opacity: 1; transform: none; }

.doc.folder .thumb { aspect-ratio: 3 / 2; }
.doc.folder .thumb .ph { opacity: 1; }
.doc.folder .thumb .ph .i { width: 44px; height: 44px; stroke-width: 1.6; fill: color-mix(in srgb, var(--a1-vivid) 22%, transparent); }
.list .doc.folder .thumb .ph .i { width: 24px; height: 24px; }

.section-title {
  font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 22px 4px 10px;
}

.empty { text-align: center; color: var(--muted); padding: 56px 24px; display: flex; flex-direction: column; align-items: center; }
.empty .big, .gate .big {
  width: 92px; height: 92px; margin: 0 auto 18px; border-radius: 32px; display: grid; place-items: center;
  background: var(--grad-soft); color: var(--a-ink);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--a1-vivid) 25%, transparent);
  animation: float 4.5s ease-in-out infinite;
}
.empty .big .i, .gate .big .i { width: 42px; height: 42px; stroke-width: 1.75; }
.empty h2, .empty strong { color: var(--text); font-weight: 800; }
.empty p { margin: 6px 0; max-width: 34ch; font-size: 15px; }
.empty .btn { margin-top: 14px; }

.usage { display: flex; align-items: center; gap: 10px; margin: 22px 2px 0; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.usage .track { flex: 1; height: 6px; background: var(--surface-2); border-radius: 99px; overflow: hidden; }
.usage .fill { display: block; height: 100%; background: var(--grad); border-radius: inherit; }

/* Skeletons: same shapes as the real tiles so nothing jumps when they land. */
.sk {
  border-radius: var(--r-md);
  background: linear-gradient(90deg, var(--surface-2) 30%, color-mix(in srgb, var(--surface-2) 55%, var(--surface)) 50%, var(--surface-2) 70%);
  background-size: 200% 100%; animation: shimmer 1.6s linear infinite;
}
.sk.doc { aspect-ratio: 3 / 5; border-radius: var(--r-lg); border: 0; box-shadow: none; }
.sk.row { height: 62px; }

/* List entrance: added by ui.js enter() on navigation only, never on a keystroke. */
.stagger > * { animation: rise var(--dur-3) var(--ease-out) both; }
.stagger > :nth-child(2) { animation-delay: 30ms; } .stagger > :nth-child(3) { animation-delay: 60ms; }
.stagger > :nth-child(4) { animation-delay: 90ms; } .stagger > :nth-child(5) { animation-delay: 120ms; }
.stagger > :nth-child(6) { animation-delay: 150ms; } .stagger > :nth-child(7) { animation-delay: 180ms; }
.stagger > :nth-child(8) { animation-delay: 210ms; } .stagger > :nth-child(9) { animation-delay: 240ms; }
.stagger > :nth-child(10) { animation-delay: 270ms; } .stagger > :nth-child(n+11) { animation-delay: 300ms; }

/* --------------------------------------------------------------------- fab */

.fab {
  position: fixed; right: max(16px, var(--safe-r)); bottom: calc(var(--fab-bottom) + var(--safe-b)); z-index: var(--z-fab);
  width: var(--fab-size); height: var(--fab-size); border: 0; border-radius: 22px; padding: 0; display: grid; place-items: center;
  background: var(--grad); color: #fff; font-size: 0; line-height: 0; box-shadow: var(--glow-lg);
  transition: transform var(--dur-2) var(--ease-spring), box-shadow var(--dur-2), opacity var(--dur-2);
}
.fab .i { width: 28px; height: 28px; stroke-width: 2.6; transition: transform var(--dur-3) var(--ease-spring); }
@media (hover: hover) { .fab:hover { transform: translateY(-2px) scale(1.04); } .fab:hover .i { transform: rotate(90deg); } }
.fab:active { transform: scale(.9); }
/* Picking documents: the selection bar owns the bottom edge. */
body.picking .fab { opacity: 0; transform: scale(.6); pointer-events: none; }

/* ------------------------------------------------------------ sheet/dialog */

/* Above .busy (z-index 80): a sheet can legitimately open while a batch
   operation is already showing its spinner - the password prompt during a
   multi-file upload is exactly this - and a modal asking for input must
   always be reachable, never trapped behind a passive progress indicator. */
.scrim { position: fixed; inset: 0; background: var(--scrim); z-index: var(--z-scrim); animation: fade-in var(--dur-2) var(--ease-out); }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sheet); margin: 0 auto; max-width: 560px;
  max-height: min(88vh, 88dvh); overflow: auto; overscroll-behavior: contain;
  padding: 10px var(--s-3) calc(var(--s-4) + var(--safe-b));
  background: var(--surface); border-radius: var(--r-xl) var(--r-xl) 0 0; box-shadow: var(--sh-3);
  border: 1px solid var(--border); border-bottom: 0;
  animation: sheet-up var(--dur-3) var(--ease-out);
}
.sheet .grab { width: 42px; height: 5px; border-radius: 99px; background: var(--border-strong); opacity: .5; margin: 2px auto 14px; }
.sheet h2 { font-size: var(--fs-lg); margin: 2px 8px 12px; }
.opt {
  display: flex; align-items: center; gap: 14px; width: 100%; min-height: 56px; padding: 8px 10px; border: 0; background: none;
  border-radius: var(--r-md); text-align: left; color: inherit;
  transition: background-color var(--dur-2), transform var(--dur-1) var(--ease-out);
}
.opt:active { transform: scale(.98); background: var(--surface-2); }
@media (hover: hover) { .opt:hover { background: var(--surface-2); } }
.opt .ic {
  width: 42px; height: 42px; border-radius: 14px; flex: none; display: grid; place-items: center; overflow: hidden;
  background: var(--grad-soft); color: var(--a-ink); font-size: 18px; font-weight: 800;
}
.opt[aria-pressed="true"] .ic { background: var(--grad); color: #fff; }
.opt .t { font-size: 15.5px; font-weight: 700; }
.opt .d { font-size: var(--fs-sm); color: var(--muted); margin-top: 1px; }
.opt.danger .t { color: var(--danger); }
.opt.danger .ic { background: var(--danger-soft); color: var(--danger); }

.field { margin: 10px 4px 14px; }
.field label { display: block; font-size: 12.5px; font-weight: 700; color: var(--muted); margin-bottom: 6px; }
.field input, .field textarea, .field select {
  width: 100%; min-height: 48px; padding: 12px 14px; font-size: 16px; color: var(--text);
  background: var(--surface-2); border: 1.5px solid transparent; border-radius: var(--r-md); outline: none;
  transition: border-color var(--dur-2), box-shadow var(--dur-2), background-color var(--dur-2);
}
.field input::placeholder, .field textarea::placeholder { color: var(--muted); opacity: .85; }
.field input:focus, .field textarea:focus, .field select:focus {
  background: var(--surface); border-color: var(--a1-vivid);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--a1-vivid) 24%, transparent);
}
.field textarea { min-height: 180px; resize: vertical; line-height: 1.55; }
.row { display: flex; gap: var(--s-2); }
.btn {
  position: relative; flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 12px 20px; border: 0; border-radius: var(--r-md);
  background: var(--grad); color: #fff; font-weight: 700; font-size: 15.5px; letter-spacing: -.005em; text-decoration: none;
  box-shadow: var(--glow);
  transition: transform var(--dur-1) var(--ease-out), box-shadow var(--dur-2), background-color var(--dur-2), filter var(--dur-2);
}
@media (hover: hover) { .btn:hover { filter: brightness(1.08) saturate(1.05); } }
.btn:active { transform: scale(.97); }
.btn.ghost { background: transparent; color: var(--text); box-shadow: inset 0 0 0 1.5px var(--border); }
@media (hover: hover) { .btn.ghost:hover { background: var(--surface-2); filter: none; } }
.btn.danger { background: var(--danger); color: #fff; box-shadow: none; }
.btn.ghost.danger { background: var(--danger-soft); color: var(--danger); box-shadow: none; }
.btn:disabled { opacity: .5; pointer-events: none; }
.btn .i { width: 19px; height: 19px; }

/* ------------------------------------------------------------------ viewer */

#viewer { display: flex; flex-direction: column; height: calc(100dvh - var(--appbar-h) - var(--safe-t)); }
#pages {
  flex: 1; overflow: auto; padding: 14px 10px calc(96px + var(--safe-b));
  background: var(--surface-2); scroll-behavior: smooth;
}
/* Pages are paper: they must stay white in dark mode. */
.pagewrap {
  position: relative; margin: 0 auto 14px; background: #fff; box-shadow: var(--sh-2);
  width: fit-content; border-radius: 6px; overflow: hidden;
}
.pagewrap canvas { display: block; max-width: 100%; height: auto; }
/* An invisible copy of the page's text, positioned over the picture of it, so
   selection and copy work the way they do in any other PDF reader. The text
   itself stays invisible (each span is color: transparent - the canvas
   underneath already drew the glyphs), but the *layer* is kept fully opaque
   so the browser's own selection highlight - which paints on this layer, not
   the canvas - is not also crushed to invisible by the opacity. */
.textlayer {
  position: absolute; inset: 0; overflow: hidden; opacity: 1; line-height: 1;
  user-select: text; -webkit-user-select: text;
}
.textlayer span { position: absolute; white-space: pre; transform-origin: 0 0; color: transparent; }
.textlayer ::selection { background: color-mix(in srgb, var(--a1-vivid) 45%, transparent); }
.textlayer ::-moz-selection { background: color-mix(in srgb, var(--a1-vivid) 45%, transparent); }
/* Debug aid (Document menu, "Show the text layer"): tints the selectable boxes. */
.textlayer.visible span { background: color-mix(in srgb, var(--a1-vivid) 18%, transparent); outline: 1px solid color-mix(in srgb, var(--a1-vivid) 35%, transparent); }
.hl { position: absolute; background: color-mix(in srgb, #fbbf24 55%, transparent); border-radius: 2px; pointer-events: none; }
.hl.on { background: color-mix(in srgb, var(--a1-vivid) 55%, transparent); }
.pagenum { position: absolute; right: 8px; bottom: 6px; font-size: 11px; font-weight: 700; color: var(--muted);
  background: var(--glass-strong); padding: 2px 8px; border-radius: 8px; }

/* The tool dock: a floating glass pill (the viewer's tools, the selection bar,
   the save bar and the share page's tools all share it). */
.toolbar {
  position: fixed; left: 50%; transform: translateX(-50%); right: auto; bottom: calc(12px + var(--safe-b)); z-index: var(--z-dock);
  display: flex; align-items: center; justify-content: center; gap: 2px; padding: 6px;
  width: auto; max-width: calc(100vw - 24px);
  border-radius: var(--r-pill); background: var(--glass-strong);
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  border: 1px solid var(--glass-border); box-shadow: var(--sh-3);
  animation: pop-dock var(--dur-3) var(--ease-spring) both;
}
@keyframes pop-dock { from { opacity: 0; transform: translateX(-50%) translateY(16px) scale(.94); } to { opacity: 1; transform: translateX(-50%); } }
/* The save/selection bars take over the same spot: don't let the viewer's own
   (wider) dock show around their edges. */
body:has(.savebar) #viewer-tools { visibility: hidden; }
.tool {
  position: relative; isolation: isolate; flex: 1 1 auto; min-width: 56px; min-height: 52px;
  display: grid; place-items: center; align-content: center; justify-items: center; gap: 3px;
  padding: 6px 10px; border: 0; background: none; border-radius: var(--r-pill);
  color: var(--muted); font: 700 10.5px/1 var(--font); letter-spacing: .01em; white-space: nowrap;
  transition: color var(--dur-2), transform var(--dur-1) var(--ease-out);
}
.tool .ic { display: grid; place-items: center; }
.tool .ic .i { width: 22px; height: 22px; transition: transform var(--dur-3) var(--ease-spring); }
.tool::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--grad);
  opacity: 0; transform: scale(.55);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-3) var(--ease-spring);
}
.tool:active { transform: scale(.92); }
@media (hover: hover) { .tool:hover { color: var(--text); } }
.tool[aria-pressed="true"], .tool.primary { color: #fff; }
.tool[aria-pressed="true"]::before, .tool.primary::before { opacity: 1; transform: scale(1); box-shadow: var(--glow); }
.tool[aria-pressed="true"] .ic .i { transform: translateY(-1px) scale(1.08); }
.tool:disabled { opacity: .4; }

/* Region capture: drag a box on the page to copy or lift it out. */
.capture { position: absolute; inset: 0; cursor: crosshair; background: rgba(10, 12, 16, .28); }
.capture .box { position: absolute; border: 2px solid var(--a1-vivid); background: rgba(255, 255, 255, .12);
  box-shadow: 0 0 0 9999px rgba(10, 12, 16, .28); }

/* Signature pad */
.padwrap { border: 1.5px dashed var(--border-strong); border-radius: var(--r-md); background: var(--surface-2);
  position: relative; overflow: hidden; }
.padwrap canvas { display: block; width: 100%; height: 190px; touch-action: none; }
.padwrap .hintline { position: absolute; left: 8%; right: 8%; bottom: 46px; border-bottom: 1px solid var(--border-strong); opacity: .5; }
.padwrap .hint { position: absolute; left: 0; right: 0; bottom: 16px; text-align: center;
  font-size: 12.5px; color: var(--muted); pointer-events: none; }

/* A stamp being positioned before it is committed to the page. */
.placing { position: absolute; z-index: 5; border: 1.5px dashed var(--a1-vivid);
  background: color-mix(in srgb, var(--a1-vivid) 8%, transparent); touch-action: none; }
.placing img { width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
.placing .grip { position: absolute; right: -11px; bottom: -11px; width: 24px; height: 24px;
  border-radius: 50%; background: var(--grad); border: 2px solid #fff; box-shadow: var(--sh-1); touch-action: none; }
.placing .txt { padding: 2px 4px; white-space: pre; font-family: Helvetica, Arial, sans-serif; }

/* ---------------------------------------------------------------- ai panel */

.chat { display: flex; flex-direction: column; gap: 10px; max-height: 52vh; overflow: auto; padding: 4px; }
.msg { padding: 10px 14px; border-radius: 18px; font-size: 14.5px; max-width: 88%; white-space: pre-wrap; }
.msg.me { background: var(--grad); color: #fff; align-self: flex-end; border-bottom-right-radius: 6px; }
.msg.ai { background: var(--surface-2); align-self: flex-start; border-bottom-left-radius: 6px; }
.msg.err { background: var(--danger-soft); color: var(--danger); align-self: flex-start; }
.asking { display: flex; gap: 5px; padding: 12px; align-self: flex-start; }
.asking i { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); animation: bob 1.1s infinite; }
.asking i:nth-child(2) { animation-delay: .15s; }
.asking i:nth-child(3) { animation-delay: .3s; }
@keyframes bob { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-4px); } }

.suggest { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0 10px; }
.suggest button { min-height: 40px; border: 1.5px solid var(--border); background: var(--surface); color: var(--muted);
  border-radius: var(--r-pill); padding: 6px 14px; font-size: 13.5px; font-weight: 700; }
.suggest button:active { transform: scale(.95); }

/* -------------------------------------------------------------- feedback --- */

.toast {
  position: fixed; left: 50%; width: max-content; bottom: calc(96px + var(--safe-b)); transform: translateX(-50%); z-index: var(--z-toast);
  max-width: min(92vw, 460px); padding: 12px 20px; border-radius: 22px; text-align: center;
  background: var(--toast-bg); color: var(--toast-fg); font-size: 14.5px; font-weight: 600;
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  box-shadow: var(--sh-3); animation: toast-in var(--dur-3) var(--ease-spring) both;
}
.toast.err { background: var(--danger); color: #fff; }
.progress { position: fixed; top: 0; left: 0; height: 3px; background: var(--grad); z-index: var(--z-progress);
  border-radius: 0 3px 3px 0; transition: width .18s ease; }
.busy { position: fixed; inset: 0; z-index: var(--z-busy); display: grid; place-items: center;
  background: color-mix(in srgb, var(--bg) 72%, transparent); animation: fade-in var(--dur-2) var(--ease-out); }
.busy .box { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 22px 28px;
  box-shadow: var(--sh-3); text-align: center; font-size: 14.5px; font-weight: 600; animation: pop-in var(--dur-2) var(--ease-spring); }
.spin { width: 28px; height: 28px; margin: 0 auto 12px; border: 3px solid var(--surface-3);
  border-top-color: var(--a1-vivid); border-radius: 50%; animation: spin .8s linear infinite; }

.gate { display: grid; place-items: center; min-height: 70vh; text-align: center; padding: 20px; }
.gate h2 { font-size: var(--fs-xl); margin: 0 0 4px; }
.note { font-size: 13px; color: var(--muted); background: var(--surface-2); border-radius: var(--r-md);
  padding: 10px 14px; margin: 10px 4px; }
.note.warn { color: var(--warn); background: var(--warn-soft); }

@media (min-width: 720px) {
  .sheet { bottom: auto; top: 50%; transform: translateY(-50%); border-radius: var(--r-xl); border-bottom: 1px solid var(--border);
    max-height: 82vh; animation: pop-center var(--dur-3) var(--ease-out); }
}

/* The file tree: the vault browsed by path. The breadcrumb spans the whole
   grid so the cards below it stay on the same rhythm as everywhere else. */
.crumbs {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 2px;
  font-size: 13.5px; font-weight: 600; color: var(--muted); margin: -2px 0 2px;
}
.crumb { border: 0; background: none; padding: 6px 8px; min-height: 36px; border-radius: var(--r-xs);
  color: var(--a-ink); font: inherit; font-weight: 700; cursor: pointer; }
.crumb:hover { background: var(--surface-2); }
.crumb.current { color: var(--text); font-weight: 800; cursor: default; display: inline-flex; align-items: center; }
.crumb-sep { opacity: .5; }

/* Note saying how many filed files the visibility setting is hiding. */
.kind-hint { grid-column: 1 / -1; font-size: 13px; color: var(--muted); margin: 0 0 10px; }
.kind-hint button { color: var(--a-ink); background: none; border: 0; padding: 4px 0; font: inherit; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }

/* share.html's "View only" / "Can edit" pill, next to the document title. */
.badge {
  display: inline-flex; align-items: center; gap: 4px; flex: none; font-size: 12px; font-weight: 700; line-height: 1;
  padding: 6px 12px; border-radius: var(--r-pill); background: var(--grad-soft); color: var(--a-ink);
}

/* ---------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    animation-delay: 0s !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
  .fab:hover, .doc:hover { transform: none; }
  .spin { animation: spin 1.4s linear infinite !important; }
  .sk { animation: none !important; }
}

/* App logo beside the title on the library screen only (back button hidden). */
.topbar .brand-logo{display:none;width:34px;height:34px;border-radius:10px;flex:none;box-shadow:var(--sh-1)}
.topbar #back[hidden] + .brand-logo{display:block}

/* ------------------------------------------------ hub ✦ assistant: room for it
   Only present for admins/Elite users (html.hub-agent-on). Where the FAB is
   hidden (picking, viewer) the dock owns the bottom edge (bottom 12px, 66px
   tall); ✦ stacks 12px above it, at the plain right edge. */
body.picking, body.viewing { --hub-agent-bottom: calc(12px + 66px + 12px); --hub-agent-right: max(16px, var(--safe-r)); }
html.hub-agent-on main { padding-bottom: calc(var(--dock-clear) + 62px + var(--safe-b)); }
html.hub-agent-on #pages { padding-bottom: calc(96px + 60px + var(--safe-b)); }

/* Legacy-host notice (host-move.js): Docs is now Pagejo. */
.move-notice {
  position: fixed; left: 50%; top: calc(24px + var(--safe-t, 0px)); transform: translateX(-50%); z-index: var(--z-progress);
  width: min(92vw, 420px); padding: 14px 20px; border-radius: 22px; text-align: center;
  background: var(--toast-bg); color: var(--toast-fg); font-size: 14.5px; font-weight: 600;
  -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
  box-shadow: var(--sh-3); animation: fade-in var(--dur-3) var(--ease-out) both;
}
.move-notice p { margin: 10px 0 14px; font-weight: 500; font-size: 13.5px; line-height: 1.45; opacity: .9; }
.move-notice .btn { width: 100%; }
