/* ════════════════════════════════════════════════════════════════════
   Reelax — Customer App · admin.css?v=66
   Editorial redesign · drop-in for css/admin.css
   Preserves every existing class name + JS hook from admin.php.
   Dark = default · light via existing toggleTheme() / [data-theme="light"].
   Accent reads var(--accent) — set per-org by admin-core.js at runtime.
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* Dark (default) */
  --bg:           #0A0A0A;
  --surface:      #131313;
  --card:         #161616;
  --card-hover:   #1C1C1C;
  --border:       #222;
  --border-hover: #3A3A3A;
  --border-soft:  rgba(255,255,255,.08);

  --text:         #FFF;
  --text-muted:   #878B8B;
  --text-sub:     #878B8B;
  --text-3:       rgba(255,255,255,.30);
  --text-label:   rgba(255,255,255,.35);

  /* Accent — overridable per-org via inline style on <html>.
   * Default is an editorial ochre (#E35E00 / rgb(255, 108, 0)) that
   * harmonizes with the cream surfaces in light theme and reads
   * cleanly on the near-black dark surfaces too. Per-org accent
   * choices applyOrgAccentColor() always win. */
  --accent:        #E35E00;
  --accent-bg:     rgba(255,108,0,.15);
  --accent-border: rgba(255,108,0,.40);
  --accent-ink:    #FFF;

  --chip-ok:   #4ADE80;
  /* Attention / "needs action" amber. Tokenized so it has a light-mode value —
     the hardcoded #b45309 it replaces had none, so the NEW badge and the
     duplicate-review card were unreadable-ish on the cream theme. */
  --attn:      #E08A2B;
  --danger:    rgba(255,80,80,.7);
  --chip-wrap: rgba(255,255,255,.4);

  --input-bg:     rgba(255,255,255,.05);
  --input-border: rgba(255,255,255,.10);
  --modal-bg:     #0F0F0F;
  /* Modal header/footer strip color — see Style Guide §7c. In dark
   * mode it's intentionally identical to --modal-bg so the existing
   * dark behavior is preserved (don't alter dark per spec). The light
   * theme override below paints the cream strip. */
  --modal-strip:  #0F0F0F;
  --overlay-bg:   rgba(0,0,0,.72);

  --font-sans:  'DM Sans', system-ui, -apple-system, sans-serif;
  --font-serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --font-mono:  'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
}

[data-theme="light"] {
  --bg:           #F5F1E8;
  --surface:      #EDE7DA;
  --card:         #FFFFFF;
  --card-hover:   #FAF7F0;
  --border:       #D8D2C4;
  --border-hover: #6E665B;
  --border-soft:  rgba(26,22,18,.08);

  --text:         #1A1612;
  --text-muted:   #6E665B;
  --text-sub:     #6E665B;
  --text-3:       rgba(26,22,18,.38);
  --text-label:   rgba(26,22,18,.45);

  --accent-bg:    color-mix(in srgb, var(--accent) 12%, transparent);
  --accent-border:color-mix(in srgb, var(--accent) 35%, transparent);
  --accent-ink:   #FFFFFF;

  --chip-ok:   #4F7A4A;
  --attn:      #8A5A0C;
  --danger:    #A8362C;
  --chip-wrap: rgba(26,22,18,.35);

  --input-bg:     #FFFFFF;
  --input-border: #D8D2C4;
  --modal-bg:     #FFFFFF;
  /* Cream strip for modal header + footer (Style Guide §7c). Body
   * stays --modal-bg white; this paints only the bookend strips. */
  --modal-strip:  #EDE7DA;
  --overlay-bg:   rgba(26,22,18,.55);
}

/* base */
*,*::before,*::after { box-sizing: border-box; }
html, body { margin:0; padding:0; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--font-sans); font-size: 13px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ── header ─────────────────────────────────────────────────────────── */
.header {
  height: 56px; padding: 0 24px; background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  position: sticky; top: 0; z-index: 30;
}
.header-left { display: flex; align-items: center; gap: 14px; }
.header-logo { height: 22px; }
[data-theme="light"] .header-logo-dark { display: none !important; }
[data-theme="light"] .header-logo-light { display: inline !important; }
.header-divider { width: 1px; height: 22px; background: var(--border); }
.header-tool {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted);
}
.theme-toggle {
  height: 30px; padding: 0 12px; background: transparent;
  border: 1px solid var(--border); color: var(--text-muted);
  font-family: var(--font-sans); font-size: 11px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.theme-toggle:hover { border-color: var(--text); color: var(--text); }
.help-link { text-decoration: none; }
.help-link:hover { text-decoration: none; }
.header-user { font-size: 12px; color: var(--text-muted); }
.user-menu { position: relative; }
.user-avatar-btn {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent-bg); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-weight: 600; font-size: 12px;
  cursor: pointer; border: 1px solid var(--accent-border);
}
.user-dropdown {
  position: absolute; top: 40px; right: 0; min-width: 200px;
  background: var(--card); border: 1px solid var(--border);
  display: none; flex-direction: column; padding: 6px;
}
.user-dropdown.open { display: flex; }
.user-dropdown-name {
  padding: 10px 12px 8px; font-size: 12px; color: var(--text-muted);
  border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.user-dropdown-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; background: transparent; border: 0;
  color: var(--text); font-family: var(--font-sans); font-size: 12px;
  cursor: pointer; text-align: left;
}
.user-dropdown-item:hover { background: var(--card-hover); }
.user-dropdown-item.danger { color: var(--danger); }

/* ── auth ───────────────────────────────────────────────────────────── */
.auth-screen {
  min-height: calc(100vh - 56px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 32px 16px; gap: 16px;
}
.auth-card {
  width: 100%; max-width: 400px; padding: 36px 32px 28px;
  background: var(--card); border: 1px solid var(--border);
}
.auth-logo { width: 96px; display: block; margin: 0 auto 22px; }
[data-theme="light"] .auth-logo-dark { display: none !important; }
[data-theme="light"] .auth-logo-light { display: inline !important; }
.auth-org-logo { max-width: 120px; max-height: 48px; margin-bottom: 8px; }
.auth-org-name {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted);
}
.auth-title {
  font-family: var(--font-serif); font-size: 36px; line-height: .95;
  letter-spacing: -.02em; text-align: center; margin: 4px 0 6px;
}
.auth-title::after { content:'.'; color: var(--accent); }

/* Auth intent gateway — two-track picker shown at first visit. */
.auth-intent-gate {
  display: flex; flex-direction: column; gap: 10px;
  margin: 18px 0 4px;
  text-align: left;
}
/* The rows themselves are canonical .cl-radio-option / .cl-radio-body /
   .cl-radio-label / .cl-radio-help (editorial-chrome.css §5.6). The former
   .auth-intent-row / -body / -title / -help look-alike was DELETED
   2026-08-24, not overridden: it painted its selected state in --accent,
   which §5.6 forbids ("no accent fill — keeps the control quiet"), so the
   login screen was the one place on the platform where picking a radio
   turned the card orange. Only the gate's column layout above is local. */
#authIntentContinue { margin-top: 6px; }
/* Track-aware hint copy shown below providers when the member track is active. */
.auth-track-hint {
  font-size: 11.5px; color: var(--text-muted); text-align: center;
  margin-top: 14px; line-height: 1.5;
}
.auth-track-hint a, .auth-track-hint button {
  background: none; border: 0; padding: 0;
  color: var(--accent); cursor: pointer; font: inherit;
}

/* Nav-restore loading state — when showDashboard() defers reveal
   because we're routing through orgPicker→projects→projectDetail,
   body[data-nav-restoring] hides the auth card content and shows a
   neutral "Loading workspace…" message so the screen stays calm
   instead of flashing through intermediate views. */
body[data-nav-restoring="1"] .auth-card > * { display: none !important; }
body[data-nav-restoring="1"] .auth-card::before {
  content: 'Loading workspace…';
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: center;
  padding: 24px 8px;
}
body[data-nav-restoring="1"] .auth-card {
  border: 0;
  background: transparent;
  box-shadow: none;
}
.auth-sub {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em;
  color: var(--text-muted); text-align: center; margin: 0 0 22px;
}
.google-btn-wrap, .apple-btn { margin-bottom: 8px; }
/* Full width, like every other control in the auth card (.apple-btn,
   .email-toggle, .btn-full, the inputs — all 100%). It used to be pinned to
   300px to stop the GIS iframe rendering at a jittery, layout-dependent width
   between reloads; that fixed the jitter but left Google 34px narrower than
   everything below it. admin-google.js now MEASURES this wrapper and renders
   the iframe at that exact pixel width, so the button matches its siblings and
   still can't render at an arbitrary size. min-height reserves the row so the
   card doesn't reflow while the iframe paints. */
.google-btn-wrap { width: 100%; max-width: 100%; min-height: 40px; margin-left: auto; margin-right: auto; display: flex; justify-content: center; }
/* ITP-proof redirect fallback button — shown when the GIS iframe can't render
   (Safari ITP). Triggers the server-side OAuth redirect, NOT One Tap. */
.google-fallback-btn {
  width: 100%; min-height: 44px; display: inline-flex; align-items: center;
  justify-content: center; gap: 10px; padding: 11px 16px;
  background: #131314; color: #e3e3e3; border: 1px solid #5f6368;
  border-radius: 8px; font: 500 14px/1 'DM Sans', system-ui, sans-serif;
  cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.google-fallback-btn:hover { background: #1f1f20; border-color: #8a8f96; }
.google-fallback-btn:active { background: #2a2a2b; }
.apple-btn {
  width: 100%; height: 40px; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); cursor: not-allowed;
  font-family: var(--font-sans); font-size: 12px; position: relative;
}
.coming-soon-badge {
  font-family: var(--font-mono); font-size: 8px; letter-spacing: .12em;
  padding: 2px 6px; background: var(--accent-bg); color: var(--accent);
  margin-left: 6px;
}
.email-toggle {
  width: 100%; height: 36px; background: transparent; border: 1px dashed var(--border);
  color: var(--text-muted); cursor: pointer; font-family: var(--font-sans); font-size: 12px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.email-toggle:hover { color: var(--text); border-color: var(--text-muted); }
.auth-tabs { display: flex; margin: 16px 0 12px; border-bottom: 1px solid var(--border); }
.auth-tab {
  flex: 1; padding: 10px 0; background: transparent; border: 0;
  border-bottom: 2px solid transparent; cursor: pointer;
  font-family: var(--font-sans); font-size: 12.5px; color: var(--text-muted);
}
.auth-tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 500; }

/* "Forgot password?" link row — sits below the Sign In button. The link is
   subtle (muted color, underline-on-hover) so it stays visually quieter
   than the primary CTA above it. Same row pattern is reused inside the
   forgot form ("Back to sign in"). */
/* "Keep me signed in" — sits directly above the Sign In button. Whole label
   is the hit target so the text is tappable, not just the 13px box. */
.auth-remember {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 4px;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-dim, #878B8B);
  cursor: pointer;
  user-select: none;
}
/* Control painted by the canonical checkbox (editorial-chrome.css §5.7);
   size, margin, flex-shrink and cursor are all canonical too, so the whole
   rule went. It selected `input` bare, which is why the type-based audit
   missed it. */
.auth-forgot-row {
  margin-top: 12px;
  text-align: center;
  font-family: var(--font-sans);
  font-size: 12px;
}
.auth-forgot-link {
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .12s, border-color .12s;
}
.auth-forgot-link:hover {
  color: var(--text);
  border-bottom-color: var(--text-muted);
}

/* Title above the Set-new-password form (the only auth-screen view that
   needs its own heading — login/register sit under the auth-tabs strip). */
.auth-tab-title {
  font-family: var(--font-serif);
  font-size: 22px; line-height: 1.1;
  color: var(--text);
  margin: 4px 0 14px;
}
.auth-tab-title::after { content: '.'; color: var(--accent); }

/* Inline status line for the forgot + reset flows. Neutral by default,
   green on success, red on error. Sits below the action button. */
.auth-forgot-status {
  margin-top: 12px;
  padding: 10px 12px;
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-muted);
  background: var(--bg);
  border: 1px solid var(--border);
}
.auth-forgot-status.is-ok  { color: var(--chip-ok,    #4ADE80); border-color: color-mix(in srgb, var(--chip-ok, #4ADE80) 40%, var(--border)); }
.auth-forgot-status.is-err { color: var(--danger);              border-color: color-mix(in srgb, var(--danger)              40%, var(--border)); }

.auth-powered {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted);
}
.auth-legal {
  margin-top: 10px; text-align: center;
  font-size: 11.5px; color: var(--text-muted); display: flex;
  gap: 8px; justify-content: center; align-items: center;
}
.auth-legal a { color: var(--text-muted); text-decoration: none; }
.auth-legal a:hover { color: var(--text); text-decoration: underline; }

/* ── layout · sidebar · main ────────────────────────────────────────── */
.layout { display: grid; grid-template-columns: 220px 1fr; min-height: calc(100vh - 56px); }
.sidebar {
  background: var(--surface); border-right: 1px solid var(--border);
  padding: 18px 0; display: flex; flex-direction: column; gap: 2px;
  /* Stick to viewport under the 56px header so the nav stays in
     reach while the user scrolls a long view (Members list, Projects
     grid, Audit Log, etc.). align-self:start is required inside the
     .layout grid; without it the row stretches to the grid track and
     sticky never engages. The ≤900 px media query later in this file
     swaps .sidebar to position:fixed (mobile drawer) which overrides
     these rules — no need to wrap them in a min-width query. */
  position: sticky; top: 56px;
  align-self: start;
  height: calc(100vh - 56px);
  overflow-y: auto;
  z-index: 20;
}
.sidebar.collapsed { grid-column: auto; }
.layout:has(.sidebar.collapsed) { grid-template-columns: 56px 1fr; }
.sidebar.collapsed .nav-label,
.sidebar.collapsed .sidebar-org-info,
.sidebar.collapsed .sidebar-nav-group { display: none; }
/* When the sidebar is collapsed (56 px), the canonical .nav-item
 * padding of `8px 20px` consumes 40 px horizontally — leaving only
 * 14 px of content room for a 16 px icon. The icon gets clipped or
 * pushed off, so the visible state looks like the project icons
 * disappeared. Reset the padding to zero and center each icon inside
 * the narrow column. Same fix for the project sub-nav so its
 * Tools / Members / Branding / Client View icons remain visible. */
.sidebar.collapsed .nav-item,
.sidebar.collapsed .proj-sub-item,
.sidebar.collapsed .sidebar-collapse {
  padding: 8px 0;
  gap: 0;
  justify-content: center;
}
.sidebar.collapsed .proj-sub-nav { padding-left: 0; }
.sidebar.collapsed .proj-sub-item { padding-left: 0; }

.sidebar-org {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 16px 18px; cursor: pointer;
  border-bottom: 1px solid var(--border); margin-bottom: 12px;
}
.sidebar-org-avatar {
  width: 50px; height: 50px; background: var(--accent-bg); color: var(--accent);
  border: 0; border-radius: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-weight: 600; font-size: 12px;
  flex-shrink: 0; overflow: hidden;
}
.sidebar-org-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sidebar-org-info { min-width: 0; flex: 1; }
.sidebar-org-name {
  font-family: 'DM Sans', system-ui, -apple-system, Segoe UI, sans-serif;
  font-size: 14px; font-weight: 500; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sidebar-org-switch {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .15em;
  text-transform: uppercase; color: var(--text-muted); margin-top: 2px;
}

.sidebar-nav-group {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--text-3);
  padding: 14px 20px 6px;
}
.nav-item, .proj-sub-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 20px; height: 32px;
  background: transparent; border: 0; border-left: 2px solid transparent;
  color: var(--text-muted); font-family: var(--font-sans); font-size: 12.5px;
  text-align: left; cursor: pointer; width: 100%;
}
.nav-item:hover, .proj-sub-item:hover { background: var(--card-hover); color: var(--text); }
.nav-item.active, .proj-sub-item.active {
  background: var(--accent-bg); color: var(--accent);
  border-left-color: var(--accent); font-weight: 500;
}
.proj-sub-nav { padding-left: 14px; }
.proj-sub-item { height: 28px; font-size: 11.5px; padding-left: 28px; }

.sidebar-collapse {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 20px; background: transparent; border: 0;
  color: var(--text-3); cursor: pointer;
}
.sidebar-collapse:hover { color: var(--text); }
.sidebar-legal {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 20px 4px; margin-top: 2px;
  border-top: 1px solid var(--border);
}
.sidebar-legal a {
  font-size: 10.5px; letter-spacing: .3px;
  color: var(--text-3); text-decoration: none;
}
.sidebar-legal a:hover { color: var(--text); }

.main { padding: 0; min-width: 0; }

/* ── Phase 4 — billing read-only banner + write-UI suppression ──────── */
.billing-readonly-banner {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 32px;
  background: rgba(227,94,0,.12);
  border-bottom: 1px solid var(--accent);
  font-size: 13px; color: var(--text);
}
.billing-readonly-banner button {
  margin-left: auto; flex-shrink: 0;
  background: var(--accent); color: #fff; border: 0;
  padding: 6px 14px; font-size: 11px; cursor: pointer;
  font-family: var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
}
@media (max-width: 700px) {
  .billing-readonly-banner { padding: 10px 16px; flex-wrap: wrap; }
  .billing-readonly-banner button { margin-left: 0; }
}

/* Trial banner — informational, not restrictive. Softer than the
   read-only banner: a subtle surface tint + a thin rule, no fill.
   Mirrors the readonly banner's layout so they're visually a family. */
.billing-trial-banner {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 32px;
  background: var(--card-alt, rgba(0,0,0,.03));
  border-bottom: 1px solid var(--border);
  font-size: 13px; color: var(--text-2);
  /* Stick to the top of the main scroll area, sitting directly
     under the 56 px header. z-index sits below the header (30) but
     above page chrome (sidebar = 20) so it spans the full main
     column without being hidden by sticky table headers etc. */
  position: sticky; top: 56px;
  z-index: 25;
}
.billing-trial-banner button {
  margin-left: auto; flex-shrink: 0;
  background: transparent; color: var(--accent);
  border: 1px solid var(--accent);
  padding: 6px 14px; font-size: 11px; cursor: pointer;
  font-family: var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
}
.billing-trial-banner button:hover { background: var(--accent); color: #fff; }
/* Urgency tiers — applied by _applyTrialBanner based on days_remaining.
   .is-warn  → amber tint, ≤10 days left
   .is-urgent → red tint, ≤5 days left
   Both keep the same layout/padding; only color changes so the row
   doesn't reflow as the countdown crosses thresholds. */
.billing-trial-banner.is-warn {
  background: color-mix(in srgb, #B07A1F 12%, transparent);
  border-bottom-color: color-mix(in srgb, #B07A1F 40%, var(--border));
  color: var(--text);
}
.billing-trial-banner.is-warn button { color: #B07A1F; border-color: #B07A1F; }
.billing-trial-banner.is-warn button:hover { background: #B07A1F; color: #fff; }
/* Urgent state: solid danger fill so the banner reads as a true alert
   (was a 12% wash). Inverts the button so the contained CTA stays
   readable against the solid red. */
.billing-trial-banner.is-urgent {
  background: var(--danger);
  border-bottom-color: var(--danger);
  color: #fff;
}
.billing-trial-banner.is-urgent button {
  color: #fff;
  border-color: rgba(255, 255, 255, .85);
  background: transparent;
}
.billing-trial-banner.is-urgent button:hover {
  background: #fff;
  color: var(--danger);
  border-color: #fff;
}
@media (max-width: 700px) {
  .billing-trial-banner { padding: 9px 16px; flex-wrap: wrap; }
  .billing-trial-banner button { margin-left: 0; }
}
/* When read-only, hide the primary write affordances. The server-side
   requireBillingWrite() gate is the real enforcement — this just keeps
   the UI honest so users don't click into a guaranteed 402. */
body.billing-readonly #newProjectBtn,
body.billing-readonly .proj-card-empty { display: none !important; }

/* ── view header ────────────────────────────────────────────────────── */
.view-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: 36px 32px 18px; border-bottom: 1px solid var(--border); gap: 16px;
  margin-bottom: 24px;
}
.view-title {
  font-family: var(--font-serif); font-size: 48px; line-height: .9;
  letter-spacing: -.03em; color: var(--text);
}
.view-title::after { content:'.'; color: var(--accent); }
.view-sub {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em;
  color: var(--text-muted); margin-top: 6px;
}

/* ── empty / loading states (editorial) ─────────────────────────────── */
.empty-state {
  margin: 48px 32px; padding: 64px 32px; text-align: center;
  border: 1px dashed var(--border);
}
.empty-eyebrow {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 12px;
}
.empty-headline {
  font-family: var(--font-serif); font-size: 40px; line-height: .95;
  letter-spacing: -.02em; color: var(--text); margin-bottom: 10px;
}
.empty-headline::after { content:'.'; color: var(--accent); }
.empty-copy {
  font-size: 13px; color: var(--text-muted); max-width: 460px;
  margin: 0 auto 22px; line-height: 1.6;
}
.loading-row { display: flex; justify-content: center; padding: 48px; }
.spinner {
  width: 24px; height: 24px; border: 2px solid var(--border);
  border-top-color: var(--accent); border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── grids · cards ──────────────────────────────────────────────────── */
.org-picker-grid, .projects-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(480px, 1fr));
  gap: 14px; padding: 0 32px 32px;
}
.card {
  background: var(--card); border: 1px solid var(--border); padding: 18px;
  cursor: pointer; transition: border-color .15s;
}
.card:hover { background: var(--card-hover); border-color: var(--border-hover); }

/* Templates view — the Org Templates card sits flush against the view
   gutters by default, which looks pinched against the wide page. Add
   35 px horizontal margins and bump the card title so it carries the
   same editorial weight as a section eyebrow. Scoped to #viewTemplates
   so other .card instances (modals, settings, etc.) are unaffected. */
#viewTemplates > .card {
  margin-left: 35px;
  margin-right: 35px;
}
/* Header inside the Templates card — use the editorial eyebrow +
   italic-serif title pattern (same as Settings → Brand sections).
   Slightly larger than the brand-section default so it carries the
   weight of a card-level headline. */
#viewTemplates .brand-section-eyebrow { font-size: 10px; }
#viewTemplates .brand-section-title {
  font-size: 28px; margin-top: 10px; line-height: 1.05;
}

/* Tool-filter pill bar in the Templates card. Replaces the legacy
   <select> with a segmented row of clickable pills. The active pill
   carries the accent treatment (filled with --accent-bg, accent text
   colour, accent border) so it reads as a tab-like selection rather
   than a button group. */
.tmpl-pill-bar {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.tmpl-pill {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}
.tmpl-pill:hover { color: var(--text); border-color: var(--text-muted); }
.tmpl-pill.is-active {
  color: var(--accent);
  background: var(--accent-bg);
  border-color: var(--accent-border, var(--accent));
}

/* ── buttons ────────────────────────────────────────────────────────── */
.btn-full, .btn-primary, .btn-secondary, .btn-danger, .btn-success {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; padding: 0 14px;
  font-family: var(--font-sans); font-size: 12px; font-weight: 500;
  border: 1px solid; cursor: pointer;
  border-radius: 0; /* §6.2 */
}
.btn-full { width: 100%; height: 40px; font-size: 13px; background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-primary:hover { filter: brightness(1.1); }
.btn-secondary { background: transparent; color: var(--text); border-color: var(--border); }
.btn-secondary:hover { border-color: var(--text); }
.btn-danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: var(--danger); color: #FFF; }
/* Success / recover variant — green outline button. Mirror of
   .btn-danger but reads as a constructive action (e.g. Recover
   Organization). Uses --chip-ok which adapts in dark mode. */
.btn-success { background: transparent; color: var(--chip-ok); border-color: var(--chip-ok); }
.btn-success:hover { background: var(--chip-ok); color: #FFF; }

/* ── fields ─────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted); font-weight: 500;
}
.field input, .field select, .field textarea {
  height: 36px; padding: 0 12px; background: var(--input-bg);
  border: 1px solid var(--input-border); color: var(--text);
  font-family: var(--font-sans); font-size: 13px;
  border-radius: 0; /* §6.2 squared everywhere */
}
/* Strip the native select chevron + rounded corners (Safari rounds
   even with border-radius: 0 because the OS draws the control), then
   draw our own caret via inline SVG. Keeps the dropdown visually
   consistent with the editorial input rhythm. */
.field select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent); background: var(--card);
}

/* ── chips ──────────────────────────────────────────────────────────── */
.chip-ok, .chip-exp, .chip-wrap {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 9px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .14em;
  text-transform: uppercase; font-weight: 500; border: 1px solid;
}
.chip-ok   { color: var(--chip-ok);   border-color: color-mix(in srgb, var(--chip-ok) 35%, transparent); background: color-mix(in srgb, var(--chip-ok) 12%, transparent); }
.chip-exp  { color: var(--danger);    border-color: color-mix(in srgb, var(--danger) 35%, transparent);  background: color-mix(in srgb, var(--danger) 12%, transparent); }
.chip-wrap { color: var(--chip-wrap); border-color: var(--border); background: transparent; }
.chip-ok::before, .chip-exp::before { content:'●'; font-size: 10px; }

/* ── modals ─────────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; background: var(--overlay-bg);
  display: flex; align-items: center; justify-content: center;
  z-index: 100; backdrop-filter: blur(2px);
}
.modal {
  width: min(560px, 92vw); max-height: 86vh; overflow: auto;
  background: var(--modal-bg); border: 1px solid var(--border);
}

/* Create-Org wizard (Migration 031 Phase 2) — multi-step modal.
   Step containers are hidden by display:none; the active step has
   .wiz-step--active applied by _wizRender. The plan cards are canonical
   .cl-radio-option rows (editorial-chrome.css §5.6); .wiz-plan-radio was
   DELETED 2026-08-24 — it duplicated the canonical hover/checked treatment
   and painted the checked card in --accent, which §5.6 forbids. */
.modal-wizard { width: min(540px, 94vw); }
/* Header / footer strips per Style Guide §7c — cream in light, dark
 * gray in dark (via --modal-strip). The body sits between them on
 * --modal-bg unchanged. */
.modal-header {
  padding: 18px 22px; border-bottom: 1px solid var(--border);
  background: var(--modal-strip);
  display: flex; align-items: baseline; justify-content: space-between;
}
.modal-header h2 {
  margin: 0; font-family: var(--font-serif); font-size: 26px;
  letter-spacing: -.02em; line-height: 1;
}
.modal-body { padding: 18px 22px; }
.modal-footer {
  padding: 14px 22px; border-top: 1px solid var(--border);
  background: var(--modal-strip);
  display: flex; justify-content: flex-end; gap: 10px;
}

/* New-project brand slots */
.brand-slots { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; margin: 14px 0; }
.brand-slot {
  border: 1px dashed var(--border); padding: 14px; text-align: center;
  cursor: pointer; min-height: 100px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
}
.brand-slot:hover { border-color: var(--accent); border-style: solid; background: var(--accent-bg); }
.brand-slot-label {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted);
}

/* ── command palette ────────────────────────────────────────────────── */
.cmd-palette-overlay {
  position: fixed; inset: 0; background: var(--overlay-bg);
  z-index: 200; display: none; align-items: flex-start; justify-content: center;
  padding-top: 14vh; backdrop-filter: blur(8px);
}
.cmd-palette-overlay.open { display: flex; }
.cmd-palette {
  width: min(580px, 92vw); background: var(--card);
  border: 1px solid var(--accent-border);
}
.cmd-palette-input {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.cmd-palette-input input {
  flex: 1; background: transparent; border: 0; outline: none;
  color: var(--text); font-family: var(--font-sans); font-size: 15px;
}
.cmd-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 18px; cursor: pointer; border-bottom: 1px solid var(--border-soft);
}
.cmd-row.active { background: var(--accent-bg); }
.cmd-row .cat {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .14em;
  color: var(--text-3); width: 80px; text-transform: uppercase;
}
.cmd-row .title { flex: 1; font-size: 13px; color: var(--text); }
.cmd-foot {
  display: flex; justify-content: space-between;
  padding: 8px 18px; background: var(--surface);
  font-family: var(--font-mono); font-size: 10px; color: var(--text-3);
}
.kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  font-family: var(--font-mono); font-size: 10px; color: var(--text-muted);
  background: var(--input-bg); border: 1px solid var(--border);
}

/* ── Global mobile overflow safety net ──────────────────────────────
   When the .header or .sidebar contained content wider than the
   phone viewport, the browser would let the BODY grow past 100vw
   and the user had to scroll sideways. Force-clip horizontally on
   small screens so no descendant can ever push the page wider than
   the viewport, regardless of which @media block is winning the
   cascade. Also pin min-width:0 on the header so its flex children
   truncate instead of insisting on their intrinsic width. */
@media (max-width: 900px) {
  /* Style Guide §3.9.1 — overflow safety net. Both html/body AND
     direct body children are clipped to 100vw so no descendant can
     push the page off-screen. */
  html, body { max-width: 100vw; width: 100vw; overflow-x: hidden; }
  body > * { max-width: 100vw; box-sizing: border-box; }
  .header { min-width: 0; }
  .header > *, .header-left { min-width: 0; }
  .header-crumb, .header-tool { min-width: 0; }
}

/* Drawer profile block + mobile theme item — hidden by default
   (desktop uses the top-right header for theme/help/profile). The
   mobile @media block reveals them so the sidebar drawer is the
   single mobile menu surface. */
.sidebar-profile-mobile,
.sidebar-theme-mobile { display: none !important; }
.sidebar-profile-name {
  padding: 8px 20px 4px; font-size: 12px; color: var(--text-muted);
  font-family: var(--font-sans);
}
.nav-item.nav-danger { color: var(--danger); }

/* Hamburger + mobile org logo — base (hidden on desktop). The mobile
   @media block below promotes them to inline-flex / inline-block. */
.header-hamburger {
  display: none;
  align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0; margin: 0;
  background: transparent; border: 1px solid var(--border);
  color: var(--text-muted); cursor: pointer;
}
.header-hamburger:hover { color: var(--text); border-color: var(--text); }
.header-mobile-org-logo {
  display: none; height: 24px; max-width: 96px; object-fit: contain;
}
.header-mobile-org-logo[hidden] { display: none !important; }

/* Sidebar backdrop — only used when the drawer is open on mobile. */
.sidebar-backdrop {
  display: none; position: fixed; inset: 0; z-index: 40;
  background: rgba(0,0,0,.45);
}
.sidebar-backdrop.open { display: block; }

/* ── responsive ─────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* Layout: single column. The sidebar leaves flow and becomes a
     fixed left drawer; main fills the row. */
  .layout { grid-template-columns: 1fr; }
  .main { padding-top: 0; }

  /* Header row 1 — hamburger + org logo + ADMIN/MEMBER + Org name.
     Hide the Reelax wordmark on mobile; org branding takes over. */
  .header { height: 52px; padding: 0 12px; gap: 8px; }
  .header-left { gap: 8px; min-width: 0; flex: 1; }
  .header-hamburger { display: inline-flex; }
  /* Specificity note: [data-theme="light"] .header-logo-light is
     (0,2,0), which outranks a bare `.header-logo` rule. We mirror
     that specificity with [data-theme] so the mobile hide wins in
     both light and dark themes. */
  [data-theme] .header-logo,
  .header-divider { display: none !important; }
  .header-mobile-org-logo:not([hidden]) { display: inline-block; }
  .header-tool { font-size: 10px; letter-spacing: .14em; }
  .header-crumb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
  .header-crumb-sep { margin: 0 6px; }

  /* Single header row only — the right cluster (theme/help/avatar)
     is entirely hidden on mobile. Every menu surface (nav, theme,
     help, profile) lives inside the hamburger drawer. */
  .header > div:last-child { display: none !important; }

  /* Sidebar drawer — slides in from the left when toggled. */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: 260px; max-width: 80vw; z-index: 50;
    background: var(--surface); border-right: 1px solid var(--border);
    border-bottom: 0;
    transform: translateX(-100%);
    transition: transform .22s ease;
    overflow-y: auto;
    padding: 14px 0 24px;
    flex-direction: column;
  }
  .sidebar.open { transform: translateX(0); box-shadow: 0 10px 40px rgba(0,0,0,.35); }
  /* Drawer composition — Org switcher pinned to the top (sticky so
     it's always visible when the user scrolls a long nav list), the
     nav fills the middle, the profile block lives at the bottom. We
     hide the .sidebar-nav-group labels on mobile to keep the menu
     uncluttered. The icon-rail collapse button has no meaning inside
     a slide-in drawer, so we hide it as well. */
  .sidebar-org {
    display: flex;
    position: sticky; top: 0; z-index: 2;
    background: var(--surface);
    margin-bottom: 8px;
  }
  .sidebar-nav-group { display: none !important; }
  .sidebar-collapse { display: none; }
  .nav-item, .proj-sub-item {
    width: 100%; height: 40px;
    padding: 8px 18px;
    border-left: 2px solid transparent;
    border-bottom: 0;
    font-size: 13px;
  }
  .nav-item.active, .proj-sub-item.active {
    border-left-color: var(--accent);
    border-bottom: 0;
    background: var(--accent-bg);
  }

  /* Misc page-chrome sizing on mobile. */
  .view-title { font-size: 36px; }
  .view-header { padding: 18px 16px 12px; }
  .org-picker-grid, .projects-grid { padding: 0 16px 16px; }
  .brand-slots { grid-template-columns: 1fr; }
  /* Hide the "+ new project" CTA pill on phones — the screen is too
     narrow to share the row with search + client filter without the
     pill wrapping awkwardly. Project creation is still available from
     desktop and from the empty-state card in the grid. */
  #newProjectBtn { display: none !important; }

  /* Project card name — the desktop rule uses clamp(20px,2.4vw,36px)
     which floors at 20 px on phones (viewport width math hits the
     min). Force a larger size on mobile where each card spans the
     full row and there's room for a bolder headline. */
  .proj-card-name { font-size: 32px !important; }
  .proj-card-client { font-size: 13px !important; }

  /* Drawer profile section — only shown after login. JS toggles the
     inline display:'' once we have a user; this rule promotes that
     to a visible block on mobile. */
  .sidebar-profile-mobile[style*="display:none"] { display: none !important; }
  .sidebar-profile-mobile:not([style*="display:none"]) { display: block !important; }
  /* Theme toggle inside the drawer — always visible on mobile. */
  .sidebar-theme-mobile { display: flex !important; }
}

/* ── Hardened phone breakpoint (≤480 px) ─────────────────────────────
   Belt-and-suspenders rules for narrow phones. The 900 px block above
   already restructures the layout, but at iPhone widths (375–430 px)
   even a single long org name can push the header off-screen. Truncate
   aggressively, drop the role pill, and shrink the brand-bar height
   one more notch so we never overflow horizontally. */
@media (max-width: 480px) {
  .header { height: 48px; padding: 0 10px; }
  .header-tool { display: none; }      /* drop "ADMIN/MEMBER" pill */
  .header-crumb-sep { display: none; } /* drop the "|" separator */
  .header-crumb { font-size: 11.5px; }
  .header-mobile-org-logo { height: 22px; max-width: 80px; }
  .view-title { font-size: 32px; }
  .view-header { padding: 14px 12px 10px; }
  .org-picker-grid, .projects-grid { padding: 0 12px 16px; }
}

/* ════════════════════════════════════════════════════════════════════
   LOCAL EXTENSIONS · classes used by admin.php beyond the Phase-2 baseline
   ────────────────────────────────────────────────────────────────────
   The 438-line baseline above ships from handoff-phase2/admin.css and is
   the editorial design system. Everything below preserves the structural
   markup added to admin.php since Phase 1 (project cards, tool cards,
   settings sub-nav, upload zones, modals, crew DB, project detail tabs)
   — re-styled to match the same editorial language by consuming the
   baseline's tokens (--font-serif, --font-mono, --accent, --border, etc.).
   No new tokens, no purple, no rounded radii > 4px. Cascade-friendly so a
   future re-architecture can replace this block without touching JS.
   ════════════════════════════════════════════════════════════════════ */

/* legacy aliases (admin-app.js still references these names in places) */
:root {
  --card-bg:        var(--card);
  --card-border:    var(--border);
  --card-hover-bg:  var(--card-hover);
  --surface-bg:     var(--surface);
  --surface-border: var(--border-soft);
  --text-hi:        var(--text);
  --text-2:         var(--text-muted);
  --header-border:  var(--border);
  --accent-mid:     color-mix(in srgb, var(--accent) 25%, transparent);
  --chip-ok-bg:     color-mix(in srgb, var(--chip-ok) 12%, transparent);
  --chip-ok-bd:     color-mix(in srgb, var(--chip-ok) 35%, transparent);
  --chip-exp-bg:    color-mix(in srgb, var(--danger) 12%, transparent);
  --chip-exp-bd:    color-mix(in srgb, var(--danger) 35%, transparent);
}

/* Header crumb (editorial breadcrumb after "ADMIN" eyebrow). The
   eyebrow + "|" stay in the mono UI font; the org name itself
   (#headerCrumbOrg, rendered inside the crumb) uses the org's
   heading font so the header carries the brand identity. */
.header-crumb {
  font-family: var(--font-mono); font-size: 12px;
  color: color-mix(in srgb, var(--text) 85%, transparent);
  letter-spacing: .02em;
}
#headerCrumbOrg {
  font-family: 'DM Sans', system-ui, -apple-system, Segoe UI, sans-serif;
  font-weight: 500;
  font-size: 14px; letter-spacing: -.01em;
}
.header-crumb-sep { margin: 0 12px; opacity: .35; }

/* User avatar in the top-right of the header.
 * admin-auth.js sets `.innerHTML = '<img src="…">'` with no inline
 * sizing, so without these rules the image renders at natural
 * resolution and overflows the 32px round button. */
.user-avatar-btn {
  overflow: hidden;
  padding: 0;
  flex-shrink: 0;
}
.user-avatar-btn img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  border-radius: inherit;
}
/* The mono-initial fallback (when no avatar_url is set) — keep it
 * centered within the 32px round button. */
.user-avatar-btn span {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
}

/* The header-right wrapper (name + avatar + dropdown menu).
 * It has inline `style="display:none"` until login, then JS clears
 * the inline style — falling back to default block display, which
 * stacks the name above the avatar. Force flex so they sit on the
 * same line, vertically centered. */
.header-right {
  display: flex !important;
  align-items: center;
  gap: 12px;
}
#headerRight[style*="display:none"],
#headerRight[style*="display: none"] { display: none !important; }
.header-user {
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--text-muted);
  white-space: nowrap;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis;
}

/* ── Org picker (when user has no active org selected) ─────────── */
.org-picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; padding: 0 32px 32px; }
.org-picker-card {
  background: var(--card); border: 1px solid var(--border);
  padding: 22px 20px; cursor: pointer; transition: border-color .15s, background .15s;
  display: flex; flex-direction: column; gap: 10px;
  min-height: 140px;
}
.org-picker-card:hover { background: var(--card-hover); border-color: var(--border-hover); }
.org-picker-card-avatar {
  width: 96px; height: 96px; flex-shrink: 0;
  background: var(--accent-bg); border: 1px solid var(--accent-border); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-size: 44px; line-height: 1;
}
.org-picker-card-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.org-picker-card-name {
  font-family: 'DM Sans', system-ui, -apple-system, Segoe UI, sans-serif;
  font-size: 22px; font-weight: 600; line-height: 1.05;
  letter-spacing: -.02em; color: var(--text);
}
.org-picker-card-meta {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  color: var(--text-muted);
}
.org-picker-card-role {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em;
  color: var(--text-muted); margin-top: 6px;
}

/* Pending cancellation (scheduled_delete_at set, deleted_at null) —
   card is dimmed but still fully interactive; the customer is still
   inside the period they paid for. The amber status line spells out
   the close date so they can plan ahead. */
.org-picker-card.is-pending-delete,
.org-picker-card.is-deleted {
  opacity: .35;
  background: var(--card-alt);
  border-color: var(--danger);
}
.org-picker-card.is-pending-delete:hover,
.org-picker-card.is-deleted:hover { opacity: .6; }
/* Deleted = inside 60-day recovery window. Same red border as pending
   but dashed to read as "out of normal flow" / awaiting decision. */
.org-picker-card.is-deleted { border-style: dashed; }

/* Sub-line under the role row, used by both pending + deleted
   states. Mono uppercase, danger-soft color so it reads as a
   warning without competing with the role line above. */
.org-picker-card-status {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  color: var(--danger); margin-top: 4px;
  text-transform: uppercase;
}

/* ── Project cards (16:9, editorial layout) ───────────────────── */
/* Always exactly 4 cards per row at desktop widths — the grid
 * stretches with the window. Halves to 2-up on tablets, collapses
 * to 1-up on phones. The aspect-ratio: 16/9 on each card means the
 * height scales naturally with the column width, no media-query
 * matrix needed for the box itself.
 *
 * Internal type sizes use clamp() so the title and chips scale
 * with the card width too — small at narrow desktops, larger when
 * the user has a wide display. */
.projects-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(8px, 1vw, 16px);
  padding: 0 32px 32px;
}
@media (max-width: 1100px) { .projects-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 820px)  { .projects-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px)  { .projects-grid { grid-template-columns: 1fr; } }

.proj-card {
  position: relative; aspect-ratio: 16 / 9;
  background: var(--card); border: 1px solid var(--border);
  cursor: pointer; overflow: hidden;
  transition: border-color .15s, transform .2s;
}
.proj-card:hover { border-color: var(--border-hover); transform: translateY(-1px); }
/* ── Audit log table (Security view, admin-only) ────────────────
   Dense table of org-scoped audit_log rows. Mono font for actor
   names + action keys keeps it scannable. The details column is
   intentionally narrow + clipped — full payload is in the audit_log
   row, this is just a one-line preview for fast triage. */
.audit-log-list { margin-top: 16px; }

/* Horizontal scroller around the table. On desktop the audit section
   container is 1440px so the table fits and the scroller is a no-op.
   On phones the column widths total ~1080px so the wrapper takes the
   overflow instead of squishing Details into single characters. */
.audit-log-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Subtle inset shadow on the right edge hints there's more
     content to swipe to — only visible when the table actually
     overflows. */
  background:
    linear-gradient(to right, var(--bg) 30%, rgba(0,0,0,0)) left center / 20px 100% no-repeat,
    linear-gradient(to right, rgba(0,0,0,0), var(--bg) 70%) right center / 20px 100% no-repeat,
    linear-gradient(to right, rgba(0,0,0,.25), rgba(0,0,0,0)) left center / 8px 100% no-repeat,
    linear-gradient(to left,  rgba(0,0,0,.25), rgba(0,0,0,0)) right center / 8px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.audit-log-scroll::-webkit-scrollbar { height: 6px; }
.audit-log-scroll::-webkit-scrollbar-thumb {
  background: var(--border); border-radius: 3px;
}
.audit-log-table {
  width: 100%; border-collapse: collapse; font-size: 12.5px;
  /* Fixed layout so the column widths below are honored. With auto
     layout the browser shrinks Details to single-character width
     because word-break:break-all gives it no word boundaries. */
  table-layout: fixed;
}
.audit-log-table thead th {
  text-align: left; padding: 8px 10px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted); font-weight: 500;
  border-bottom: 1px solid var(--border);
}
.audit-log-table tbody td {
  padding: 10px; border-bottom: 1px solid var(--border-soft, var(--border));
  vertical-align: top;
}
.audit-log-table tbody tr:hover { background: var(--card-alt); }
.audit-log-table .audit-when {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-muted);
  white-space: nowrap;
  padding-right: 28px;
}
.audit-log-table thead th.audit-when { padding-right: 28px; }
.audit-log-table .audit-actor { color: var(--text); }
.audit-log-table .audit-action code,
.audit-log-table .audit-details code {
  font-family: var(--font-mono); font-size: 11px;
  background: var(--card-alt); padding: 1px 6px;
  border-radius: 0; /* §6.2 */
  color: var(--text-2, var(--text));
  vertical-align: middle;
}
/* Action keys are short — keep on one line. */
.audit-log-table .audit-action code {
  white-space: nowrap;
  display: inline-block;
}
/* Details JSON can be long — let it break across multiple lines
   instead of getting ellipsis-clipped at 280px. With the wider
   container (.audit-log-section max-width 1320px) there's room. */
.audit-log-table .audit-details code {
  display: inline-block;
  white-space: normal;
  word-break: break-all;
  max-width: 100%;
}
/* Constrain the action + when columns so the details column gets
   the most width to expand into. */
.audit-log-table .audit-when   { width: 180px; }
.audit-log-table .audit-actor  { width: 180px; word-break: break-word; }
.audit-log-table .audit-action { width: 180px; }
.audit-log-table .audit-target { width: 220px; }
/* Details claims everything left over (min 320px so it stays
   readable even when the table is rendered in a narrow viewport). */
.audit-log-table .audit-details { width: auto; min-width: 320px; }
.audit-log-table .audit-target-type {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted);
  background: var(--card-alt); padding: 2px 6px; border-radius: 0;
}
.audit-log-table .audit-target-label { color: var(--text); font-size: 12px; }

.audit-pager { display: flex; justify-content: center; }
.audit-pager .btn-secondary { font-size: 11px; padding: 4px 12px; }
.audit-pager .btn-secondary:disabled { opacity: .4; cursor: not-allowed; }

/* Mobile: stack filter row and date inputs side-by-side, drop the
   audit section's outer 32px gutter so the scroll wrapper can reach
   edge-to-edge (gives the table ~32px more swipe room). */
@media (max-width: 700px) {
  .audit-log-section { padding: 0 16px 24px !important; }
  .audit-filter-row {
    flex-direction: column !important;
    align-items: stretch !important;
  }
  .audit-filter-row > .field { min-width: 0 !important; width: 100%; }
  .audit-filter-row > .btn-secondary { align-self: flex-start; }
}

/* Wrapped project — read-only, scheduled for 60-day purge. Mirror
   of .sa-proj-card.is-wrapped on the SA panel: amber dashed left
   border + dimmed background, but the card stays interactive so
   the admin can still open the `⋯` menu to Unwrap. */
.proj-card.wrapped {
  opacity: .55;
  background: var(--card-alt);
  border-left: 3px dashed var(--chip-warn, #B07A1F);
}
.proj-card.wrapped:hover { opacity: .8; }
/* The menu button + status chip stay fully clickable inside a
   wrapped card so the admin can access Unwrap. */
.proj-card.wrapped .proj-menu-btn,
.proj-card.wrapped .proj-card-status { pointer-events: auto; }
.proj-card-inner { position: absolute; inset: 0; }
.proj-card-bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  filter: brightness(.88);
}
/* Diagonal-stripe placeholder when no production-still image */
.proj-card-initials {
  position: absolute; inset: 0;
  background:
    repeating-linear-gradient(135deg,
      rgba(255,255,255,.02) 0px, rgba(255,255,255,.02) 12px,
      rgba(255,255,255,.05) 12px, rgba(255,255,255,.05) 13px);
  font-size: 0;
}
[data-theme="light"] .proj-card-initials {
  background:
    repeating-linear-gradient(135deg,
      rgba(26,22,18,.025) 0px, rgba(26,22,18,.025) 12px,
      rgba(26,22,18,.06)  12px, rgba(26,22,18,.06)  13px);
}
.proj-card-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    rgba(0,0,0,0) 0%, rgba(0,0,0,.45) 65%, rgba(0,0,0,.85) 100%);
}
[data-theme="light"] .proj-card-overlay {
  background: linear-gradient(to bottom,
    rgba(26,22,18,0) 0%, rgba(26,22,18,.30) 65%, rgba(26,22,18,.62) 100%);
}

/* N° pill top-left */
.proj-card-num {
  position: absolute;
  top: clamp(6px, 0.7vw, 12px);
  left: clamp(6px, 0.7vw, 12px);
  z-index: 3;
  height: clamp(16px, 1.5vw, 22px);
  padding: 0 clamp(6px, 0.6vw, 10px);
  display: inline-flex; align-items: center;
  background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.18);
  font-family: var(--font-mono);
  font-size: clamp(8px, 0.8vw, 11px);
  letter-spacing: .04em;
  color: rgba(255,255,255,.9); border-radius: 999px;
}
[data-theme="light"] .proj-card-num {
  background: rgba(255,255,255,.85); border-color: rgba(26,22,18,.15);
  color: var(--text);
}
/* Status pill top-right */
.proj-card-status {
  position: absolute;
  top: clamp(6px, 0.7vw, 12px);
  right: clamp(6px, 0.7vw, 12px);
  z-index: 3;
}
.proj-card-status .chip {
  display: inline-flex; align-items: center;
  gap: clamp(3px, 0.4vw, 6px);
  height: clamp(16px, 1.5vw, 22px);
  padding: 0 clamp(6px, 0.6vw, 10px);
  font-family: var(--font-mono);
  font-size: clamp(7px, 0.7vw, 9.5px);
  font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  border: 1px solid; border-radius: 999px;
}
.proj-card-status .chip-active {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
}
.proj-card-status .chip-active::before {
  content: ''; width: clamp(4px, 0.4vw, 6px); height: clamp(4px, 0.4vw, 6px);
  border-radius: 50%; background: currentColor;
}
.proj-card-status .chip-wrapped, .proj-card-status .chip-expired {
  background: rgba(255,255,255,.08); color: rgba(255,255,255,.7); border-color: rgba(255,255,255,.15);
}
[data-theme="light"] .proj-card-status .chip-wrapped,
[data-theme="light"] .proj-card-status .chip-expired {
  background: var(--surface); color: var(--text-muted); border-color: var(--border);
}

.proj-card-info {
  position: absolute;
  left: clamp(8px, 1vw, 16px);
  right: clamp(8px, 1vw, 16px);
  bottom: clamp(28px, 3vw, 44px);
  z-index: 3;
}
.proj-card-name {
  font-family: var(--font-serif);
  font-size: clamp(20px, 2.4vw, 36px);
  line-height: 1;
  letter-spacing: -.015em; color: #fff;
  text-shadow: 0 2px 12px rgba(0,0,0,.6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-bottom: 3px;
}
.proj-card-client {
  font-family: var(--font-sans);
  font-size: clamp(10px, 0.9vw, 13px);
  color: rgba(255,255,255,.65);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Footer with progress + tools count */
.proj-card-footer {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; align-items: center;
  gap: clamp(6px, 0.7vw, 12px);
  padding: clamp(7px, 0.8vw, 12px) clamp(8px, 1vw, 16px);
  border-top: 1px solid rgba(255,255,255,.08);
}
[data-theme="light"] .proj-card-footer { border-top-color: rgba(255,255,255,.18); }
.proj-card-progress {
  flex: 1; height: clamp(2px, 0.25vw, 4px);
  background: rgba(255,255,255,.10);
  position: relative; overflow: hidden;
}
.proj-card-progress > span {
  position: absolute; left: 0; top: 0; bottom: 0; background: var(--accent);
}
.proj-card-tools-count {
  font-family: var(--font-mono);
  font-size: clamp(9px, 0.8vw, 12px);
  color: rgba(255,255,255,.7);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* ··· options menu — position below the status pill so they don't
 * overlap. The wrapper inline `<div class="proj-card-top" style="…">`
 * emitted by renderProjectCard is intentionally a no-op container; we
 * style the button directly so its position is independent of the
 * wrapper's inline `right:50px`. */
.proj-card-top { position: static !important; }
.proj-menu-btn {
  position: absolute !important;
  top: calc(clamp(6px, 0.7vw, 12px) + clamp(16px, 1.5vw, 22px) + 4px);
  right: clamp(6px, 0.7vw, 12px); left: auto !important;
  z-index: 4;
  background: rgba(0,0,0,.55); border: 0;
  color: #fff; cursor: pointer;
  width: clamp(22px, 2vw, 28px);
  height: clamp(16px, 1.5vw, 22px);
  padding: 0;
  font-size: clamp(10px, 0.9vw, 13px); line-height: 1;
  opacity: 0; transition: opacity .15s, background .15s;
}
.proj-card:hover .proj-menu-btn { opacity: 1; }
.proj-menu-btn:hover { background: rgba(0,0,0,.8); }
/* admin-app.js appends .proj-dropdown to document.body and positions it
   via inline top/left in pixels (from getBoundingClientRect). Must use
   position:fixed so the inline coords work, and must NOT set right/bottom
   which would fight the inline left and stretch the dropdown to the
   viewport edge (the "menu overflowing the size window" symptom). */
.proj-dropdown {
  position: fixed; z-index: 80;
  background: var(--card); border: 1px solid var(--border);
  min-width: 200px; padding: 4px;
  box-shadow: 0 12px 40px rgba(0,0,0,.45);
}
[data-theme="light"] .proj-dropdown { box-shadow: 0 12px 40px rgba(26,22,18,.18); }
.proj-dropdown-item {
  display: block; width: 100%; padding: 9px 12px;
  background: transparent; border: 0; text-align: left; cursor: pointer;
  font-family: var(--font-sans); font-size: 12.5px; color: var(--text);
}
.proj-dropdown-item:hover { background: var(--card-hover); }
.proj-dropdown-item.danger { color: var(--danger); }
.proj-dropdown-divider {
  height: 1px; background: var(--border); margin: 4px 0;
}
/* Legacy fallback if any code still emits bare <button> children */
.proj-dropdown > button {
  display: block; width: 100%; padding: 9px 12px;
  background: transparent; border: 0; text-align: left; cursor: pointer;
  font-family: var(--font-sans); font-size: 12.5px; color: var(--text);
}
.proj-dropdown > button:hover { background: var(--card-hover); }
.proj-dropdown > button.danger { color: var(--danger); }

/* "+ new project" empty card */
.proj-card-empty {
  aspect-ratio: 16 / 9;
  background: transparent; border: 1px dashed var(--border);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(4px, 0.5vw, 8px);
  font-family: var(--font-mono);
  font-size: clamp(9px, 0.8vw, 12px);
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-3);
  cursor: pointer; transition: border-color .12s, color .12s;
}
.proj-card-empty:hover { border-color: var(--accent); color: var(--accent); }
.proj-card-empty-plus { font-size: clamp(20px, 2vw, 32px); line-height: 1; }

/* WRAPPED section toggle */
.wrapped-toggle {
  display: flex; align-items: center; gap: 8px;
  background: transparent; border: 0; padding: 24px 32px 6px;
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .22em; text-transform: uppercase; color: var(--text-3);
  cursor: pointer;
}
.wrapped-toggle svg { transition: transform .2s; }
.wrapped-toggle svg.open { transform: rotate(180deg); }

/* ── Tool cards (per-project tools grid) — 4-column layout ───────
 * 4 cards per row at desktop widths. Internals sized to fit a ~280px
 * column comfortably while preserving the editorial type rhythm. */
.tools-section-label {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 0 0 12px; margin: 28px 32px 14px;
  border-bottom: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .22em; text-transform: uppercase; color: var(--text-3);
}
.tools-section-label.first { margin-top: 8px; }
.tools-grid-wrap {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px; padding: 0 32px 32px;
}
@media (max-width: 1280px) { .tools-grid-wrap { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 960px)  { .tools-grid-wrap { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .tools-grid-wrap { grid-template-columns: 1fr; } }

.tool-card {
  background: var(--card); border: 1px solid var(--border);
  padding: 18px 20px 16px;
  min-height: 200px;
  display: flex; flex-direction: column;
  text-decoration: none; color: var(--text);
  transition: border-color .15s, transform .15s;
}
.tool-card.enabled { cursor: pointer; }
.tool-card.enabled:hover { border-color: var(--accent); transform: translateY(-1px); }
.tool-card.inactive { opacity: .65; }
.tool-card.expired  { opacity: .8; }
.tool-card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 36px; }
.tool-card-bottom { margin-top: auto; display: flex; flex-direction: column; }
.tool-tag {
  display: inline-flex; align-items: center; height: 22px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: 999px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  color: var(--text-muted); background: transparent;
}
.tool-version {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  color: var(--text-3);
}
.tool-name {
  font-family: var(--font-serif); font-size: 36px; line-height: 1.05;
  letter-spacing: -.015em; color: var(--text);
  margin-bottom: 6px;
}
.tool-desc {
  font-family: var(--font-sans); font-size: 12px; line-height: 1.5;
  color: var(--text-muted); margin-bottom: 12px;
}
.tool-arrow {
  margin-top: auto; padding-top: 10px;
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .12em; text-transform: lowercase; color: var(--accent);
  display: flex; align-items: center; gap: 6px;
}

/* ── Settings · sub-nav layout + sections ─────────────────────── */
.settings-layout {
  display: grid; grid-template-columns: 200px 1fr;
  gap: 40px; padding: 0 32px 32px;
  align-items: start;
}
@media (max-width: 900px) { .settings-layout { grid-template-columns: 1fr; gap: 20px; padding: 0 20px 20px; } }
/* The content column had NO rule at all, so every section grew to the viewport
   — on a wide desktop that stretched a two-field document row and the Drive
   card across ~1500px. One measure here fixes every section at once; capping
   each component separately is how a layout ends up with six measures.
   min-width:0 because a grid child defaults to min-content and would otherwise
   refuse to shrink, pushing wide tables into a horizontal page scroll. */
.settings-content { min-width: 0; max-width: 880px; }
.settings-subnav {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 0;
  border-left: 1px solid var(--border);
  /* Settings is one long scroll, so the section list follows the reader.
     top:56px clears the sticky header, matching .sidebar's offset — this is
     the platform's one header height, not a number picked for this nav.
     Works because .settings-layout is align-items:start; a stretched grid
     item fills its row and has no room left to stick. */
  position: sticky; top: 56px;
  /* A subnav taller than the viewport must scroll on its own rather than
     have its last items become unreachable. */
  max-height: calc(100vh - 56px);
  overflow-y: auto;
}
/* Single column below 900px: the nav sits above the content, where pinning it
   would park a full-width list over what you are reading. */
@media (max-width: 900px) {
  .settings-subnav { position: static; max-height: none; overflow-y: visible; }
}
.settings-subnav-item {
  display: block; padding: 8px 14px; margin-left: -1px;
  border-left: 2px solid transparent;
  background: transparent; border-top: 0; border-right: 0; border-bottom: 0;
  font-family: var(--font-sans); font-size: 13px; color: var(--text-muted);
  text-align: left; cursor: pointer;
  transition: color .12s, border-color .12s;
}
.settings-subnav-item:hover { color: var(--text); }
.settings-subnav-item.active {
  color: var(--accent); border-left-color: var(--accent); font-weight: 500;
}
.settings-subnav-item.danger {
  color: var(--text-3); margin-top: 12px;
  border-top: 1px solid var(--border); padding-top: 16px;
}

.settings-section {
  background: transparent; border: 0;
  border-bottom: 1px solid var(--border);
  padding: 8px 0 32px; margin-bottom: 24px;
}
.settings-section:last-child { border-bottom: 0; }
.settings-section.danger .settings-section-title { color: var(--danger); }

.settings-section-title {
  font-family: var(--font-serif); font-size: 26px; font-weight: 400;
  letter-spacing: -.015em; color: var(--text);
  margin-bottom: 4px;
}
.settings-section-title::after { content: '.'; color: var(--accent); }
.settings-section-desc {
  font-family: var(--font-sans); font-size: 13px;
  color: var(--text-3); margin-bottom: 18px; line-height: 1.6;
}

.settings-section .field label,
.settings-section label {
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 8px; display: block;
  font-weight: 500;
}

/* Background swatch picker */
.bg-options {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px;
  max-width: 720px;
}
@media (max-width: 700px) { .bg-options { grid-template-columns: repeat(2, 1fr); } }
.bg-option { display: block; cursor: pointer; }
.bg-option input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.bg-option-card { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.bg-option-preview {
  width: 100%; aspect-ratio: 1.4 / 1;
  border: 1px solid var(--border);
  position: relative;
  transition: border-color .12s, transform .12s;
}
.bg-option:hover .bg-option-preview { border-color: var(--text-muted); transform: translateY(-1px); }
.bg-option input:checked + .bg-option-card .bg-option-preview {
  border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent);
}
.bg-option-label {
  font-family: var(--font-sans); font-size: 12.5px; color: var(--text-muted);
}
.bg-option input:checked + .bg-option-card .bg-option-label { color: var(--accent); font-weight: 500; }
.bg-preview-gradient { background: linear-gradient(160deg, #1A0030 0%, #000 100%); }
.bg-preview-image {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
}

/* Color picker rows */
.color-row { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.color-field-label {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted);
  min-width: 80px;
}
.color-swatch-row { display: flex; align-items: center; gap: 10px; }
.color-swatch {
  width: 36px; height: 36px;
  border: 1px solid var(--border); overflow: hidden;
}
.color-swatch input[type="color"] {
  width: 48px; height: 48px;
  margin: -6px; border: 0; cursor: pointer; padding: 0;
}
.color-hex {
  height: 36px; padding: 0 12px;
  background: var(--input-bg); border: 1px solid var(--input-border);
  color: var(--text); font-family: var(--font-mono); font-size: 12px;
  width: 110px;
}
.color-hex:focus { outline: none; border-color: var(--accent); }

.accent-presets { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.accent-preset {
  width: 28px; height: 28px;
  border: 1px solid var(--border); cursor: pointer;
  transition: transform .12s, box-shadow .12s;
}
.accent-preset:hover { transform: translateY(-1px); }
.accent-preset.active { box-shadow: 0 0 0 2px var(--text); }
/* Inline-flex + fit-content so the preview only takes the width of
 * its content (dot + label + chip + reset button) instead of stretching
 * to the full settings column width. */
.accent-preview {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 12px; margin-top: 14px;
  width: fit-content; max-width: 100%;
  background: var(--card); border: 1px solid var(--border);
}
.accent-preview-dot { width: 10px; height: 10px; border-radius: 50%; }
.accent-preview-label, .accent-preview-chip {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-muted);
}
.accent-preview-chip {
  padding: 3px 8px; background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
}

.btn-sm { height: 28px; padding: 0 10px; font-size: 11px; }
.remove-bg-btn {
  background: transparent; border: 1px solid var(--danger); color: var(--danger);
  font-family: var(--font-sans); font-size: 11px;
  height: 28px; padding: 0 10px; cursor: pointer;
}
.remove-bg-btn:hover { background: var(--danger); color: #fff; }

/* ── Upload zones (avatar / logo / project image / bg image) ──── */
.upload-zone {
  position: relative; cursor: pointer; overflow: hidden;
  border: 1px solid var(--border); background: var(--card);
  transition: border-color .15s, background .15s;
}
.upload-zone:hover { border-color: var(--accent); }
.upload-zone-img { width: 100%; height: 100%; object-fit: cover; display: none; }
.upload-zone.has-image .upload-zone-img { display: block; }
.upload-zone.has-image .upload-zone-placeholder { display: none; }
/* Logos are typically wide (wordmarks) or tall (badges) — use object-fit:
 * contain so the full logo is preserved at its native aspect inside the
 * fixed 120×56 zone instead of being cropped/distorted by `cover`. Avatars
 * and bg images stay on `cover` (their aspect ratios match the slot). */
.uz-logo .upload-zone-img { object-fit: contain; padding: 4px; }
.upload-zone-placeholder {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 10px;
  text-transform: uppercase; color: var(--text-muted);
}
.upload-zone-overlay {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.55); color: #fff;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; opacity: 0; transition: opacity .15s;
}
.upload-zone.has-image:hover .upload-zone-overlay { opacity: 1; }
.upload-zone-spinner {
  position: absolute; inset: 0;
  display: none; align-items: center; justify-content: center;
  background: rgba(0,0,0,.55);
}
.upload-zone-spinner.active { display: flex; }
.uz-org-avatar { width: 56px; height: 56px; }
.uz-avatar     { width: 72px; height: 72px; flex-shrink: 0; }
.uz-logo       { width: 120px; height: 56px; margin-right: 0; }
/* Migration 026 — dark-mode logo slot. Render against #0E0E0E so a
   white-on-transparent asset is actually visible in the preview tile. */
.uz-logo.uz-logo-dark { background: #0E0E0E; }
.uz-logo.uz-logo-dark .upload-zone-placeholder { color: rgba(255,255,255,.55); }

/* ── Settings · upload-zone grid (Avatar + Logo Light + Logo Dark) ──
   Editorial chrome rule (Style Guide §8.0): mono uppercase eyebrow,
   tight tracking, calm helper text. Replaces ad-hoc inline styles. */
.upload-zone-grid {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.upload-zone-cell {
  display: flex;
  flex-direction: column;
  max-width: 200px;
}
.upload-zone-eyebrow {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .18em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.upload-zone-help {
  font-family: var(--font-sans);
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-muted);
  margin-top: 8px;
}
.uz-bg         { width: 100%; max-width: 480px; aspect-ratio: 16 / 9; }
.uz-proj-logo  { width: 140px; height: 80px; }

/* ── Modals · backdrop visibility ─────────────────────────────────
 * admin.php uses .modal-backdrop (legacy name) and admin-core.js does
 * `.classList.add('show')` to open. The handoff baseline only defines
 * .modal-overlay — so without these rules, every modal in the page sits
 * as a plain inline div at the bottom of the layout (looks like "divs
 * outside the body"). Hide by default, show when JS adds .show. */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: var(--overlay-bg);
  display: none; align-items: center; justify-content: center;
  backdrop-filter: blur(2px);
  /* Bottom padding clears the home indicator, or a modal's action row sits
     under it on a gesture-navigation phone. */
  padding: 32px 16px calc(32px + env(safe-area-inset-bottom, 0px));
  /* If a modal is somehow still taller than the space available, the BACKDROP
     scrolls rather than clipping it. align-items:center would otherwise crop
     equally at top and bottom, putting the action row out of reach with
     nothing to scroll — which is exactly how CSV Import became uncompletable
     on a phone. */
  overflow-y: auto;
}
.modal-backdrop.show { display: flex; }
/* dvh, not vh: on mobile `vh` is the LARGE viewport (browser chrome expanded),
   so 86vh can exceed what is actually on screen while the chrome is showing. */
.modal-backdrop > .modal { width: min(560px, 92vw); max-height: 86dvh; overflow: auto; }

/* ── Modal inner (eyebrow + title + actions naming used by admin.js) ──
 * Color rhythm per Style Guide §7c — eyebrow + title + desc form the
 * cream "header strip", actions form the cream "footer strip", body
 * (anything between) sits on --modal-bg. All three strip elements
 * bleed -22px to the modal edges via negative horizontal margins so
 * the cream paint reaches the modal's outer border. */
.modal-eyebrow {
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--text-3);
  background: var(--modal-strip);
  margin: -22px -22px 0;
  padding: 18px 22px 6px;
}
.modal-title {
  font-family: var(--font-serif); font-size: 26px; line-height: 1;
  letter-spacing: -.015em; color: var(--text);
  background: var(--modal-strip);
  margin: 0 -22px;
  padding: 0 22px 6px;
}
.modal-title::after { content: '.'; color: var(--accent); }
.modal-desc {
  font-family: var(--font-sans); font-size: 13px;
  color: var(--text-muted); line-height: 1.55;
  background: var(--modal-strip);
  margin: 0 -22px 18px;
  padding: 6px 22px 14px;
  border-bottom: 1px solid var(--border);
}
/* When a modal omits the .modal-desc, .modal-title is the last strip
 * element — it needs the bottom padding + divider that .modal-desc
 * would have carried. */
.modal-title:last-child,
.modal:not(:has(> .modal-desc)) > .modal-title {
  padding-bottom: 14px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
/* In-modal warning callout — admin mirror of .sa-modal-warning. Lives
   in the body, uses the platform's danger tokens so dark mode adapts. */
.modal-warning {
  margin: 0 0 14px;
  padding: 12px 14px;
  background: var(--danger-bg, rgba(192,57,43,.08));
  border-left: 3px solid var(--danger);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
}
.modal-warning strong { color: var(--danger); }
.modal-warning ul     { margin: 6px 0 0; padding-left: 18px; }
.modal-warning li + li { margin-top: 4px; }
.modal-warning a       { color: var(--text); text-decoration: underline; }

.modal-actions {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px;
  padding: 14px 22px 18px;
  border-top: 1px solid var(--border);
  background: var(--modal-strip);
  margin: 18px -22px -22px;
}

/* Tool-license quote summary inside the enable-tool modal. Four rows
   (Tool / Duration / Charged today / Payment method) — populated by
   promptEnableTool() via getToolLicenseQuote. */
.license-quote {
  margin-top: 14px; padding: 14px 16px;
  border: 1px solid var(--border);
  background: var(--card-alt, rgba(0,0,0,.02));
}
.license-quote-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; padding: 5px 0;
  font-size: 12.5px;
}
.license-quote-row + .license-quote-row {
  border-top: 1px solid var(--border);
}
.license-quote-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted);
}
.license-quote-value { color: var(--text); }
.license-quote-amount { font-weight: 600; font-size: 15px; }
.modal { padding: 22px; }
.modal .field:last-of-type { margin-bottom: 0; }

/* ── Project detail (Tools / Members / Branding tabs) ─────────── */
.back-btn {
  background: transparent; border: 1px solid var(--border);
  width: 32px; height: 32px; cursor: pointer;
  color: var(--text-muted);
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color .15s, color .15s;
}
.back-btn:hover { border-color: var(--text); color: var(--text); }

.proj-members-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 32px 16px; gap: 16px;
}
.proj-members-title {
  font-family: var(--font-serif); font-size: 22px; line-height: 1;
  letter-spacing: -.01em;
}
.proj-members-title::after { content: '.'; color: var(--accent); }
.proj-members-list {
  padding: 0 32px 32px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 10px;
}
@media (max-width: 700px) { .proj-members-list { grid-template-columns: 1fr; } }

/* Each member rendered by loadProjectMembers — was unstyled, so the rows
   were laying out as default block divs and pushing past the page. */
.proj-member-card {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  background: var(--card); border: 1px solid var(--border);
  min-width: 0;
}
.proj-member-av {
  width: 36px; height: 36px; flex-shrink: 0;
  border-radius: 50%; overflow: hidden;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 13px; font-weight: 600;
}
.proj-member-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.proj-member-info { min-width: 0; }
.proj-member-name {
  font-family: var(--font-sans); font-size: 13px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.proj-member-role {
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .04em; color: var(--text-muted);
  margin-top: 2px;
}

/* Accent role chip used by the role label inside .proj-member-role */
.chip-accent {
  display: inline-flex; align-items: center; gap: 4px;
  height: 18px; padding: 0 7px;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase; font-weight: 500;
  border-radius: 999px;
}

/* "Change image" small overlay button on project cards (admin only) */
.proj-card-img-btn {
  position: absolute; bottom: 56px; right: 18px; z-index: 4;
  opacity: 0; transition: opacity .15s;
}
.proj-card:hover .proj-card-img-btn { opacity: 1; }

/* ── Branding tab (per-project logo slots) ─────────────────────
 * Two-section editorial layout:
 *   1. Live preview card showing how the document header strip will
 *      render (Reelax | Client | Agency | Prod Co), updated whenever
 *      a slot loads / uploads / removes.
 *   2. Three slot cards with descriptive copy + drop zones + Replace
 *      / Remove actions in a clean footer row. */

.brand-section { padding: 0 32px 32px; display: flex; flex-direction: column; gap: 20px; }

/* ── Preview card ── */
.brand-preview-card {
  background: var(--card); border: 1px solid var(--border);
  padding: 22px 24px;
}
.brand-preview-eyebrow {
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .22em; text-transform: uppercase; color: var(--text-3);
  margin-bottom: 6px;
}
.brand-preview-title {
  font-family: var(--font-serif); font-size: 22px; line-height: 1;
  letter-spacing: -.015em; color: var(--text); margin-bottom: 4px;
}
.brand-preview-title::after { content: '.'; color: var(--accent); }
.brand-preview-sub {
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--text-muted); margin-bottom: 18px; max-width: 600px;
}

/* The actual mock header strip — dark like the real PDF chrome */
.brand-preview-strip {
  display: flex; align-items: center; gap: 18px;
  background: #0e0e0e;
  border: 1px solid #1a1a1a;
  padding: 18px 22px;
  min-height: 64px;
  border-radius: 0;   /* §6.2 squared editor chrome */
  overflow: hidden;
}
.brand-preview-slot {
  display: flex; align-items: center; justify-content: center;
  min-height: 40px; min-width: 60px; flex: 0 0 auto;
}
[data-theme="light"] .brand-preview-strip {
  background: #0e0e0e; /* keep the strip dark in both themes — matches actual PDF header */
}
.brand-preview-divider {
  width: 1px; height: 22px; background: rgba(255,255,255,.18); flex-shrink: 0;
}
.brand-preview-empty {
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.32);
}
.brand-preview-slot.is-filled img {
  height: 28px; width: auto; max-width: 110px; object-fit: contain;
}

/* Org logo slot — when empty, render a button-like CTA that jumps to
   Settings where the user can upload the org logo. Initial letter sits
   in a small accent tile so the slot doesn't look broken. */
.brand-preview-slot--org { flex: 0 0 auto; }
.brand-preview-empty-cta {
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent; border: 1px dashed rgba(255,255,255,.22);
  padding: 5px 10px 5px 5px;
  cursor: pointer;
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.62);
  transition: border-color .12s, color .12s;
}
.brand-preview-empty-cta:hover {
  border-color: rgba(255,255,255,.45); color: #fff;
}
.brand-preview-empty-cta::before {
  content: attr(data-letter);
  width: 22px; height: 22px;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-size: 13px;
  letter-spacing: 0; text-transform: none;
}
.brand-preview-empty-cta > span:first-child:not([class]) {
  /* The leading initial we inject (a bare text node wrapping into a span
   * via JS) acts as the avatar tile. Match the ::before tile size so
   * either path renders identically. */
  width: 22px; height: 22px; flex-shrink: 0;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-serif); font-size: 13px;
  letter-spacing: 0; text-transform: none;
}

.brand-preview-note {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px;
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .04em; color: var(--text-muted);
}
.brand-preview-note svg { color: var(--chip-ok); flex-shrink: 0; }
.brand-preview-note-link {
  background: transparent; border: 0; padding: 0;
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .04em; color: var(--accent);
  cursor: pointer; text-decoration: none;
  margin-left: 4px;
}
.brand-preview-note-link:hover { text-decoration: underline; }

/* ── Slot cards ── */
.brand-slots-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
}
@media (max-width: 1100px) { .brand-slots-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px)  { .brand-slots-grid { grid-template-columns: 1fr; } }

.brand-slot-card {
  background: var(--card); border: 1px solid var(--border);
  padding: 16px 18px 14px;
  display: flex; flex-direction: column;
  transition: border-color .12s;
}
.brand-slot-card.has-image { border-color: var(--accent-border); }
.brand-slot-head { margin-bottom: 14px; }
.brand-slot-label {
  font-family: var(--font-serif); font-size: 18px; line-height: 1;
  letter-spacing: -.005em; color: var(--text);
  margin-bottom: 4px;
}
.brand-slot-desc {
  font-family: var(--font-sans); font-size: 11.5px;
  color: var(--text-muted); line-height: 1.45;
}

/* The drop zone fills the slot card width and sits between head + foot */
.brand-slot-zone.uz-proj-logo {
  width: 100% !important;
  height: 110px;
  margin-bottom: 12px;
  border-radius: 4px;
}

.brand-slot-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .04em; color: var(--text-3);
}
.brand-slot-meta { white-space: nowrap; }
.brand-slot-remove {
  background: transparent; border: 0; color: var(--danger);
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer; padding: 0;
  display: none;
}
.brand-slot-card.has-image .brand-slot-remove { display: inline; }
.brand-slot-remove:hover { text-decoration: underline; }

/* Tip footer */
.brand-tip {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  background: var(--input-bg); border: 1px solid var(--border);
  font-family: var(--font-sans); font-size: 12px; line-height: 1.5;
  color: var(--text-muted);
}
.brand-tip svg { color: var(--accent); flex-shrink: 0; margin-top: 1px; }

/* ── Project Accent Color (Branding tab, Migration 024) ─────────
 * Sits beneath the logo slots. Round 28 px native-color picker
 * (Style Guide §5.1 single deliberate exception to squared corners),
 * a hex text input next to it, and a Reset button that clears the
 * project override so the org accent flows through. */
.brand-section-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--text-muted);
}
.brand-section-title {
  /* Match the canonical .view-title editorial style: serif headline,
     tight tracking, accent dot. Brand Fonts overrides removed
     (Refactor 2026-05-18: Brand Fonts removal) — typography is now fixed at the platform level. */
  font-family: var(--font-serif, 'Instrument Serif'), serif;
  font-size: 28px; font-weight: 400; line-height: .95;
  color: var(--text);
  letter-spacing: -.02em;
  margin-top: 4px;
}
.brand-section-title::after { content: '.'; color: var(--accent); }
.brand-section-sub {
  font-family: var(--font-sans);
  font-size: 13px; line-height: 1.5;
  color: var(--text-muted);
  margin-top: 6px;
  max-width: 640px;
}
.proj-accent-row {
  display: flex; align-items: center; gap: 12px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.proj-accent-swatch {
  width: 28px; height: 28px;
  padding: 0; cursor: pointer; flex-shrink: 0;
  background: transparent;
  border: 2px solid var(--border);
  border-radius: 50%;
  overflow: hidden;
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
}
.proj-accent-swatch:hover { border-color: var(--text-muted); }
.proj-accent-swatch::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; }
.proj-accent-swatch::-webkit-color-swatch { border: 0; border-radius: 50%; }
.proj-accent-swatch::-moz-color-swatch { border: 0; border-radius: 50%; }
.proj-accent-hex {
  width: 130px;
  height: 32px;
  padding: 0 12px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: 12.5px; letter-spacing: .04em;
  color: var(--text);
  outline: none;
  text-transform: uppercase;
}
.proj-accent-hex:focus { border-color: var(--text); }
.proj-accent-hex::placeholder { color: var(--text-3); text-transform: uppercase; }
.proj-accent-clear {
  height: 32px;
  padding: 0 12px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  transition: color .12s, border-color .12s;
}
.proj-accent-clear:hover { color: var(--text); border-color: var(--text-muted); }
.proj-accent-status {
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--chip-ok, var(--text-muted));
}
.proj-accent-fallback {
  font-family: var(--font-sans);
  font-size: 12px; line-height: 1.5;
  color: var(--text-3);
  margin-top: 8px;
  max-width: 640px;
}
/* Read-only members see the picker disabled — same affordance the
 * logo upload zones use via `.brand-section.is-readonly`. */
.brand-section.is-readonly .proj-accent-swatch,
.brand-section.is-readonly .proj-accent-hex,
.brand-section.is-readonly .proj-accent-clear {
  opacity: .55;
  pointer-events: none;
}

/* Legacy proj-branding-* aliases — old class names still emitted in
   one or two stale code paths. Keep harmless so they don't break. */
.proj-branding-block, .proj-logo-grid, .proj-logo-item,
.proj-branding-title, .proj-branding-desc, .proj-logo-label,
.proj-logo-remove { display: revert; }

/* Members toolbar — search input + role-filter pills.
 * Sits between the view header and the rows; mirrors the editorial
 * filter pattern used on the SA Organizations listing. */
.org-members-toolbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 0 32px 14px;
}
@media (max-width: 900px) { .org-members-toolbar { padding: 0 20px 12px; } }
.org-members-search {
  position: relative;
  display: flex; align-items: center; gap: 8px;
  flex: 1 1 240px; min-width: 200px;
  height: 34px; padding: 0 12px;
  background: var(--input-bg); border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-muted);
  transition: border-color .12s;
}
.org-members-search:focus-within {
  border-color: var(--accent);
  color: var(--text);
}
.org-members-search input {
  flex: 1; min-width: 0;
  background: transparent; border: 0; outline: 0;
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--text);
}
.org-members-search input::placeholder { color: var(--text-muted); }

.org-members-pills {
  display: inline-flex; align-items: center; padding: 3px;
  background: var(--input-bg); border: 1px solid var(--border);
  border-radius: 999px;
}
.org-members-pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 12px;
  background: transparent; border: 0; border-radius: 999px;
  font-family: var(--font-sans); font-size: 12px;
  color: var(--text-muted); cursor: pointer;
  transition: background .12s, color .12s;
}
.org-members-pill:hover { color: var(--text); }
.org-members-pill.active {
  background: var(--text); color: var(--bg);
  font-weight: 500;
}
.org-members-pill > span {
  font-family: var(--font-mono); font-size: 10px;
  padding: 1px 6px; border-radius: 999px;
  background: var(--border); color: inherit;
  font-variant-numeric: tabular-nums;
}
.org-members-pill.active > span {
  background: rgba(255,255,255,.15); color: var(--bg);
}
[data-theme="light"] .org-members-pill.active > span { background: rgba(255,255,255,.20); }

.org-members-clear {
  height: 30px; padding: 0 12px;
  background: transparent; border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-muted); cursor: pointer; border-radius: 999px;
  transition: color .12s, border-color .12s;
}
.org-members-clear:hover { color: var(--danger); border-color: var(--danger); }

/* Members view — gutters + editorial row layout.
 * #membersList sits directly under .view-header in #viewMembers, with no
 * intermediate .settings-section, so it has to own its horizontal gutter. */
#membersList {
  padding: 0 32px 32px;
  display: flex; flex-direction: column; gap: 8px;
}
@media (max-width: 900px) { #membersList { padding: 0 20px 20px; } }
#crewDbMemberList { display: flex; flex-direction: column; gap: 6px; }

.org-member-row {
  display: grid;
  grid-template-columns: 40px 1fr auto auto;
  gap: 14px; align-items: center;
  padding: 12px 14px;
  background: var(--card); border: 1px solid var(--border);
  transition: border-color .12s, background .12s;
  min-width: 0;
}
.org-member-row:hover { border-color: var(--border-hover); }
.org-member-av {
  width: 40px; height: 40px; border-radius: 50%; overflow: hidden;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-weight: 600; font-size: 14px;
}
.org-member-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.org-member-info { min-width: 0; }
.org-member-name {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-bottom: 2px;
}
.org-member-you {
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 999px;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent-border);
}
.org-member-email {
  font-family: var(--font-mono); font-size: 11px;
  color: var(--text-muted); letter-spacing: .02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.org-member-role {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 10px;
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .14em; text-transform: uppercase; font-weight: 500;
  border: 1px solid var(--border); border-radius: 999px;
  color: var(--text-muted);
  white-space: nowrap; flex-shrink: 0;
}
.org-member-role--admin {
  color: var(--accent);
  background: var(--accent-bg);
  border-color: var(--accent-border);
}
.org-member-role--admin::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor;
}

/* ··· menu button */
.org-member-menu-btn {
  width: 28px; height: 28px; padding: 0;
  background: transparent; border: 1px solid transparent;
  color: var(--text-3); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
  transition: background .12s, color .12s, border-color .12s;
  opacity: 0;
}
.org-member-row:hover .org-member-menu-btn { opacity: 1; }
.org-member-menu-btn:hover {
  color: var(--text); background: var(--input-bg); border-color: var(--border);
}

/* Floating menu (appended to <body>; positioned via inline coords) */
.org-member-menu {
  position: fixed; z-index: 80;
  min-width: 220px; padding: 4px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 12px 40px rgba(0,0,0,.45);
}
[data-theme="light"] .org-member-menu { box-shadow: 0 12px 40px rgba(26,22,18,.18); }
.org-member-menu-item {
  display: block; width: 100%; padding: 9px 12px;
  background: transparent; border: 0; text-align: left; cursor: pointer;
  font-family: var(--font-sans); font-size: 12.5px; color: var(--text);
}
.org-member-menu-item:hover { background: var(--card-hover); }
.org-member-menu-item.danger { color: var(--danger); }
.org-member-menu-divider {
  height: 1px; background: var(--border); margin: 4px 0;
}

/* Narrow viewport: drop the role chip on a second row, keep menu inline */
@media (max-width: 600px) {
  .org-member-row { grid-template-columns: 40px 1fr auto; }
  .org-member-role {
    grid-column: 2 / 3; grid-row: 2;
    justify-self: start; margin-top: 2px;
  }
}

/* Crew DB view — its children are .settings-section blocks rendered
 * directly inside #viewCrewDb (no .settings-layout wrapper). Without
 * horizontal padding they sit flush against the sidebar. Force the
 * 32px page gutter on the view itself. */
#viewCrewDb > .settings-section { margin-left: 32px; margin-right: 32px; }
@media (max-width: 900px) { #viewCrewDb > .settings-section { margin-left: 20px; margin-right: 20px; } }

/* ── Dietary Restrictions dropdown (Crew Member edit modal) ──────
 * Multi-select implemented as a button + panel pair. The trigger looks
 * like a regular form input; clicking it reveals the checkbox list.
 * `data-open="1"` shows the panel. crewDietarySync() writes the
 * comma-joined value into a hidden #edit-dietary input that the existing
 * save flow reads — zero changes to the API contract. */
.dietary-dd { position: relative; }
.dietary-dd-btn {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; width: 100%; box-sizing: border-box;
  background: var(--input-bg); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px;
  font-family: var(--font-sans); font-size: 13px;
  color: var(--text); text-align: left;
  cursor: pointer; outline: none;
}
.dietary-dd-btn:hover { border-color: var(--border-hover); }
.dietary-dd[data-open="1"] .dietary-dd-btn { border-color: var(--accent); }
.dietary-dd-summary {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1;
}
.dietary-dd-btn svg { transition: transform .15s; }
.dietary-dd[data-open="1"] .dietary-dd-btn svg { transform: rotate(180deg); }

.dietary-dd-panel {
  display: none;
  position: absolute; left: 0; right: 0; top: calc(100% + 4px);
  z-index: 20;
  max-height: 320px; overflow-y: auto;
  background: var(--card); border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 6px;
  box-shadow: 0 12px 40px rgba(0,0,0,.4);
}
[data-theme="light"] .dietary-dd-panel { box-shadow: 0 12px 40px rgba(26,22,18,.18); }
.dietary-dd[data-open="1"] .dietary-dd-panel { display: block; }

.dietary-dd-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  cursor: pointer; user-select: none;
  border-radius: 4px;
  font-family: var(--font-sans); font-size: 13px; color: var(--text);
  transition: background .1s;
}
.dietary-dd-item:hover { background: var(--card-hover); }
/* Control painted by the canonical checkbox (editorial-chrome.css §5.7). */

.dietary-dd-other {
  margin-top: 6px; padding: 10px 10px 6px;
  border-top: 1px solid var(--border);
}
.dietary-dd-other input {
  width: 100%; box-sizing: border-box;
  background: var(--input-bg); border: 1px solid var(--border);
  border-radius: 4px; padding: 6px 8px;
  font-family: var(--font-sans); font-size: 12.5px; color: var(--text);
  outline: none;
}
.dietary-dd-other input:focus { border-color: var(--accent); }

/* Unify <button>.btn-secondary and <label>.btn-secondary so the
 * file-picker pattern (label wrapping a hidden input) renders byte-for-byte
 * the same as a real button. The handoff base rule sets the family/size/
 * height/padding for the class, but browsers default <button> and <label>
 * differently for line-height, vertical-align, text alignment, and white-
 * space — those need explicit overrides on both selectors below. */
.btn-secondary,
button.btn-secondary,
label.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  box-sizing: border-box;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  text-decoration: none;
  margin: 0;
}
label.csv-import-btn input[type="file"] { display: none; }

/* ── Crew DB · invite link box ─────────────────────────────────── */
.crew-db-link-box {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px;
  background: var(--input-bg); border: 1px solid var(--border);
  margin-bottom: 10px;
}
.crew-db-link-url {
  flex: 1; min-width: 0;
  font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text); word-break: break-all;
}

/* ── Crew DB · member rows ────────────────────────────────────────
 * Was a 3-col grid with 6 children — items overflowed into a second
 * grid row. Replaced with flex: avatar | name+meta (flex-1) | status
 * pill | action cluster, all on one line, all wrapping cleanly on
 * narrow viewports. */
/* ── Crew DB toolbar (search + filter pills) ─────────────────────
 * Sits above the member list. Search input is squared per Style
 * Guide §5.1, with a magnifier icon prefixed inside via a wrapper.
 * Filter pills are mono uppercase outlined buttons with an active
 * solid state. Each cluster (Status / Assignment) renders as one
 * .crew-db-filter-row so they wrap cleanly on narrow viewports. */
.crew-db-toolbar {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  gap: 12px; row-gap: 10px;
  margin-bottom: 18px;
}
.crew-db-toolbar-title {
  display: flex; align-items: center; gap: 10px;
  flex-shrink: 0;
}
/* Right side of the toolbar — search box + "+ Add Crew Member" CTA.
 * Wraps below the title on narrow viewports via the parent's flex-wrap. */
.crew-db-toolbar-right {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.crew-db-search-wrap {
  position: relative;
  width: 280px; max-width: 100%;
}
.crew-db-search-wrap svg {
  position: absolute;
  left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}
.crew-db-search {
  width: 100%; height: 32px;
  padding: 0 12px 0 32px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: 0;
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--text);
  outline: none;
  transition: border-color .12s, background .12s;
}
.crew-db-search:focus { border-color: var(--text); background: var(--card); }
.crew-db-search::placeholder { color: var(--text-3); }

.crew-db-filter-row {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px; row-gap: 6px;
  margin-bottom: 12px;
}
.crew-db-filter-label {
  font-family: var(--font-mono);
  font-size: 9.5px; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--text-muted);
  margin-right: 6px;
}
.crew-db-filter-pill {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: 8px;
  height: 26px; padding: 0 11px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
}
.crew-db-filter-pill:hover { color: var(--text); border-color: var(--text-muted); }
.crew-db-filter-pill.is-active {
  color: var(--card);
  background: var(--text);
  border-color: var(--text);
}
.crew-db-filter-pill .crew-db-filter-count {
  font-size: 9px;
  opacity: .65;
  margin-left: 2px;
}

/* ── Edit / Detail modal — Style-Guide-aligned form fields ────
 * The legacy modal body was rendered with inline styles that drifted
 * from the platform editorial style: 6px border-radius, 9px labels
 * with 1px letter-spacing, custom font-family inheritance. These
 * classes restore the canonical look:
 *   .crew-edit-field   = column wrapper, 12px bottom margin
 *   .crew-edit-label   = mono uppercase 10px / .18em / weight 700
 *   .crew-edit-input   = squared, cream-alt bg, 36px tall, focus to surface
 *   .crew-edit-section = mono section-eyebrow (Emergency / Sensitive / Bank)
 *   .crew-edit-grid-2  = two-column grid with 8px gap (used for Phone+Relation, Account+Routing)
 * Drop-in replacements for the inline-style soup in
 * openCrewMemberDetailEdit / openCrewMemberDetail. */
.crew-edit-body { display: flex; flex-direction: column; }
.crew-edit-field { margin-bottom: 12px; }
.crew-edit-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.crew-edit-input {
  width: 100%;
  height: 36px;
  padding: 0 12px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: 0;
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 34px;
  color: var(--text);
  outline: none;
  transition: border-color .12s, background .12s;
}
.crew-edit-input:focus {
  border-color: var(--text);
  background: var(--card);
}
.crew-edit-input::placeholder { color: var(--text-3); }
/* Textarea variant — same look but multi-line */
.crew-edit-input.crew-edit-textarea {
  height: auto;
  min-height: 70px;
  padding: 9px 12px;
  line-height: 1.45;
  resize: vertical;
}
/* Native select — same shape; rely on the OS chevron */
select.crew-edit-input {
  appearance: none; -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
    linear-gradient(-45deg, transparent 50%, var(--text-muted) 50%);
  background-position:
    calc(100% - 14px) 50%,
    calc(100% - 9px)  50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 28px;
}
.crew-edit-section {
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--text-muted);
  margin: 12px 0 8px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.crew-edit-section:first-child {
  margin-top: 0; padding-top: 0; border-top: 0;
}
.crew-edit-section-hint {
  font-family: var(--font-sans);
  font-size: 11.5px; font-weight: 400;
  letter-spacing: 0; text-transform: none;
  color: var(--text-3);
  margin-left: 6px;
}
.crew-edit-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* "On file: ••••1234" hint shown beneath sensitive-field inputs.
 * The mask itself comes from the API (national_id_mask /
 * bank_account_mask), computed server-side from the decrypted last 4
 * chars so the client never sees full plaintext until reveal. */
.crew-edit-hint {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-top: 5px;
}
.crew-edit-mask {
  font-family: var(--font-mono);
  letter-spacing: .14em;
  color: var(--text-muted);
}

/* Crew DB rows. No avatar — Crew DB members are imported records,
 * not platform users. Avatars are reserved for Organization Members
 * (rendered separately).
 *
 * Layout:
 *   [ name + meta + notes + extras ]   [ status pill + icon strip ]
 * The whole row is clickable (admin → edit modal, member → details).
 */
/* Compact row layout — single content line for name + meta,
 * optional second line for notes. The right cluster (chips +
 * status + actions) sits centered with the headline so the row's
 * visual height is one line tall when there are no notes. */
.crew-db-row {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px;
  background: var(--card); border: 1px solid var(--border);
  margin-bottom: 6px;
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.crew-db-row:hover { border-color: var(--border-hover); background: var(--card-hover, var(--card)); }

/* Checkbox + identity travel together. The checkbox used to be a sibling of
   the main block, so the narrow-viewport `flex-direction: column` gave it a
   line of its own above the name — a control attached to nothing. */
.crew-db-row-lead { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px; }
.crew-db-row-lead .crew-db-sel { flex-shrink: 0; margin: 0; }
.crew-db-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.crew-db-row-side {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
}

/* The headline holds Name · email · phone on a single ellipsised line.
 * The mid-dot separator stays muted. */
.crew-db-headline {
  display: flex; align-items: baseline;
  gap: 8px;
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.crew-db-name {
  font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
  color: var(--text);
  flex-shrink: 0;
}
.crew-db-headline-sep {
  color: var(--text-3);
  flex-shrink: 0;
}
.crew-db-meta-inline {
  font-family: var(--font-mono); font-size: 12px;
  color: var(--text-muted);
  letter-spacing: .02em;
  min-width: 0;
  overflow: hidden; text-overflow: ellipsis;
}
/* Below ~960px the headline doesn't have room for both name and full
 * email/phone alongside the right cluster. Stack meta on its own
 * line so neither gets truncated — the row gracefully wraps to
 * 2 lines instead of ellipsising the contact fields. */
@media (max-width: 960px) {
  .crew-db-headline {
    flex-wrap: wrap;
    white-space: normal;
  }
  .crew-db-meta-inline { flex-basis: 100%; }
  .crew-db-headline-sep { display: none; }
}
.crew-db-notes {
  font-family: var(--font-sans); font-size: 11.5px;
  color: var(--text-3);
  line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}

/* Chip strip — sensitive-field markers + project count. Sits inside
 * the right cluster so the row collapses to one visual line. */
.crew-db-chips {
  display: inline-flex; flex-wrap: wrap; gap: 4px;
  align-items: center;
}
.crew-db-chip {
  display: inline-flex; align-items: center;
  height: 18px; padding: 0 7px;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 0;
}
.crew-db-chip--proj.is-active {
  color: var(--chip-ok, #2E7A5C);
  background: color-mix(in srgb, var(--chip-ok, #2E7A5C) 10%, transparent);
  border-color: color-mix(in srgb, var(--chip-ok, #2E7A5C) 30%, transparent);
}

/* Action icon strip — sits next to the status pill. Same
 * .cl-section-icon-btn pattern from Style Guide §6.1 (used in
 * GT Tool's vehicle head). 22×22 transparent buttons that hover
 * into a cream chip. Stops click propagation so the parent
 * row's onclick (edit/details) doesn't fire. */
.crew-db-actions {
  display: flex; align-items: center; gap: 2px;
}
.crew-db-actions .cl-section-icon-btn {
  width: 26px; height: 26px; padding: 0;
  background: transparent; border: 1px solid transparent;
  cursor: pointer;
  color: var(--text-muted);
  display: inline-flex; align-items: center; justify-content: center;
  transition: color .12s, background .12s;
}
.crew-db-actions .cl-section-icon-btn:hover {
  color: var(--text); background: var(--input-bg);
}
.crew-db-actions .cl-section-icon-btn--danger:hover { color: var(--chip-err, #A8362C); }

/* Status pill — three states (invited / pending / complete) */
.crew-db-status {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 10px;
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .14em; text-transform: uppercase; font-weight: 500;
  border: 1px solid; border-radius: 999px;
  white-space: nowrap; flex-shrink: 0;
}
.crew-db-status::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor;
}
.crew-db-status.complete {
  color: var(--chip-ok);
  background: color-mix(in srgb, var(--chip-ok) 12%, transparent);
  border-color: color-mix(in srgb, var(--chip-ok) 35%, transparent);
}
.crew-db-status.pending {
  color: #C98A1A;
  background: rgba(201,138,26,.12);
  border-color: rgba(201,138,26,.35);
}
[data-theme="light"] .crew-db-status.pending {
  color: #95660d;
  background: rgba(149,102,13,.10);
  border-color: rgba(149,102,13,.35);
}
.crew-db-status.invited {
  color: var(--text-muted);
  background: var(--input-bg);
  border-color: var(--border);
}

/* Legacy direct-child button rules removed — actions now live inside
 * .crew-db-actions as .cl-section-icon-btn icons (see above). The old
 * Edit/Assign/Delete text buttons next to the row don't exist anymore;
 * the whole row is clickable to edit, the icon strip handles the rest. */

/* Narrow viewport: stack the side cluster (status pill + actions)
 * below the main content so neither side gets clipped. */
@media (max-width: 720px) {
  .crew-db-row { flex-direction: column; align-items: stretch; }
  .crew-db-row-side {
    justify-content: space-between;
    margin-top: 6px;
  }
}

/* ── CSV Import preview modal ──────────────────────────────────
 * Opens when the user picks a CSV file in the Crew DB toolbar.
 * Shows every parsed row with a checkbox + Full Name + (optional)
 * Notes preview so the user can deselect before submitting. */
.csv-import-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.csv-import-toggle-all {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer; user-select: none;
}
/* Control painted by the canonical checkbox (editorial-chrome.css §5.7). */
.csv-import-summary {
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
}

.csv-import-list {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
  padding-right: 2px;   /* leave room for the scrollbar */
  margin-bottom: 14px;
}

.csv-import-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  background: var(--card);
  margin-bottom: 4px;
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.csv-import-row:hover { border-color: var(--border-hover); background: var(--card-hover, var(--card)); }
/* Baseline nudge + the row's own 12px gutter only; the box is canonical. */
.csv-import-row input[type="checkbox"] { margin: 3px 12px 0 0; }
.csv-import-row-body { flex: 1 1 auto; min-width: 0; }
.csv-import-row-name {
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.csv-import-row-notes {
  font-family: var(--font-sans); font-size: 11.5px;
  color: var(--text-muted);
  margin-top: 3px; line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Toast ─────────────────────────────────────────────────────── */
.toast {
  position: fixed; bottom: 24px; right: 24px; z-index: 500;
  padding: 12px 18px;
  background: var(--card); border: 1px solid var(--border);
  font-family: var(--font-sans); font-size: 13px; color: var(--text);
  opacity: 0; transform: translateY(8px);
  transition: opacity .2s, transform .2s;
  pointer-events: none; max-width: 360px;
}
.toast.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
/* The four states toast() in admin-js/admin-core.js can emit. Keep this set and
   TOAST_KINDS there in step: a kind with no rule here renders as the neutral
   base, which is how a warning ended up indistinguishable from a confirmation.
   `info` is deliberately the unstyled base — neutral IS the info treatment. */
.toast.error   { border-color: var(--danger); color: var(--danger); }
.toast.warn    { border-color: var(--cl-warn, #8A5A0C); color: var(--cl-warn, #8A5A0C); }
.toast.success { border-color: var(--cl-ok,   #2E7A5C); color: var(--cl-ok,   #2E7A5C); }

/* ── Editorial filter pills (Projects view toolbar) ───────────── */
.rx-pill-cluster { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rx-filter-pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 14px;
  background: transparent; border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-sans); font-size: 12px; color: var(--text-muted);
  cursor: pointer; transition: background .12s, color .12s, border-color .12s;
}
.rx-filter-pill:hover { color: var(--text); border-color: var(--text-muted); }
.rx-filter-pill.is-active { color: var(--accent); border-color: var(--accent); }
/* Client filter dropdown — the pill anchors an absolutely-positioned menu. */
.rx-filter-wrap { position: relative; display: inline-flex; }
.rx-filter-menu {
  display: none; position: absolute; top: 38px; left: 0; z-index: 60;
  min-width: 190px; max-height: 300px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 6px; box-shadow: 0 10px 30px rgba(0,0,0,.22);
}
.rx-filter-menu.is-open { display: block; }
.rx-filter-menu-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border-radius: 7px; cursor: pointer;
  font-family: var(--font-sans); font-size: 13px; color: var(--text); white-space: nowrap;
}
.rx-filter-menu-item:hover { background: rgba(127,127,127,.14); }
.rx-filter-menu-item.is-selected { color: var(--accent); font-weight: 500; }
.rx-filter-menu-item .rx-check { opacity: 0; font-size: 12px; }
.rx-filter-menu-item.is-selected .rx-check { opacity: 1; }
.rx-filter-pill--accent {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
  font-weight: 500;
}
.rx-filter-pill--accent:hover { filter: brightness(1.08); }

/* ── Misc ─────────────────────────────────────────────────────── */
.view-title em, .view-title-italic { font-style: italic; }
#viewOrgPicker .view-header { border-bottom: 0; padding-bottom: 0; }

/* ── PDF / Document Brand Style picker ────────────────────────────
 * Org Settings → Brand Style. Three full-page mock-ups, one per style.
 * Clicking a card calls saveOrgPdfStyle(...). Markup is rendered by
 * _renderPdfStyleOptions(active, isAdmin) in admin-app.js.
 *
 * Each preview is a self-contained mini A4 page (~200×283 ratio) with
 * hand-tuned chrome that matches the corresponding [data-pdf-style="X"]
 * block in apps/css/pdf-styles.css. We don't reuse the production
 * .pdf-page CSS here because admin.php doesn't load the per-tool
 * stylesheets — and the previews don't need to be pixel-perfect to
 * the printed output, just visually representative.
 */
.pdf-style-picker {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-top: 14px;
  max-width: 880px;
}
@media (max-width: 760px) {
  .pdf-style-picker { grid-template-columns: 1fr; }
}

.pdf-style-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 14px 16px;
  background: var(--surface, #FFFFFF);
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 0;  /* Style Guide §8.0 — Editorial chrome is squared */
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.pdf-style-card:hover {
  border-color: var(--text-2, #4A4A4A);
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .08);
}
.pdf-style-card.is-active {
  border: 3px solid #0E0E0E;
  box-shadow: none;
}
.pdf-style-card.is-disabled {
  cursor: not-allowed;
  opacity: .55;
}
.pdf-style-card.is-disabled:hover {
  transform: none;
  box-shadow: none;
  border-color: var(--border, #E5E7EB);
}
.pdf-style-check {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent, #E35E00);
  color: #fff;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(.6);
  transition: opacity .15s, transform .15s;
  pointer-events: none;
}
.pdf-style-card.is-active .pdf-style-check {
  opacity: 0;
  transform: scale(.6);
}
.pdf-style-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pdf-style-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text, #1A1612);
}
.pdf-style-desc {
  font-size: 11.5px;
  color: var(--text-muted, #6E665B);
  line-height: 1.4;
}

/* Each preview card stacks a PDF document mock (top, A4-portrait
 * proportions) and an email-signature mock (bottom). Aspect ratio is
 * driven by the inner .pdf-style-mock-doc; the card itself grows to
 * fit signature + eyebrow underneath. Each variant is hand-tuned
 * below to match what apps/css/pdf-styles.css produces. */
.pdf-style-preview {
  position: relative;
  width: 100%;
  background: transparent;
  font-family: 'DM Sans', system-ui, sans-serif;
  color: #1A1612;
  pointer-events: none; /* whole card is clickable */
  user-select: none;
}
/* Force border-box on every descendant so 1px borders + 10–16px padding
   on .pdf-style-mock-sig + .pdf-style-mock-doc don't push children past
   the card's right edge (the signature was overflowing visibly in the
   Modern variant where padding-left jumps to 16px). */
.pdf-style-preview, .pdf-style-preview * { box-sizing: border-box; }
.pdf-style-mock-doc {
  width: 100%;
  aspect-ratio: 210 / 297;
  background: #FFFFFF;
  border: 1px solid var(--border-soft, #ECECEC);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.pdf-style-mock-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 12px;
  flex-shrink: 0;
}
.pdf-style-mock-title {
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -.02em;
  line-height: 1;
}
.pdf-style-mock-subtitle {
  font-size: 7.5px;
  color: rgba(255,255,255,.55);
  margin-top: 3px;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.pdf-style-mock-logos {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pdf-style-mock-logo {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: rgba(255,255,255,.18);
}
.pdf-style-mock-accent {
  height: 3px;
  background: #FF6C00;
  flex-shrink: 0;
}
.pdf-style-mock-body {
  flex: 1;
  padding: 8px 12px 6px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 0;
}
.pdf-style-mock-section-label {
  font-size: 6.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #1A1612;
  padding: 3px 0;
}
.pdf-style-mock-table-head {
  display: grid;
  grid-template-columns: 12px 1.1fr 1.4fr 1fr;
  gap: 4px;
  padding: 4px 6px;
  background: #F5F5F2;
  border-radius: 3px;
  font-size: 5.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #9CA3AF;
}
.pdf-style-mock-row {
  display: grid;
  grid-template-columns: 12px 1.1fr 1.4fr 1fr;
  gap: 4px;
  padding: 3px 6px;
  font-size: 6px;
  border-bottom: 1px solid #F1F5F9;
  line-height: 1.2;
}
.pdf-style-mock-row > div {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pdf-style-mock-row .num {
  color: #B0B0AC;
  font-weight: 700;
}
.pdf-style-mock-footer-accent {
  height: 2px;
  background: #FF6C00;
  flex-shrink: 0;
}
.pdf-style-mock-footer {
  background: #0E0E0E;
  color: rgba(255,255,255,.55);
  padding: 4px 12px;
  font-size: 6px;
  letter-spacing: .1em;
  text-transform: uppercase;
  display: flex;
  justify-content: space-between;
  flex-shrink: 0;
}
/* ── Email signature mock (shared base) ────────────────────────── */
.pdf-style-mock-eyebrow {
  margin-top: 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 7px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--text-muted, #6E665B);
  padding-bottom: 6px;
}
.pdf-style-mock-sig {
  position: relative;
  width: 100%;
  background: #FFFFFF;
  border: 1px solid var(--border-soft, #ECECEC);
  padding: 10px 12px 9px;
  display: flex;
  flex-direction: column;
  font-size: 7px;
  line-height: 1.35;
  color: #1A1612;
  overflow: hidden;
}
.pdf-style-mock-sig-rule {
  position: absolute; left: 0; right: 0; top: 0;
  height: 1px; background: #1A1612;
}
.pdf-style-mock-sig-bar {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 0;          /* shown only by the modern variant */
  background: #FF6C00;
}
.pdf-style-mock-sig-inner {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.pdf-style-mock-sig-name {
  font-weight: 700;
  font-size: 11px;
  letter-spacing: -.02em;
  line-height: 1;
  color: #111111;
}
.pdf-style-mock-sig-title {
  font-size: 6px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #555555;
  margin-top: 1px;
}
.pdf-style-mock-sig-contacts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 10px;
  margin-top: 5px;
  font-size: 6.5px;
  color: #111111;
}
.pdf-style-mock-sig-contacts .lbl {
  color: #888888;
  font-weight: 600;
  letter-spacing: .05em;
  margin-right: 2px;
}
.pdf-style-mock-sig-logo {
  width: 32px; height: 12px;
  background: rgba(0,0,0,.18);
  border-radius: 1px;
  margin-top: 6px;
}
.pdf-style-mock-sig-disclaimer {
  margin-top: 6px;
  padding-top: 4px;
  border-top: 1px solid #E5E7EB;
  font-size: 5.5px;
  color: #9CA3AF;
  line-height: 1.3;
}

/* ── Variant: EDITORIAL — already matches the base treatment ──── */
.pdf-style-preview[data-variant="classic"] .pdf-style-mock-sig-rule {
  background: #1A1612;
}

/* ── Variant: CLASSIC ──────────────────────────────────────────── */
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-sig-rule {
  background: #FF6C00;          /* client-color top stripe */
  height: 2px;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-sig {
  padding-top: 12px;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-sig-name {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 14px;
  letter-spacing: -.005em;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-sig-title {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  text-transform: none;
  letter-spacing: 0;
  font-size: 8px;
  color: #6B7280;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-sig-contacts .lbl {
  color: #6B7280;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-sig-disclaimer {
  border-top-color: #FF6C00;
}

/* ── Variant: MODERN ──────────────────────────────────────────── */
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig {
  background: #FAFAF7;
  padding-left: 16px;            /* room for the vertical block */
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-rule {
  display: none;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-bar {
  width: 6px;                    /* vertical client-color block */
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-name {
  font-family: 'DM Sans', system-ui, sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -.02em;
  font-size: 13px;
  line-height: .95;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-title {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: .22em;
  font-weight: 700;
  color: #1A1612;
  margin-top: 3px;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-contacts {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 6px;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-contacts .lbl {
  color: #FF6C00;
  text-transform: uppercase;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-logo {
  background: rgba(0,0,0,.22);
  border-radius: 0;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-sig-disclaimer {
  border-top-color: #1A1612;
}

/* ── Variant: CLASSIC (magazine, true-black header) ───────────── */
.pdf-style-preview[data-variant="classic"] .pdf-style-mock-header {
  background: #0E0E0E;
  color: #FFFFFF;
  height: 32px;
}
.pdf-style-preview[data-variant="classic"] .pdf-style-mock-title {
  color: #FFFFFF;
}

/* ── Variant: EDITORIAL (default Reelax look) ─────────────────── */
.pdf-style-preview[data-variant="editorial"] {
  background: #FFFFFF;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-header {
  background: #FFFFFF;
  height: 36px;
  border-top: 3px solid #FF6C00;
  border-bottom: 1px solid #E5E7EB;
  color: #0E0E0E;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-title {
  color: #0E0E0E;
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 15px;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-subtitle {
  color: #6B7280;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-logo {
  background: rgba(0,0,0,.12);
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-accent {
  display: none;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-section-label {
  font-family: 'DM Sans', sans-serif;
  text-transform: none;
  letter-spacing: .02em;
  font-size: 7px;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-footer-accent {
  display: none;
}
.pdf-style-preview[data-variant="editorial"] .pdf-style-mock-footer {
  background: #FFFFFF;
  color: #6B7280;
  border-top: 1px solid #FF6C00;
}

/* ── Variant: MODERN ───────────────────────────────────────────── */
.pdf-style-preview[data-variant="modern"] {
  background: #FAFAF7;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-header {
  background: #FAFAF7;
  height: 44px;
  border-left: 6px solid #FF6C00;
  padding: 0 10px 0 8px;
  align-items: flex-end;
  padding-bottom: 4px;
  color: #0E0E0E;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-title {
  color: #0E0E0E;
  font-family: 'DM Sans', system-ui, sans-serif;
  font-style: normal;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -.035em;
  line-height: .92;
  text-transform: uppercase;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-subtitle {
  color: #1A1612;
  letter-spacing: .22em;
  font-weight: 700;
  margin-top: 4px;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-logo {
  background: rgba(0,0,0,.15);
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-accent {
  height: 4px;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-section-label {
  display: inline-block;
  align-self: flex-start;
  border: 1px solid #FF6C00;
  color: #FF6C00;
  padding: 2px 6px;
  font-size: 6px;
  letter-spacing: .18em;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-table-head {
  background: transparent;
  border-radius: 0;
  border-bottom: 1.5px solid #1A1612;
  color: #1A1612;
  font-size: 5px;
  letter-spacing: .18em;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-row .num {
  color: #FF6C00;
  font-weight: 700;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-footer-accent {
  display: none;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-footer {
  background: #FAFAF7;
  color: #1A1612;
  border-top: 1px solid #E5E7EB;
  border-left: 6px solid #FF6C00;
}
.pdf-style-preview[data-variant="modern"] .pdf-style-mock-footer div:first-child {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: .2em;
  font-weight: 700;
  font-size: 6px;
  color: #1A1612;
}

/* ── Design System v1.2 — new canonical variant names ────────────────
 * These blocks mirror the legacy editorial/classic/modern variants but
 * use the new data-variant names (studio/edition/field). The picker JS
 * (_renderPdfStylePreview) now emits the new names; the legacy blocks
 * above stay for any stale DOM that cached the old names.
 *
 * Preview accent color is each style's design-system default:
 *   Studio  → emerald  #0d7a5f
 *   Edition → vermillion #c84a2e
 *   Field   → teal  #0f5e5a
 */

/* ── Variant: STUDIO (charcoal header/footer, emerald accent) ─── */
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-header {
  background: #0e1014;
  color: #fafaf9;
  height: 32px;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-title {
  color: #fafaf9;
  font-family: "Hanken Grotesk", system-ui, sans-serif;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: -.025em;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-subtitle {
  color: rgba(250,250,249,.55);
  font-family: "JetBrains Mono", monospace;
  letter-spacing: .13em;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-logo {
  background: rgba(255,255,255,.18);
  border-radius: 2px;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-accent {
  background: #0d7a5f;   /* emerald */
  height: 3px;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-section-label {
  font-family: "JetBrains Mono", monospace;
  color: #0d7a5f;
  letter-spacing: .12em;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-table-head {
  border-radius: 3px;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-row .num {
  color: #9a9c9f;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-footer-accent {
  display: none;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-footer {
  background: #0e1014;
  color: rgba(250,250,249,.55);
}
/* Studio email sig — hairline top rule, brand-color accent word */
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-sig-rule {
  background: #e4e1dc;    /* hairline */
  height: 1px;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-sig-name {
  font-family: "Hanken Grotesk", system-ui, sans-serif;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: -.02em;
  color: #0e1014;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-sig-title {
  font-family: "JetBrains Mono", monospace;
  color: #0d7a5f;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-size: 6px;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-sig-contacts .lbl {
  color: #9a9c9f;
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-sig-logo {
  border-radius: 2px;
  background: rgba(0,0,0,.16);
}
.pdf-style-preview[data-variant="studio"] .pdf-style-mock-sig-disclaimer {
  border-top-color: #e4e1dc;
}

/* ── Variant: EDITION (paper-on-paper, serif italic, vermillion) ─ */
.pdf-style-preview[data-variant="edition"] {
  background: #f4efe6;   /* cream paper */
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-doc {
  background: #f4efe6;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-header {
  background: #f4efe6;
  height: 36px;
  border-bottom: 1px solid #1a1814;
  color: #1a1814;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-title {
  color: #1a1814;
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 15px;
  letter-spacing: 0;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-subtitle {
  color: #7a766e;   /* ink-mute */
  font-family: "JetBrains Mono", monospace;
  letter-spacing: .17em;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-logo {
  background: rgba(26,24,20,.12);
  border-radius: 0;
  border: 1px dashed #c8bfb0;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-accent {
  display: none;   /* edition: no stripe */
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-section-label {
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  color: #c84a2e;    /* vermillion */
  text-transform: none;
  letter-spacing: 0;
  font-size: 9px;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-table-head {
  background: #f4efe6;
  border-radius: 0;
  border-bottom: 1px solid #1a1814;
  color: #7a766e;
  font-family: "JetBrains Mono", monospace;
  letter-spacing: .16em;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-row {
  border-bottom-color: #dcd3c1;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-row .num {
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  color: #c84a2e;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-footer-accent {
  display: none;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-footer {
  background: #f4efe6;
  color: #7a766e;
  border-top: 1px solid #1a1814;
}
/* Edition email sig — ink underline, serif italic name, vermillion accent */
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-sig {
  background: #f4efe6;
  padding-top: 12px;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-sig-rule {
  background: #c84a2e;   /* vermillion accent line */
  height: 2px;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-sig-name {
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 14px;
  letter-spacing: -.005em;
  color: #1a1814;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-sig-title {
  font-family: "Instrument Serif", Georgia, serif;
  font-style: italic;
  text-transform: none;
  letter-spacing: 0;
  font-size: 8px;
  color: #7a766e;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-sig-contacts .lbl {
  color: #7a766e;
}
.pdf-style-preview[data-variant="edition"] .pdf-style-mock-sig-disclaimer {
  border-top-color: #c84a2e;
  color: #7a766e;
}

/* ── Variant: FIELD (panel chrome, teal hash stripe, bracketed mono) */
.pdf-style-preview[data-variant="field"] {
  background: #f4f2eb;   /* eggshell */
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-doc {
  background: #f4f2eb;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-header {
  background: #16191a;   /* panel */
  color: #f4f2eb;
  height: 30px;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-title {
  color: #f4f2eb;
  font-family: "Archivo Narrow", "Archivo", sans-serif;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: -.005em;
  text-transform: uppercase;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-subtitle {
  color: #d3e3e1;   /* teal-soft on dark bg */
  font-family: "IBM Plex Mono", monospace;
  letter-spacing: .12em;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-logo {
  background: rgba(244,242,235,.15);
  border-radius: 0;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-accent {
  /* 4px teal hash stripe — Field's signature */
  height: 4px;
  background: repeating-linear-gradient(
    90deg,
    #0f5e5a 0, #0f5e5a 5px,
    #0a4543 5px, #0a4543 10px
  );
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-section-label {
  font-family: "IBM Plex Mono", monospace;
  color: #1a1c18;
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: 6px;
  /* bracketed label look */
  padding: 1px 4px;
  border: 1px solid #b8b4a6;
  align-self: flex-start;
  display: inline-block;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-body {
  background: #f4f2eb;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-table-head {
  background: #e8e5db;   /* paper-deep */
  border-radius: 0;
  border-bottom: 1px solid #b8b4a6;
  color: #8a8d85;
  font-family: "IBM Plex Mono", monospace;
  letter-spacing: .12em;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-row {
  border-bottom-color: #e2dfd5;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-row .num {
  color: #8a8d85;
  font-family: "IBM Plex Mono", monospace;
  font-weight: 400;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-footer-accent {
  display: none;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-footer {
  background: #16191a;
  color: rgba(244,242,235,.6);
  font-family: "IBM Plex Mono", monospace;
  border-top: none;
}
/* Field email sig — panel bar on left, teal accent labels */
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig {
  background: #f4f2eb;
  padding-left: 16px;   /* room for panel left bar */
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-rule {
  display: none;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-bar {
  width: 5px;
  background: #0f5e5a;  /* teal left-edge bar */
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-name {
  font-family: "Archivo Narrow", "Archivo", sans-serif;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: -.005em;
  text-transform: uppercase;
  color: #1a1c18;
  line-height: .95;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-title {
  font-family: "IBM Plex Mono", monospace;
  letter-spacing: .14em;
  font-weight: 400;
  color: #0f5e5a;  /* teal */
  text-transform: uppercase;
  font-size: 6px;
  margin-top: 2px;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-contacts {
  font-family: "IBM Plex Mono", monospace;
  font-size: 6px;
  color: #1a1c18;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-contacts .lbl {
  color: #0f5e5a;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-logo {
  background: rgba(0,0,0,.18);
  border-radius: 0;
}
.pdf-style-preview[data-variant="field"] .pdf-style-mock-sig-disclaimer {
  border-top-color: #d4d1c5;
  color: #8a8d85;
}

/* ── Style tagline (one-liner below the name) ──────────────────── */
.pdf-style-tagline {
  display: block;
  font-size: 10px;
  font-weight: 400;
  color: var(--text-muted, #6E665B);
  letter-spacing: .01em;
  margin-top: 1px;
}

/* ════════════════════════════════════════════════════════════════
   FOUNDATIONS CARDS  (sff-* prefix)
   Design System v1.2 style picker — Option A layout.
   Each card communicates the voice of a style, not a document mock:
   chrome strip · accent stripe · type block · signature move · swatches.
   ════════════════════════════════════════════════════════════════ */

.sff-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  pointer-events: none;
  user-select: none;
  overflow: hidden;
}
.sff-card, .sff-card * { box-sizing: border-box; }

/* ── Chrome strip (header bar treatment) ─────────────────────── */
.sff-chrome {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  height: 28px;
  flex-shrink: 0;
}
.sff-chrome-left {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.sff-chrome-org {
  width: 16px;
  height: 16px;
  border-radius: 1px;
  flex-shrink: 0;
}
.sff-chrome-title {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sff-chrome-chips {
  display: flex;
  gap: 3px;
  flex-shrink: 0;
}
.sff-chrome-chip {
  width: 18px;
  height: 10px;
  border-radius: 1px;
}

/* ── Accent stripe ───────────────────────────────────────────── */
.sff-stripe {
  height: 3px;
  flex-shrink: 0;
}

/* ── Body: eyebrow + headline + signature ────────────────────── */
.sff-body {
  flex: 1;
  padding: 10px 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 0;
}
.sff-eyebrow {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 6px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.sff-headline {
  font-size: 17px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.025em;
}
.sff-sig {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* ── Swatch row ──────────────────────────────────────────────── */
.sff-swatches {
  display: flex;
  gap: 4px;
  padding: 8px 10px 10px;
  flex-shrink: 0;
}
.sff-swatch {
  width: 18px;
  height: 10px;
  border-radius: 2px;
}

/* ══════════════════════════════════════════════════════════════
   STUDIO variant
   ══════════════════════════════════════════════════════════════ */
.sff-card[data-variant="studio"] .sff-chrome {
  background: #0e1014;
}
.sff-card[data-variant="studio"] .sff-chrome-title {
  color: #fafaf9;
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
  font-weight: 800;
  letter-spacing: -.015em;
}
.sff-card[data-variant="studio"] .sff-chrome-org {
  background: rgba(255,255,255,.18);
  border: 1px dashed rgba(255,255,255,.3);
}
.sff-card[data-variant="studio"] .sff-chrome-chip {
  background: rgba(255,255,255,.15);
  border: 1px dashed rgba(255,255,255,.25);
}
.sff-card[data-variant="studio"] .sff-stripe {
  background: #0d7a5f;
}
.sff-card[data-variant="studio"] .sff-body {
  background: #fafaf9;
}
.sff-card[data-variant="studio"] .sff-eyebrow {
  color: #0d7a5f;
}
.sff-card[data-variant="studio"] .sff-headline {
  color: #0e1014;
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
}
/* Studio signature: 6×6 brand-dot bullets */
.sff-dot-row {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
  font-size: 7px;
  color: #3a3d44;
}
.sff-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #0d7a5f;
  flex-shrink: 0;
}
/* Studio footer (the swatch strip doubles as a mini footer band) */
.sff-card[data-variant="studio"] .sff-swatches {
  background: #0e1014;
  border-top: none;
  gap: 5px;
  padding: 6px 10px 8px;
}
.sff-card[data-variant="studio"] .sff-swatch {
  border-radius: 2px;
}

/* ══════════════════════════════════════════════════════════════
   EDITION variant
   ══════════════════════════════════════════════════════════════ */
.sff-card[data-variant="edition"] .sff-chrome {
  background: #f4efe6;
  border-bottom: 1px solid #1a1814;
  height: 32px;
  padding-top: 4px;
}
.sff-card[data-variant="edition"] .sff-chrome-title {
  color: #1a1814;
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0;
}
.sff-card[data-variant="edition"] .sff-chrome-chip {
  background: transparent;
  border: 1px dashed #c8bfb0;
  height: 12px;
  width: 20px;
  border-radius: 0;
}
.sff-card[data-variant="edition"] .sff-stripe {
  display: none; /* Edition: no stripe */
}
.sff-card[data-variant="edition"] .sff-body {
  background: #f4efe6;
  padding-top: 12px;
}
.sff-card[data-variant="edition"] .sff-eyebrow {
  color: #7a766e;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: .17em;
}
.sff-card[data-variant="edition"] .sff-headline {
  color: #1a1814;
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  font-style: normal;
  font-size: 20px;
  letter-spacing: -.01em;
}
/* Edition signature: italic vermillion section number + body excerpt */
.sff-edition-num {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 18px;
  color: #c84a2e;
  line-height: 1;
  letter-spacing: -.01em;
}
.sff-edition-body {
  font-family: 'Newsreader', Georgia, serif;
  font-size: 7px;
  color: #43403a;
  line-height: 1.5;
  margin-top: 2px;
}
.sff-edition-body em {
  font-style: italic;
  color: #c84a2e;
}
.sff-card[data-variant="edition"] .sff-swatches {
  background: #f4efe6;
  border-top: 1px solid #c8bfb0;
  padding: 7px 10px 10px;
}
.sff-card[data-variant="edition"] .sff-swatch {
  border-radius: 0;
}

/* ══════════════════════════════════════════════════════════════
   FIELD variant
   ══════════════════════════════════════════════════════════════ */
.sff-card[data-variant="field"] .sff-chrome {
  background: #16191a;
}
.sff-card[data-variant="field"] .sff-chrome-title {
  color: #f4f2eb;
  font-family: 'Archivo Narrow', 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 9px;
  letter-spacing: .02em;
  text-transform: uppercase;
}
.sff-card[data-variant="field"] .sff-chrome-chip {
  background: rgba(244,242,235,.12);
  border: 1px dashed rgba(244,242,235,.25);
  border-radius: 0;
  height: 12px;
}
.sff-card[data-variant="field"] .sff-stripe {
  height: 4px;
  background: repeating-linear-gradient(
    90deg,
    #0f5e5a 0, #0f5e5a 5px,
    #0a4543 5px, #0a4543 10px
  );
}
.sff-card[data-variant="field"] .sff-body {
  background: #f4f2eb;
}
.sff-card[data-variant="field"] .sff-eyebrow {
  color: #8a8d85;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  letter-spacing: .12em;
  /* bracketed label treatment */
  display: inline-block;
  align-self: flex-start;
  border: 1px solid #b8b4a6;
  padding: 1px 4px;
}
.sff-card[data-variant="field"] .sff-headline {
  color: #1a1c18;
  font-family: 'Archivo Narrow', 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -.005em;
  text-transform: uppercase;
  line-height: 1.05;
}
/* Field signature: left-edge teal bar + row data */
.sff-field-row {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 6.5px;
  color: #1a1c18;
  padding: 2px 0;
  border-bottom: 1px solid #e2dfd5;
}
.sff-bar {
  display: inline-block;
  width: 3px;
  height: 12px;
  background: #0f5e5a;
  flex-shrink: 0;
  border-radius: 0;
}
.sff-field-name {
  flex: 1;
}
.sff-field-role {
  color: #8a8d85;
  font-size: 6px;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.sff-card[data-variant="field"] .sff-swatches {
  background: #16191a;
  border-top: none;
  padding: 6px 10px 8px;
}
.sff-card[data-variant="field"] .sff-swatch {
  border-radius: 0;
}

.pdf-style-saved {
  margin-top: 10px;
  font-size: 11px;
  color: #2E7A5C;
  font-weight: 600;
}

/* Brand Fonts picker styles removed by Refactor 2026-05-18 (Brand Fonts removal) (the feature
   itself was retired; typography is fixed at the platform level). */

/* ── Email Signature defaults form (Migration 020) ────────────────
 * Four stacked rows: Office / Web / Address / Disclaimer. Each row is
 * a label, an input (or textarea for the disclaimer), and a hint line
 * underneath. Save button + "Saved ✓" indicator at the foot. The
 * pdf-style-saved class is reused so the green pill matches the rest
 * of Settings without redefining colors. */
.sig-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 14px;
  max-width: 720px;
}
.sig-form-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sig-form-row label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-muted, #6E665B);
}
.sig-form-optional {
  font-family: var(--font-sans, -apple-system, sans-serif);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-3, #9C9384);
  margin-left: 4px;
}
.sig-form-row input,
.sig-form-row textarea {
  width: 100%;
  padding: 9px 12px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: 0;  /* Style Guide §8.0 — Editorial chrome is squared */
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--text);
  transition: border-color .12s;
}
.sig-form-row input:focus,
.sig-form-row textarea:focus {
  outline: none;
  border-color: var(--accent, #FF6C00);
}
.sig-form-row input:disabled,
.sig-form-row textarea:disabled {
  background: var(--input-bg);
  opacity: .6;
  color: var(--text-muted);
  cursor: not-allowed;
}
.sig-form-row textarea {
  resize: vertical;
  min-height: 78px;
  line-height: 1.5;
}
.sig-form-hint {
  font-size: 11.5px;
  color: var(--text-muted, #6E665B);
  line-height: 1.4;
}
.sig-form-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 4px;
}
.sig-form-actions .btn-primary:disabled {
  opacity: .55;
  cursor: not-allowed;
}

/* ── Pending Invites (Migration 021) ───────────────────────────
 * Lives at the foot of the Members view. The whole section
 * auto-hides when zero pending; when shown, each row is a horizontal
 * card with email + meta on the left and Resend / Cancel buttons
 * on the right.
 *
 * #viewMembers itself has no horizontal padding (the .view-header at
 * the top sets its own gutter), so the section has to own the same
 * 32px / 20px gutters as #membersList above it. */
#pendingInvitesSection {
  padding: 0 32px 32px;
}
@media (max-width: 900px) {
  #pendingInvitesSection { padding: 0 20px 20px; }
}
.pending-invite-count {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px; font-weight: 700;
  letter-spacing: .14em;
  color: var(--accent, #FF6C00);
  background: var(--accent-bg, rgba(81, 71, 168, .12));
  border: 1px solid var(--accent-border, rgba(81, 71, 168, .35));
  padding: 2px 9px;
  border-radius: 999px;
  display: inline-flex; align-items: center;
  min-width: 24px; justify-content: center;
}
.pending-invites-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 14px;
}
.pending-invite-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 12px 16px;
  background: var(--card, #FFFFFF);
  border: 1px solid var(--border-soft, #ECECEC);
  border-radius: 6px;
  transition: border-color .12s;
}
.pending-invite-row:hover { border-color: var(--border, #D8D2C4); }
.pending-invite-main { min-width: 0; flex: 1; }
.pending-invite-email {
  font-size: 14px;
  font-weight: 600;
  color: var(--text, #1A1612);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4px;
}
.pending-invite-meta {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 6px;
  font-size: 11.5px;
  color: var(--text-muted, #6E665B);
  line-height: 1.4;
}
.pending-invite-role {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted, #6E665B);
  border: 1px solid var(--border, #D8D2C4);
  padding: 2px 7px;
  border-radius: 2px;
}
.pending-invite-sep { color: var(--text-3, #B0A99A); }
.pending-invite-actions {
  display: flex; align-items: center; gap: 6px;
  flex-shrink: 0;
}
.pending-invite-actions .btn-sm {
  font-size: 11px;
  padding: 5px 10px;
  border-radius: 4px;
}
.pending-invite-actions .btn-sm.danger {
  color: #C0392B;
  border-color: rgba(192, 57, 43, .35);
}
.pending-invite-actions .btn-sm.danger:hover {
  background: rgba(192, 57, 43, .08);
  border-color: rgba(192, 57, 43, .55);
}

/* ── Project Branding read-only state (non-admin members) ──────
 * The Branding tab stays visible for any team member so they can see
 * what logos the org / project carries, but the upload + remove
 * actions are disabled and the upload zones are visually muted. */
.brand-section.is-readonly .upload-zone {
  cursor: default;
  opacity: .85;
}
.brand-section.is-readonly .upload-zone:not(.has-image):hover {
  border-color: var(--border, #D8D2C4);
  background: var(--card-deep, #F2EFE6);
}
.brand-section.is-readonly .upload-zone-placeholder {
  opacity: .6;
}
.branding-readonly-banner {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 14px;
  margin-bottom: 22px;
  background: var(--card-alt, #F7F4EC);
  border: 1px solid var(--border-soft, #E6E0D2);
  border-radius: 4px;
  font-size: 12.5px;
  color: var(--text-muted, #6E665B);
  line-height: 1.45;
}
.branding-readonly-banner svg {
  flex-shrink: 0;
  color: var(--text-3, #9C9384);
}

/* ── Empty-state for the org picker ────────────────────────────
 * Shown when the logged-in user is in zero organizations. Carries
 * an "Accept invite" paste form so a stranded invitee (signed in
 * before clicking the email link) can recover without re-login. */
.no-orgs-state {
  grid-column: 1 / -1;            /* span all org-picker columns */
  max-width: 520px;
  margin: 24px auto 0;
  padding: 36px 32px;
  background: var(--card, #FFFFFF);
  border: 1px solid var(--border-soft, #ECECEC);
  border-radius: 6px;
  text-align: center;
}
.no-orgs-icon {
  width: 56px; height: 56px;
  margin: 0 auto 14px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--card-alt, #F7F4EC);
  color: var(--text-muted, #6E665B);
}
.no-orgs-title {
  font-family: var(--font-serif, 'Instrument Serif', Georgia, serif);
  font-size: 26px; font-weight: 400;
  letter-spacing: -.01em; line-height: 1.1;
  color: var(--text, #1A1612);
  margin-bottom: 4px;
}
.no-orgs-sub {
  font-size: 13px;
  color: var(--text-muted, #6E665B);
  line-height: 1.5;
  margin-bottom: 24px;
}
.no-orgs-invite {
  display: flex; flex-direction: column; gap: 8px;
  text-align: left;
  padding-top: 22px;
  border-top: 1px solid var(--border-soft, #ECECEC);
}
.no-orgs-invite-label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted, #6E665B);
}
.no-orgs-invite-row {
  display: flex; gap: 8px;
}
.no-orgs-invite-row input {
  flex: 1; min-width: 0;
  padding: 10px 13px;
  font-family: var(--font-sans, -apple-system, sans-serif);
  font-size: 13px;
  color: var(--text, #1A1612);
  background: var(--card-alt, #F7F4EC);
  border: 1px solid var(--border-soft, #E6E0D2);
  border-radius: 4px;
  outline: none;
  transition: border-color .12s, background .12s;
}
.no-orgs-invite-row input:focus {
  border-color: var(--text, #1A1612);
  background: var(--card, #FFFFFF);
}
.no-orgs-invite-row input::placeholder {
  color: var(--text-3, #9C9384);
}
.no-orgs-invite-row .btn-primary {
  flex-shrink: 0;
  padding: 10px 18px;
  font-size: 12px;
}
.no-orgs-invite-hint {
  font-size: 11.5px;
  color: var(--text-muted, #6E665B);
  line-height: 1.4;
  transition: color .15s;
}
.no-orgs-invite-hint.is-error {
  color: #C0392B;
}

/* ── Background image overlay slider (Migration 022) ─────────── */
.bg-overlay-control {
  display: flex; flex-direction: column; gap: 6px;
  max-width: 420px;
}
.bg-overlay-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.bg-overlay-label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted, #6E665B);
}
.bg-overlay-value {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px; font-weight: 700;
  letter-spacing: .04em;
  color: var(--text, #FFFFFF);
  min-width: 36px; text-align: right;
}
.bg-overlay-control input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%; height: 4px;
  background: var(--border, #222);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
  margin: 8px 0 4px;
}
.bg-overlay-control input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px; height: 16px;
  background: var(--accent, #E35E00);
  border: 2px solid var(--card, #161616);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--accent, #E35E00);
}
.bg-overlay-control input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px;
  background: var(--accent, #E35E00);
  border: 2px solid var(--card, #161616);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--accent, #E35E00);
}
.bg-overlay-hint {
  font-size: 11.5px;
  color: var(--text-muted, #6E665B);
  line-height: 1.4;
}

/* ── Edit Member modal ──────────────────────────────────────────
 * Used by the "Edit access…" item in the Members → row menu.
 * Mirrors the Invite Member modal but pre-populates with the
 * member's existing role + project_ids and adapts visible
 * controls to the chosen role. */
.edit-member-target {
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border, #2a2a2a);
  border-radius: 6px;
  padding: 10px 12px;
}
[data-theme="light"] .edit-member-target {
  background: var(--card-alt, #F7F4EC);
  border-color: var(--border-soft, #E6E0D2);
}
.edit-member-name  {
  font-size: 13px; font-weight: 600; color: var(--text);
  margin-bottom: 2px;
}
.edit-member-email {
  font-size: 11.5px; color: var(--text-muted, #878B8B);
}

.edit-member-project {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text);
  padding: 6px 0;
  cursor: pointer;
  border-bottom: 1px solid var(--border-soft, rgba(255,255,255,.04));
}
.edit-member-project:last-child { border-bottom: none; }
/* Control painted by the canonical checkbox (editorial-chrome.css §5.7). */


/* ── Settings → People (Migration 027) ─────────────────────────────
   Policy form for the org's invite + auth defaults. Style Guide §8.0
   editor chrome — squared corners, mono uppercase labels, theme-aware. */
.people-policy-block {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.people-policy-block:first-of-type { margin-top: 14px; }
.people-policy-label {
  font-family: var(--font-mono);
  font-size: 9px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.people-policy-help {
  font-family: var(--font-sans);
  font-size: 11.5px; line-height: 1.5;
  color: var(--text-muted);
  margin-bottom: 10px;
  max-width: 560px;
}
.people-policy-select {
  width: 100%; max-width: 420px;
  height: 36px; padding: 0 32px 0 12px; /* right padding leaves room for the chevron */
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 13px;
  border-radius: 0;
  cursor: pointer;
  /* Strip the native macOS rounded chrome — Safari rounds the
     control regardless of border-radius without this — then draw
     our own caret (matches the .field select treatment §6.2). */
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
}
.people-policy-select:focus { outline: none; border-color: var(--accent); background-color: var(--card); }
.people-policy-select:disabled { opacity: .55; cursor: not-allowed; }
/* Save button — section's primary action. Wants breathing room from
   the policy controls above it. */
#ppSaveBtn { margin-top: 18px; }
.people-policy-checkrow {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 8px;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--text);
}
/* Nudge only. :disabled is canonical now (§5.7) — the local copy of it was
   deleted rather than left to drift from the shared rule. */
.people-policy-checkrow input[type="checkbox"] { margin-top: 2px; }
.people-policy-domain-row {
  display: flex; align-items: center; gap: 0;
  margin-top: 8px;
  margin-left: 24px;   /* aligned under the checkbox label */
  max-width: 360px;
}
.people-policy-domain-at {
  height: 36px; padding: 0 10px;
  display: inline-flex; align-items: center;
  background: var(--card-deep, var(--input-bg));
  border: 1px solid var(--input-border);
  border-right: 0;
  font-family: var(--font-mono);
  font-size: 13px; color: var(--text-muted);
}
.people-policy-domain-row input {
  flex: 1;
  height: 36px;
  padding: 0 12px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 13px;
  border-radius: 0;
}
.people-policy-domain-row input:focus { outline: none; border-color: var(--accent); background: var(--card); }
.people-policy-domain-row input:disabled { opacity: .55; cursor: not-allowed; }
.people-policy-inline-err {
  margin-top: 6px;
  margin-left: 24px;
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--danger);
}
.people-policy-methods {
  margin-top: 14px;
  padding: 14px 14px 8px;
  background: var(--card);
  border: 1px solid var(--border);
}
.people-policy-methods-label {
  font-family: var(--font-mono);
  font-size: 9px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 12px;
}
.people-policy-method { padding: 4px 0; }
.people-policy-method-text { display: flex; flex-direction: column; gap: 2px; line-height: 1.45; }
.people-policy-method-text strong { font-weight: 600; color: var(--text); }
.people-policy-method-text em {
  font-style: normal;
  font-size: 11.5px;
  color: var(--text-muted);
}
.link-btn {
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.link-btn:hover { opacity: .85; }


/* ── Edit Profile modal — MFA block + help text (Migration 028) ──── */
.profile-help {
  margin-top: 6px;
  font-family: var(--font-sans);
  font-size: 11px; line-height: 1.45;
  color: var(--text-muted);
}
.profile-mfa-block {
  margin-top: 8px; margin-bottom: 18px;
  padding: 16px;
  background: var(--card);
  border: 1px solid var(--border);
}
.profile-mfa-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}
.profile-mfa-title {
  font-family: var(--font-mono);
  font-size: 9px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted);
}
.profile-mfa-status {
  margin-top: 4px;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--text);
}
.profile-mfa-status[data-state="enrolled"] { color: var(--chip-ok, #2E7A5C); }
.profile-mfa-required {
  font-family: var(--font-mono);
  font-size: 9px; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent-border, var(--accent));
  padding: 3px 8px;
  align-self: flex-start;
}
.profile-mfa-methods { display: flex; flex-direction: column; gap: 10px; }
.profile-mfa-method {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 10px 0;
  border-top: 1px solid var(--border-soft, var(--border));
}
.profile-mfa-method:first-child { border-top: 0; padding-top: 0; }
.profile-mfa-method-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.profile-mfa-method-text strong {
  font-family: var(--font-sans); font-size: 13px; font-weight: 600;
  color: var(--text);
}
.profile-mfa-method-text em {
  font-style: normal;
  font-size: 11px; line-height: 1.45;
  color: var(--text-muted);
}
.profile-mfa-method[data-enrolled="1"] .btn-secondary {
  border-color: var(--chip-ok, #2E7A5C);
  color: var(--chip-ok, #2E7A5C);
}


/* ── Edit Profile modal layout (replaces inline element.style) ───── */
.profile-edit-row {
  display: flex;
  align-items: flex-start;
  margin-bottom: 18px;
}
.profile-edit-row > div:first-child { margin-right: 18px; flex-shrink: 0; }
.profile-edit-fields {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.profile-edit-fields .field { margin-bottom: 12px; }
.profile-edit-fields .field:last-child { margin-bottom: 0; }


/* Edit Member — read-only MFA hint */
.profile-mfa-readonly {
  font-family: var(--font-sans);
  font-size: 11px; line-height: 1.4;
  color: var(--text-muted);
  max-width: 200px;
  text-align: right;
}

/* ── Project Detail · Client View tab ──────────────────────────────── */
/* Operator-side share-link surface — generates / rotates the per-project
   share token used by /apps/tools/client-view. Mirrors the 32px horizontal
   inset the Branding (.brand-section) and Members (.proj-members-header /
   .proj-members-list) tabs use so the four project tabs read as a family. */
.cv-tab {
  padding: 0 32px 32px;
  max-width: 760px;
}
.cv-tab-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 10px;
}
.cv-tab-title {
  font-family: var(--font-serif);
  font-size: 28px;
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--text);
  margin-bottom: 8px;
}
.cv-tab-sub {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
  margin-bottom: 24px;
  max-width: 600px;
}
.cv-tab-card {
  background: var(--card);
  border: 1px solid var(--border);
  padding: 20px 22px;
  margin-bottom: 16px;
}
.cv-tab-card-head { margin-bottom: 14px; }
.cv-tab-card-title {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 4px;
}
.cv-tab-card-sub {
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.5;
}
.cv-tab-row { display: flex; flex-direction: column; gap: 6px; }
.cv-tab-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-3);
}
.cv-tab-url-wrap {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.cv-tab-url-input {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 12px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--border);
  /* --card-alt isn't a canonical admin token (only used with fallbacks
     elsewhere in this file); the input bg should be the page bg so it
     reads as a quiet field, not a card surface. */
  background: var(--bg);
  color: var(--text);
}
.cv-tab-url-input:focus { outline: none; border-color: var(--text); }
.cv-tab-btn { min-width: 90px; }
.cv-tab-btn-open { min-width: 110px; }
.cv-tab-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.cv-tab-status {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-left: 4px;
}
/* --danger is the canonical admin token for error states (see :root). */
.cv-tab-status.is-err,
.cv-tab-status.is-error { color: var(--danger); }

/* Brand-bar color picker row (Client View tab). Inline layout: swatch
   + hex text + reset button + status. */
.cv-brand-color-row {
  flex-direction: row !important;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.cv-brand-color-swatch {
  width: 44px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  background: var(--bg);
  cursor: pointer;
  border-radius: 0;
}
.cv-brand-color-swatch::-webkit-color-swatch-wrapper { padding: 2px; }
.cv-brand-color-swatch::-webkit-color-swatch         { border: 0; border-radius: 0; }
.cv-brand-color-hex {
  width: 130px;
  font-family: var(--font-mono);
  text-transform: uppercase;
}
.cv-tab-note {
  font-family: var(--font-sans);
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft, var(--border));
}

.cv-tab-preview-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.cv-tab-preview-card {
  border: 1px solid var(--border);
  background: var(--card);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cv-tab-preview-card.is-muted { opacity: .55; }
.cv-tab-preview-card-name {
  font-family: var(--font-serif);
  font-size: 16px;
  color: var(--text);
}
.cv-tab-preview-card-status {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.cv-tab-preview-card-desc {
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.45;
}
.cv-tab-preview-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 20px;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-3);
  border: 1px dashed var(--border);
  background: var(--bg);
}


/* ═══════════════════════════════════════════════════════════════════
   DOCUMENT STYLE LIVE PREVIEW  (dsp-* prefix)
   Org Settings → Document Style section.

   #docStylePreview carries a data-doc-style attribute. doc-tokens.css
   sets the --doc-* custom properties on that element for each variant
   so every dsp-* rule that uses var(--doc-*) re-skins automatically
   when JS changes the attribute — no per-property JS required.

   Selector pattern for variant differences:
     #docStylePreview[data-doc-style="studio"]  .dsp-*
     #docStylePreview[data-doc-style="edition"] .dsp-*
     #docStylePreview[data-doc-style="field"]   .dsp-*
   ═══════════════════════════════════════════════════════════════════ */

/* ── Wrapper + label ─────────────────────────────────────────────── */
.dsp-wrap {
  margin-top: 20px;
  max-width: 520px;
}

.dsp-wrap-label {
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--text-3, var(--text-muted));
  margin-bottom: 8px;
}

/* ── Outer preview shell ─────────────────────────────────────────── */
#docStylePreview {
  overflow: hidden;
  border-radius: 5px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.14);
  display: flex;
  flex-direction: column;
  font-size: 12px;
  line-height: 1.4;
  user-select: none;
}
#docStylePreview, #docStylePreview * { box-sizing: border-box; }

/* ── Header chrome ───────────────────────────────────────────────── */
.dsp-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  gap: 8px;
}

/* Studio: charcoal bar */
#docStylePreview[data-doc-style="studio"] .dsp-header {
  background: var(--doc-charcoal, #0e1014);
  color: #ffffff;
}

/* Edition: warm cream header, ink hairline at base */
#docStylePreview[data-doc-style="edition"] .dsp-header {
  background: var(--doc-paper-deep, #ebe3d3);
  color: var(--doc-ink, #1a1814);
  border-bottom: 1px solid var(--doc-hairline, #c8bfb0);
}

/* Field: near-black panel */
#docStylePreview[data-doc-style="field"] .dsp-header {
  background: var(--doc-panel, #16191a);
  color: #ffffff;
}

.dsp-header-left {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* Studio: small logo placeholder block */
.dsp-org-mark {
  width: 20px;
  height: 14px;
  border-radius: 2px;
  flex-shrink: 0;
}
#docStylePreview[data-doc-style="studio"]  .dsp-org-mark { background: rgba(255,255,255,0.18); }
#docStylePreview[data-doc-style="edition"] .dsp-org-mark { background: var(--doc-hairline, #c8bfb0); }
#docStylePreview[data-doc-style="field"]   .dsp-org-mark { background: rgba(255,255,255,0.15); }

.dsp-title {
  font-family: var(--doc-font-display, var(--font-sans));
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Edition: Instrument Serif italic, no weight */
#docStylePreview[data-doc-style="edition"] .dsp-title {
  font-style: italic;
  font-weight: 400;
  font-size: 13px;
  color: var(--doc-ink, #1a1814);
}

/* Field: Archivo Narrow uppercase */
#docStylePreview[data-doc-style="field"] .dsp-title {
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.dsp-chips {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}

.dsp-chip {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 2px 6px;
}

/* Studio: dashed mono chips, white-60 */
#docStylePreview[data-doc-style="studio"] .dsp-chip {
  border: 1px dashed rgba(255,255,255,0.38);
  color: rgba(255,255,255,0.70);
  border-radius: 3px;
  font-family: var(--doc-font-mono, monospace);
}

/* Edition: hairline square */
#docStylePreview[data-doc-style="edition"] .dsp-chip {
  border: 1px solid var(--doc-hairline, #c8bfb0);
  color: var(--doc-ink-mute, #7a766e);
  border-radius: 0;
  font-family: var(--doc-font-body);
}

/* Field: solid teal fill, mono, no radius */
#docStylePreview[data-doc-style="field"] .dsp-chip {
  background: var(--doc-brand, #0f5e5a);
  color: #fff;
  border-radius: 0;
  font-family: var(--doc-font-mono, monospace);
}

/* ── Accent bar ──────────────────────────────────────────────────── */
.dsp-accent-bar { height: 0; }   /* hidden unless overridden */

#docStylePreview[data-doc-style="studio"] .dsp-accent-bar {
  height: 3px;
  background: var(--doc-brand, #0d7a5f);
}

/* Edition: no accent stripe — the hairline header rule does the work */

#docStylePreview[data-doc-style="field"] .dsp-accent-bar {
  height: 4px;
  background: repeating-linear-gradient(
    90deg,
    var(--doc-teal,      #0f5e5a)  0px, var(--doc-teal,      #0f5e5a)  6px,
    var(--doc-teal-deep, #0a4543)  6px, var(--doc-teal-deep, #0a4543) 12px
  );
}

/* ── Document body ───────────────────────────────────────────────── */
.dsp-body {
  background: var(--doc-paper, #fafaf9);
  padding: 12px 16px 14px;
  flex: 1;
}

.dsp-section-label {
  font-family: var(--doc-font-display, var(--font-sans));
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--doc-ink-mute, #9a9c9f);
  margin-bottom: 8px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--doc-hairline, #e4e1dc);
}

/* Edition: small-caps serif, different hairline */
#docStylePreview[data-doc-style="edition"] .dsp-section-label {
  font-family: var(--doc-font-body, serif);
  font-variant-caps: small-caps;
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: none;
  color: var(--doc-ink-soft, #43403a);
}

/* Field: bracketed mono label */
#docStylePreview[data-doc-style="field"] .dsp-section-label {
  font-family: var(--doc-font-mono, monospace);
  font-size: 8px;
  color: var(--doc-ink-soft, #4a4d47);
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
#docStylePreview[data-doc-style="field"] .dsp-section-label::before { content: "[ "; }
#docStylePreview[data-doc-style="field"] .dsp-section-label::after  { content: " ]"; }

/* ── Crew table ──────────────────────────────────────────────────── */
.dsp-crew-table {
  display: flex;
  flex-direction: column;
}

.dsp-crew-row {
  display: flex;
  align-items: center;
  padding: 5px 0;
  border-bottom: 1px solid var(--doc-hairline, #e4e1dc);
  color: var(--doc-ink, #3a3d44);
  font-family: var(--doc-font-body, var(--font-sans));
}

.dsp-crew-row.dsp-crew-head {
  font-family: var(--doc-font-display, var(--font-sans));
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--doc-ink-mute, #9a9c9f);
  padding-left: 9px;   /* visual indent to align with bar-indented rows */
}

.dsp-crew-row.dsp-crew-head .dsp-col-tag {
  /* header tag cell has no pill — just the label */
  background: none;
  color: var(--doc-ink-mute, #9a9c9f);
  padding: 0;
  font-size: 8px;
}

.dsp-col-name {
  flex: 0 0 36%;
  font-size: 11px;
  font-weight: 500;
  padding-right: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dsp-col-role {
  flex: 1 1 auto;
  font-size: 10px;
  color: var(--doc-ink-soft, #6b6e74);
  padding-right: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dsp-col-tag {
  flex: 0 0 auto;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: var(--doc-radius-pill, 999px);
  white-space: nowrap;
}

/* Status pill fills */
.dsp-tag-confirmed {
  background: var(--doc-brand-soft, #dcefe6);
  color: var(--doc-brand-deep, #0a5e48);
}
.dsp-tag-pending {
  background: var(--doc-amber-soft, #f7ead0);
  color: var(--doc-amber, #c8923a);
}

/* Edition: no radius on pills */
#docStylePreview[data-doc-style="edition"] .dsp-col-tag {
  border-radius: 0;
}
#docStylePreview[data-doc-style="edition"] .dsp-tag-confirmed {
  background: var(--doc-moss-soft, #e7ecda);
  color: var(--doc-moss, #3d4b3a);
}
#docStylePreview[data-doc-style="edition"] .dsp-tag-pending {
  background: var(--doc-amber-soft, #f3e2c4);
  color: var(--doc-amber, #a05e1c);
}

/* Field: mono font on status tags, no radius */
#docStylePreview[data-doc-style="field"] .dsp-col-tag {
  font-family: var(--doc-font-mono, monospace);
  border-radius: 0;
}
#docStylePreview[data-doc-style="field"] .dsp-tag-confirmed {
  background: var(--doc-sage-soft, #dee5d4);
  color: var(--doc-sage, #5e7a52);
}
#docStylePreview[data-doc-style="field"] .dsp-tag-pending {
  background: var(--doc-amber-soft, #f4e1cd);
  color: var(--doc-amber, #c4761a);
}

/* ── Left-edge accent bar ────────────────────────────────────────── */
.dsp-left-bar {
  display: block;
  width: 3px;
  align-self: stretch;   /* full row height */
  flex-shrink: 0;
  margin-right: 6px;
}

#docStylePreview[data-doc-style="studio"]  .dsp-left-bar { background: var(--doc-brand, #0d7a5f); }
#docStylePreview[data-doc-style="field"]   .dsp-left-bar { background: var(--doc-teal, #0f5e5a); }
#docStylePreview[data-doc-style="edition"] .dsp-left-bar { display: none; }

/* Edition: no left indent from bar */
#docStylePreview[data-doc-style="edition"] .dsp-crew-row { padding-left: 0; }

/* ── Footer chrome ───────────────────────────────────────────────── */
.dsp-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 16px;
  font-family: var(--doc-font-body, var(--font-sans));
  font-size: 9px;
}

#docStylePreview[data-doc-style="studio"] .dsp-footer {
  background: var(--doc-charcoal, #0e1014);
  color: rgba(255,255,255,0.45);
}

#docStylePreview[data-doc-style="field"] .dsp-footer {
  background: var(--doc-panel, #16191a);
  color: rgba(255,255,255,0.40);
}

#docStylePreview[data-doc-style="edition"] .dsp-footer {
  background: var(--doc-paper-deep, #ebe3d3);
  color: var(--doc-ink-mute, #7a766e);
  border-top: 1px solid var(--doc-hairline, #c8bfb0);
}

.dsp-footer-org { font-weight: 500; }

/* Crew onboarding — required-fields checklist (Settings → Onboarding) */
#onbForm .onb-check { display: flex; align-items: center; gap: 9px; padding: 7px 0; font-size: 13px; color: var(--text, #1a1a1a); cursor: pointer; }
/* Control painted by the canonical checkbox (editorial-chrome.css §5.7). */

/* Bank sub-group inside the onboarding required-fields checklist */
#onbForm .onb-subgroup { margin: 6px 0 2px; padding: 8px 0 4px 14px; border-left: 2px solid var(--border, #e0e0e0); }
#onbForm .onb-subgroup-label { font-size: 12px; color: var(--text-muted, #777); line-height: 1.45; margin-bottom: 4px; }

/* ── SEARCH-LED FILTER BAR (Crew DB) ──────────────────────────────
   One line: scope · search · Filters toggle. Category is the search's SCOPE
   and lives only here — repeating it in the drawer would give one control two
   homes. Refinements below are deliberately quieter than the bar: 22px pills,
   accent-tinted, against the bar's 34px. Hierarchy expressed in size, not
   just position. */
.crew-scope {
  display: flex; align-items: stretch;
  border: 1px solid var(--border);
  height: 34px; width: 100%;
  margin-bottom: 12px;
}
.crew-scope-cat {
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px; border: 0; border-right: 1px solid var(--border);
  background: transparent; cursor: pointer;
  font-family: var(--font-mono); font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--text);
  white-space: nowrap;
}
.crew-scope-cat .cv { color: var(--accent); }
.crew-scope-cat .cr { color: var(--text-3); }
.crew-scope-q { flex: 1; display: flex; align-items: center; gap: 9px; padding: 0 12px; min-width: 0; }
.crew-scope-q svg { color: var(--text-3); flex-shrink: 0; }
.crew-scope-q input {
  flex: 1; min-width: 0; height: 100%;
  border: 0; background: transparent; outline: none;
  font-family: var(--font-sans); font-size: 13px; color: var(--text);
}
.crew-scope-q input::placeholder { color: var(--text-3); }
.crew-scope-adv {
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px; border: 0; border-left: 1px solid var(--border);
  background: var(--surface); cursor: pointer; user-select: none;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted);
  white-space: nowrap;
}
.crew-scope-adv .cr { display: inline-block; transition: transform .15s ease; }
.crew-scope-adv.open .cr { transform: rotate(180deg); }
/* The count badge is the whole reason a closed drawer is safe: it says
   something is on without needing to be opened. */
.crew-scope-adv .ct {
  width: 16px; height: 16px; display: grid; place-items: center;
  background: var(--accent); color: var(--accent-ink); font-size: 9px;
}
.crew-drawer {
  border: 1px solid var(--border); border-top: none;
  background: var(--surface);
  padding: 9px 14px 11px;
  margin-top: -12px; margin-bottom: 12px;
}
.crew-drawer.hid { display: none; }
.crew-drawer .dr { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 5px 0; }
.crew-drawer .dr + .dr { border-top: 1px solid var(--border-soft); }
/* The label is a FIXED COLUMN so the pill rows align down the drawer — but it
   has to actually fit its longest word in both languages ("ASSIGNMENT",
   "ASIGNACIÓN", "DOCUMENTOS"). At 80px the text overflowed its box and ran
   under the first pill. Sized to the content and clipped rather than allowed
   to spill. */
.crew-drawer .dr > .crew-db-filter-label {
  flex: 0 0 104px; width: 104px;
  margin: 0; padding-right: 10px;
  font-size: 8.5px; letter-spacing: .14em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The pill margin that separates pills from each other must not double up
   against the label column, which already carries its own padding. */
.crew-drawer .dr > .crew-db-filter-pill:first-of-type { margin-left: 0; }
.crew-drawer .crew-db-filter-pill { height: 22px; padding: 0 8px; font-size: 9px; letter-spacing: .12em; }
/* Accent-tinted, NOT the ink invert used for scope — legible, but quieter
   than a scope change, which is the point of the hierarchy. */
/* Active refinement: accent FILL, not a tint. The tint read as "slightly
   different" rather than "on" once three rows were visible at once. Still
   quieter than a scope change — that inverts to ink — but no longer something
   you have to look for. */
.crew-drawer .crew-db-filter-pill.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
}
.crew-drawer .crew-db-filter-pill.is-active:hover { filter: brightness(1.08); }
/* The row also marks itself, so a glance down the labels shows which rows are
   filtered without reading every pill. */
.crew-drawer .dr:has(.crew-db-filter-pill.is-active:not([data-value="all"])) > .crew-db-filter-label {
  color: var(--accent);
}
.crew-drawer-clear {
  margin-left: auto;
  height: 22px; padding: 0 9px;
  border: 1px solid var(--border); background: transparent;
  color: var(--text-muted); cursor: pointer;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
}
.crew-drawer-clear:hover { color: var(--text); border-color: var(--text-muted); }
.crew-drawer-clear[hidden] { display: none; }
.crew-drawer-count {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-3);
}
/* Removable tokens for anything left on behind a CLOSED drawer. */
.crew-tokens { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 12px; }
.crew-tokens:empty { display: none; }
.crew-token {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 8px;
  border: 1px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
}
[data-theme="light"] .crew-token { color: #B04B00; }
.crew-token .x { opacity: .7; }
.crew-token:hover .x { opacity: 1; }

/* ── Required-documents editor rows ───────────────────────────────
   The repeatable-row pattern this panel did not previously have. Built on the
   .csv-import-row rhythm so it reads as the same family. */
/* Name and hint sit SIDE BY SIDE, not stacked: they are one document's two
   halves, and stacking made a 3-line row for what reads as a single record.
   minmax(0,…) on both text columns so a long value scrolls inside its input
   instead of widening the grid. Name gets the larger share — it is the field
   an operator scans for. */
.docreq-row {
  display: grid; grid-template-columns: 20px minmax(0, 1.35fr) minmax(0, 1fr) auto;
  gap: 12px; align-items: center;
  padding: 11px 12px;
  border: 1px solid var(--border); background: var(--card);
  margin-bottom: 6px;
}
.docreq-row:hover { border-color: var(--border-hover); }
/* Both inputs share one height now that they are peers — the old 30/26px
   split existed only to signal the hint was secondary, which the column
   position now says on its own. */
.docreq-row .crew-edit-input { height: 30px; }
.docreq-row .docreq-hint { font-size: 11.5px; }
/* Under ~720px the four-column row cannot hold two text fields plus the
   required toggle. Drop to the stacked shape rather than letting the inputs
   collapse to unusable widths. */
@media (max-width: 720px) {
  .docreq-row { grid-template-columns: 20px minmax(0, 1fr) auto; align-items: start; }
  .docreq-row .docreq-hint { grid-column: 2 / 3; }
  .docreq-row .docreq-actions { grid-row: 1 / 3; grid-column: 3 / 4; }
}
/* Drag affordance drawn rather than iconed — it reads as a grip at 10px where
   a glyph would need explaining. */
.docreq-drag {
  width: 10px; height: 14px; margin-top: 8px; cursor: grab;
  background: repeating-linear-gradient(to bottom, var(--border-hover) 0 1px, transparent 1px 4px);
}
.docreq-row[draggable="true"]:active { cursor: grabbing; }

/* ── GOOGLE DRIVE CONNECTION CARD ─────────────────────────────────────
   Style audit (2026-08-22): the card was built entirely from inline styles,
   including a hand-rolled copy of `.crew-db-status.complete`'s exact colour
   triplet. Chrome moved here; the status pill now carries the canonical
   modifier instead of re-declaring it (§3.3.0 rule 1). No colour, radius or
   type is redefined below — this block is layout and spacing only. */
.drive-card {
  border: 1px solid var(--border); background: var(--card);
  padding: 14px 16px;
}
/* Key/value rows. The label column is fixed so values align into a column an
   eye can run down; ch units keep that true when the labels are translated. */
.drive-kv { display: grid; grid-template-columns: 13ch 1fr; gap: 4px 14px; margin-top: 12px; }
.drive-kv dt {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-3); align-self: center;
}
.drive-kv dd { margin: 0; font-size: 12px; color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.drive-kv dd.is-missing { color: var(--attn); }

/* Notices. Same left-rule language as the rest of the panel; tone is the only
   difference between the "no folder yet" prompt and a real error. */
.drive-note { padding: 10px 12px; margin-top: 12px; font-size: 12px; line-height: 1.45; }
.drive-note--attn { border-left: 3px solid var(--attn);   background: color-mix(in srgb, var(--attn) 8%, transparent); color: var(--text-muted); }
.drive-note--bad  { border-left: 3px solid var(--danger); background: color-mix(in srgb, var(--danger) 8%, transparent); }
.drive-note__title { font-weight: 600; color: var(--text); margin-bottom: 4px; }
/* Google's error text, verbatim — the one detail that says whether to re-share
   a folder or re-authorize, so it gets mono and is allowed to wrap anywhere. */
.drive-note__reason { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); overflow-wrap: anywhere; }
.drive-note__calm { font-size: 11.5px; color: var(--text-3); margin-top: 6px; }

/* Actions. Destination actions sit LEFT, connection actions RIGHT: choosing a
   folder is routine and reconnect/disconnect are not, so they should not read
   as one undifferentiated row of four equal buttons. */
.drive-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; align-items: center; }
/* Child selector, not the bare class: the unified button rule above carries
   `button.btn-secondary { margin: 0 }` at specificity 0,1,1, which outranks a
   lone class no matter how late it is declared. 0,2,0 wins it honestly —
   an !important here would just hide the collision from the next reader. */
.drive-actions > .drive-actions__spacer { margin-left: auto; }
@media (max-width: 520px) {
  .drive-actions > .drive-actions__spacer { margin-left: 0; }
  .drive-actions > button { flex: 1 1 auto; }
}

/* ── CREW DB · ADD MODAL, TWO SHAPES ──────────────────────────────────
   Style Guide audit (2026-08-17): the category switch was a tool-local
   look-alike of .crew-db-filter-pill — same job (a two-state mono pill in the
   Crew DB), different radius, letter-spacing and active fill. Deleted; the
   markup now carries the canonical class and this block holds LAYOUT ONLY.
   §3.3.0 rule 1: never redeclare a canonical rule in a local stylesheet. */
.crew-add-type { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 18px; }
/* The canonical pill carries margin-left:8px for inline filter rows; inside a
   two-up grid that would break the columns. Layout override only — no colours,
   no radius, no type. */
.crew-add-type .crew-db-filter-pill { margin-left: 0; justify-content: center; }

/* A vendor contact is a small record inside the form, so it reads as a block
   rather than four more loose fields. Squared to match the Crew DB family
   (.crew-db-chip / .crew-db-filter-pill are all border-radius:0). */
.crew-add-contact {
  border: 1px solid var(--border-soft); border-radius: 0;
  padding: 12px 14px; margin-bottom: 10px; background: var(--input-bg);
}
.crew-add-contact-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
/* Primary is the canonical INVERTED active state (--text fill, --card ink) —
   the same treatment .crew-db-filter-pill.is-active uses, so a filled marker
   means one thing across the panel. */
.crew-add-contact-tag {
  display: inline-flex; align-items: center; height: 18px; padding: 0 7px;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  background: var(--text); color: var(--card);
  border: 1px solid var(--text); border-radius: 0;
}
.crew-add-contact-tag.sec {
  background: var(--input-bg); color: var(--text-muted); border-color: var(--border);
}
.crew-add-contact-x {
  margin-left: auto; background: none; border: 0; cursor: pointer;
  color: var(--text-3); font-size: 15px; line-height: 1; padding: 0 2px;
}
.crew-add-contact-x:hover { color: var(--text); }

/* Edition-only logo warning under the document-style picker. Uses the
   canonical .brand-preview-note type; the amber rule marks it as an
   action the operator must take, not a status. */
.edition-logo-notice {
  align-items: flex-start;
  border-left: 3px solid var(--chip-warn, #c4761a);
  padding: 8px 0 8px 10px;
  line-height: 1.55;
}
.edition-logo-notice strong { color: var(--text); font-weight: 700; }

/* Destination folder opens in Drive. Underlined on hover only — inside a
   key/value list a permanently underlined value competes with the labels. */
/* Path reads as context, not as the value — muted and allowed to wrap, with
   the linked folder name carrying the weight at the end of it. */
.drive-folder-path { color: var(--text-3); margin-right: 5px; overflow-wrap: anywhere; }
.drive-folder-link { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--border-hover); }
.drive-folder-link:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* Storage-policy toggle. A checkbox that changes what "delete" means deserves
   its explanation inline, not in a tooltip the operator will never open. */
.drive-purge { display: flex; gap: 10px; align-items: flex-start; margin-top: 14px;
  padding: 10px 12px; border: 1px solid var(--border); background: var(--input-bg); cursor: pointer; }
.drive-purge input { margin-top: 2px; flex-shrink: 0; }
.drive-purge > span { display: block; font-size: 12px; color: var(--text); line-height: 1.45; }
.drive-purge__hint { display: block; margin-top: 3px; font-size: 11.5px; color: var(--text-3); }

/* ── Sidebar attention badge ────────────────────────────────────────────
   Same idiom as .crew-scope-adv .ct — a small squared count that says
   something needs attention without opening anything. Used by the Security
   item when a support-access request is pending.

   Deliberately quiet: this is the PERSISTENT signal. It sits there until the
   request is answered, where the interrupt band is loud and temporary. A badge
   nobody can miss is just a band that fits in the sidebar. */
.nav-item { position: relative; }
.nav-item .nav-badge {
  min-width: 16px; height: 16px; padding: 0 4px;
  display: grid; place-items: center;
  margin-left: auto;
  /* Fixed red, deliberately NOT var(--accent): the accent is the org's own
     brand colour, so on a green- or blue-accented org this badge would read as
     decoration rather than "something needs you". An attention signal has to
     mean the same thing in every workspace.
     Not var(--cl-err) either — its dark value (#D04A3F) is 4.44:1 against
     white, and this is 9px bold, so it has to clear 4.5:1 rather than the
     large-text 3:1. #A8362C is 6.50:1, #C0392B is 5.44:1. */
  background: #A8362C; color: #FFFFFF;
  font-family: var(--font-mono, ui-monospace, Menlo, monospace);
  font-size: 9px; font-weight: 700; letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}
.nav-item .nav-badge[hidden] { display: none; }

/* Dark canvas: the same red sits muddy against near-black, so lift it —
   #C0392B is 5.44:1 with white, still clear of AA. */
[data-theme="dark"] .nav-item .nav-badge { background: #C0392B; }
