/* ============================================================
   DocAct - design system (POC v2)
   ------------------------------------------------------------
   Plain HTML/CSS, no build, no Tailwind, no external fonts.
   Two independent theming axes:
     - SURFACE theme (chrome / backgrounds)        → [data-theme]
     - WHITE-LABEL brand (accent only, per tenant) → --brand / --brandacc
   Every component below renders correctly under any combination.
   ============================================================ */


/* ────────────────────────────────────────────────────────────
   1. TOKENS - default surface theme: NAVY + GOLD (light)
   ──────────────────────────────────────────────────────────── */
:root,
[data-theme="navy-gold"],
[data-theme-base="navy-gold"]{
  /* surface - cool near-white with a whisper of the navy brand hue (never a
     warm-cream default); the committed navy + gold below are untouched */
  --bg:            #f4f6fa;   /* cool near-white, navy-tinted */
  --bg-elev:       #e9edf4;
  --paper:         #ffffff;   /* card surface */
  --paper-2:       #f6f8fb;   /* subtle inner panel, a hair cooler than paper */
  --line:          #e4e8f0;   /* cool hairline */
  --line-strong:   #c3ccda;
  --ink:           #14182a;   /* body text */
  --ink-strong:    #0a0d18;
  --ink-muted:     #5c6373;   /* AA on --paper/--bg (5.5-6.0:1) */
  --ink-faint:     #636a79;   /* AA on --paper and --bg (5.0-5.4:1) */

  /* chrome (topbar / sidebar in this theme) */
  --chrome:        #0b1730;   /* deep navy */
  --chrome-2:      #142450;
  --chrome-line:   #1f3266;
  --chrome-ink:    #e8ddb8;
  --chrome-muted:  #9aa6c1;

  /* white-label brand defaults (tenant may override) */
  --brand:         #0b1730;   /* deep navy */
  --brand-ink:     #ffffff;   /* text on brand */
  --brand-soft:    #e6e1cf;   /* tinted background hint */
  --brand-soft-ink:#1a2440;
  --brandacc:      #b08c4a;   /* antique gold accent */
  --brandacc-ink:  #2a1f08;   /* text on solid --brandacc */
  --brandacc-soft: #efe2bf;
  --brandacc-soft-ink:#2a1f08;/* text on --brandacc-soft (e.g. .tag.gold) */

  /* status (theme-stable, slightly desaturated to match palette) */
  --ok:      #3e7d4f;  --ok-soft:   #dee9d8;  --ok-ink:   #1f3f28;
  --warn:    #a06b1d;  --warn-soft: #f1e1c1;  --warn-ink: #4a2f06;
  --bad:     #a93233;  --bad-soft:  #f1d6d4;  --bad-ink:  #4b0f10;  --bad-btn-ink: #ffffff; /* text on solid --bad */
  --info:    #2c5680;  --info-soft: #d8e3ef;  --info-ink: #14304b;

  /* focus + elevation */
  --focus:         color-mix(in srgb, var(--brand) 38%, transparent);
  --shadow-1:      0 1px 0 rgba(20,24,42,.04);
  --shadow-2:      0 1px 0 rgba(20,24,42,.04), 0 8px 24px -8px rgba(20,24,42,.16);
  --shadow-3:      0 2px 0 rgba(20,24,42,.04), 0 24px 60px -18px rgba(20,24,42,.28);

  /* radii / type */
  --r-xs: 4px;  --r-sm: 6px;  --r-md: 10px;  --r-lg: 14px;  --r-xl: 20px;
  --serif: "Iowan Old Style", "Hoefler Text", "Apple Garamond", "Garamond", "Cambria", Georgia, serif;
  --sans:  ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", sans-serif;
  --mono:  ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;

  color-scheme: light;
}


/* ────────────────────────────────────────────────────────────
   2. SURFACE THEMES (additional)
   ──────────────────────────────────────────────────────────── */

/* PARCHMENT - warm sepia, "old-world law office" */
[data-theme="parchment"],
[data-theme-base="parchment"]{
  --bg:#efe6cf; --bg-elev:#e7daba; --paper:#fbf4dd; --paper-2:#f6ecc6;
  --line:#d6c599; --line-strong:#b8a164;
  --ink:#2a200c; --ink-strong:#1a1206; --ink-muted:#6b5a30; --ink-faint:#716444;
  --chrome:#3a2a10; --chrome-2:#4b3818; --chrome-line:#604a25;
  --chrome-ink:#f3e4b7; --chrome-muted:#cfb87d;
  --brand:#5a3d12; --brand-ink:#fff7df; --brand-soft:#ead9a9; --brand-soft-ink:#3a2a10;
  --brandacc:#a96f1d; --brandacc-ink:#3a2206; --brandacc-soft:#f0d99a; --brandacc-soft-ink:#3a2206;
  --focus: color-mix(in srgb, var(--brand) 38%, transparent);
  color-scheme: light;
}

/* SLATE - cool neutral light */
[data-theme="slate"],
[data-theme-base="slate"]{
  --bg:#eef1f6; --bg-elev:#e2e7ef; --paper:#ffffff; --paper-2:#f6f8fb;
  --line:#dde3ec; --line-strong:#b5bfcf;
  --ink:#16202e; --ink-strong:#0b1320; --ink-muted:#5e6a7b; --ink-faint:#666d78;
  --chrome:#1a2638; --chrome-2:#243349; --chrome-line:#324560;
  --chrome-ink:#e2e7ef; --chrome-muted:#9ba7b9;
  --brand:#23436f; --brand-ink:#ffffff; --brand-soft:#dde3ec; --brand-soft-ink:#23436f;
  --brandacc:#3b6a99; --brandacc-ink:#ffffff; --brandacc-soft:#d3deeb; --brandacc-soft-ink:#0b1320;
  color-scheme: light;
}

/* MIDNIGHT - dark navy + gold */
[data-theme="midnight"],
[data-theme-base="midnight"]{
  --bg:#070d1b; --bg-elev:#0d152a; --paper:#101b36; --paper-2:#0b1426;
  --line:#1f2c4a; --line-strong:#33446b;
  --ink:#e7e2d0; --ink-strong:#f7f3df; --ink-muted:#9aa3b9; --ink-faint:#7a85a0;
  --chrome:#04081a; --chrome-2:#0a1330; --chrome-line:#1b264a;
  --chrome-ink:#e7e2d0; --chrome-muted:#8e98b3;
  --brand:#c79d57; --brand-ink:#0a0d18; --brand-soft:#1d2748; --brand-soft-ink:#e3c46d;
  --brandacc:#c79d57; --brandacc-ink:#0a0d18; --brandacc-soft:#1d2748; --brandacc-soft-ink:#e3c46d;
  --ok:#6fb37e; --ok-soft:#162d1b; --ok-ink:#cbe7c8;
  --warn:#d8a64f; --warn-soft:#2c1f06; --warn-ink:#f1deab;
  --bad:#d77476; --bad-soft:#2a0e10; --bad-ink:#f1c1c0; --bad-btn-ink:#2a0e10;
  --info:#7aa4cb; --info-soft:#0e1f30; --info-ink:#cfdfee;
  --shadow-1: 0 1px 0 rgba(0,0,0,.4);
  --shadow-2: 0 1px 0 rgba(0,0,0,.4), 0 8px 24px -8px rgba(0,0,0,.6);
  --shadow-3: 0 2px 0 rgba(0,0,0,.4), 0 24px 60px -16px rgba(0,0,0,.7);
  color-scheme: dark;
}

/* GRAPHITE - dark neutral */
[data-theme="graphite"],
[data-theme-base="graphite"]{
  --bg:#15171c; --bg-elev:#1d2027; --paper:#21252d; --paper-2:#1a1d24;
  --line:#2c313b; --line-strong:#3c424e;
  --ink:#e6e7ea; --ink-strong:#f6f7f9; --ink-muted:#a0a4ad; --ink-faint:#878d9b;
  --chrome:#0e1014; --chrome-2:#181b22; --chrome-line:#2a2f3a;
  --chrome-ink:#e6e7ea; --chrome-muted:#9499a3;
  --brand:#d6d2c4; --brand-ink:#15171c; --brand-soft:#262a32; --brand-soft-ink:#e6e7ea;
  --brandacc:#bf975a; --brandacc-ink:#15171c; --brandacc-soft:#2a2620; --brandacc-soft-ink:#d9b56f;
  --ok:#6fb37e; --ok-soft:#16241b; --ok-ink:#cbe7c8;
  --warn:#d8a64f; --warn-soft:#2a1f06; --warn-ink:#f1deab;
  --bad:#d77476; --bad-soft:#2a0e10; --bad-ink:#f1c1c0; --bad-btn-ink:#2a0e10;
  --info:#7aa4cb; --info-soft:#0e1f30; --info-ink:#cfdfee;
  --shadow-1: 0 1px 0 rgba(0,0,0,.4);
  --shadow-2: 0 1px 0 rgba(0,0,0,.4), 0 8px 24px -8px rgba(0,0,0,.6);
  --shadow-3: 0 2px 0 rgba(0,0,0,.4), 0 24px 60px -16px rgba(0,0,0,.7);
  color-scheme: dark;
}


/* ────────────────────────────────────────────────────────────
   3. RESET + BASE
   ──────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body{
  font-family: var(--sans);
  font-size: 0.90625rem; /* 14.5px at the 16px default */
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern", "liga", "ss01";
}
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
hr { border: 0; border-top: 1px solid var(--line); margin: 16px 0; }

/* visible focus everywhere */
:where(a, button, [role="button"], input, select, textarea, [tabindex]):focus-visible{
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

::selection { background: var(--brandacc-soft); color: var(--brandacc-ink); }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after { animation: none !important; transition: none !important; }
}


/* ────────────────────────────────────────────────────────────
   4. TYPOGRAPHY
   ──────────────────────────────────────────────────────────── */
.font-serif { font-family: var(--serif); }
.font-sans  { font-family: var(--sans);  }
.font-mono  { font-family: var(--mono); font-size: .9em; }

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; letter-spacing: -.01em; margin: 0; color: var(--ink-strong); text-wrap: balance; }
h1 { font-size: 2rem;    line-height: 1.15; letter-spacing: -.015em; }
h2 { font-size: 1.5rem;  line-height: 1.2; }
h3 { font-size: 1.18rem; line-height: 1.3; }
h4 { font-size: 1rem;    line-height: 1.35; }

.eyebrow{
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.lead { color: var(--ink-muted); font-size: 1rem; margin: 4px 0 20px; max-width: 64ch; }
.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }

p { margin: 0 0 12px; text-wrap: pretty; }


/* ────────────────────────────────────────────────────────────
   5. WORDMARK (DocAct logo, structural class)
   ──────────────────────────────────────────────────────────── */
.wordmark{
  display: inline-flex; align-items: baseline; gap: 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.18rem;
  letter-spacing: -.01em;
  color: var(--chrome-ink);
}
.wordmark .doc { color: var(--chrome-ink); }
.wordmark .act { color: var(--brandacc); }
.wordmark .dot { color: var(--brandacc); margin: 0 1px; }
.wordmark .tld { font-style: italic; color: var(--brandacc); opacity: .85; }
.wordmark.lg { font-size: 1.7rem; }
.wordmark.xl { font-size: 2.2rem; }

/* tenant wordmark - solid, used in white-labelled chrome */
.tenant-mark{
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--serif); font-weight: 600; font-size: 1.05rem;
  color: var(--chrome-ink); letter-spacing: -.005em;
}
.tenant-mark .sigil{
  width: 32px; height: 32px;
  display: grid; place-items: center;
  background: var(--brandacc);
  color: var(--brandacc-ink);
  font-family: var(--serif); font-weight: 700;
  border-radius: var(--r-sm);
  font-size: .95rem;
  flex: none;
}


/* ────────────────────────────────────────────────────────────
   6. LAYOUT PRIMITIVES
   ──────────────────────────────────────────────────────────── */
.container { max-width: 1280px; margin: 0 auto; padding: 0 24px; }
.container.narrow { max-width: 880px; }
.container.wide { max-width: 1440px; }
/* Phones: keep an explicit horizontal gutter on the shell content so body
   text never sits flush against the viewport edge (impeccable
   body-text-viewport-edge fires under a 16px gap). 20px clears it with
   margin; vertical padding stays owned by the ≤880px shell rule. */
@media (max-width: 600px){
  .shell-main > .container{ padding-left: 20px; padding-right: 20px; }
}

.stack > * + * { margin-top: 12px; }
.stack-lg > * + * { margin-top: 20px; }
.stack-xl > * + * { margin-top: 32px; }

.row { display: flex; gap: 12px; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.row.between { justify-content: space-between; }
.row.end { justify-content: flex-end; }
.spacer { flex: 1; }

.grid { display: grid; gap: 16px; }
.grid.c2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid.c3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid.c4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.grid.c5 { grid-template-columns: repeat(5, minmax(0,1fr)); }
@media (max-width: 1024px){ .grid.c4, .grid.c5 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 720px) { .grid.c2, .grid.c3, .grid.c4, .grid.c5 { grid-template-columns: 1fr; } }


/* ────────────────────────────────────────────────────────────
   7. SHELL - topbar, sidebar, main (used in app + admin)
   ──────────────────────────────────────────────────────────── */
.shell{
  --shell-top: 60px;
  --shell-side: 244px;
  min-height: 100vh;
}
.shell-top{
  position: fixed; inset: 0 0 auto 0; z-index: 30;
  height: var(--shell-top);
  background: var(--chrome);
  color: var(--chrome-ink);
  display: flex; align-items: center; gap: 14px;
  padding: 0 18px;
  border-bottom: 1px solid var(--chrome-line);
}
.shell-top .divider{
  width: 1px; align-self: stretch;
  margin: 14px 2px;
  background: var(--chrome-line);
}
.shell-side{
  position: fixed;
  top: var(--shell-top); bottom: 0; left: 0;
  width: var(--shell-side);
  background: var(--paper);
  border-right: 1px solid var(--line);
  padding: 18px 12px 16px;
  overflow: auto;
  /* column layout so .sidebar-kbd can pin to the bottom of the rail */
  display: flex; flex-direction: column;
}
.shell-side > nav{ flex: none; }
.sidebar-kbd{
  margin-top: auto;
  padding: 10px 12px 0;
  border-top: 1px dashed var(--line);
  font-size: .78rem;
}
/* When the Control-panel foot is present it takes the free space above it, so
   the kbd block sits directly below it with just a small gap instead of its
   own auto-margin (which would split the two apart). */
.sidebar-foot + .sidebar-kbd{ margin-top: 12px; }
.sidebar-kbd a{ color: var(--ink-faint); }
.sidebar-kbd a:hover{ color: var(--ink-muted); }
.shell-main{
  margin-left: var(--shell-side);
  padding-top: var(--shell-top);
  min-height: 100vh;
}
.shell-main > .container { padding-top: 28px; padding-bottom: 80px; }

/* nav inside shell-side */
.nav-group { margin-top: 18px; }
.nav-group:first-child { margin-top: 4px; }
.nav-group > .label{
  font-size: .72rem; font-weight: 600; color: var(--ink-faint);
  padding: 6px 12px 8px;
}
.nav-item{
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 12px;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-weight: 500;
  font-size: .92rem;
  text-align: left;
  border-left: 2px solid transparent;
  background: none;
}
.nav-item:hover { background: var(--bg-elev); text-decoration: none; }
.nav-item[aria-current="page"], .nav-item.active{
  background: var(--brand-soft);
  color: var(--brand-soft-ink);
  border-left-color: var(--brandacc);
}
.nav-item .ic{ width: 18px; flex: none; opacity: .8; }
.nav-item .badge{
  margin-left: auto; min-width: 20px; padding: 1px 7px;
  border-radius: 999px; text-align: center;
  font-size: .72rem; font-weight: 700; font-family: var(--mono);
  background: var(--brandacc-soft); color: var(--brandacc-ink);
}
.sidebar-foot{
  margin-top: auto; padding: 10px 12px;
  border-top: 1px dashed var(--line);
  font-size: .82rem;
}
.sidebar-foot a{ display: block; color: var(--ink-muted); }
.sidebar-foot a:hover{ color: var(--brand-soft-ink); }


/* ────────────────────────────────────────────────────────────
   8. CARDS / PANELS
   ──────────────────────────────────────────────────────────── */
.card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
.card .ch{
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px;
}
.card .ch :is(h2, h3){ font-size: 1rem; font-family: var(--serif); }
.card .cb{ padding: 18px; }
.card .cf{ padding: 12px 18px; border-top: 1px solid var(--line); background: var(--paper-2); border-radius: 0 0 var(--r-lg) var(--r-lg); }
.card.flush .cb{ padding: 0; }
/* Round the corners of a table inside `.card.flush` per-cell instead of via
   `overflow: hidden` on the table - `overflow: hidden` clipped per-row
   `<details class="row-popover">` popovers (Edit / Invite admin / Delete)
   so the form contents fell inside the table's clip rect and looked empty. */
.card.flush table { border-radius: 0 0 var(--r-lg) var(--r-lg); }
.card.flush table thead tr:first-child th:first-child { border-top-left-radius: var(--r-lg); }
.card.flush table thead tr:first-child th:last-child  { border-top-right-radius: var(--r-lg); }
.card.flush table tbody tr:last-child  td:first-child { border-bottom-left-radius: var(--r-lg); }
.card.flush table tbody tr:last-child  td:last-child  { border-bottom-right-radius: var(--r-lg); }

.stat{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 18px 20px;
}
.stat .label{
  font-size: .78rem; font-weight: 600; color: var(--ink-muted);
}
.stat .value{
  font-family: var(--serif);
  font-size: 2rem; font-weight: 600; color: var(--ink-strong);
  letter-spacing: -.02em;
  line-height: 1.05;
  margin-top: 8px;
}
.stat .delta{ font-size: .82rem; color: var(--ink-muted); margin-top: 6px; }


/* ────────────────────────────────────────────────────────────
   9. BUTTONS
   ──────────────────────────────────────────────────────────── */
.btn{
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: var(--r-sm);
  font-weight: 600;
  font-size: .9rem;
  line-height: 1.2;
  letter-spacing: .005em;
  background: var(--brand);
  color: var(--brand-ink);
  border: 1px solid var(--brand);
  transition: filter .12s ease, background .12s ease, border-color .12s ease;
  text-decoration: none;
  white-space: nowrap;
}
.btn:hover { filter: brightness(1.06); text-decoration: none; }
.btn:active { filter: brightness(.95); }
.btn[disabled], .btn.is-disabled { opacity: .45; cursor: not-allowed; filter: none; }

.btn.secondary{
  background: var(--paper);
  color: var(--ink-strong);
  border-color: var(--line-strong);
}
.btn.secondary:hover{ background: var(--bg-elev); }

.btn.ghost{
  background: transparent;
  color: var(--ink);
  border-color: transparent;
}
.btn.ghost:hover{ background: var(--bg-elev); }

.btn.accent{
  background: var(--brandacc); color: var(--brandacc-ink); border-color: var(--brandacc);
}
.btn.danger{
  background: var(--bad); color: var(--bad-btn-ink, #fff); border-color: var(--bad);
}
.btn.danger.ghost{
  background: transparent; color: var(--bad); border-color: var(--bad);
}

.btn.sm  { padding: 6px 11px; font-size: .82rem; border-radius: var(--r-xs); }
.btn.lg  { padding: 12px 22px; font-size: 1rem; }
.btn.block { width: 100%; }
.btn.icon { padding: 8px; aspect-ratio: 1; }


/* ────────────────────────────────────────────────────────────
   10. FORM CONTROLS
   ──────────────────────────────────────────────────────────── */
.field { display: block; margin-bottom: 14px; }
.field > .label,
label.field-label{
  display: block;
  font-size: .82rem; font-weight: 600;
  color: var(--ink-strong);
  margin-bottom: 6px;
}
.field > .help{ display: block; font-size: .78rem; color: var(--ink-muted); margin-top: 6px; }
.field > .err { display: block; font-size: .78rem; color: var(--bad);     margin-top: 6px; }

input[type=text], input[type=email], input[type=password],
input[type=search], input[type=number], input[type=url],
input[type=date], textarea, select{
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: .92rem;
  transition: border-color .12s ease, box-shadow .12s ease;
}
input:focus, textarea:focus, select:focus{
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--focus);
}
textarea{ min-height: 92px; resize: vertical; font-family: var(--sans); }
select{
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%),
                    linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
/* Per-user 2FA mode select: floor its width so the longest option
   ("Inherit (optional)") is not clipped by the narrow table cell. */
.mfa-mode{ min-width: 13rem; }

/* checkbox / radio */
.check{
  display: inline-flex; align-items: center; gap: 9px;
  font-size: .9rem; color: var(--ink); cursor: pointer;
}
.check input[type=checkbox],
.check input[type=radio]{
  appearance: none;
  width: 16px; height: 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-xs);
  background: var(--paper);
  display: grid; place-items: center;
  margin: 0;
  cursor: pointer;
  flex: none;
}
.check input[type=radio]{ border-radius: 50%; }
.check input:checked{
  background: var(--brand); border-color: var(--brand);
}
.check input[type=checkbox]:checked::after{
  content: ""; width: 8px; height: 4px;
  border-left: 2px solid var(--brand-ink);
  border-bottom: 2px solid var(--brand-ink);
  transform: rotate(-45deg) translate(1px,-1px);
}
.check input[type=radio]:checked::after{
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--brand-ink);
}

/* switch */
.switch{
  position: relative;
  display: inline-block;
  width: 38px; height: 22px;
  flex: none;
}
.switch input{ position: absolute; opacity: 0; pointer-events: none; }
.switch .track{
  position: absolute; inset: 0;
  background: var(--line-strong); border-radius: 999px;
  transition: background .15s ease;
}
.switch .track::after{
  content: ""; position: absolute;
  top: 2px; left: 2px; width: 18px; height: 18px;
  background: var(--paper); border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,.25);
  transition: transform .15s ease;
}
.switch input:checked + .track{ background: var(--brand); }
.switch input:checked + .track::after{ transform: translateX(16px); }

/* search */
.search{
  display: flex; align-items: center; gap: 8px;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  padding: 6px 10px;
}
.search:focus-within{ border-color: var(--brand); box-shadow: 0 0 0 3px var(--focus); }
.search input{ border: 0; padding: 4px 0; background: transparent; }
.search input:focus{ box-shadow: none; }
.search .ico{ color: var(--ink-muted); font-size: 1rem; flex: none; }


/* ────────────────────────────────────────────────────────────
   11. TABS
   ──────────────────────────────────────────────────────────── */
.tabs{
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}
.tab{
  padding: 10px 16px;
  font-weight: 600; font-size: .9rem;
  color: var(--ink-muted);
  border: 0; background: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
}
.tab:hover{ color: var(--ink-strong); }
.tab[aria-selected="true"], .tab[aria-current="page"], .tab.active{
  color: var(--ink-strong);
  border-bottom-color: var(--brandacc);
}


/* ────────────────────────────────────────────────────────────
   12. TABLES
   ──────────────────────────────────────────────────────────── */
table.data{
  width: 100%;
  border-collapse: collapse;
  font-size: .9rem;
  background: var(--paper);
}
table.data thead th{
  text-align: left;
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--ink-muted);
  font-weight: 700;
  padding: 12px 16px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
}
table.data tbody td{
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
table.data tbody tr:last-child td{ border-bottom: 0; }
table.data tbody tr:hover{ background: var(--paper-2); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.actions{ text-align: right; white-space: nowrap; }

/* Drive listing on phones: the secondary columns (Tags / Vaults / Size /
   Created) push the 6-column table past the viewport and force the page to
   scroll horizontally. Hide them ≤600px so the row stays Name + Actions and
   let a long filename wrap in its cell. No overflow wrapper - it would clip
   the per-row Manage popover. */
@media (max-width: 600px){
  table.data.listing th.col-2nd, table.data.listing td.col-2nd,
  table.data.listing th.num,     table.data.listing td.num { display: none; }
  table.data.listing .fname .nm { overflow-wrap: anywhere; word-break: break-word; }

  /* Page headers pair a heading with a right-aligned action; on phones a long
     action label ("New organization") can't share the row, so let it wrap
     below the heading instead of overflowing the viewport. */
  .page-head{ flex-wrap: wrap; }
}


/* ────────────────────────────────────────────────────────────
   13. BADGES, TAGS
   ──────────────────────────────────────────────────────────── */
.tag{
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .72rem; font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--bg-elev);
  color: var(--ink-strong);
  border: 1px solid var(--line);
  white-space: nowrap;
}
.tag.solid{ background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
.tag.outline{ background: transparent; }
.tag.ok    { background: var(--ok-soft);   color: var(--ok-ink);   border-color: transparent; }
/* Warn chips keep the flash.warn grammar (soft fill + full warn border): the
   ring is what separates "Readable by DocAct" from the near-identical gold
   "Sealed" fill (1.0-1.1:1 between the two soft fills in every theme). */
.tag.warn  { background: var(--warn-soft); color: var(--warn-ink); border-color: var(--warn); }
.tag.bad   { background: var(--bad-soft);  color: var(--bad-ink);  border-color: transparent; }
.tag.info  { background: var(--info-soft); color: var(--info-ink); border-color: transparent; }
.tag.gold  { background: var(--brandacc-soft); color: var(--brandacc-soft-ink, var(--brandacc-ink)); border-color: transparent; }

.dot{
  display: inline-block;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--ink-faint);
  vertical-align: -1px;
  margin-right: 5px;
}
.dot.ok { background: var(--ok); }
.dot.warn { background: var(--warn); }
.dot.bad { background: var(--bad); }
.dot.info { background: var(--info); }


/* ────────────────────────────────────────────────────────────
   14. BREADCRUMBS
   ──────────────────────────────────────────────────────────── */
.crumbs{
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: .85rem;
  color: var(--ink-muted);
  margin-bottom: 6px;
}
.crumbs a{ color: var(--ink-muted); }
.crumbs a:hover{ color: var(--ink-strong); text-decoration: none; }
.crumbs .sep{ color: var(--ink-faint); user-select: none; }
.crumbs .here{ color: var(--ink-strong); font-weight: 600; }


/* ────────────────────────────────────────────────────────────
   15. MODAL - native <dialog>
   ──────────────────────────────────────────────────────────── */
/* Opened with showModal() by the document-page script, so Esc, focus trap
   and ::backdrop come from the browser. Without JS, `dialog:target` shows
   the dialog (non-modal) and the `.close` anchor (href="#_") clears the
   fragment without a scroll jump. */
dialog.modal{
  padding: 0;
  margin: auto;
  width: calc(100% - 40px);
}
dialog.modal::backdrop{
  background: color-mix(in srgb, var(--chrome) 65%, transparent);
  backdrop-filter: blur(2px);
}
dialog.modal:target{
  display: block;
  position: fixed; inset: 0; z-index: 60;
}
.modal{
  background: var(--paper);
  /* Overlays commit to elevation: the shadow-3 lift + the dimmed backdrop
     define the edge, so no hairline border (border + wide shadow together is
     the generated-UI tell the detector flags). border:0 suppresses the UA
     default <dialog> border so only the elevation defines the edge. */
  border: 0;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  width: 100%; max-width: 560px; max-height: 90vh;
  overflow: auto;
}
.modal.lg { max-width: 760px; }
.modal.xl { max-width: 980px; }
.modal .mh{
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}
.modal .mh :is(h2, h3){ font-size: 1.05rem; }
.modal .mb{ padding: 18px; }
.modal .mf{
  padding: 12px 18px;
  background: var(--paper-2);
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  display: flex; gap: 10px; justify-content: flex-end;
}
.modal .close{
  background: none; border: 0;
  font-size: 1rem; color: var(--ink-muted);
  width: 32px; height: 32px; border-radius: var(--r-sm);
}
.modal .close:hover{ background: var(--bg-elev); color: var(--ink-strong); }


/* ────────────────────────────────────────────────────────────
   16. TOAST / FLASH / HINT / EMPTY
   ──────────────────────────────────────────────────────────── */
.flash{
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--info);
  border-radius: var(--r-md);
  background: var(--info-soft);
  color: var(--info-ink);
  font-size: .9rem;
}
.flash.ok   { border-color: var(--ok);   background: var(--ok-soft);   color: var(--ok-ink); }
.flash.warn { border-color: var(--warn); background: var(--warn-soft); color: var(--warn-ink); }
.flash.bad  { border-color: var(--bad);  background: var(--bad-soft);  color: var(--bad-ink); }
.flash .icon{ flex: none; font-family: var(--serif); font-weight: 700; }
.flash .body{ flex: 1; }

.hint{
  display: block;
  padding: 10px 14px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  background: var(--paper-2);
  color: var(--ink-muted);
  font-size: .85rem;
}

.empty{
  text-align: center;
  padding: 24px;
  color: var(--ink-muted);
  font-size: .9rem;
}
.empty .icon{
  font-family: var(--serif);
  font-size: 2.6rem;
  color: var(--ink-faint);
  margin-bottom: 8px;
}
.empty :is(h2, h3){ font-size: 1.1rem; margin-bottom: 4px; }


/* ────────────────────────────────────────────────────────────
   17. PAGER
   One pager component. `.pager` is the canonical markup (drive
   listings); `.pagination` (tenant/platform audit, admin vaults)
   is an ALIAS onto the same rules so that markup keeps working -
   its `.pg` chips restyled to the pager's quiet ghost look.
   ──────────────────────────────────────────────────────────── */
.pager, .pagination{
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  padding: 12px 0; font-size: .85rem;
}
.pagination .pg{
  min-width: 32px; height: 32px; padding: 0 8px;
  display: inline-grid; place-items: center;
  border: 1px solid transparent;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}
.pagination .pg:hover{ background: var(--bg-elev); }
.pagination .pg[aria-current="page"]{
  background: var(--paper); border-color: var(--line-strong); color: var(--ink-strong);
}
.pagination .pg[disabled]{ opacity: .35; pointer-events: none; }


/* ────────────────────────────────────────────────────────────
   18. FILE-TYPE TILES (icons.js draws SVG; this styles the chip)
   ──────────────────────────────────────────────────────────── */
.ftile{
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: 600;
}
.ftile .fic{
  width: 28px; height: 28px; flex: none;
  display: grid; place-items: center;
}
.ftile .fic.lg{ width: 40px; height: 40px; }
.ftile .meta{ display: block; font-size: .76rem; color: var(--ink-muted); font-weight: 400; margin-top: 1px; }


/* ────────────────────────────────────────────────────────────
   19. KEYBOARD KEY
   ──────────────────────────────────────────────────────────── */
kbd{
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: var(--r-xs);
  background: var(--paper);
  color: var(--ink-strong);
  font-family: var(--mono);
  font-size: .76rem;
}


/* ────────────────────────────────────────────────────────────
   20. UTIL
   ──────────────────────────────────────────────────────────── */
.hr-dashed{ border-top: 1px dashed var(--line-strong); margin: 16px 0; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.nowrap { white-space: nowrap; }
.tnum { font-variant-numeric: tabular-nums; }
@media (max-width: 720px){ .hide-sm { display: none !important; } }


/* ============================================================
   DocAct app-specific styles
   ------------------------------------------------------------
   Layered on top of the POC theme.css design system above.
   Auth surface, control-panel layout, vault picker, audit log.
   ============================================================ */

/* ───────── 21. AUTH SURFACE (login / set-password) ───────── */
.auth{
  /* leaves room for footer.powered-by below the fold-filling panel */
  min-height: calc(100vh - 48px);
  display:grid;
  grid-template-columns: 1.05fr 1fr;
}
@media(max-width:880px){ .auth{ grid-template-columns: 1fr; } .auth .marque{ display:none; } }
.auth .marque{
  background: var(--chrome);
  color: var(--chrome-ink);
  padding: 56px 56px 40px;
  position: relative;
  overflow: hidden;
  display: flex; flex-direction: column;
}
.auth .marque::before{
  content:"";
  position:absolute; inset: -20%;
  background: radial-gradient(420px 280px at 78% 12%, color-mix(in srgb, var(--brandacc) 18%, transparent), transparent 70%);
  pointer-events:none;
}
.auth .marque > *{ position: relative; }
.auth .marque .wordmark{ font-size: 1.4rem; }
.auth .marque .pitch{ margin-top: auto; max-width: 36ch; }
.auth .marque .pitch .eyebrow{ color: color-mix(in srgb, var(--brandacc) 80%, var(--chrome-ink)); }
.auth .marque .pitch h1{
  font-family: var(--serif);
  font-size: clamp(2rem, 3.6vw, 3.2rem);
  line-height: 1.05;
  color: var(--chrome-ink);
  margin: 10px 0 16px;
  letter-spacing: -.02em;
  text-wrap: balance;
}
.auth .marque .pitch h1 em{ font-style: italic; color: var(--brandacc); font-weight: 500; }
.auth .marque .pitch p{
  color: var(--chrome-muted);
  margin: 0;
  font-size: 1rem;
  line-height: 1.55;
  max-width: 38ch;
  text-wrap: pretty;
}
.auth .marque .seal{
  display:flex; align-items:center; gap: 14px;
  margin-top: 24px; padding-top: 18px;
  border-top: 1px solid var(--chrome-line);
  font-size: .82rem; color: var(--chrome-muted);
}
.auth .panel{
  display:flex; align-items:center; justify-content:center;
  padding: 40px 28px;
  background: var(--bg);
  position: relative;
}
.auth .form-card{ width:100%; max-width: 380px; }
.auth .form-card h2{ font-size: 1.6rem; margin-bottom: 4px; }
.auth .form-card .sub{ color: var(--ink-muted); margin-bottom: 26px; font-size: .94rem; }
.auth .topright{ position: absolute; top: 18px; right: 18px; z-index: 5; }
.auth .login-error,
.auth .error{
  background: var(--bad-soft); color: var(--bad-ink);
  border: 1px solid var(--bad); border-radius: var(--r-sm);
  padding: 10px 12px; font-size:.86rem;
  margin-bottom: 14px;
}
.auth .legal{
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: .78rem; color: var(--ink-muted);
  text-align: center;
}

/* set-password variant - single column with topbar */
.auth-top{
  background: var(--chrome); color: var(--chrome-ink);
  padding: 14px 20px;
  display:flex; align-items:center; gap: 16px;
  border-bottom: 1px solid var(--chrome-line);
}
.auth-top .spacer{ flex:1; }
.auth-top .meta{ font-size:.82rem; color: var(--chrome-muted); }
.auth-wrap{ flex:1; display:flex; align-items:center; justify-content:center; padding: 40px 20px; min-height: calc(100vh - 110px); }
.auth-wrap .card-wrap{ width:100%; max-width: 460px; }
.auth-wrap .card-wrap h1{ font-size: 1.7rem; margin-bottom: 4px; }
.auth-wrap .card-wrap > .sub{ color: var(--ink-muted); margin-bottom: 22px; }
.invite-banner{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 14px 16px;
  margin-bottom: 18px;
  display: flex; align-items: center; gap: 14px;
}
.invite-banner .sigil{
  width:42px; height:42px; flex:none;
  background: var(--brand); color: var(--brand-ink);
  border-radius: var(--r-sm);
  display:grid; place-items:center;
  font-family: var(--serif); font-weight:600; font-size: 1.2rem;
}
.invite-banner .nm{ font-family: var(--serif); font-weight:600; color: var(--ink-strong); }
.invite-banner .em{ font-size: .82rem; color: var(--ink-muted); }
.footer-bar{ padding: 14px 20px; border-top: 1px solid var(--line); color: var(--ink-muted); font-size: .78rem; text-align: center; }


/* ───────── 22. ERROR PAGES ───────── */
.err-page{
  min-height: 100vh;
  display: flex; flex-direction: column;
  background: var(--bg);
}
.err-page .topbar{
  display:flex;align-items:center;gap:16px;padding:14px 24px;
  background: var(--chrome);
  border-bottom:1px solid var(--chrome-line);
}
.err-page .topbar .spacer{flex:1}
.err-page main{
  flex: 1;
  display: grid; place-items: center;
  padding: 40px 24px;
}
.err-card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 48px 40px;
  /* Resting card: defined by its border, flat like the rest of the card family. */
  box-shadow: var(--shadow-1);
  max-width: 520px;
  text-align: center;
}
.err-card .code{
  font-family: var(--serif);
  font-size: clamp(5rem, 14vw, 8rem);
  line-height: 1;
  color: var(--brandacc);
  letter-spacing: -.04em;
  margin-bottom: 10px;
}
.err-card h2{ font-size: 1.6rem; margin-bottom: 10px; }
.err-card p{ color: var(--ink-muted); margin: 0 auto 22px; max-width: 42ch; }
.err-card .actions{ display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.err-card .meta{
  margin-top: 22px; padding-top: 14px;
  border-top: 1px dashed var(--line-strong);
  font-family: var(--mono); font-size: .74rem; color: var(--ink-faint);
}


/* ───────── 23. SHELL TOPBAR EXTRAS (drive + panel) ───────── */
.shell-top .right{ margin-left:auto; display:flex; align-items:center; gap:10px; }
.shell-top .who{
  display:flex; align-items:center; gap:10px;
  font-size:.88rem;
  color: color-mix(in srgb, var(--chrome-ink) 85%, transparent);
}
.shell-top .who .av{
  width:30px; height:30px; border-radius:50%;
  background: color-mix(in srgb, var(--chrome-ink) 22%, transparent);
  display:grid; place-items:center;
  color:var(--chrome-ink); font-weight:700; font-size:.78rem;
}
.shell-top .title{ font-family: var(--serif); color: var(--chrome-ink); font-size: 1.02rem; }
/* logout form blends into topbar */
form.logout{ margin: 0; display: inline-flex; }
form.logout button{
  padding: 6px 10px;
  background: transparent;
  color: var(--chrome-ink);
  border: 1px solid var(--chrome-line);
  border-radius: var(--r-sm);
  font-size: .82rem; font-weight: 600;
  cursor: pointer;
}
form.logout button:hover{ background: color-mix(in srgb, var(--chrome-ink) 8%, transparent); }
/* topbar account entry point: initials avatar + name, links to /account */
.shell-top .who.account-link{
  text-decoration: none; color: inherit;
  padding: 3px 8px 3px 3px; border-radius: 999px;
  border: 1px solid transparent;
}
.shell-top .who.account-link:hover{
  background: color-mix(in srgb, var(--chrome-ink) 8%, transparent);
  border-color: var(--chrome-line);
}
.shell-top .who.account-link .nm{ font-weight: 600; }
.shell-top .who.account-link .caret{ font-size: .7rem; opacity: .7; }

/* Topbar profile menu: a native <details> dropdown. The summary is the
   account-link chip; the panel drops below it, right-aligned. */
.account-menu{ position: relative; margin: 0; }
.account-menu > summary{
  list-style: none; cursor: pointer; user-select: none;
}
.account-menu > summary::-webkit-details-marker{ display: none; }
.account-menu > summary::marker{ content: ""; }
.account-pop{
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  min-width: 200px; padding: 6px;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: var(--shadow-pop, 0 8px 24px rgba(0,0,0,.18));
  display: flex; flex-direction: column; gap: 2px;
}
.account-pop-item{
  display: block; padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--ink); text-decoration: none; font-size: .9rem;
}
.account-pop-item:hover{ background: var(--bg-elev); text-decoration: none; }
/* the sign-out form sits in the menu; its button spans the row like a menu item */
.account-pop form.logout{ display: block; }
.account-pop form.logout button{
  width: 100%; text-align: left; border: 0; background: none;
  padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--ink); font-size: .9rem; font-weight: 500;
}
.account-pop form.logout button:hover{ background: var(--bg-elev); }

/* Avatar image (Gravatar, opt-in): covers the initials sigil when it loads;
   on a 404 avatar.js removes it and the initials remain. */
.av{ position: relative; overflow: hidden; }
.av .ini{ display: block; line-height: 1; }
.av-img{
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border-radius: inherit;
}

/* account settings page (/account) */
.account-grid{ display: flex; flex-direction: column; gap: 20px; max-width: 680px; }
.account-id{ display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.account-id .av.lg{
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--brand); color: var(--brand-ink);
  display: grid; place-items: center;
  font-weight: 700; font-size: 1rem; flex: none;
}
.account-id-text .nm{ display: block; color: var(--ink-strong); font-weight: 600; }
.account-id-text .em{ display: block; font-size: .82rem; color: var(--ink-muted); }
/* Gravatar opt-in toggle on the Profile card (client-side only, default off). */
.gravatar-opt{
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 16px; font-size: .88rem;
}
.gravatar-opt input[type="checkbox"]{ flex: none; }
.account-theme .theme-pick{ display: inline-flex; }
@media (max-width: 620px){
  .shell-top .who.account-link .nm{ display: none; }
}

/* org-switcher in topbar */
.org-switcher{ margin: 0; display: inline-flex; }
.org-switcher select{
  background: color-mix(in srgb, var(--chrome-ink) 8%, transparent);
  color: var(--chrome-ink);
  border: 1px solid var(--chrome-line);
  border-radius: var(--r-sm);
  padding: 6px 26px 6px 10px;
  font-size: .85rem; font-weight: 600;
  width: auto;
}


/* ───────── 24. PANEL DASHBOARD - section tiles ───────── */
.panel-nav-grid{ display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 22px; }
@media (max-width: 880px){ .panel-nav-grid{ grid-template-columns: repeat(2, 1fr); } }
.panel-nav-grid a, .panel-nav-grid .cur{
  display: block; padding: 16px 18px;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-lg);
  color: inherit; text-decoration: none;
  transition: border-color .15s ease, transform .15s ease;
}
.panel-nav-grid a:hover{ border-color: var(--brandacc); transform: translateY(-1px); text-decoration:none; }
.panel-nav-grid .cur, .panel-nav-grid a.cur{ background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
.panel-nav-grid .lab{ font-family: var(--mono); font-size:.72rem; opacity: .7; }
.panel-nav-grid .ti{ font-family: var(--serif); font-size: 1.05rem; margin-top: 4px; display: block; }
.panel-nav-grid .ds{ font-size: .78rem; opacity: .85; margin-top: 2px; display: block; }


/* ───────── 25. DRIVE LISTING (filename rows) ───────── */
/* Breadcrumbs use the canonical `.crumbs`/`.here` classes (section 14). */
.fname{ display:flex; align-items:center; gap:10px; font-weight:600; color:var(--ink-strong); text-decoration: none; }
.fname:hover{ text-decoration: none; }
.fname .fic{ width:28px; height:28px; display:grid; place-items:center; flex:none; }
.fname .nm{ font-weight: 600; color: var(--ink-strong); }
.fileactions{ text-align:right; white-space:nowrap; }
.fileactions a{ margin-left: 12px; font-weight: 600; font-size: .85rem; }
table { width: 100%; border-collapse: collapse; }
.card > :is(h2, h3){ padding: 12px 18px; margin: 0; border-bottom: 1px solid var(--line); font-family: var(--serif); font-size: 1rem; }
.card > table thead th{
  text-align: left; font-size: .68rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-muted); font-weight: 700; padding: 12px 16px;
  background: var(--paper-2); border-bottom: 1px solid var(--line);
}
.card > table tbody td{
  padding: 12px 16px; border-bottom: 1px solid var(--line);
  vertical-align: middle; font-size: .9rem;
}
.card > table tbody tr:last-child td{ border-bottom: 0; }
.card > table tbody tr:hover{ background: var(--paper-2); }

/* tags inside drive listing */
.tagrow{ display:flex; gap:5px; flex-wrap:wrap; }
.residency{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px;
  font-size: .72rem; font-weight: 600;
  background: var(--bg-elev); color: var(--ink-strong);
  border: 1px solid var(--line);
  border-radius: 999px;
  margin-right: 4px;
}
.residency .flag{ font-size: .85rem; }
.toolbar{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  margin: 12px 0 16px;
}
.toolbar .search{ flex: 1; min-width: 240px; max-width: 520px; display:flex; align-items:center; }
form.search{
  display:flex; align-items:center; gap:8px;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); padding: 6px 10px;
  flex: 1; min-width: 240px; max-width: 520px;
}
form.search input{ border: 0; padding: 4px 0; background: transparent; flex: 1; }
form.search input:focus{ box-shadow: none; outline: none; border-color: transparent; }

/* Narrow screens: stack the toolbar so the search row, the scope radios +
   Search button, and the view toggle never collide on one line. The search
   input takes its own full-width row; the `/` keycap (a keyboard-only hint)
   drops out on touch. */
@media (max-width: 600px){
  .toolbar{ flex-direction: column; align-items: stretch; gap: 8px; }
  .toolbar .search, form.search{ max-width: none; min-width: 0; width: 100%; flex-wrap: wrap; }
  form.search input{ flex: 1 1 100%; min-width: 0; }
  .toolbar .search .kbd{ display: none; }
  .view-toggle{ align-self: flex-start; }
}


/* ───────── 26. UPLOADBOX (details/summary inline forms) ───────── */
.uploadbox{
  background: var(--paper-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  padding: 12px 16px;
  margin-top: 14px;
  font-size: .9rem;
}
.uploadbox > summary{
  cursor: pointer; font-weight: 600; color: var(--ink-strong);
  padding: 4px 0;
}
.uploadbox[open] > summary{ margin-bottom: 10px; }
.uploadbox .f{ display: block; font-size: .82rem; font-weight: 600; color: var(--ink-strong); margin: 8px 0 6px; }
.uploadbox button{ margin-top: 10px; }
.uploadbox.muted{ color: var(--ink-muted); }

/* Inline toolbar popovers built from <details>. The summary is a button; the
   .popover panel anchors to the right edge so it doesn't push the toolbar
   layout when it opens. */
.toolbar-popover{ position: relative; }
.toolbar-popover > summary{
  list-style: none; cursor: pointer; user-select: none;
}
.toolbar-popover > summary::-webkit-details-marker{ display: none; }
.toolbar-popover[open] > summary{ box-shadow: 0 0 0 2px var(--brand-soft); }
.toolbar-popover .popover{
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 280px; z-index: 5;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); padding: 14px 16px;
  box-shadow: 0 8px 24px rgba(0,0,0,.08);
}
.toolbar-popover .popover .f{
  display: block; font-size: .82rem; font-weight: 600;
  color: var(--ink-strong); margin: 8px 0 6px;
}

/* Per-row inline popover inside data tables (e.g. platform org rows). Mirrors
   .toolbar-popover but anchors against the table cell. The native disclosure
   marker is suppressed so the <summary> reads as a button. */
.row-popover{ position: relative; display: inline-block; }
.row-popover > summary{ list-style: none; cursor: pointer; user-select: none; }
.row-popover > summary::-webkit-details-marker{ display: none; }
.row-popover[open] > summary{ box-shadow: 0 0 0 2px var(--brand-soft); }
.row-popover .popover{
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 280px; z-index: 5;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); padding: 14px 16px;
  /* Dropdowns commit to a defined edge: keep the border, keep the lift tight
     (blur < 16px) so it isn't the border+wide-shadow tell. */
  box-shadow: 0 4px 12px rgba(0,0,0,.10);
  text-align: left;
}
.row-popover .popover .f{
  display: block; font-size: .82rem; font-weight: 600;
  color: var(--ink-strong); margin: 8px 0 6px;
}

/* Destructive per-row confirm well. Renders the trigger as a danger ghost
   button; the body opens below the table cell with the "type the name to
   confirm" affordance. */
.danger-zone{ position: relative; display: inline-block; }
.danger-zone > summary{ list-style: none; cursor: pointer; user-select: none; }
.danger-zone > summary::-webkit-details-marker{ display: none; }
.danger-zone .danger-body{
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 320px; z-index: 6;
  background: var(--paper); border: 1px solid var(--bad);
  border-radius: var(--r-md); padding: 14px 16px;
  /* Keep the red danger border; keep the lift tight (blur < 16px). */
  box-shadow: 0 4px 12px rgba(0,0,0,.10);
  color: var(--ink);
  text-align: left;
}
.danger-zone .danger-body p{ margin: 0 0 8px; }
.danger-zone .danger-body .warn{ color: var(--bad-ink); font-weight: 600; }

/* Vault tile rendered as a checkbox-card inside .vault-grid. The native
   checkbox is hidden; :checked styles the parent label. */
.vault-grid .vault.opt{
  display: block; cursor: pointer;
}
.vault-grid .vault.opt input[type="checkbox"]{
  position: absolute; top: 10px; right: 10px;
}
.vault-grid .vault.opt:has(input:checked){
  border-color: var(--brandacc);
  box-shadow: 0 0 0 1px var(--brandacc) inset;
}


/* ───────── 27. ROLE / USER editor cards ───────── */
.role-row, .role-new, .member-row, .user-invite{ padding: 18px; margin-top: 12px; }
.role-row label.f, .role-new label.f,
.member-row label.f, .user-invite label.f{
  display: block; font-size: .82rem; font-weight: 600;
  color: var(--ink-strong); margin: 8px 0 6px;
}
.action-matrix{
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 10px 12px; margin: 12px 0;
  background: var(--paper-2);
}
.action-matrix legend{
  padding: 0 6px; font-weight: 600; font-size: .82rem; color: var(--ink-strong);
}
.action-chip{
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 9px; margin: 3px;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: .8rem; font-weight: 500;
  cursor: pointer;
}
.member-id{ margin-bottom: 10px; }
.member-email, .member-role{ color: var(--ink-muted); font-size: .88rem; }
/* The role name renders as a `.tag` pill; the muted grouping above washed it
   out on the tinted pill fill. Use strong ink so the role is clearly legible. */
.member-role.tag{ color: var(--ink-strong); }
.member-panel{ color: var(--brandacc-ink); background: var(--brandacc-soft); padding: 1px 7px; border-radius: 999px; font-size: .72rem; }
.invite-link{ padding: 14px 18px; background: var(--info-soft); color: var(--info-ink); border: 1px solid var(--info); border-radius: var(--r-md); }
.invite-link a{ color: var(--info-ink); text-decoration: underline; }
.btn-danger{ background: var(--bad); color: var(--bad-btn-ink, #fff); border-color: var(--bad); margin-top: 8px; }


/* ───────── 28. VAULT SELECT (residency) ───────── */
.vault-select th, .vault-select td{ padding: 10px 14px; }
.vault-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px;
}
.vault-grid .vault{
  position: relative;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 16px 18px;
}
.vault :is(h2, h3){ font-size: 1rem; margin: 6px 0 2px; }
.vault-grid .vault .flag{ font-size: 1.4rem; }
.vault-grid .vault .id{
  font-family: var(--mono); font-size: .72rem; color: var(--ink-muted);
}
.vault-grid .vault .meta{
  font-size: .82rem; color: var(--ink-muted); margin-top: 6px;
}


/* ───────── 29. REPLICATION PROGRESS ───────── */
ul.stats{ list-style: none; padding: 12px 18px; margin: 0; }
ul.stats li{ padding: 4px 0; font-size: .9rem; color: var(--ink-muted); }
ul.stats li strong{ color: var(--ink-strong); font-family: var(--serif); margin-right: 4px; }
.repl{
  display: inline-flex; padding: 2px 8px; border-radius: 999px;
  font-size: .72rem; font-weight: 600;
}
.repl.ok      { background: var(--ok-soft);   color: var(--ok-ink); }
.repl.pending { background: var(--warn-soft); color: var(--warn-ink); }
.repl.failed  { background: var(--bad-soft);  color: var(--bad-ink); }
.repl.absent  { background: var(--bg-elev);   color: var(--ink-muted); }


/* ───────── 30. BRANDING EDITOR ───────── */
/* Vertical stack: the edit form (top Identity|Themes grid + full-width Advanced
   card) then the top-level theming-contract disclosure - never a card in a card. */
.branding-layout{ display: flex; flex-direction: column; gap: 28px; }
.branding-grid{
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 22px; align-items: start;
}
@media (max-width: 880px){ .branding-grid{ grid-template-columns: minmax(0, 1fr); } }
/* Give this page's compact controls (the "sanitized server-side" pill and the
   small action buttons) the same comfortable padding as the rest of the form,
   off the cramped end of the scale. */
.branding-layout .tag.micro{ padding: 4px 11px; }
.branding-layout .btn.sm{ padding: 8px 14px; }
.css-editor{
  font-family: var(--mono); font-size: .82rem; line-height: 1.55;
  padding: 12px 14px; width: 100%; min-height: 220px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--paper-2); color: var(--ink);
  resize: vertical; tab-size: 2;
}
.css-editor:focus{ outline:none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--focus); }
.logo-up{
  display:flex; align-items:center; gap: 14px;
  padding: 12px;
  background: var(--paper-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
}
.logo-up .pre{
  width: 56px; height: 56px;
  background: var(--brand); color: var(--brand-ink);
  border-radius: var(--r-sm);
  display: grid; place-items: center;
  font-family: var(--serif); font-weight: 600; font-size: 1.5rem;
}
.color-row{ display:flex; gap: 10px; align-items: center; }
.color-row input[type=color]{
  width: 44px; height: 36px; padding: 2px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--paper); cursor: pointer;
}
.color-row input[type=text]{ width: 140px; font-family: var(--mono); font-size: .82rem; }


/* ───────── 31. THEMING CONTRACT (read-only doc page) ───────── */
.contract-section{ margin-bottom: 32px; }
.contract-section h2{ font-size: 1.2rem; margin-bottom: 8px; }
.contract-section table{ width: 100%; border-collapse: collapse; font-size: .88rem; }
.contract-section th, .contract-section td{
  text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--line);
}
.contract-section code{
  font-family: var(--mono); font-size: .82rem; color: var(--brand);
}


/* ───────── 32. BACK-COMPAT for older class names ───────── */
/* Older tests/markup may still reference these. They map to the new system. */
.flag{ display: inline-block; }
.error{
  background: var(--bad-soft); color: var(--bad-ink);
  border: 1px solid var(--bad); border-radius: var(--r-sm);
  padding: 10px 12px; font-size:.86rem; margin: 12px 0;
}
.topbar{
  display: flex; align-items: center; gap: 14px;
}
.topbar-actions{ display: flex; align-items: center; gap: 10px; }
.brand-mark{
  display: inline-grid; place-items: center;
  width: 32px; height: 32px; border-radius: var(--r-sm);
  background: var(--brandacc); color: var(--brandacc-ink);
  font-family: var(--serif); font-weight: 700; font-size: .95rem;
}
.tlabel{ display:none; }
.theme-pick{ display: inline-flex; align-items: center; gap: 6px; }
.theme-select{
  width: auto; padding: 6px 26px 6px 10px;
  background: color-mix(in srgb, var(--chrome-ink) 8%, transparent);
  color: var(--chrome-ink);
  border: 1px solid var(--chrome-line);
  font-size: .82rem; font-weight: 600;
}
/* Unified "+ New" dropdown in the drive toolbar - nested <details> cascade. */

/* Top-of-page banner shown when an operator is acting via a support grant.
   Warm amber so it reads as a temporary, audited mode - not an error. */
.grant-banner{
    display: flex; align-items: center; gap: 12px;
    padding: 10px 14px; margin-bottom: 16px;
    background: var(--warn-soft); color: var(--warn-ink);
    border: 1px solid var(--warn); border-radius: var(--r-md);
    font-size: .9rem;
}
.grant-banner > div:first-child{ flex: 1; }

/* Skip-to-content link - only visible on keyboard focus. Sits above all
   chrome so a screenreader / keyboard user can jump past the sidebar. */
.skip-link {
    position: fixed; top: 8px; left: 8px;
    background: var(--brand); color: var(--brand-ink);
    padding: 8px 14px; border-radius: var(--r-sm);
    font-weight: 600; text-decoration: none; z-index: 1000;
    transform: translateY(-200%);
    transition: transform .15s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
    transform: translateY(0);
    outline: 2px solid var(--brandacc);
    outline-offset: 2px;
}

/* Replication / vaults progress (admin/vaults.rs). Scoped to #vaults-progress
   so the short, generic class names below never leak into other surfaces. */
#vaults-progress .overall{ display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; margin-bottom: 18px; }
#vaults-progress .fleet-headline{ font-family: var(--serif); font-size: 2.4rem; line-height: 1; }
#vaults-progress .bytes-headline{ font-family: var(--serif); font-size: 1.8rem; }
#vaults-progress .note{ font-size: .85rem; }
#vaults-progress .summary{ margin-top: 6px; font-size: .9rem; }
#vaults-progress .summary.sm{ font-size: .85rem; }
#vaults-progress .vault-cards{ display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; margin-bottom: 18px; }
#vaults-progress .vault-card{ padding: 14px 16px; }
#vaults-progress .vault-card .row{ gap: 8px; align-items: center; flex-wrap: wrap; }
#vaults-progress .vault-card .pct{ font-family: var(--serif); font-size: 1.4rem; margin-top: 8px; }
#vaults-progress .vault-card.warn .pct{ color: var(--warn); }
#vaults-progress .vault-card .meta{ margin-top: 6px; font-size: .78rem; color: var(--ink-muted); }
#vaults-progress .tag.xs{ font-size: .7rem; }

/* ── UI/UX a11y polish ───────────────────────────────────────────────── */

/* Anchored deep links (FAQ sections, /account cards, disclosure-chip "?")
   land under the fixed topbar without an offset; keep the target heading
   visible below the chrome. */
.shell-main [id]{ scroll-margin-top: calc(var(--shell-top) + 14px); }

/* Screen-reader-only: visually hidden but announced (e.g. labels on inputs
   whose purpose is clear visually but absent for assistive tech). */
.sr-only{
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Option rows (radio/checkbox + label) inside a form field stack vertically as
   flex rows. Scoped to `.field` so the vault-grid's `.vault.opt` cards keep
   their own grid layout. A `.field.stack` adds the 12px inter-row rhythm. */
.field .opt{ display: flex; align-items: center; gap: 8px; }
/* The flex `display` above would defeat the `hidden` attribute (class beats the
   UA `[hidden]` rule); keep `hidden` authoritative for JS-revealed rows such as
   the drive seal opt-ins. */
.field .opt[hidden]{ display: none; }

/* Keyboard focus rings on controls whose hover state was styled but whose
   focus relied implicitly on the global rule - make each explicit so a custom
   tenant background can never swallow the indicator. */
.modal .close:focus-visible,
.pagination .pg:focus-visible{
    outline: 2px solid var(--brand); outline-offset: 2px;
}
/* Topbar controls sit on the chrome bar, where a --brand (often navy) ring can
   vanish; use the accent so the focus ring is always visible on chrome. */
form.logout button:focus-visible,
.theme-pick button:focus-visible{
    outline: 2px solid var(--brandacc); outline-offset: 2px;
}
.tab:focus-visible{ outline: 2px solid var(--brand); outline-offset: -2px; }

/* Disabled affordance for the secondary/ghost button variants (the base
   `.btn[disabled]` only dimmed opacity). */
.btn.secondary[disabled], .btn.secondary:disabled{
    opacity: .5; cursor: not-allowed;
}
.btn.ghost[disabled], .btn.ghost:disabled{ opacity: .45; cursor: not-allowed; }


/* ───────── 33. DOCUMENT DETAIL (web/document.rs) ─────────
   Ported from poc/2/06-document.html: header card, two-column layout,
   version timeline, activity lines, vault rows, share sidebar, grants. */
.doc-head{
  display: grid; grid-template-columns: auto 1fr auto; gap: 16px;
  padding: 18px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  margin-bottom: 18px;
}
.doc-head .icbig{ width: 64px; height: 64px; display: grid; place-items: center; flex: none; }
.doc-head .icbig svg{ width: 48px; height: 56px; }
/* min-width:0 lets the text column shrink; overflow-wrap breaks a long
   single-token filename so the title never bleeds past the card. break-word
   prefers real break opportunities (spaces) and only splits a word as a last
   resort - gentler than `anywhere` for multi-word titles. */
.doc-head > div{ min-width: 0; }
.doc-head h1{ font-size: 1.5rem; margin-bottom: 4px; overflow-wrap: break-word; }
.doc-head .ml{ display: flex; gap: 14px; flex-wrap: wrap; font-size: .85rem; color: var(--ink-muted); }
.doc-head .ml b{ color: var(--ink-strong); font-weight: 600; }
.doc-head .actions{ display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; justify-content: flex-end; }
@media (max-width: 720px){
  .doc-head{ grid-template-columns: auto 1fr; }
  .doc-head .actions{ grid-column: 1 / -1; justify-content: flex-start; }
  .doc-head h1{ font-size: 1.28rem; }
}
.dot-sep{ color: var(--ink-faint); user-select: none; }
.mini-tag{ font-size: .7rem; }

.twocol{ display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 22px; align-items: start; }
@media (max-width: 1100px){ .twocol{ grid-template-columns: 1fr; } }

/* version timeline */
.timeline{ list-style: none; margin: 0; padding: 4px 0 0; position: relative; }
.timeline::before{
  content: ""; position: absolute; left: 8px; top: 4px; bottom: 4px;
  width: 2px; background: var(--line);
}
.timeline li{ position: relative; padding: 6px 0 12px 28px; }
.timeline li::before{
  content: ""; position: absolute; left: 3px; top: 12px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--paper); border: 2px solid var(--line-strong);
}
.timeline li.cur::before{
  background: var(--brandacc); border-color: var(--brandacc);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brandacc) 24%, transparent);
}
.timeline .v{ font-family: var(--serif); font-weight: 600; font-size: .95rem; color: var(--ink-strong); }
.timeline .meta{ font-size: .78rem; color: var(--ink-muted); margin-top: 2px; }
.timeline .lbl{ font-size: .72rem; font-weight: 700; color: var(--ok); margin-top: 4px; display: inline-block; letter-spacing: .06em; }
.timeline .acts{ margin-top: 6px; display: flex; gap: 6px; flex-wrap: wrap; }

/* activity + comment stream; the .t column fits the canonical
   `YYYY-MM-DD HH:MM UTC` stamp from web::fmt */
.act-line{
  display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 8px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--line);
  font-size: .86rem;
}
.act-line:last-child{ border-bottom: 0; }
.act-line .t{ font-family: var(--mono); font-size: .74rem; color: var(--ink-muted); }
@media (max-width: 600px){ .act-line{ grid-template-columns: 1fr; gap: 2px; } }

/* per-document grants table (modal) */
.perm-matrix th, .perm-matrix td{ padding: 9px 12px; }
.perm-matrix input[type=checkbox]{ accent-color: var(--brand); }

/* vault status rows (sidebar) */
.vault-row{
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--line);
  font-size: .88rem;
}
.vault-row:last-child{ border-bottom: 0; }
.vault-row .flag{ font-size: 1rem; width: 22px; flex: none; }
.vault-row .name{ flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* share links list (sidebar) */
.share-row{
  padding: 10px 0;
  border-bottom: 1px dashed var(--line);
  font-size: .86rem;
}
.share-row:first-child{ padding-top: 0; }
.share-row:last-child{ border-bottom: 0; }
.share-row .font-mono{ overflow-wrap: anywhere; }

/* "share link created" confirmation card */
.share-flash{
  padding: 14px;
  margin-bottom: 16px;
  border-color: var(--ok);
  background: color-mix(in srgb, var(--ok) 8%, var(--paper));
}
.share-flash code{ font-family: var(--mono); font-size: .84rem; }

/* inline forms: create-share, add-grant, add-comment */
.share-form .f, .grant-form .f, .comment-form .f{
  display: block; font-size: .82rem; font-weight: 600;
  color: var(--ink-strong); margin: 8px 0 6px;
}
.grant-form{ padding-top: 12px; border-top: 1px dashed var(--line-strong); }
.comment-form{ padding-top: 12px; border-top: 1px dashed var(--line); }


/* ───────── 34. SHARE VIEWER (sharing/routes.rs) ─────────
   Ported from poc/2/15-share-viewer.html: guest share gate, OTP step,
   branded viewer with confidentiality watermark. */
.share-page{
  min-height: 100vh;
  display: flex; flex-direction: column;
  background: var(--bg);
}
/* Chrome surface (not tenant brand) so the org name always reads AA. */
.share-top{
  background: var(--chrome);
  color: var(--chrome-ink);
  padding: 14px 20px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  border-bottom: 1px solid var(--chrome-line);
}
.share-top .tenant-mark{ color: var(--chrome-ink); }
.share-top .lbl{ font-size: .82rem; color: var(--chrome-muted); }
.share-top .timer{
  background: color-mix(in srgb, var(--chrome-ink) 10%, transparent);
  color: var(--chrome-ink);
  border-color: var(--chrome-line);
}

.share-wrap{
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 48px 20px;
}
@media (max-width: 600px){ .share-wrap{ padding: 24px 12px; } }
.share-card{ width: 100%; max-width: 460px; }
.share-card.wide{ max-width: 880px; }

/* server always renders the active step with `cur`; others are hidden */
.step{ display: none; }
.step.cur{ display: block; }

.shield{
  width: 56px; height: 56px;
  margin: 0 auto 14px;
  background: var(--brand); color: var(--brand-ink);
  border-radius: var(--r-md);
  display: grid; place-items: center;
  font-family: var(--serif); font-size: 1.6rem;
}

.file-chip{
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px 14px;
  margin: 14px 0 6px;
  text-align: left;
}
.file-chip .nm{ font-weight: 600; color: var(--ink-strong); overflow-wrap: anywhere; }
.file-chip .meta{ display: block; font-size: .78rem; color: var(--ink-muted); margin-top: 2px; }

/* single 6-digit code input (server-rendered, no per-digit JS boxes) */
.otp{ display: flex; justify-content: center; margin: 16px 0; }
.otp input{
  max-width: 220px; height: 56px;
  text-align: center;
  font-family: var(--serif); font-size: 1.4rem; font-weight: 700;
  letter-spacing: .35em; text-indent: .35em;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--paper); color: var(--ink-strong);
}

/* expiry pill - brandacc-soft/-ink is a pre-validated AA pair */
.timer{
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--brandacc-soft);
  color: var(--brandacc-ink);
  border: 1px solid color-mix(in srgb, var(--brandacc) 40%, transparent);
  font-family: var(--mono); font-size: .74rem;
  padding: 3px 9px; border-radius: 999px;
  white-space: nowrap;
}

.viewer-head{ display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.viewer-head .who{ font-size: .85rem; color: var(--ink-muted); }
.viewer-head .who b{ color: var(--ink-strong); }

/* rendered "document sheet" fallback preview */
.doc-paper{
  background: var(--paper); color: var(--ink);
  padding: 38px 44px;
  font-family: var(--serif);
  /* A document "sheet": commit to the soft lift (paper floating), no border. */
  box-shadow: var(--shadow-2);
  position: relative;
  min-height: 320px;
  overflow: hidden;
}
.doc-paper h4{ font-family: var(--serif); font-size: 1.2rem; margin-bottom: 8px; }
.doc-paper p{ font-size: .9rem; line-height: 1.6; }
@media (max-width: 600px){ .doc-paper{ padding: 24px 18px; } }
.num-line{ font-family: var(--mono); font-size: .74rem; color: var(--ink-muted); }

/* confidentiality watermark - oversized, rotated, faint, non-interactive */
.wm{
  position: absolute; inset: 0;
  display: grid; place-items: center;
  pointer-events: none;
  user-select: none;
  opacity: .07;
  font-family: var(--serif); font-weight: 600;
  font-size: 3.2rem; line-height: 1.8; letter-spacing: .08em;
  transform: rotate(-22deg);
  color: var(--ink);
  text-align: center;
  overflow: hidden;
}

/* inline PDF/image viewer */
.share-frame{
  width: 100%; height: 62vh;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
  display: block;
}

/* watermark overlay wrapper for the inline PDF/image viewer:
   positions .wm (inset:0) over the frame; z-index lifts it above the
   iframe within the wrapper's stacking context */
.share-frame-wrap{ position: relative; }
.share-frame-wrap .wm{ z-index: 2; }

/* viewer action row + audit assurance */
.vacts{ display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 14px; }
.vacts .audit-pill{ margin-left: auto; }
.audit-pill{
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .78rem; font-weight: 600;
  color: var(--ok);
}

.legal-line{
  text-align: center;
  font-size: .78rem; color: var(--ink-muted);
  padding: 14px 20px;
  border-top: 1px solid var(--line);
}


/* ───────── 35. MISC PORTS (auth, audit, error, admin, platform) ───────── */

/* login: password label line + remember-me row (auth/routes.rs) */
.pwline{ display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.pwline a{ font-size: .82rem; }
.row.toggles{ margin: 6px 0 18px; }

/* audit log filter bar (web/audit.rs) */
.filter-strip{
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr));
  gap: 10px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px 14px;
  margin-bottom: 14px;
  align-items: end;
}
.filter-strip .field{ margin: 0; }
.filter-strip .field .label{
  font-size: .78rem; font-weight: 600; color: var(--ink-muted);
}
@media (max-width: 880px){ .filter-strip{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px){ .filter-strip{ grid-template-columns: 1fr; } }

/* error page eyebrow (error.rs) */
.err-card .preview-label{
  font-family: var(--mono);
  font-size: .74rem; font-weight: 600;
  color: var(--ink-muted);
  margin-bottom: 6px;
}

/* right-aligned action cells in member/operator tables */
.actions-cell{ text-align: right; white-space: nowrap; }
.actions-cell .btn.sm{ padding: 5px 9px; }

/* person cell: avatar + name + email (admin/users.rs, platform/operators.rs) */
.person{ display: flex; align-items: center; gap: 10px; }
.person .av{
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--brand); color: var(--brand-ink);
  display: grid; place-items: center;
  font-weight: 700; font-size: .78rem; flex: none;
}
.person .nm{ display: block; font-weight: 600; color: var(--ink-strong); }
.person .em{ display: block; font-size: .78rem; color: var(--ink-muted); }
tr.operator-row.disabled td{ color: var(--ink-muted); }
tr.operator-row.disabled .person .av{ background: var(--bg-elev); color: var(--ink-muted); }

/* platform org list: sigil + name cell, collapsible admins (platform/orgs.rs) */
.org-mini{ display: flex; align-items: center; gap: 10px; }
.org-mini .sg, .sg{
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  background: var(--brand); color: var(--brand-ink);
  border-radius: var(--r-sm);
  font-family: var(--serif); font-weight: 700; font-size: .82rem;
}
.org-admins{ margin-top: 6px; }
.org-admins > summary{
  cursor: pointer; user-select: none;
  font-size: .78rem; color: var(--ink-muted);
  list-style: none;
}
.org-admins > summary::-webkit-details-marker{ display: none; }
.org-admins > summary::before{ content: "\203A "; display: inline-block; transition: transform .15s ease; }
.org-admins[open] > summary::before{ transform: rotate(90deg); }
.org-admins > summary:hover{ color: var(--ink-strong); }

/* drive: the folder-name anchor is the row's navigation affordance */
tr.row-folder .fname{ color: var(--ink-strong); }

/* residency vault picker (admin/settings.rs) */
.vault-check, .vault-default{ accent-color: var(--brand); cursor: pointer; }
.vault-grid .vault.sel{
  border-color: var(--brandacc);
  box-shadow: 0 0 0 1px var(--brandacc) inset;
}

/* replication headline cards (admin/vaults.rs) - roomier than default .cb */
#vaults-progress .bigprog .cb{ padding: 20px 22px; }


/* ────────────────────────────────────────────────────────────
   36. RESPONSIVE - rail/split layouts + shell collapse
   ──────────────────────────────────────────────────────────── */
/* rail: main column + fixed 320px aside (dashboard, drive root) */
.grid.rail{ grid-template-columns: minmax(0,1fr) 320px; gap: 22px; }
/* split: asymmetric two-column card layouts */
.grid.split{ grid-template-columns: 1.4fr 1fr; gap: 22px; }
.grid.split-wide{ grid-template-columns: 2fr 1fr; gap: 22px; }

/* Collapsed rail/split tracks stay minmax(0,1fr), not 1fr: a bare 1fr is
   minmax(auto,1fr), whose auto floor lets a card's min-content (wide table,
   long unbroken string) blow the track past the viewport. Paired with
   min-width:0 on the items so grid children can shrink below their content. */
.grid.rail > *, .grid.split > *, .grid.split-wide > *, .branding-grid > *{ min-width: 0; }

@media (max-width: 1100px){
  .grid.rail{ grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 880px){
  .grid.split, .grid.split-wide{ grid-template-columns: minmax(0, 1fr); }

  /* shell: the sidebar becomes a wrapping nav strip under the topbar.
     Explicit 100% (not auto) so it fills the row on every page - a wide
     listing must never shrink-wrap it to a half-width block. */
  .shell-side{
    position: static;
    width: 100%;
    margin-top: var(--shell-top);
    padding: 8px 14px 10px;
    border-right: 0;
    border-bottom: 1px solid var(--line);
    overflow: visible;
    display: flex; flex-wrap: wrap; align-items: center; gap: 2px 18px;
  }
  .shell-side nav{ display: flex; flex-wrap: wrap; align-items: center; gap: 2px 18px; }
  .shell-side .nav-group{ margin-top: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
  .shell-side .nav-group > .label{ display: none; }
  .shell-side .nav-item{ width: auto; }
  .shell-side .sidebar-foot{ margin-top: 0; padding: 8px 12px; border-top: 0; }
  .shell-side .sidebar-kbd{ margin-top: 0; padding: 8px 12px 8px; border-top: 0; }
  .shell-main{ margin-left: 0; padding-top: 0; }
  .shell-main > .container{ padding-top: 20px; padding-bottom: 48px; }

  /* topbar: tighter; the left-side marks shrink and truncate so the right-side
     controls (theme / account / sign-out) stay reachable instead of the whole
     bar pushing the page into horizontal scroll. overflow:hidden clips any
     residual left overflow without clipping the native <select> menu. */
  .shell-top{ gap: 8px; padding: 0 12px; overflow: hidden; }
  .shell-top .divider{ display: none; }
  .shell-top .title,
  .shell-top .tenant-mark,
  .shell-top .platform-pill,
  .shell-top .wordmark{ min-width: 0; flex-shrink: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .shell-top .right{ flex: none; }
  .theme-pick .tlabel{ display: none; }

  /* wide tables scroll inside their card instead of the page. contain:layout
     isolates the block-table's scrollable overflow so its intrinsic content
     width (which a display:block table otherwise leaks into the document's
     scrollWidth in Chromium, even with the box clipped) can't force
     page-level horizontal scroll. Paint is NOT contained, so per-row popovers
     still open past the table edge. */
  table.data, .card.flush table{ display: block; overflow-x: auto; contain: layout; }
}

/* share modal: reveal the anonymous-consent warning only once the anonymous
   mode is selected; browsers without :has() keep it always visible. */
@supports selector(:has(*)) {
  .share-form #anon-warn{ display: none; }
  .share-form:has(input[name="mode"][value="anonymous"]:checked) #anon-warn{ display: block; }
}
/* ────────────────────────────────────────────────────────────
   37. TYPE & TEXT HELPERS - sanctioned small-print scale
   (replaces the inline font-size drift; three steps only)
   ──────────────────────────────────────────────────────────── */
.fine { font-size: .82rem; }   /* secondary copy */
.finer{ font-size: .78rem; }   /* meta lines, hints */
.micro{ font-size: .7rem; }    /* ids, chip text */
/* Document-ID value: a monospace, muted secondary line, but held at 13px so it
   clears the tiny-text floor (<12px) that .micro (11.2px) tripped. */
.doc-id{ font-size: .8125rem; color: var(--ink-muted); }
.row.tight{ gap: 6px; }
.break-all{ word-break: break-all; overflow-wrap: anywhere; }

/* ────────────────────────────────────────────────────────────
   38. INLINE-STYLE PORTS - web / auth / sharing templates
   ──────────────────────────────────────────────────────────── */

/* forms that sit inline beside sibling content (revoke, resend, exit-grant) */
.inline-form{ display: inline; }

/* page header row: h1 + .lead + optional actions (dashboard, drive, audit) */
.page-head{ margin-bottom: 14px; }
.page-head .lead{ margin: 2px 0 0; }

/* stat-tile band under the page head (dashboard, audit, admin home) */
.stat-band{ margin: 6px 0 20px; }

/* hairline byte rows in the drive vaults rail */
.dashed-row{ padding: 6px 0; border-bottom: 1px dashed var(--line); }

/* submit row spaced from surrounding content (popovers, editor sections) */
.form-actions{ margin: 12px 0; }

/* document head: tag strip under the meta line */
.doc-head .tagrow{ margin-top: 10px; }

/* document sidebar: per-share revoke form */
.share-row form{ margin-top: 6px; }

/* auth: seal tagline tracking + login notice spacing */
.seal .font-mono{ letter-spacing: .04em; }
.form-card .flash{ margin-bottom: 14px; }

/* share gate / OTP cards (sharing/routes.rs) */
.share-card > .card{ padding: 32px; text-align: center; }
.share-card > .card h2{ font-size: 1.4rem; }
.share-card .consent{ text-align: left; }
.gate-form{ margin-top: 14px; }
.gate-sub{ margin: 6px auto 4px; max-width: 38ch; }
.gate-note{ margin-top: 12px; }
.shield.info{ background: var(--info); color: var(--paper); } /* --paper flips with theme, matching --info's lightness flip */
.viewer-head h2{ font-size: 1.3rem; margin: 2px 0; }
.wm-note{ margin-top: 6px; text-align: center; }

/* ────────────────────────────────────────────────────────────
   39. ADMIN PANEL PORTS - semantic classes replacing inline styles
   ──────────────────────────────────────────────────────────── */
/* success banner at the top of the content container */
.flash.notice{ margin-bottom: 14px; }

/* dashed activity-feed rows (control-panel home) */
.feed-row{ gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--line); }
.feed-row .when{ width: 80px; flex: none; }

/* members table fixed columns (admin/users.rs) */
table.data th.col-change-role{ width: 280px; }
table.data th.col-row-actions{ width: 140px; }

/* standalone editor sections sit further from the table above */
.card.user-invite, .card.role-new{ margin-top: 22px; }

/* action-matrix chip grid is tighter than the default grid gap */
.action-matrix .grid{ gap: 6px; }

/* small print hugging the control above it */
.note{ margin: 8px 0 0; }

/* Encryption-functions policy card (admin/settings.rs): the mode selects sit
   inline in a .row.wrap; the global select{width:100%} would push each one
   onto its own full-width line, so pin them to their content width. The .f
   labels are inline captions here, matching the row-form label voice. */
#function-policy .row.wrap select{ width: auto; }
#function-policy label.f{ font-size: .82rem; font-weight: 600; color: var(--ink-strong); }

/* closing hint at the bottom of a page */
.hint.foot-note{ margin-top: 14px; }


/* residency picker cards: oversized flag + default-residency row */
.vault-grid .vault.opt .flag{ font-size: 1.8rem; line-height: 1; }
.vault-grid .vault.opt .pick{ margin-top: 8px; }

/* ────────────────────────────────────────────────────────────
   40. DOCUMENT TAGS - clickable chips + sidebar edit form
   ──────────────────────────────────────────────────────────── */
/* tag chips rendered as links filter the drive by exact tag */
a.tag:hover{ border-color: var(--brand); text-decoration: none; }

/* collapsed "Edit tags" form in the document Properties panel */
.tags-edit > summary{
  cursor: pointer; user-select: none;
  font-size: .82rem; color: var(--ink-muted);
}
.tags-edit > summary:hover{ color: var(--ink-strong); }
.tags-edit form{ margin-top: 8px; }

/* ────────────────────────────────────────────────────────────
   41. SURFACE THEMES - topbar picker form + curation page
   ──────────────────────────────────────────────────────────── */
/* The picker is a real form (select + explicit Apply, WCAG 3.2.2); the
   button mirrors the logout button so the pair reads as one topbar group. */
.theme-pick{ margin: 0; }
.theme-pick button{
  padding: 6px 10px;
  background: transparent;
  color: var(--chrome-ink);
  border: 1px solid var(--chrome-line);
  border-radius: var(--r-sm);
  font-size: .82rem; font-weight: 600;
}
.theme-pick button:hover{ background: color-mix(in srgb, var(--chrome-ink) 8%, transparent); }

/* Theme gallery on /admin/branding/themes: one card per theme (preset or
   custom) with a mini-preview swatch, all inside ONE availability form. */
.theme-gallery{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.theme-card{
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1);
}
.theme-card-id{ display: flex; align-items: center; gap: 8px; }
.theme-card-id b{ font-family: var(--serif); font-weight: 600; color: var(--ink-strong); }
.theme-card-id .tag{ margin-left: auto; }
.theme-card-controls{
  display: flex; align-items: center; gap: 12px;
  border-top: 1px solid var(--line); padding-top: 10px;
}
.theme-pick-ctl{
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .82rem; color: var(--ink-muted); white-space: nowrap;
}
.theme-pick-ctl input{ margin: 0; }
.theme-card-act{ font-size: .82rem; font-weight: 600; }
.theme-card-act.danger{ color: var(--bad); }
.theme-card-new{
  align-items: center; justify-content: center; text-align: center;
  border-style: dashed; color: inherit; text-decoration: none;
  min-height: 130px;
}
.theme-card-new:hover{ border-color: var(--brandacc); text-decoration: none; }
.theme-card-new .plus{
  font-size: 1.6rem; line-height: 1; color: var(--ink-muted);
}
.save-bar{
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line);
  align-items: center; gap: 16px;
}
.save-bar .note{ margin: 0; max-width: 60ch; }

/* The mini-preview swatch: chrome bar over a bg/paper split + accent dot. */
.theme-swatch{
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  overflow: hidden;
}
.theme-swatch .sw-chrome{ height: 12px; }
.theme-swatch .sw-body{ display: flex; height: 30px; position: relative; }
.theme-swatch .sw-body > div{ flex: 1; }
.theme-swatch .sw-dot{
  position: absolute; right: 8px; top: 9px;
  width: 12px; height: 12px; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,.18);
}

/* Base-preset picker on the create/edit views: the same swatches as cards. */
.base-pick-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
}
.base-pick{
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px; border: 1px solid var(--line); border-radius: var(--r-md);
  font-size: .82rem; cursor: pointer;
}
.base-pick:hover{ border-color: var(--brandacc); }
.base-pick input{ position: absolute; opacity: 0; pointer-events: none; }
.base-pick:has(input:checked){
  border-color: var(--brand); box-shadow: 0 0 0 2px var(--focus);
}
.base-pick:has(input:focus-visible){ outline: 2px solid var(--brand); outline-offset: 2px; }
.theme-form{ max-width: 720px; }

/* Advanced settings on the custom-theme create/edit views: collapsed
   per-token override grid + nested raw editor. */
.advanced-settings > summary{
  cursor: pointer; user-select: none;
  font-size: .86rem; font-weight: 600; color: var(--ink-muted);
}
.advanced-settings > summary::-webkit-details-marker{ display: none; }
.advanced-settings > summary:hover{ color: var(--ink-strong); }
.advanced-settings .advanced-body{ margin-top: 12px; }
.ov-group{
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 10px 12px; margin: 0;
}
.ov-group legend{
  font-size: .78rem; font-weight: 600; color: var(--ink-muted); padding: 0 4px;
}
.ov-grid{
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 18px;
}
@media (max-width: 720px){
  .ov-grid{ grid-template-columns: 1fr; }
}
.ov-row{ display: flex; align-items: center; gap: 8px; min-width: 0; }
.ov-row .ov-name{
  display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0;
}
.ov-row code{
  font-family: var(--mono); font-size: .76rem; color: var(--ink-muted);
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.ov-input{
  width: 92px; flex: none;
  font-family: var(--mono); font-size: .78rem;
}
.ov-swatch{
  width: 16px; height: 16px; flex: none;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
}
.raw-editor > summary{
  cursor: pointer; user-select: none;
  font-size: .82rem; font-weight: 600; color: var(--ink-muted);
}
.raw-editor > summary::-webkit-details-marker{ display: none; }
.raw-editor > summary:hover{ color: var(--ink-strong); }
.ov-raw{ width: 100%; font-family: var(--mono); font-size: .8rem; }

/* Live preview on the custom-theme create/edit views: the iframe (host
   page) and the standalone sample page it loads (real shell-top over a
   plain padded main - the iframe is that page's own viewport). */
.preview-pane{ max-width: 720px; margin-top: 20px; }
.preview-pane h2{ font-size: 1.05rem; margin-bottom: 8px; }
.theme-preview{
  display: block; width: 100%; height: 420px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
}
.pv-main{
  padding: calc(var(--shell-top) + 18px) 20px 24px;
  display: grid; gap: 14px;
}

/* theming contract folded into the branding page as a collapsed details */
.theming-contract > summary{
  cursor: pointer; user-select: none;
  font-size: .86rem; font-weight: 600; color: var(--ink-muted);
}
.theming-contract > summary:hover{ color: var(--ink-strong); }
.theming-contract .contract-details{ margin-top: 14px; }


/* ────────────────────────────────────────────────────────────
   42. PAGE GRAMMAR - disclosure cards, header counts, empty CTAs
   Shared vocabulary: drive, admin, platform, auth, and share
   surfaces all reuse these classes - extend here, don't fork.
   ──────────────────────────────────────────────────────────── */

/* card-header count: "Access · 3" style chip inside .ch h3 */
.card .ch :is(h2, h3) .count{
  margin-left: 8px;
  font-family: var(--mono);
  font-size: .74rem;
  font-weight: 600;
  color: var(--ink-muted);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 8px;
  vertical-align: 2px;
}

/* disclosure card: a <details class="card disclose"> whose <summary>
   is the card header, so collapsed panels look exactly like .card */
details.card.disclose > summary.ch{
  cursor: pointer; user-select: none;
  list-style: none;
}
details.card.disclose > summary.ch::-webkit-details-marker{ display: none; }
details.card.disclose > summary.ch::after{
  content: "▸";
  margin-left: auto;
  color: var(--ink-faint);
  font-size: .8rem;
}
details.card.disclose[open] > summary.ch::after{ content: "▾"; }
details.card.disclose:not([open]) > summary.ch{ border-bottom: 0; }

/* empty states: 16px stroke icon scaled up, action spaced below */
.empty .icon svg{ width: 32px; height: 32px; }
.empty p{ margin-bottom: 10px; }
.empty .empty-upload{
  margin: 4px auto 0;
  max-width: 340px;
  display: flex; flex-direction: column; gap: 10px;
  align-items: center;
}

/* ────────────────────────────────────────────────────────────
   43. PAGE-GRAMMAR RECONCILIATION - accordion + empty-state glyphs
   ──────────────────────────────────────────────────────────── */
/* role accordion: the card header doubles as the details summary */
details.role-row > summary{ list-style: none; cursor: pointer; user-select: none; }
details.role-row > summary::-webkit-details-marker{ display: none; }
details.role-row > summary .ch :is(h2, h3)::before,
details.role-row > summary.ch :is(h2, h3)::before{ content: "▸ "; color: var(--ink-faint); }
details.role-row[open] > summary .ch :is(h2, h3)::before,
details.role-row[open] > summary.ch :is(h2, h3)::before{ content: "▾ "; }

/* empty states that place the 16px nav glyph directly (admin/platform) */
.empty > svg.ic{ display: block; margin: 0 auto 6px; width: 20px; height: 20px; opacity: .6; }

/* flush cards that gained a .ch header: the table no longer owns the top corners */
.card.flush .ch + table thead tr:first-child th{ border-radius: 0; }

/* ────────────────────────────────────────────────────────────
   44. DRIVE MANAGEMENT - bulk selection, pager, search keycap
   ──────────────────────────────────────────────────────────── */
/* `/` shortcut keycap beside the drive search input */
.toolbar .search .kbd{ margin-left: 8px; }

/* Bulk selection: the checkbox column stays narrow; the bar sits under the
   listing and posts to /documents/bulk. Checkboxes associate with the bar's
   form via the `form` attribute (the rows also contain the folder Manage
   forms, so nesting the table inside the bulk form would be invalid HTML). */
table.data th.selcell, table.data td.selcell{ width: 32px; text-align: center; }
.selcell .selbox{ margin: 0; }
.bulkbar{
  display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center;
  margin-top: 10px; padding: 10px 14px;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
}
.bulkbar .bulk-hint{ font-size: .82rem; }
.bulkbar .bulk-actions{ display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }
.bulkbar .bulk-actions .grp{ display: inline-flex; gap: 6px; align-items: center; }
.bulkbar .bulk-actions input[type="text"],
.bulkbar .bulk-actions select{ max-width: 220px; }
/* Progressive disclosure: on :has()-capable browsers the actions only appear
   once a row is checked; elsewhere the bar renders statically with the hint. */
@supports selector(:has(*)){
  .bulk-scope .bulkbar .bulk-actions{ display: none; }
  .bulk-scope:has(.selbox:checked) .bulkbar .bulk-actions{ display: flex; }
  .bulk-scope:has(.selbox:checked) .bulkbar .bulk-hint{ display: none; }
}

/* Document pager extras: per-page select rides the pager's right edge */
.pager .per-page{ display: inline-flex; gap: 6px; align-items: center; margin-left: auto; }
.pager .per-page select{ width: auto; }

/* Popover section separators inside the folder Manage menu */
.row-popover .popover hr{ border: 0; border-top: 1px solid var(--line); margin: 12px 0; }

/* ────────────────────────────────────────────────────────────
   45. WHITE-LABEL CHROME + FIELD-ERROR + COPY BUTTON
   ──────────────────────────────────────────────────────────── */
/* discreet platform attribution on tenant-branded surfaces */
.powered-by{ display: block; margin-top: .5em; opacity: .65; font-size: .75em; }
span.powered-by{ display: inline-block; margin: 0 0 0 10px; }

/* tenant-mark standing in for the wordmark on auth + error chrome */
.marque .tenant-mark, .auth-top .tenant-mark, .err-page .topbar .tenant-mark{
  font-family: var(--serif); font-size: 1.05rem; font-weight: 700;
  display: inline-flex; align-items: center; gap: 10px;
  color: inherit; text-decoration: none;
}

/* uploaded org logo standing in for the sigil (topbars + auth marques);
   the branding form's preview gets a little more headroom */
.org-logo{ display: block; max-height: 32px; max-width: 180px; width: auto; }
.logo-up .org-logo.preview{ max-height: 48px; max-width: 240px; }

/* compact in-cell copy button: tighter than .btn.sm so table rows keep rhythm */
.btn.copy{ padding: 2px 8px; font-size: .75rem; line-height: 1.4; border-radius: var(--r-xs); }

/* slim field-adjacent error: quieter than the boxy .error banner */
.field-error{ display: block; font-size: .78rem; color: var(--bad); margin: 6px 0 0; }

/* ────────────────────────────────────────────────────────────
   46. DOCUMENT HEADER ACTIONS - icon buttons + More-actions popover
   ──────────────────────────────────────────────────────────── */
/* Icon-only header action (the "⋯" More-actions summary). Keeps the .btn chrome
   but squares the padding so a lone glyph reads as a button. */
.icon-btn{ padding: 8px 12px; line-height: 1; }

/* Split-button: a primary .btn seamed to a caret <details> that reveals the
   no-watermark "original" variant. The two read as one connected control. A
   non-holder renders just the primary (no .split-menu, so :has leaves it a
   normal button). */
.split{ display: inline-flex; align-items: stretch; }
/* When a caret follows, square the seam between the two halves. */
.split:has(.split-menu) > .btn{
  border-top-right-radius: 0; border-bottom-right-radius: 0;
}
.split-menu{ position: relative; display: inline-flex; }
.split-menu > summary{ list-style: none; cursor: pointer; user-select: none; }
.split-menu > summary::-webkit-details-marker{ display: none; }
/* The caret shares the primary's chrome/height; square its left edge and pull it
   flush so the 1px borders collapse into one seam, tinted as a subtle divider. */
.split-caret{
  padding: 9px 10px;
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  margin-left: -1px;
  border-left-color: color-mix(in srgb, var(--brand-ink) 35%, transparent);
}
.split-menu[open] > summary{ filter: brightness(.95); }
/* The revealed menu: a small anchored popover - crisp border + tight shadow
   (blur < 16px), matching .row-popover, never a wide-shadow dropdown. */
.split-menu .popover{
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 200px; z-index: 5;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); padding: 8px 10px;
  box-shadow: 0 4px 12px rgba(0,0,0,.10);
  text-align: left;
}
.split-menu .popover .menu-link{
  display: block; padding: 4px 0; font-size: .88rem; font-weight: 600;
  color: var(--ink); text-decoration: none; white-space: nowrap;
}
.split-menu .popover .menu-link:hover{ color: var(--ink-strong); }
.split-menu .popover .muted{ font-weight: 500; }

/* Document-header "More actions" overflow: a .row-popover whose panel is a
   vertical action list (platform shell's Manage▾ pattern, app surface). */
.manage-popover .menu-link{
  display: block; padding: 4px 0; font-size: .88rem; font-weight: 600;
  color: var(--ink); text-decoration: none;
}
.manage-popover .menu-link:hover{ color: var(--ink-strong); }
.manage-popover .manage-section{ position: static; display: block; padding: 6px 0; }
.manage-popover .manage-section > summary{
  list-style: none; cursor: pointer; user-select: none;
  font-size: .88rem; font-weight: 600; padding: 4px 0;
}
.manage-popover .manage-section > summary::-webkit-details-marker{ display: none; }
.manage-popover .manage-section > summary::before{ content: "\25B8"; margin-right: 6px; color: var(--ink-faint); }
.manage-popover .manage-section[open] > summary::before{ content: "\25BE"; }
.manage-popover .manage-section > summary:hover{ color: var(--ink-strong); }
.manage-popover .manage-section.danger > summary{ color: var(--bad-ink); }
.manage-popover .manage-section > .section-body{ position: static; min-width: 0; border: 0; box-shadow: none; padding: 6px 0 4px; }
.manage-popover .manage-section.danger > .section-body{ border: 1px solid var(--bad); border-radius: var(--r-md); padding: 10px 12px; }
.manage-popover .manage-section.danger .section-body p{ margin: 0 0 8px; }
.manage-popover .manage-section.danger .warn{ color: var(--bad-ink); font-weight: 600; }

/* Folder-tree move picker (document Move, folder Manage▾ Move, bulk bar) */
.tree-picker{ display: block; min-width: 220px; }
.tree-scroll{ max-height: 280px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-sm); }
.tree-node{
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px calc(8px + var(--tree-depth, 0) * 18px);
  border-radius: var(--r-xs); cursor: pointer;
}
.tree-node:hover{ background: var(--brand-soft); }
.tree-node:has(input:checked){ background: var(--brand-soft); color: var(--brand-soft-ink); }
.tree-node .muted{ color: var(--ink-faint); }
.tree-node.disabled{ color: var(--ink-faint); cursor: not-allowed; }
.tree-node.disabled:hover{ background: transparent; }
.tree-node input[type="radio"]{ flex: none; }

/* auth pages: the made-with credit sits visibly under the auth panel */
footer.powered-by{ text-align: center; padding: 14px 20px; }

/* ────────────────────────────────────────────────────────────
   47. DRIVE GRID VIEW + VIEW TOGGLE + DROPZONE
   ──────────────────────────────────────────────────────────── */
/* Toolbar list/grid toggle: two icon links; the active layout gets the
   pressed chrome and carries aria-current for assistive tech. */
.view-toggle{
  display: inline-flex; gap: 2px; padding: 2px;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
}
.view-toggle .vt{
  display: inline-flex; align-items: center; justify-content: center;
  padding: 6px 10px; border-radius: var(--r-xs);
  color: var(--ink-muted); line-height: 1;
}
.view-toggle .vt:hover{ color: var(--ink-strong); background: var(--paper-2); }
.view-toggle .vt.active{
  color: var(--brand-soft-ink); background: var(--brand-soft);
}

/* Grid-mode sort control (the grid has no column headers): a compact
   segmented control mirroring the adjacent view-toggle, so sorting reads as
   the same affordance in both views. The active link carries the same pressed
   chrome the active table header implies. */
.sort-links{
  display: inline-flex; gap: 2px; align-items: center;
  padding: 2px 2px 2px 10px;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-size: .85rem;
}
.sort-links > .muted{
  font-size: .78rem; font-weight: 600;
}
.sort-links .sort-link{
  display: inline-flex; align-items: center; gap: 2px;
  padding: 6px 10px; border-radius: var(--r-xs);
  color: var(--ink-muted); font-weight: 600; text-decoration: none; line-height: 1;
}
.sort-links .sort-link:hover{ color: var(--ink-strong); background: var(--paper-2); }
.sort-links .sort-link.active{ color: var(--brand-soft-ink); background: var(--brand-soft); }

/* Card grid: folder cards above document cards, sharing the bulk checkbox
   and residency chips with the table view. */
.drive-grid{
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.drive-card{
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 20px 12px 14px; text-align: center;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.drive-card:hover{ border-color: var(--line-strong); background: var(--paper-2); }
.drive-card > .selcell{ position: absolute; top: 8px; left: 8px; }
.drive-card .fname{ flex-direction: column; gap: 8px; max-width: 100%; }
.drive-card .fname .fic{ width: auto; height: auto; }
.drive-card .fname .fic svg{ width: 44px; height: 50px; }
.drive-card.folder .fname .fic svg{ width: 52px; height: 42px; }
.drive-card .fname .nm{
  max-width: 100%; overflow: hidden;
  /* Two lines instead of one: names use the card's full width/height before
     truncating, and a long single token still wraps rather than clips. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow-wrap: anywhere; white-space: normal;
}
.drive-card .meta{ margin: 0; font-size: .75rem; color: var(--ink-muted); }
.drive-card .chips{
  display: flex; flex-wrap: wrap; gap: 4px; justify-content: center;
}

/* Drag-and-drop target over the listing region (drive.js). The highlight only
   appears mid-drag, so the affordance never lies to a no-JS visitor. */
.dropzone-active{
  outline: 2px dashed var(--brandacc); outline-offset: 4px;
  border-radius: var(--r-md);
  background: var(--brand-soft);
}

/* Async upload progress panel (drive.js): one row per file with a live bar.
   Created only once an XHR upload starts; the classic form is the no-JS path. */
.upload-progress{
  margin: 0 0 16px; padding: 12px 14px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-md);
  display: flex; flex-direction: column; gap: 8px;
}
.upload-progress.has-error{ border-color: var(--bad); }
.up-head{
  font-size: .8rem; font-weight: 600; color: var(--ink-muted);
  letter-spacing: .02em;
}
.upload-progress.has-error .up-head{ color: var(--bad-ink); }
.up-row{
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: 4px 10px;
}
.up-name{
  grid-column: 1; font-size: .88rem; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.up-pct{
  grid-column: 2; grid-row: 1; font-size: .78rem; color: var(--ink-muted);
  font-family: var(--mono); min-width: 3.5em; text-align: right;
}
.up-track{
  grid-column: 1 / -1; grid-row: 2; height: 6px;
  background: var(--bg-elev); border-radius: 999px; overflow: hidden;
}
.up-bar{
  display: block; width: 0; height: 100%;
  background: var(--brandacc); border-radius: inherit;
  transition: width .15s ease;
}
.up-row.ok .up-bar{ background: var(--ok, var(--brandacc)); }
.up-row.ok .up-pct{ color: var(--ok-ink, var(--ink-muted)); }
.up-row.err .up-bar{ background: var(--bad); }
.up-row.err .up-pct{ color: var(--bad-ink); }

/* Keyboard help + "Go to…" palette (dialogs reuse .modal) */
.kbd-map{ width: 100%; border-collapse: collapse; }
.kbd-map td{ padding: 6px 10px; border-bottom: 1px solid var(--line); font-size: .9rem; }
.kbd-map td:first-child{ width: 40%; white-space: nowrap; }
#cmd-palette{ max-width: 480px; }
.cmd-palette-body input{
  width: 100%; padding: 8px 10px; margin-bottom: 10px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink);
}
.cmd-palette-body input:focus{ outline: 2px solid var(--brand); outline-offset: 1px; }
.cmd-list{ display: flex; flex-direction: column; max-height: 40vh; overflow: auto; }
.cmd-item{
  padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--ink); text-decoration: none;
}
.cmd-item:hover{ background: var(--bg-elev); }
.cmd-item.sel{ background: var(--brand); color: var(--brand-ink); }
/* Group captions ("Actions", "Go to") that separate the palette sections. */
.cmd-group{
  padding: 8px 10px 4px; font-size: .72rem; font-weight: 600;
  color: var(--ink-faint);
}
.cmd-group:first-child{ padding-top: 2px; }
.cmd-hint{ margin-left: 8px; font-size: .78rem; color: var(--ink-muted); }
.cmd-item.sel .cmd-hint{ color: var(--brand-ink); }

/* Deposit (drop-box) surface: the blind upload page a member with Upload but
   no View gets instead of the drive listing. One calm card, centered; the
   wrapper is the drive.js drag-and-drop zone. */
.deposit-drop{ max-width: 640px; margin: 24px auto 0; }
.deposit-card .cb{ padding: 24px; }
.deposit-card .f{
  display: block; font-size: .82rem; font-weight: 600;
  color: var(--ink-strong); margin: 8px 0 6px;
}
.deposit-grant-row{ padding: 4px 0; border-bottom: 1px dashed var(--line); }
.deposit-grant-row:last-of-type{ border-bottom: 0; }

/* ────────────────────────────────────────────────────────────
   50. ROLES MATRIX - legible chips (label + description), clusters, presets
   ──────────────────────────────────────────────────────────── */
/* In the roles matrix each action reads as a small card: the checkbox + name
   on one line, a one-line description underneath. Scoped to .action-matrix so
   the pill-shaped .action-chip elsewhere is untouched. */
.action-matrix .action-chip{
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  border-radius: var(--r-sm);
  padding: 8px 12px; margin: 0;
  width: 100%;
}
.action-matrix .action-chip .chip-label{
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 600;
}
.action-matrix .action-chip .chip-desc{
  color: var(--ink-muted); font-size: .74rem; line-height: 1.35;
  padding-left: 22px;
}
.action-matrix .action-chip:has(input:checked){
  background: var(--brand-soft); border-color: var(--brandacc);
}
.action-matrix .action-chip:has(input:checked) .chip-desc{ color: var(--brand-soft-ink); }
.action-matrix input[type="checkbox"]{ accent-color: var(--brand); }

/* Captioned sub-group inside the Documents fieldset (read vs write clusters). */
.matrix-cluster{ margin-top: 10px; }
.matrix-cluster-caption{
  font-size: .8rem; color: var(--ink-muted); font-weight: 600;
  margin: 0 0 6px;
}

/* "Advanced - individual capabilities" disclosure wrapping the full matrix, so
   named presets stay the primary choice. Boxes stay in the DOM when collapsed
   (details hides, never disables) - the no-JS form still submits them. */
.advanced-matrix{ margin-top: 4px; }
.advanced-matrix > summary{
  cursor: pointer; user-select: none;
  font-size: .82rem; font-weight: 600; color: var(--ink-muted);
  padding: 8px 0;
}
.advanced-matrix > summary:hover{ color: var(--ink-strong); }
.advanced-matrix[open] > summary{ margin-bottom: 6px; }

/* Named capability presets above the New-role matrix: quick-apply links. */
.preset-bar{
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-bottom: 14px;
}
.preset-bar .preset-label{ color: var(--ink-muted); font-size: .82rem; }
.preset-bar button[aria-current="true"]{
  background: var(--brand); color: var(--brand-ink); border-color: var(--brand);
}


/* ────────────────────────────────────────────────────────────
   38. PROSE MEASURE & FLUSH-TABLE INSET (impeccable clean-ups)
   ──────────────────────────────────────────────────────────── */

/* Cap long descriptive copy to a comfortable measure so lines wrap before the
   ~80ch mark impeccable's line-length flags. Scoped to the specific prose
   blocks on /admin/roles and /admin/branding - tables, labels, and UI chrome
   keep their own width. */
.role-new .cb > p,
.action-matrix .action-chip .chip-desc,
.matrix-cluster-caption,
.branding-layout .cb p,
.help-faq .cb > p,
.contract-section p{ max-width: 65ch; }

/* The drive listing table fills its flush card edge-to-edge; a small vertical
   inset lifts the header row and last row off the card's top/bottom border so
   they no longer read as flush (impeccable cramped-padding needs >2px inset on
   a bounded side). Scoped via :has so other .card.flush tables are untouched. */
.card.flush:has(> table.listing){ padding-block: 4px; }

/* ────────────────────────────────────────────────────────────
   39. ACCOUNT SECURITY (2FA: TOTP QR, recovery codes, passkeys)
   ──────────────────────────────────────────────────────────── */

/* The provisioning QR: a bounded, light plate so the SVG scans on any theme. */
.totp-qr{
  display: inline-block; padding: 12px; margin: 8px 0;
  background: #fff; border-radius: 10px; border: 1px solid var(--line, #d8d8d8);
}
.totp-qr svg{ display: block; width: 200px; height: 200px; }

/* Show-once recovery codes: a monospace grid that reads as a discrete block. */
.recovery-codes{
  list-style: none; margin: 8px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
}
.recovery-codes li code{
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 15px; letter-spacing: 0.04em;
}
.backup-codes-panel{ border: 1px solid var(--accent, #b45309); }

/* E2EE recovery phrase: a numbered, monospace 2-column grid so the 24 words
   read as a discrete, ordered block that is easy to transcribe. */
.recovery-phrase{
  margin: 8px 0 0; padding-left: 1.6em;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 16px;
}
.recovery-phrase li{
  font-family: var(--mono);
  font-size: 15px; letter-spacing: 0.02em;
}
.e2e-setup .e2e-step{ margin-top: 8px; }

/* Registered passkeys: one row each with its remove control pushed to the end. */
.passkey-list{ list-style: none; margin: 8px 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.passkey-row{
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border: 1px solid var(--line, #d8d8d8); border-radius: 8px;
}
.passkey-enroll{ margin-top: 8px; }


/* Small layout utilities: keep markup free of inline style attributes. */
.txt-center{ text-align: center; }
.w-7em{ width: 7em; }
.w-5em{ width: 5em; }
