/*
 * guide-x-adapter.css
 *
 * Bridge sheet that re-styles the legacy class names emitted by the
 * working app's JS (.message, .welcome, .source-item, .gf-upload-rect,
 * .gf-chat-pill, .doc-item, .gf-thinking, …) using the Guide-x token
 * vocabulary (var(--ink), --flame, --surface, --ease, …).
 *
 * Loaded AFTER guide-x.css. Adds zero new DOM classes — the JS keeps
 * writing exactly what it always wrote; this file makes those classes
 * look right under the Guide-x design.
 */

/* ────────────────────────────────────────────────────────────────── *
 *  legacy token aliases — the bundled modal / plan-builder / pdf-prep
 *  / chat-plan-pane / citations stylesheets reference --ink-2, --bg-2,
 *  --blue, --flame-soft, --shadow-*, --font-size-*, --z-popover, etc.
 *  We map those to Guide-x equivalents so every old surface composes
 *  in the new palette without touching its rules.
 * ────────────────────────────────────────────────────────────────── */
:root {
  --ink-2: var(--ink-soft);
  --ink-3: var(--muted);
  --bg-2: var(--surface);
  --hover-2: var(--hover);
  --paper-2: var(--paper);
  /* Soft cool blue for selections, page indicators, and other neutral
     "selection vibe" affordances. Was aliased to --flame which made every
     crop overlay and page-pill orange — too brand-y for utilitarian UI. */
  --blue: oklch(58% 0.18 255);
  --blue-soft: rgba(91, 127, 255, 0.14);
  --flame-soft: rgba(99, 199, 106, .10);
  --white: #fff;

  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --font-size-xs: 10.5px;
  --font-size-sm: 12px;
  --font-size-md: 13.5px;
  --font-size-lg: 16px;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  --shadow-1: 0 1px 2px rgba(20,14,4,.06);
  --shadow-2: 0 4px 12px rgba(40,30,14,.10);
  --shadow-3: 0 12px 32px rgba(40,30,14,.16);
  --shadow-soft: 0 1px 2px rgba(20,14,4,.04), 0 0 0 1px rgba(20,14,4,.02);
  --shadow-lift: 0 4px 18px rgba(40,30,14,.10);

  --z-modal: 1000;
  --z-popover: 1200;

  --tap-min: 36px;
  --pf-picker-scale: 1;
}

/* ────────────────────────────────────────────────────────────────── *
 *  base
 * ────────────────────────────────────────────────────────────────── */
html, body { height: 100%; margin: 0; overflow: hidden; }
body {
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 14px;
  line-height: 1.45;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
input, textarea { font: inherit; color: inherit; }

/* Kill the legacy decorative aurora */
#gfBottomAurora { display: none !important; }

/* visually-hidden utility used by legacy label-for inputs */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ────────────────────────────────────────────────────────────────── *
 *  sidebar — legacy classes used by the JS
 * ────────────────────────────────────────────────────────────────── */
/* Container .sidebar already styled by guide-x.css */

/* Legacy sidebar collapse */
.gf-sidebar-collapsed .sidebar { display: none; }
.gf-sidebar-collapsed .app { --side-w: 0px; }

.sidebar-section { padding: 0; }
.sidebar-label {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 8px 8px;
  font-size: 11px; letter-spacing: .12em; font-weight: 600;
  color: var(--muted); text-transform: uppercase;
}
hr.sidebar-divider { display: none; }

/* Source rows — JS toggles .source-checkbox.checked */
.source-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--r);
  cursor: pointer; transition: background 180ms var(--ease);
  position: relative;
}
.source-item:hover { background: var(--hover); }
.source-item.muted { opacity: .55; }
.source-item.muted .source-name { color: var(--muted); }

.source-checkbox {
  width: 16px; height: 16px; border-radius: 4px;
  border: 1.5px solid var(--border-strong); background: var(--surface);
  flex: none; display: grid; place-items: center;
  transition: background 160ms var(--ease), border-color 160ms var(--ease), transform 160ms var(--ease);
  position: relative;
}
.source-checkbox::after {
  content: ""; width: 8px; height: 4px;
  border-left: 1.6px solid #fff; border-bottom: 1.6px solid #fff;
  transform: rotate(-45deg) translate(0, -1px) scale(.5);
  opacity: 0;
  transition: opacity 160ms var(--ease), transform 200ms var(--ease);
}
.source-checkbox.checked { background: var(--ink); border-color: var(--ink); }
.source-checkbox.checked::after { opacity: 1; transform: rotate(-45deg) translate(0, -1px) scale(1); }
.source-item:active .source-checkbox { transform: scale(.92); }

.source-name {
  flex: 1; font-size: 13px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; letter-spacing: -.005em;
}
.source-badge {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  padding: 2px 6px; border-radius: 4px;
  color: var(--muted-2); background: var(--hover);
  border: 1px solid var(--border);
}
/* Res/Comm badges — quiet ash at rest; ticking the row animates them into
   the Project-brief type chip look (.gf-brief-type-chip): brand green on
   pale green, mono caps, no border. Owner call 2026-07-31. */
.gf-badge-resi, .gf-badge-comm,
.ribbon.resi, .ribbon.comm {
  font-size: 10px; letter-spacing: .1em; font-weight: 600;
  padding: 3px 7px; border-radius: 4px;
  color: var(--muted-2) !important;
  background: var(--hover) !important;
  border: 0 !important;
  transition: color .18s ease, background-color .18s ease;
}
/* Ticked — the green chip. Triggered by .source-checkbox.checked inside the
   row (that's what toggleSource actually toggles). */
.source-item:has(.source-checkbox.checked) .gf-badge-resi,
.source-item:has(.source-checkbox.checked) .gf-badge-comm,
.src-item:has(.source-checkbox.checked) .ribbon.resi,
.src-item:has(.source-checkbox.checked) .ribbon.comm {
  color: var(--flame) !important;
  background: var(--flame-soft) !important;
}
/* Muted rows (the other family is locked out) stay quiet grey. */
.source-item.muted .source-badge,
.src-item.muted .ribbon.resi,
.src-item.muted .ribbon.comm { color: var(--muted-2) !important; background: rgba(122,111,94,.06) !important; }

/* Custodial-only badge (FSDG) — same ash→green-chip behaviour as res/comm. */
.gf-badge-custodial {
  font-size: 10px; letter-spacing: .1em; font-weight: 600;
  padding: 3px 7px; border-radius: 4px;
  color: var(--muted-2) !important; background: var(--hover) !important;
  border: 0 !important;
  transition: color .18s ease, background-color .18s ease;
}
.source-item:has(.source-checkbox.checked) .gf-badge-custodial,
.src-item:has(.source-checkbox.checked) .gf-badge-custodial {
  color: var(--flame) !important; background: var(--flame-soft) !important;
}

/* Slight section divider between the guidance list and Project Context */
.src-section-sep {
  height: 1px; background: var(--border);
  margin: 12px 8px;
}

/* Subtle disclaimer under the chat composer */
.gf-chat-disclaimer {
  margin: 10px 0 0; text-align: center;
  font-size: 10px; line-height: 1.2; font-weight: 400;
  color: var(--muted-2); opacity: .7; letter-spacing: .01em;
  user-select: none; pointer-events: none;
}

/* "Beta" tag next to the 2D Layout section header */
.gf-beta-tag {
  display: inline-block; margin-left: 6px; vertical-align: middle;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: .06em; text-transform: none;
  padding: 2px 6px; border-radius: 4px;
  color: var(--muted-2); background: var(--hover);
  border: 1px solid var(--border);
}

/* BS 9999 row: calculator icon hugs the standard name; badge to far right */
.src-item[data-standard="BS9999"] .source-name { flex: 0 1 auto; }
.src-item[data-standard="BS9999"] .source-badge { margin-left: auto; }

/* ── BS 9999 calculator launch button (on the guidance row) ── */
.gx-calc-btn {
  flex: none; display: inline-grid; place-items: center;
  width: 24px; height: 24px; margin-left: 2px; padding: 0;
  background: transparent; border: 0; border-radius: 6px;
  color: var(--muted-2); cursor: pointer;
  opacity: .35; transition: color 160ms var(--ease),
    background 160ms var(--ease), opacity 160ms var(--ease);
}
.gx-calc-btn svg { width: 15px; height: 15px; }
.gx-calc-btn[disabled] { opacity: .3; cursor: not-allowed; color: var(--muted-2); }
.gx-calc-btn:not([disabled]) { opacity: 1; color: var(--muted); }
.gx-calc-btn:not([disabled]):hover {
  color: var(--flame); background: rgba(99,199,106,.10);
}
.gx-calc-btn:not([disabled]):active { transform: scale(.92); }

/* ── BS 9999 calculator window ── */
.gx-calc-backdrop.open { display: flex; align-items: center; justify-content: center; }
.gx-calc-window {
  display: flex; flex-direction: column;
  width: min(1180px, 94vw); height: min(900px, 92vh);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--r-lg, 14px); box-shadow: var(--shadow-3);
  overflow: hidden;
}
.gx-calc-bar {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  height: 48px; padding: 0 14px 0 18px;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.gx-calc-bar-title {
  font-family: var(--font-display); font-size: 13px; font-weight: 700;
  color: var(--ink); letter-spacing: -.01em;
}
.gx-calc-bar-mark {
  font-family: var(--font-mono); font-weight: 600; color: var(--flame);
  margin-right: 6px;
}
.gx-calc-close {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  background: transparent; border: 0; border-radius: 7px;
  color: var(--muted); cursor: pointer;
  transition: color 160ms var(--ease), background 160ms var(--ease);
}
.gx-calc-close:hover { color: var(--flame); background: var(--hover); }
.gx-calc-body { flex: 1; min-height: 0; background: var(--bg); }
.gx-calc-body iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ── Licensed-copy gate modal ── */
.gf-gate-drop {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 22px 16px; text-align: center; cursor: pointer;
  border: 1.5px dashed var(--border-strong); border-radius: var(--r-md, 10px);
  background: var(--surface);
  transition: border-color 160ms var(--ease), background 160ms var(--ease);
}
.gf-gate-drop:hover,
.gf-gate-drop.dragover { border-color: var(--ink-soft); background: var(--hover); }
.gf-gate-drop.has-file { border-style: solid; border-color: var(--ink-soft); }
.gf-gate-drop-ico {
  width: 30px; height: 30px; display: grid; place-items: center;
  color: var(--muted);
}
.gf-gate-drop-ico svg { width: 22px; height: 22px; }
.gf-gate-drop-text { font-size: 13px; color: var(--muted); }
.gf-gate-add {
  margin-top: 2px; padding: 6px 14px; border-radius: 999px;
  background: var(--bg); border: 1px solid var(--border-strong);
  font-size: 12px; font-weight: 600; color: var(--ink); cursor: pointer;
  transition: background 160ms var(--ease), border-color 160ms var(--ease);
}
.gf-gate-add:hover { background: var(--hover); border-color: var(--ink-soft); }
.gf-gate-filename {
  margin-top: 4px; max-width: 100%; font-family: var(--font-mono);
  font-size: 11.5px; color: var(--ink); word-break: break-all;
}
/* Legal attribution notice (FSDG) — shown above the acknowledgement. */
.gf-gate-notice {
  margin: 12px 0 2px; padding: 9px 11px; border-radius: 8px;
  background: var(--hover); border: 1px solid var(--border);
  font-size: 11.5px; line-height: 1.5; color: var(--muted);
}
.gf-gate-confirm {
  display: flex; align-items: flex-start; gap: 9px; cursor: pointer;
  font-size: 12px; line-height: 1.5; color: var(--muted);
}
.gf-gate-confirm input[type="checkbox"] {
  flex: none; margin-top: 1px; width: 15px; height: 15px;
  accent-color: var(--ink); cursor: pointer;
}

/* ── Ownership-gate check strip (js/standard-verify.js) ── */
.gf-gate-check { display: flex; flex-direction: column; gap: 8px; margin: 2px 0 4px; }
.gf-gate-check-bar {
  height: 5px; border-radius: 999px; background: var(--hover); overflow: hidden;
}
.gf-gate-check-fill {
  height: 100%; width: 0; border-radius: 999px; background: var(--flame);
  transition: width 200ms var(--ease);
}
.gf-gate-check[data-state="error"] .gf-gate-check-fill { background: var(--red); }
.gf-gate-check[data-state="pass"] .gf-gate-check-fill { background: var(--green); }
.gf-gate-check[data-state="partial"] .gf-gate-check-fill { background: var(--muted-2); }
.gf-gate-check-msg { font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); }
.gf-gate-check[data-state="error"] .gf-gate-check-msg { color: var(--red); }
.gf-gate-check[data-state="pass"] .gf-gate-check-msg { color: var(--green-deep); }
.gf-gate-check-cancel {
  align-self: flex-start; font-size: 12px; color: var(--muted);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 3px 10px; background: var(--surface); cursor: pointer;
}
.gf-gate-check-cancel:hover { background: var(--hover); color: var(--ink); }
.gf-gate-check[data-state="locked"] .gf-gate-check-fill { background: var(--muted-2); }
/* Password prompt for ordinary encrypted PDFs (never for proprietary DRM —
   there is no password to ask for there). */
.gf-gate-pw { display: flex; gap: 8px; align-items: center; }
.gf-gate-pw-input {
  flex: 1; min-width: 0; padding: 6px 10px; font-size: 13px;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
}
.gf-gate-pw-input:focus { outline: none; border-color: var(--flame); box-shadow: 0 0 0 3px var(--flame-tint); }
.gf-gate-pw-btn {
  flex: none; padding: 6px 14px; font-size: 12.5px; font-weight: 600;
  border-radius: var(--r-sm); border: 1px solid var(--ink);
  background: var(--ink); color: #fff; cursor: pointer;
}
.gf-gate-pw-btn:hover { background: var(--green); border-color: var(--green); }

/* ── "How we handle your standards" link + panel ── */
.gf-gate-terms-link {
  align-self: flex-start; margin-top: -2px;
  font-size: 12px; color: var(--muted); text-decoration: underline;
  text-underline-offset: 2px; background: none; border: 0; padding: 0;
  cursor: pointer;
}
.gf-gate-terms-link:hover { color: var(--flame); }
/* Above the licensed-copy modal, which stays open underneath. */
.gf-terms-backdrop { z-index: 12000; }
.gf-terms-box { max-width: 620px; }
.gf-terms-body {
  max-height: 58vh; overflow-y: auto; padding-right: 6px;
  font-size: 13px; line-height: 1.6; color: var(--ink-soft);
}
.gf-terms-body h4 {
  margin: 16px 0 4px; font-size: 12px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink);
}
.gf-terms-body h4:first-of-type { margin-top: 8px; }
.gf-terms-body p { margin: 0 0 4px; }
.gf-terms-placeholder {
  padding: 6px 10px; border-radius: var(--r-sm);
  background: var(--flame-soft); color: var(--flame-deep);
  font-size: 12px; font-weight: 600;
}

/* ── Guidance list — single bounded scroll area (selectable + coming-soon) ── */
.src-scroll {
  max-height: 252px; overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain; padding-right: 2px;
}
.src-scroll::-webkit-scrollbar { width: 6px; }
.src-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }
.src-soon-item .source-name { font-weight: 500; color: var(--muted); }
.src-soon-item:hover .source-name { color: var(--ink); }
/* Visual-only checkbox — present for alignment, never ticks. */
.src-soon-item .source-checkbox { opacity: .5; pointer-events: none; }
.src-soon-item:active .source-checkbox { transform: none; }
.gf-badge-soon {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  padding: 2px 6px; border-radius: 4px; flex: none;
  color: var(--muted-2); background: var(--hover);
  border: 1px solid var(--border);
}

/* Coming-soon modal — full title + notice */
.soon-std-code {
  font-family: var(--font-mono); font-size: 13px; font-weight: 600;
  color: var(--flame); letter-spacing: .01em; margin: 2px 0 6px;
}
.soon-std-desc {
  font-size: 13.5px; line-height: 1.55; color: var(--ink);
  margin-bottom: 14px;
}

/* The decorative 'breathe' pulse from the old skin — silenced */
.gf-breathe { animation: none !important; }

/* Upload tiles (button.gf-upload-rect) */
.gf-upload-rect {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--r-lg);
  border: 1px dashed var(--border-strong); background: var(--surface);
  margin: 4px 0; cursor: pointer;
  transition: border-color 180ms var(--ease), background 180ms var(--ease), transform 120ms var(--ease);
  width: 100%; text-align: left; position: relative;
}
.gf-upload-rect:hover { border-color: var(--ink-soft); background: var(--hover); }
.gf-upload-rect:active { transform: scale(.99); }
.gf-upload-rect-icon {
  width: 28px; height: 28px; border-radius: var(--r);
  background: var(--bg); border: 1px solid var(--border);
  display: grid; place-items: center; color: var(--ink-soft); flex: none;
}
.gf-upload-rect-icon svg, .gf-upload-rect-icon i { width: 14px; height: 14px; }
.gf-upload-rect-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.gf-upload-rect-text strong { font-size: 12.5px; font-weight: 600; color: var(--ink); letter-spacing: -.005em; }
.gf-upload-rect-text small {
  font-size: 11px; color: var(--muted); margin-top: 1px;
  font-family: var(--font-mono); letter-spacing: .02em;
}

/* Project Context button (#contextBtn) — same shape as upload tile, solid border */
.gf-context-btn {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--r-lg);
  border: 1px solid var(--border); background: var(--surface);
  margin: 4px 0; cursor: pointer;
  transition: border-color 180ms var(--ease), background 180ms var(--ease);
  width: 100%; text-align: left;
  font-size: 12.5px; font-weight: 600; color: var(--ink); letter-spacing: -.005em;
}
.gf-context-btn:hover { border-color: var(--ink-soft); background: var(--hover); }
.gf-context-btn i { width: 14px; height: 14px; color: var(--ink-soft); flex: none; }
.gf-context-btn.complete { border-color: var(--green); }
/* The label is a single line now (no subtitle). The .meta column is stretched
   (flex:1), so centre its content vertically rather than letting the label
   pin to the top of the button. */
.gf-context-btn .meta { justify-content: center; }

/* Doc list rows (plans + docs) */
.doc-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--r);
  cursor: pointer; transition: background 180ms var(--ease);
  margin: 2px 0; min-width: 0;
}
.doc-item:hover { background: var(--hover); }
.doc-item.active { background: var(--hover); }
.doc-item .doc-icon {
  width: 22px; height: 22px; display: grid; place-items: center;
  color: var(--muted); flex: none;
}
.doc-item .doc-icon svg, .doc-item .doc-icon i { width: 14px; height: 14px; }
/* The name wrapper is the shrinkable flex child — min-width:0 lets it fall
   below the intrinsic filename width so .doc-name can ellipsis and the
   edit/delete buttons (flex:none) always stay visible inside the row. */
.doc-item .doc-info { flex: 1; min-width: 0; overflow: hidden; }
.doc-item .doc-name {
  font-size: 12.5px; font-weight: 500; color: var(--ink); letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.doc-item .doc-size, .doc-item .doc-meta {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--muted-2); letter-spacing: .02em;
  flex: none;
}
.doc-item .doc-delete, .doc-item .doc-edit {
  width: 22px; height: 22px; border-radius: 5px;
  display: grid; place-items: center;
  color: var(--muted-2); background: transparent; flex: none;
  opacity: 0; transform: scale(.85);
  transition: opacity 160ms var(--ease), transform 160ms var(--ease),
              color 160ms var(--ease), background 160ms var(--ease);
}
.doc-item:hover .doc-delete, .doc-item:hover .doc-edit { opacity: 1; transform: scale(1); }
.doc-item .doc-delete:hover { background: var(--red-soft); color: var(--red); }
.doc-item .doc-edit:hover { background: var(--hover); color: var(--ink); }
.doc-item .doc-delete svg, .doc-item .doc-delete i,
.doc-item .doc-edit svg, .doc-item .doc-edit i { width: 11px; height: 11px; }

.list-empty {
  padding: 8px 10px; font-size: 11.5px; color: var(--muted-2);
  font-style: italic; letter-spacing: .005em;
}

/* ── Knowledge hub (was Documents; owner, 5 Oct 2026) ──────────────────
 * Six sections, always listed: a row with a count and a +, opening onto its
 * files (rows are the ordinary .doc-item). Built by gxHubReset in
 * js/pages/workspace/documents.js. A closed section only hides its files:
 * they stay in #docList, and the AI reads every one of them. */
.gx-hub-section { margin: 1px 0; }
.gx-hub-row {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 8px; border-radius: var(--r);
  cursor: pointer; user-select: none; min-width: 0;
  font-size: 12.5px; font-weight: 500; color: var(--ink); letter-spacing: -.005em;
  transition: background 180ms var(--ease);
}
.gx-hub-row:hover { background: var(--hover); }
.gx-hub-section.is-open > .gx-hub-row { background: var(--sidebar-soft); }
.gx-hub-chev {
  width: 14px; height: 14px; display: grid; place-items: center;
  color: var(--muted); flex: none; transition: transform 160ms var(--ease);
}
.gx-hub-chev svg { width: 12px; height: 12px; }
.gx-hub-section.is-open .gx-hub-chev { transform: rotate(90deg); }
.gx-hub-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gx-hub-count {
  font-family: var(--font-mono); font-size: 11px; font-weight: 400;
  color: var(--muted-2); letter-spacing: 0; flex: none;
}
.gx-hub-add {
  width: 22px; height: 22px; border-radius: 5px; flex: none;
  display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--border); color: var(--ink-soft);
  transition: border-color 160ms var(--ease), color 160ms var(--ease), background 160ms var(--ease);
}
.gx-hub-add:hover { border-color: var(--ink-soft); color: var(--ink); }
.gx-hub-add svg { width: 12px; height: 12px; }
.gx-hub-body { display: none; padding: 2px 0 6px 6px; }
/* "Sent 12 Mar 2026" on one line, cut like the name if there is no room. */
.gx-hub-files .doc-item .doc-meta { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gx-hub-section.is-open > .gx-hub-body { display: block; }
.gx-hub-hint { margin: 4px 0 2px 8px; font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.gx-hub-section:not(.is-empty) .gx-hub-hint,
.gx-hub-section:not(.is-empty) .gx-hub-empty { display: none; }
/* While a file uploads, nothing else can start one (the old single Upload
   button hid itself for the same reason). Dimmed, not click-through: a click
   on a + must not fall onto its row; uploadDoc says to wait instead. */
#docList.is-uploading .gx-hub-add,
#docList.is-uploading .gx-hub-empty { opacity: .45; cursor: progress; }
/* Files dragged from the computer over a section (_gxHubWireDrop): a green
   dashed outline round the whole section, and a line naming where the files
   will go. The note takes no room until a drag is over the section. */
.gx-hub-section { position: relative; border-radius: var(--r); }
.gx-hub-section.is-drop-target {
  background: var(--flame-tint);
  outline: 1.5px dashed var(--green); outline-offset: -1.5px;
}
.gx-hub-section.is-drop-target > .gx-hub-row { background: transparent; }
.gx-hub-drop-note { display: none; }
.gx-hub-section.is-drop-target > .gx-hub-drop-note {
  display: block; padding: 4px 8px 8px 30px;
  font-size: 11.5px; font-weight: 600; color: var(--green);
  pointer-events: none;
}
#docList.is-uploading .gx-hub-section.is-drop-target { background: var(--sidebar-soft); outline-color: var(--border-strong); }
#docList.is-uploading .gx-hub-section.is-drop-target > .gx-hub-drop-note { color: var(--muted); }
/* The move button takes no room until the row is pointed at or tabbed into,
   so a file's name is as wide as it was before the hub. */
.doc-item .doc-move {
  width: 22px; height: 22px; border-radius: 5px;
  display: none; place-items: center;
  color: var(--muted-2); background: transparent; flex: none;
  transition: color 160ms var(--ease), background 160ms var(--ease);
}
.doc-item:hover .doc-move, .doc-item:focus-within .doc-move,
.doc-item.is-menu-open .doc-move { display: grid; }
.doc-item .doc-move:hover { background: var(--hover); color: var(--ink); }
/* A file in the hub opens in the Guidex Reader when clicked. */
.doc-item.is-openable { cursor: pointer; }
.doc-item.is-openable .doc-info:focus-visible {
  outline: 2px solid var(--ink-soft); outline-offset: 2px; border-radius: 4px;
}
.doc-item .doc-move svg { width: 12px; height: 12px; }
.gx-hub-move-menu {
  position: fixed; z-index: 3000; min-width: 196px; padding: 4px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lift);
}
.gx-hub-move-title {
  padding: 6px 8px 4px; font-size: 10.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.gx-hub-move-menu button {
  display: block; width: 100%; text-align: left;
  padding: 7px 8px; border-radius: var(--r-sm);
  font-size: 12.5px; color: var(--ink);
}
.gx-hub-move-menu button:hover, .gx-hub-move-menu button:focus-visible { background: var(--hover); outline: none; }

/* User pill at bottom of sidebar */
.gf-user {
  border-top: 1px solid var(--border); padding: 12px 14px;
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  transition: background 180ms var(--ease);
  width: 100%; background: transparent;
}
.gf-user:hover { background: var(--sidebar-soft); }
.gf-avatar {
  width: 32px; height: 32px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 500; font-size: 12px; letter-spacing: .5px;
  flex: none;
}
.gf-user-info { flex: 1; min-width: 0; text-align: left; }
.gf-user-name { font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: -.005em; }
.gf-user-caret { color: var(--muted-2); display: inline-flex; }
.gf-user-caret svg, .gf-user-caret i { width: 14px; height: 14px; }

/* ────────────────────────────────────────────────────────────────── *
 *  topbar
 * ────────────────────────────────────────────────────────────────── */
.gf-sidebar-toggle {
  width: 30px; height: 30px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--surface);
  color: var(--ink-soft); display: grid; place-items: center;
  transition: background 180ms var(--ease), color 180ms var(--ease);
  flex: none; cursor: pointer;
}
.gf-sidebar-toggle:hover { background: var(--hover); color: var(--ink); }
.gf-sidebar-toggle .gf-toggle-bar {
  display: block; width: 14px; height: 1.5px; background: currentColor;
  margin: 1.5px 0;
}

.project-selector {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: var(--r);
  background: transparent; cursor: pointer;
  color: var(--ink); font-size: 13.5px; font-weight: 600; letter-spacing: -.005em;
  transition: background 180ms var(--ease);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.project-selector:hover { background: var(--hover); }
.project-selector .project-dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: var(--flame); box-shadow: 0 0 0 3px rgba(99,199,106,.16);
  flex: none;
}

.btn-new-project, .btn-initial-assess {
  position: relative; display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: var(--r);
  background: var(--surface); border: 1px solid var(--border);
  color: var(--ink); font-size: 13px; font-weight: 600; letter-spacing: -.005em;
  transition: background 200ms var(--ease), border-color 200ms var(--ease),
              color 200ms var(--ease), transform 120ms var(--ease);
  flex: none; white-space: nowrap; cursor: pointer;
}
.btn-new-project:hover, .btn-initial-assess:hover {
  background: var(--hover); border-color: var(--border-strong);
}
.btn-new-project:active, .btn-initial-assess:active { transform: translateY(1px); }
.btn-new-project i, .btn-initial-assess i { width: 13px; height: 13px; }

.btn-initial-assess {
  background: var(--ink); color: #fff; border-color: var(--ink);
}
.btn-initial-assess:hover { background: var(--green); border-color: var(--green); box-shadow: 0 1px 2px rgba(20,14,4,.08); }
.btn-initial-assess:active { background: var(--green-deep); }

/* Project dropdown panel — anchored to the topbar chevron via JS (top/right set inline). */
.project-panel {
  position: fixed; top: 60px; right: 24px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: 0 12px 32px rgba(40,30,14,.14);
  padding: 6px; display: none; min-width: 240px; z-index: 1300;
  max-height: 60vh; overflow-y: auto;
  transform-origin: top right;
  animation: projPanelIn 180ms var(--ease) both;
}
.project-panel.open { display: block; }
@keyframes projPanelIn {
  from { opacity: 0; transform: translateY(-4px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Topbar project-switch chevron — sits inside the status pill, next to the project name */
.topbar-switch {
  display: inline-grid; place-items: center;
  width: 18px; height: 18px;
  margin-left: 4px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 160ms var(--ease), border-color 160ms var(--ease), color 160ms var(--ease), transform 160ms var(--ease);
}
.topbar-switch svg { width: 10px; height: 10px; }
.topbar-switch:hover { background: var(--hover); border-color: var(--ink-soft); color: var(--ink); }
.topbar-switch:active { transform: translateY(1px); }

.project-panel.open { display: block; }
.project-panel .panel-title {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
  padding: 10px 12px 6px;
}
.proj-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: 6px;
  cursor: pointer; transition: background 160ms var(--ease);
  font-size: 12.5px; color: var(--ink);
}
.proj-item:hover { background: var(--hover); }
.proj-item.active { background: var(--hover); font-weight: 600; }
.proj-dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: var(--muted-2); flex: none;
}
.proj-item.active .proj-dot { background: var(--flame); box-shadow: 0 0 0 3px rgba(99,199,106,.16); }
.proj-name {
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.proj-rename, .proj-delete {
  width: 22px; height: 22px; border-radius: 5px;
  display: grid; place-items: center;
  color: var(--muted-2); background: transparent; flex: none;
  opacity: 0; transition: opacity 160ms var(--ease), color 160ms var(--ease), background 160ms var(--ease);
}
.proj-item:hover .proj-rename, .proj-item:hover .proj-delete { opacity: 1; }
.proj-rename:hover { background: var(--hover); color: var(--ink); }
.proj-delete:hover { background: var(--red-soft); color: var(--red); }
.proj-rename svg, .proj-rename i, .proj-delete svg, .proj-delete i { width: 11px; height: 11px; }
.new-proj-row {
  padding: 10px 11px; border-radius: 6px;
  cursor: pointer; font-size: 12.5px; color: var(--ink); font-weight: 500;
  border-top: 1px solid var(--border); margin-top: 4px;
  transition: background 160ms var(--ease);
}
.new-proj-row:hover { background: var(--hover); }

/* ────────────────────────────────────────────────────────────────── *
 *  chat area
 * ────────────────────────────────────────────────────────────────── */
.chat-area {
  grid-column: 2; grid-row: 2;
  display: flex; flex-direction: column;
  position: relative; background: var(--bg); min-width: 0; overflow: hidden;
}

.chat-messages {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 64px 32px 12px 80px !important;
  display: flex; flex-direction: column; gap: 24px;
  scroll-behavior: smooth;
  scroll-padding-top: 64px;
}
@media (max-width: 1100px) {
  .chat-messages { padding-left: 96px !important; }
}
.app[data-pdf="open"] .chat-messages,
.app[data-spatial="open"] .chat-messages { padding-left: 64px !important; }
/* First child inside the scroll container also gets a guaranteed top margin —
   defends against any future flex collapse / negative-margin behaviour. */
.chat-messages > .message:first-child,
.chat-messages > .gf-thinking:first-child,
.chat-messages > .gf-streaming:first-child { margin-top: 8px; }
.chat-messages::-webkit-scrollbar { width: 6px; }
.chat-messages::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }
.chat-messages > .welcome { flex: none; }

/* Welcome block — bridged to Guide-x .start-block visual */
.welcome {
  padding-top: 0;
  transition: opacity 320ms var(--ease), transform 320ms var(--ease);
  transform-origin: top;
}
.welcome.hidden {
  opacity: 0; transform: translateY(-12px);
  pointer-events: none; height: 0; margin: 0; overflow: hidden;
}
.welcome-flame { display: none; }
.welcome-title {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(36px, 4.4vw, 56px); line-height: 1.06; letter-spacing: -1.5px;
  color: var(--ink); margin: 0 0 18px; text-wrap: balance;
}
.welcome-title .soft { color: var(--muted-2); font-weight: 400; }
.welcome-subtitle {
  font-size: 15.5px; line-height: 1.55; color: var(--ink-soft);
  max-width: 640px; margin: 0 0 36px;
}
.welcome-subtitle br { display: none; }

/* Suggestions */
.suggestions {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 4px;
}
.suggestions:empty { display: none; }
.suggestions > * {
  display: flex; align-items: flex-start; justify-content: flex-start; gap: 6px;
  padding: 11px 14px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r);
  cursor: pointer; text-align: left;
  transition: border-color 180ms var(--ease), background 180ms var(--ease);
  min-width: 0;
  font-size: 12.5px; font-weight: 500; color: var(--ink); letter-spacing: -.005em;
  white-space: normal; overflow-wrap: anywhere; line-height: 1.35;
}
.suggestions .suggestion-arrow { flex: none; }
.suggestions > *:hover { background: var(--hover); border-color: var(--border-strong); }
@media (max-width: 1100px) {
  .suggestions { grid-template-columns: repeat(2, 1fr); }
}

/* fadeUp entrance from Guide-x */
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.welcome, .welcome-title, .welcome-subtitle, .suggestions { animation: fadeUp 600ms var(--ease) both; }
.welcome-title { animation-delay: 90ms; }
.welcome-subtitle { animation-delay: 180ms; }
.suggestions { animation-delay: 260ms; }

/* ────────────────────────────────────────────────────────────────── *
 *  message bubbles — JS emits .message.user / .message.assistant
 *
 *  The JS sets .textContent or .innerHTML directly on .message.{role}
 *  (no inner .bubble wrapper). So we treat the message div itself as
 *  the bubble/article, not as a flex row. Block-level markdown children
 *  (p, h2, ul, pre) stack naturally.
 * ────────────────────────────────────────────────────────────────── */
.message {
  display: block; width: 100%; max-width: 100%; min-width: 0;
  animation: msgIn 360ms var(--ease) both;
}
@keyframes msgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* USER — LEFT-aligned card bubble (same side as assistant per reference).
   Matches reference: .message.user is the flex row, .bubble inside is
   flex:0 0 auto with max-width:80%; the bubble shrinks to fit its text
   and breaks at WORD boundaries (NOT every character), so "what is the
   purpose group" stays on one line. The root cause of multi-line short
   bubbles was overflow-wrap:anywhere collapsing min-content to 1ch. */
.message.user {
  display: flex; align-items: flex-start; justify-content: flex-start;
  background: transparent; border: 0; padding: 0;
  width: 100%; max-width: 100%;
  margin: 0;
}
.message.user > .bubble {
  background: #f1f0ee; border: 1px solid var(--border-strong);
  border-radius: 8px; padding: 10px 14px;
  font-size: 14px; line-height: 1.55; color: var(--ink);
  flex: 0 0 auto;
  width: max-content; max-width: min(80%, 760px); min-width: 0;
  overflow-wrap: anywhere; word-break: normal; white-space: pre-wrap;
  /* Outer drop shadow: neutral grey at 30% — owner-tuned (2026-07-31) after
     trying .05, .10, .50 and a green variant. */
  box-shadow: inset 0 1px 2px rgba(0,0,0,.06), 0 2px 6px rgba(26,29,32,.30);
}
.message.user .gf-msg-text {
  background: transparent; padding: 0; border: 0;
  color: inherit; font: inherit; white-space: inherit;
  display: block;
}
.message.user a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--muted-2); }

/* ASSISTANT — transparent article surface, full width. */
.message.assistant {
  background: transparent; padding: 0; border: 0;
  font-size: 14.5px; line-height: 1.65; color: var(--ink-soft);
  width: 100%; max-width: 760px;
  overflow-wrap: anywhere; word-break: break-word;
  overflow-x: clip;
}
.message.assistant > .gf-msg-text,
.message.assistant > .gf-stream-text { background: transparent; padding: 0; color: inherit; font: inherit; display: block; }

/* Stagger reveal — :nth-child gives each block its own delay so we
   don't depend on a JS-set --i custom property. */
.message.assistant > *,
.message.assistant > .gf-msg-text > *,
.message.assistant > .gf-stream-text > * {
  position: relative;
  animation: aiType 520ms var(--ease) both;
}
.message.assistant > *:nth-child(1)  { animation-delay: 0ms; }
.message.assistant > *:nth-child(2)  { animation-delay: 70ms; }
.message.assistant > *:nth-child(3)  { animation-delay: 140ms; }
.message.assistant > *:nth-child(4)  { animation-delay: 210ms; }
.message.assistant > *:nth-child(5)  { animation-delay: 280ms; }
.message.assistant > *:nth-child(6)  { animation-delay: 350ms; }
.message.assistant > *:nth-child(7)  { animation-delay: 420ms; }
.message.assistant > *:nth-child(8)  { animation-delay: 490ms; }
.message.assistant > *:nth-child(9)  { animation-delay: 560ms; }
.message.assistant > *:nth-child(n+10) { animation-delay: 630ms; }

.message.assistant strong { color: var(--ink); font-weight: 600; }
.message.assistant h1, .message.assistant h2, .message.assistant h3, .message.assistant h4 {
  font-family: var(--font-display); font-weight: 500;
  letter-spacing: -.01em; color: var(--ink); margin: 18px 0 10px;
}
.message.assistant h1 { font-size: 22px; }
.message.assistant h2 { font-size: 19px; }
.message.assistant h3 { font-size: 17px; }
.message.assistant h4 { font-size: 15px; }
.message.assistant > *:first-child,
.message.assistant > .gf-msg-text > *:first-child,
.message.assistant > .gf-stream-text > *:first-child { margin-top: 0; }
.message.assistant p { margin: 0 0 12px; }
.message.assistant ul, .message.assistant ol { margin: 0 0 12px; padding-left: 20px; }
.message.assistant ul li, .message.assistant ol li { margin-bottom: 6px; }
.message.assistant ul li::marker { color: var(--muted-2); }
.message.assistant blockquote {
  margin: 0 0 12px; padding: 6px 14px; border-left: 2px solid var(--border-strong);
  color: var(--muted); font-style: italic;
}
.message.assistant code {
  font-family: var(--font-mono); font-size: 13px;
  background: var(--hover); padding: 1px 5px; border-radius: 3px;
}
.message.assistant pre {
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5;
  background: var(--paper); border: 1px solid var(--border);
  padding: 12px 14px; border-radius: 6px;
  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
  margin: 0 0 12px;
}
.message.assistant pre code { background: transparent; padding: 0; }
.message.assistant a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--muted-2); transition: text-decoration-color 160ms var(--ease); }
.message.assistant a:hover { text-decoration-color: var(--ink); }
.message.assistant hr { border: 0; border-top: 1px solid var(--border); margin: 18px 0; }
.message.assistant table {
  width: 100%; border-collapse: collapse; margin: 0 0 14px;
  font-size: 13px; font-variant-numeric: tabular-nums;
}
.message.assistant th, .message.assistant td {
  border-bottom: 1px solid var(--border); padding: 8px 10px; text-align: left;
}
.message.assistant th { font-weight: 600; color: var(--ink); }

@keyframes aiType {
  0% { opacity: 0; transform: translateY(10px); filter: blur(2px); }
  60% { opacity: .92; transform: translateY(0); filter: blur(0); }
  100% { opacity: 1; transform: none; filter: blur(0); }
}
@media (prefers-reduced-motion: reduce) {
  .message.assistant > *,
  .message.assistant > .gf-msg-text > *,
  .message.assistant > .gf-stream-text > * { animation: none !important; }
}

/* Streaming */
.gf-streaming { color: var(--ink-soft); }
.gf-streaming .gf-stream-text {
  background: transparent; color: var(--ink-soft);
  font-size: 14.5px; line-height: 1.65;
}
.gf-stream-cursor {
  display: inline-block; width: 7px; height: 13px;
  background: var(--flame); margin-left: 3px;
  vertical-align: text-bottom;
  animation: gxBlink 1.05s step-end infinite;
}

/* ─── Thinking indicator → gx-loader pattern ────────────────────────
   The JS still emits .gf-thinking with .gf-thinking-orbs / .gf-thinking-row
   / .gf-thinking-bar / .gf-thinking-trail. We hide the orbs entirely and
   reskin the row to a mono caret + label line that reads as a terminal
   loader. The shimmer bar stays — it's the same loaderSlide animation
   the Guide-x assessed-loader uses. */
.gf-thinking {
  display: block; max-width: 760px;
  padding: 4px 0 2px;
  color: var(--muted); font-family: var(--font-mono); font-size: 12.5px;
  line-height: 1.4;
  animation: fadeUp 320ms var(--ease) both;
}
.gf-thinking-orbs { display: none !important; }

.gf-thinking-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.gf-thinking-row {
  display: inline-flex; align-items: baseline; gap: 6px;
  font-family: var(--font-mono); font-size: 12.5px;
  color: var(--muted); letter-spacing: .01em;
  min-height: 18px; max-width: 100%; overflow: hidden;
}
.gf-thinking-label {
  color: var(--ink-soft); font-weight: 500; white-space: nowrap;
}
.gf-thinking-label::after {
  content: '_'; display: inline-block; margin-left: 3px;
  color: var(--flame); font-weight: 700;
  animation: gxBlink 1.05s step-end infinite;
}
.gf-thinking-sep { color: var(--muted-2); }
.gf-thinking-time {
  color: var(--muted-2); font-variant-numeric: tabular-nums;
  font-size: 10.5px; letter-spacing: .04em;
}
.gf-thinking-bar {
  width: 240px; max-width: 100%; height: 3px;
  background: var(--border); border-radius: 999px; overflow: hidden;
  position: relative;
}
.gf-thinking-bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 30%;
  background: linear-gradient(90deg, transparent, var(--ink), transparent);
  animation: loaderSlide 1.6s ease-in-out infinite;
}
@keyframes loaderSlide { from { transform: translateX(-100%); } to { transform: translateX(420%); } }
.gf-thinking-trail {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--muted-2);
  letter-spacing: .04em; display: flex; flex-direction: column; gap: 3px;
}
.gf-trail-item {
  display: inline-flex; align-items: center; gap: 6px;
  opacity: 0; animation: fadeUp 360ms var(--ease) both;
}
.gf-trail-check {
  color: var(--green); font-weight: 700; font-size: 11px;
  display: inline-block; width: 12px;
}

.gf-thinking-done .gf-thinking-label::after,
.gf-thinking-done .gf-thinking-bar { display: none; }

@media (prefers-reduced-motion: reduce) {
  .gf-thinking-label::after,
  .gf-thinking-bar-fill,
  .gf-stream-cursor { animation: none !important; }
}

/* Chat notices (system messages) */
.chat-notice {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--muted);
  text-align: center; padding: 8px 12px;
  border: 1px dashed var(--border); border-radius: var(--r);
  margin: 4px 0; letter-spacing: .02em; align-self: center;
  max-width: 480px;
}

/* Inline guidance citation — verbatim copy of the reference .cite shape.
   Layered base sheets paint an orange pill on .gf-citation* — we neutralise
   that and re-apply ink + dashed underline + small ↗ glyph. NO flame here. */
.gf-citation,
.gf-citation.gf-citation-anchor,
.gf-citation.gf-citation-anchor.gf-citation-unverified,
.gf-citation.gf-citation-anchor.gf-citation-natural,
.gf-citation-anchor,
a.cite, .cite {
  display: inline !important;
  background: transparent !important;
  border: 0 !important;
  border-bottom: 1px dashed var(--ink-soft) !important;
  /* Geometry is CONSTANT across rest/hover/active — the pill's padding is
     reserved permanently and hover only repaints. If hover changed padding,
     a chip near a line-break would rewrap, slip out from under the cursor,
     un-hover, shrink back, rewrap again — a rapid vertical jitter loop. */
  border-radius: 3px !important;
  padding: 0 4px 1px !important;
  margin: 0 -2px !important;
  color: var(--ink) !important;
  font-weight: 500 !important;
  font-size: inherit !important;
  letter-spacing: 0 !important;
  line-height: inherit !important;
  text-decoration: none !important;
  white-space: nowrap;
  cursor: pointer;
  transition: color 180ms var(--ease), background 180ms var(--ease), border-color 180ms var(--ease);
}
.gf-citation::after,
.gf-citation-anchor::after,
a.cite::after, .cite::after {
  content: '↗' !important;
  display: inline-block !important;
  margin-left: 2px;
  font-size: .82em;
  font-weight: inherit !important;
  color: inherit !important;
  background: transparent !important;
  border-radius: 0 !important;
  padding: 0 !important;
  line-height: inherit !important;
  vertical-align: baseline;
  opacity: .6;
  transition: transform 180ms var(--ease), opacity 180ms var(--ease);
}
.gf-citation:hover,
.gf-citation.gf-citation-anchor:hover,
.gf-citation-anchor:hover,
a.cite:hover, .cite:hover {
  background: var(--hover) !important;
  border-bottom: 1px solid var(--ink) !important;
  color: var(--ink) !important;
  /* paint only — geometry lives in the base rule */
}
.gf-citation:hover::after,
.gf-citation-anchor:hover::after,
a.cite:hover::after, .cite:hover::after { transform: translate(1px,-1px); opacity: .9; }
.gf-citation.active,
.gf-citation-anchor.active,
a.cite.active, .cite.active {
  background: var(--hover) !important;
  border-bottom: 1px solid var(--ink) !important;
  color: var(--ink) !important;
  /* paint only — geometry lives in the base rule */
}
/* Unverified — slightly more muted so it reads as "pending". */
.gf-citation.gf-citation-unverified {
  color: var(--ink-soft) !important;
  border-bottom-color: var(--ink-soft) !important;
}
.gf-citation.gf-citation-unverified::after { opacity: .45; }

/* Spatial hyperlink — verbatim copy of the reference .room-link shape.
   Ink dot + solid ink underline, NO flame on rest/hover. */
.gf-pin-link {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--ink) !important; font-weight: 600 !important;
  text-decoration: none !important;
  border: 0 !important;
  border-bottom: 1px solid var(--ink) !important;
  border-radius: 0 !important;
  background: transparent !important;
  cursor: pointer; padding: 0 1px 1px !important;
  margin: 0 !important;
  transition: color 180ms var(--ease), background 180ms var(--ease), border-color 180ms var(--ease), padding 180ms var(--ease);
  vertical-align: baseline;
}
.gf-pin-link::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink); box-shadow: 0 0 0 2px rgba(31,26,20,.08);
  flex: none;
  transition: background 180ms var(--ease), box-shadow 180ms var(--ease);
}
.gf-pin-link:hover {
  background: var(--hover) !important;
  border-bottom-color: var(--ink-soft) !important;
  border-radius: 3px !important; padding: 0 4px 1px !important; margin: 0 -2px !important;
  color: var(--ink) !important;
}
.gf-pin-link:hover::before { box-shadow: 0 0 0 3px rgba(31,29,32,.12); }
.gf-pin-link.active {
  color: var(--flame) !important;
  border-bottom-color: var(--flame) !important;
  background: rgba(99,199,106,.06) !important;
  border-radius: 3px !important; padding: 0 4px 1px !important; margin: 0 -2px !important;
}
.gf-pin-link.active::before { background: var(--flame); box-shadow: 0 0 0 3px rgba(99,199,106,.16); }

/* ────────────────────────────────────────────────────────────────── *
 *  composer
 * ────────────────────────────────────────────────────────────────── */
.chat-input-area {
  flex: none; position: relative;
  padding: 34px 32px 3px 28px; background: var(--bg); z-index: 5;
}
.chat-input-area::before {
  content: ""; position: absolute; left: 0; right: 0; top: -24px; height: 24px;
  background: linear-gradient(to top, var(--bg), rgba(250,251,252,0));
  pointer-events: none;
}
.gf-chat-brand { display: none; } /* sidebar brand suffices */

.gf-chat-pill {
  position: relative;
  display: grid;
  grid-template-areas:
    "textarea textarea textarea"
    ".        mode     send";
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 8px 8px;
  width: 100%; max-width: 100%; margin: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 12px 14px 10px;
  box-shadow: var(--shadow-soft);
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
.gf-chat-pill:focus-within { border-color: var(--border-strong); box-shadow: var(--shadow-lift); }

.gf-chat-pill,
.composer { position: relative; }
/* (Chat image-attachment styles removed — feature deleted.) */

.chat-input {
  grid-area: textarea;
  width: 100%; border: 0; outline: 0; resize: none;
  background: transparent; color: var(--ink);
  font-size: 14px; line-height: 1.5; min-height: 22px; max-height: 200px;
  padding: 4px 2px 4px; font-family: inherit;
}
.chat-input::placeholder { color: var(--muted-2); }

/* ── Pin-mention highlight layer (js/chat-pin-context.js) ──
   The wrap takes over the textarea's grid cell; the backdrop is an exact
   text mirror painted BEHIND the (transparent-background) textarea. All
   mirror text is invisible — only the mention span paints a pale green pill
   (same family as .gf-pin-link) — so the real text and caret render on
   top, pixel-aligned. Text metrics MUST stay identical to .chat-input. */
.gx-chat-input-wrap { grid-area: textarea; position: relative; width: 100%; }
.gx-chat-input-wrap .chat-input { position: relative; z-index: 1; display: block; }
.gx-chat-input-backdrop {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
  color: transparent;
  white-space: pre-wrap; word-wrap: break-word;
  font-size: 14px; line-height: 1.5; font-family: inherit;
  padding: 4px 2px 4px;
  border: 0;
}
.gx-chat-input-backdrop .gx-mention-hl {
  background: var(--flame-soft);
  /* The chip's "padding" is faked with a same-colour ring extending the fill
     3px past the text — real padding would shift the text mirror off the
     textarea's metrics and misalign the caret. No outline: owner call. */
  box-shadow: 0 0 0 3px var(--flame-soft);
  border-radius: 6px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.gf-chat-mode-wrap { grid-area: mode; position: relative; }
.gf-chat-mode {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px;
  border-radius: 999px; background: var(--bg); border: 1px solid var(--border);
  color: var(--ink-soft); font-size: 11px; font-weight: 500;
  cursor: pointer; transition: border-color 200ms var(--ease), background 200ms var(--ease);
}
.gf-chat-mode:hover { border-color: var(--border-strong); }
.gf-chat-mode i, .gf-chat-mode svg { width: 9px; height: 9px; }

.gf-chat-mode-menu {
  position: absolute; bottom: calc(100% + 6px); right: 0;
  min-width: 220px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 12px 32px rgba(40,30,14,.14);
  padding: 6px; display: none; z-index: 30;
}
.gf-chat-mode-menu.open { display: block; }
.gf-chat-mode-item {
  display: flex; flex-direction: column; align-items: flex-start;
  padding: 9px 11px; border-radius: 6px;
  cursor: pointer; transition: background 160ms var(--ease);
  width: 100%; text-align: left;
}
.gf-chat-mode-item:hover { background: var(--hover); }
.gf-chat-mode-item.active { background: var(--hover); }
.gf-chat-mode-item-label { font-size: 12.5px; font-weight: 600; color: var(--ink); letter-spacing: -.005em; }
.gf-chat-mode-item-hint { font-size: 10.5px; color: var(--muted); margin-top: 1px; font-family: var(--font-mono); letter-spacing: .02em; }

/* Send button — Guide-x vocab */
.send-btn {
  grid-area: send;
  width: 30px; height: 30px; border-radius: var(--r);
  background: var(--ink); border: 1px solid var(--ink); color: #fff;
  display: grid; place-items: center;
  transition: background 180ms var(--ease), color 180ms var(--ease),
              border-color 180ms var(--ease), transform 120ms var(--ease);
  cursor: pointer;
}
.send-btn:hover { background: var(--flame); border-color: var(--flame); }
.send-btn:active { transform: scale(.94); }
.send-btn:disabled { background: var(--bg); border-color: var(--border); color: var(--muted-2); cursor: not-allowed; }
.send-btn i, .send-btn svg { width: 13px; height: 13px; }

/* ────────────────────────────────────────────────────────────────── *
 *  bottom status bar (mode pill + sources) — embedded above composer
 * ────────────────────────────────────────────────────────────────── */
.status-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 32px 8px 28px; background: var(--bg);
  border-top: 0; flex-shrink: 0;
}
.active-badges {
  display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.badge {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .08em;
  padding: 2px 6px; border-radius: 3px; font-weight: 600;
  color: var(--muted-2); background: var(--hover);
  border: 1px solid var(--border);
  text-transform: uppercase;
}
.status-text {
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); font-weight: 500;
}

/* ────────────────────────────────────────────────────────────────── *
 *  toast
 * ────────────────────────────────────────────────────────────────── */
.toast {
  position: fixed; top: 24px; bottom: auto; left: 50%; transform: translateX(-50%) translateY(-8px);
  background: var(--ink); color: var(--bg);
  padding: 10px 18px; border-radius: var(--r);
  font-size: 12.5px; font-weight: 500; letter-spacing: -.005em;
  box-shadow: 0 12px 32px rgba(40,30,14,.18);
  opacity: 0; pointer-events: none;
  transition: opacity 240ms var(--ease), transform 240ms var(--ease);
  z-index: 2200; max-width: 480px;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
.toast.error { background: var(--red); }
.toast.success { background: var(--green); }

/* Server down banner */
#gfServerDownBanner {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--red); color: #fff;
  padding: 10px 18px; border-radius: var(--r);
  font-size: 12.5px; font-weight: 600;
  z-index: 999; box-shadow: 0 8px 20px rgba(180,60,60,.3);
}

/* ────────────────────────────────────────────────────────────────── *
 *  upload progress ring (#uploadProgress) — match Guide-x tokens
 * ────────────────────────────────────────────────────────────────── */
.upload-progress {
  display: none; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 4px;
}
.upload-progress.active { display: flex; }
.upload-ring { width: 32px; height: 32px; transform: rotate(-90deg); }
.upload-ring-track { fill: none; stroke: var(--border); stroke-width: 3; }
.upload-ring-fill {
  fill: none; stroke: var(--flame); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 113; stroke-dashoffset: 113;
  transition: stroke-dashoffset 220ms var(--ease);
}
.upload-phase {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--muted);
  letter-spacing: .06em; text-transform: uppercase;
}

/* ────────────────────────────────────────────────────────────────── *
 *  modals (legacy structure preserved) — Guide-x reskin
 * ────────────────────────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(20, 14, 4, .42);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  display: none; align-items: center; justify-content: center;
  z-index: 100; padding: 24px;
  opacity: 0; transition: opacity 220ms var(--ease);
}
.modal-backdrop.open { display: flex; opacity: 1; }
.modal-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-xl); padding: 24px;
  box-shadow: 0 24px 56px rgba(20,14,4,.18);
  width: 100%; max-width: 460px;
  animation: modalIn 240ms var(--ease) both;
}
@keyframes modalIn { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
.modal-title {
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--flame); font-weight: 600; margin-bottom: 10px;
}
.modal-warning {
  font-size: 14px; line-height: 1.55; color: var(--ink-soft);
  margin-bottom: 20px;
}
.modal-warning strong { color: var(--ink); font-weight: 600; }
.modal-input {
  width: 100%; padding: 10px 12px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--bg);
  color: var(--ink); font-size: 14px; font-family: inherit;
  outline: 0; margin-bottom: 16px;
  transition: border-color 160ms var(--ease);
}
.modal-input:focus { border-color: var(--ink); }
.modal-actions {
  display: flex; justify-content: flex-end; align-items: center; gap: 8px;
}
.modal-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--r);
  font-size: 13px; font-weight: 600; letter-spacing: -.005em;
  cursor: pointer;
  transition: background 200ms var(--ease), border-color 200ms var(--ease), color 200ms var(--ease), transform 120ms var(--ease);
  border: 1px solid transparent;
}
.modal-btn:active { transform: translateY(1px); }
.modal-btn.cancel {
  background: var(--surface); border-color: var(--border); color: var(--ink-soft);
}
.modal-btn.cancel:hover { background: var(--hover); color: var(--ink); border-color: var(--border-strong); }
.modal-btn.confirm {
  background: var(--ink); color: #fff; border-color: var(--ink);
}
.modal-btn.confirm:hover { background: var(--green); border-color: var(--green); }
.modal-btn.danger {
  background: var(--red); color: #fff; border-color: var(--red);
}
.modal-btn.danger:hover { background: #b73f3f; border-color: #b73f3f; }
.modal-btn i, .modal-btn svg { width: 13px; height: 13px; }

/* Brief modal */
.gf-brief-box { max-width: 640px; padding: 28px; }
.gf-brief-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; margin-bottom: 22px;
}
.gf-brief-title-row { display: flex; align-items: center; gap: 10px; }
.gf-brief-title {
  font-family: var(--font-display); font-weight: 500; font-size: 22px;
  letter-spacing: -.5px; color: var(--ink);
}
.gf-brief-type-chip {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 600;
  padding: 3px 7px; border-radius: 4px;
  color: var(--flame); background: var(--flame-soft);
}
.gf-brief-sub { font-size: 13.5px; color: var(--ink-soft); margin-top: 4px; }
.gf-brief-close {
  width: 30px; height: 30px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--surface);
  color: var(--ink-soft); display: grid; place-items: center;
  flex: none; cursor: pointer;
  transition: background 180ms var(--ease), color 180ms var(--ease);
}
.gf-brief-close:hover { background: var(--hover); color: var(--ink); }
.gf-brief-close i, .gf-brief-close svg { width: 13px; height: 13px; }

.gf-brief-types { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.gf-brief-type {
  display: flex; flex-direction: column; gap: 6px;
  padding: 20px 18px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); text-align: left; cursor: pointer;
  transition: border-color 180ms var(--ease), background 180ms var(--ease), transform 120ms var(--ease);
}
.gf-brief-type:hover { border-color: var(--ink-soft); background: var(--hover); }
.gf-brief-type.selected { border-color: var(--ink); box-shadow: 0 0 0 3px rgba(31,26,20,.06); }
/* Locked-confirmation picker (building type derived from the ticked
   standard): the applicable type is highlighted + clickable, the other is
   greyed out and non-interactive. */
.gf-brief-type.is-locked {
  border-color: var(--flame, #63c76a);
  box-shadow: 0 0 0 3px rgba(99,199,106,.12);
}
.gf-brief-type.is-disabled {
  opacity: .35; cursor: not-allowed; pointer-events: none;
}
.gf-brief-type-icon {
  width: 36px; height: 36px; border-radius: var(--r);
  background: var(--ink); color: var(--bg);
  display: grid; place-items: center; flex: none;
}
.gf-brief-type-icon i, .gf-brief-type-icon svg { width: 16px; height: 16px; }
.gf-brief-type strong {
  font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -.005em;
}
.gf-brief-type small {
  font-size: 12px; color: var(--muted); line-height: 1.45;
}

.gf-brief-questions { display: flex; flex-direction: column; gap: 16px; }
.gf-brief-q { display: flex; flex-direction: column; gap: 6px; }
.gf-brief-q label {
  font-size: 12.5px; font-weight: 600; color: var(--ink); letter-spacing: -.005em;
}
.gf-brief-q input, .gf-brief-q select {
  width: 100%; padding: 9px 12px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--surface);
  font-size: 13.5px; color: var(--ink); outline: 0;
  transition: border-color 160ms var(--ease);
}
.gf-brief-q input:focus, .gf-brief-q select:focus { border-color: var(--ink); }
.gf-brief-q .gf-brief-q-hint { font-size: 11.5px; color: var(--muted); }
/* Mixed use: one header per guidance above its own questions. */
.gf-brief-group {
  font-size: 11.5px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
  padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.gf-brief-group:not(:first-child) { margin-top: 10px; }

.gf-brief-foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border);
}
.gf-brief-foot-spacer { flex: 1; }

/* ────────────────────────────────────────────────────────────────── *
 *  side plan viewer — slots into the grid as col 3, slides in on open
 * ────────────────────────────────────────────────────────────────── */
.chat-plan-panel {
  grid-column: 3; grid-row: 1 / 3;
  border-left: 1px solid var(--border);
  background: var(--bg);
}
body.gf-plan-pane-open .app { --pdf-w: 50vw; }

/* ────────────────────────────────────────────────────────────────── *
 *  modal-backdrop / modal-box — Guide-x skin
 *  (modals.css supplies the bones; we re-paint the surfaces.)
 * ────────────────────────────────────────────────────────────────── */
.modal-backdrop {
  background: rgba(20, 18, 14, 0.45);
  backdrop-filter: blur(14px) saturate(1.05);
  -webkit-backdrop-filter: blur(14px) saturate(1.05);
}
.modal-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  color: var(--ink);
}
.modal-title {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.modal-warning { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; }
.modal-warning strong { color: var(--ink); }
.modal-input {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); color: var(--ink);
  font-size: 13.5px; padding: 11px 14px;
  transition: border-color 160ms var(--ease), box-shadow 160ms var(--ease);
}
.modal-input:focus { background: var(--bg); border-color: var(--ink-soft); box-shadow: 0 0 0 3px rgba(20,14,4,.06); }
.modal-input::placeholder { color: var(--muted-2); }

/* Which product a new project belongs to. Temporary: it lives in the New
   Project modal only until the launcher screen exists, at which point the
   tile the user came in through decides, and newProject('<product>') hides
   this whole block. */
.gf-product-choice {
  display: grid; gap: 8px;
  border: 0; margin: 4px 0 0; padding: 0;
}
.gf-product-choice[hidden] { display: none; }
.gf-product-choice legend {
  padding: 0 0 8px; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.gf-product-choice label {
  display: flex; align-items: flex-start; gap: 10px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); padding: 11px 13px; cursor: pointer;
  transition: border-color 160ms var(--ease), background 160ms var(--ease);
}
.gf-product-choice label:hover { border-color: var(--border-strong); background: var(--hover); }
.gf-product-choice input { margin: 2px 0 0; accent-color: var(--green); flex: none; }
.gf-product-choice input:checked + span strong { color: var(--green-deep); }
.gf-product-choice label:has(input:checked) {
  border-color: var(--green); background: var(--flame-tint);
}
.gf-product-choice span { display: block; font-size: 12px; color: var(--muted); line-height: 1.45; }
.gf-product-choice span strong {
  display: block; font-size: 13px; color: var(--ink); margin-bottom: 2px;
}

/* Reskin modal buttons in Guide-x vocabulary */
.modal-btn {
  font-family: var(--font); font-size: 12.5px; font-weight: 600;
  letter-spacing: -.005em; border-radius: var(--r); padding: 9px 16px;
  transition: background 180ms var(--ease), border-color 180ms var(--ease),
              color 180ms var(--ease), transform 120ms var(--ease);
}
.modal-btn.cancel {
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--border); box-shadow: none;
}
.modal-btn.cancel:hover { background: var(--hover); border-color: var(--border-strong); }
.modal-btn.confirm {
  background: var(--ink); color: #fff; border: 1px solid var(--ink);
}
.modal-btn.confirm:hover { background: var(--green); border-color: var(--green); }
.modal-btn.confirm:active { transform: translateY(1px); }
.modal-btn.confirm:disabled { background: var(--muted-2); border-color: var(--muted-2); opacity: .6; cursor: not-allowed; }
.modal-btn.danger {
  background: var(--surface); color: var(--red);
  border: 1px solid rgba(212,77,77,.35);
}
.modal-btn.danger:hover { background: var(--red); color: #fff; border-color: var(--red); }

/* ────────────────────────────────────────────────────────────────── *
 *  PDF Prep modal — Guide-x skin
 *  Selectors mirror pdf-prep.css so we win the cascade and the modal
 *  reads as Guide-x instead of the old parchment theme.
 * ────────────────────────────────────────────────────────────────── */
.modal-box.pdp-modal-box, .modal-box.pdp-crop-box {
  background: var(--bg); border: 1px solid var(--border);
  box-shadow: var(--shadow-3); padding: 0;
}
.pdp-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px; border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.pdp-header-title {
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); font-weight: 700;
}
.pdp-file-badge {
  font-family: var(--font-mono); font-size: 10.5px;
  color: var(--ink-soft); background: var(--bg);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 3px 10px; margin-left: auto; max-width: 320px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  letter-spacing: .04em;
}
.pdp-close {
  width: 30px; height: 30px; border-radius: var(--r);
  background: transparent; color: var(--muted);
  display: grid; place-items: center; font-size: 16px; line-height: 1;
  border: 1px solid transparent; padding: 0;
  transition: background 160ms var(--ease), color 160ms var(--ease), border-color 160ms var(--ease);
}
.pdp-close:hover { background: var(--red-soft); color: var(--red); border-color: rgba(212,77,77,.30); }

.pdp-body { background: var(--bg); }
.pdp-left { padding: 18px 20px; }
.pdp-right {
  background: var(--surface); border-left: 1px solid var(--border);
}

.pdp-mode-tabs {
  display: inline-flex; padding: 3px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; gap: 2px;
}
.pdp-mode-tab {
  font-family: var(--font); font-size: 12.5px; font-weight: 600;
  color: var(--muted); padding: 6px 14px; border-radius: 999px;
  background: transparent; border: 0; cursor: pointer;
  transition: background 160ms var(--ease), color 160ms var(--ease);
  letter-spacing: -.005em;
}
.pdp-mode-tab:hover { color: var(--ink); }
.pdp-mode-tab.active { background: var(--ink); color: #fff; }

.pdp-mode-hint {
  font-size: 12.5px; line-height: 1.55; color: var(--muted);
  margin: 14px 0 16px;
}

.pdp-page-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
}
.pdp-page-card {
  position: relative;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
  cursor: pointer; transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease), transform 120ms var(--ease);
}
.pdp-page-card:hover { border-color: var(--ink-soft); box-shadow: 0 1px 2px rgba(20,14,4,.06); }
.pdp-page-card.selected {
  border-color: var(--ink);
  box-shadow: 0 0 0 2px rgba(31,26,20,.10), 0 1px 2px rgba(20,14,4,.06);
}
.pdp-page-card.has-crop {
  /* Quiet flame confirmation — keeps the brand orange but at a low-key
     opacity so the cropped state is recognisable without shouting. */
  border-color: rgba(99, 199, 106, 0.42);
  box-shadow: 0 0 0 1px rgba(99, 199, 106, 0.06);
}
.pdp-page-card:active { transform: translateY(1px); }
.pdp-page-checkbox {
  position: absolute; top: 8px; left: 8px; z-index: 2;
  width: 18px; height: 18px; border-radius: 4px;
  background: var(--surface); border: 1.5px solid var(--border-strong);
  display: grid; place-items: center;
  transition: background 160ms var(--ease), border-color 160ms var(--ease);
}
.pdp-page-card.selected .pdp-page-checkbox {
  background: var(--ink); border-color: var(--ink);
}
.pdp-page-card.selected .pdp-page-checkbox::after {
  content: ""; width: 8px; height: 5px;
  border-left: 1.6px solid #fff; border-bottom: 1.6px solid #fff;
  transform: rotate(-45deg) translateY(-1px);
}
.pdp-crop-badge {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: none; padding: 3px 8px; border-radius: 999px;
  /* Quiet flame pill — flame-soft tinted background + flame text instead
     of a loud solid orange fill. Reads as a label, not a tag. */
  background: rgba(99, 199, 106, 0.10);
  color: rgba(99, 199, 106, 0.85);
  border: 1px solid rgba(99, 199, 106, 0.25);
  font-family: var(--font-mono); font-size: 9.5px;
  letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
}
.pdp-page-card.has-crop .pdp-crop-badge { display: inline-flex; }
.pdp-page-thumb {
  aspect-ratio: 0.72;
  background: var(--bg); display: grid; place-items: center;
  overflow: hidden;
}
.pdp-page-thumb canvas, .pdp-page-thumb img {
  width: 100%; height: 100%; object-fit: contain; display: block;
}
.pdp-page-thumb-loading {
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .08em; color: var(--muted-2); text-transform: uppercase;
}
.pdp-page-footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px; border-top: 1px solid var(--border);
  background: var(--surface);
}
.pdp-page-label {
  font-size: 11.5px; font-weight: 600; color: var(--ink); letter-spacing: -.005em;
}
.pdp-page-num {
  font-family: var(--font-mono); font-size: 10px; color: var(--muted-2);
  letter-spacing: .04em;
}
.pdp-crop-mode-overlay {
  position: absolute; inset: 0; display: none;
  background: rgba(20,18,14,.40); color: #fff;
  align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
  backdrop-filter: blur(2px);
}
.pdp-body.crop-mode .pdp-page-card:hover .pdp-crop-mode-overlay { display: flex; }

.pdp-segments-head {
  padding: 16px 20px 8px; border-bottom: 1px solid var(--border);
}
.pdp-segments-head h3 {
  margin: 0 0 4px; font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.pdp-segments-count {
  font-size: 12px; color: var(--ink-soft); font-weight: 500;
  font-family: var(--font-mono); letter-spacing: .02em;
}
.pdp-segments-list { padding: 12px 16px; display: flex; flex-direction: column; gap: 8px; flex: 1; overflow-y: auto; }
.pdp-segments-list .pdp-empty {
  font-size: 12.5px; color: var(--muted-2); text-align: center;
  padding: 32px 12px; border: 1px dashed var(--border); border-radius: var(--r-lg);
  font-family: var(--font-mono); letter-spacing: .02em;
  line-height: 1.6;
}
.pdp-segments-list .pdp-empty-icon {
  display: block; font-size: 18px; margin-bottom: 8px; color: var(--muted-2);
}
.pdp-seg-card {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--r);
  transition: border-color 160ms var(--ease), background 160ms var(--ease);
}
.pdp-seg-card:hover { border-color: var(--border-strong); }
.pdp-seg-card .pdp-seg-thumb {
  width: 38px; height: 50px; border-radius: 4px; overflow: hidden;
  background: var(--surface); border: 1px solid var(--border); flex: none;
}
.pdp-seg-card .pdp-seg-thumb img,
.pdp-seg-card .pdp-seg-thumb canvas { width: 100%; height: 100%; object-fit: cover; }
.pdp-seg-card .pdp-seg-info { flex: 1; min-width: 0; }
.pdp-seg-card .pdp-seg-name {
  font-size: 12.5px; font-weight: 600; color: var(--ink);
  letter-spacing: -.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pdp-seg-card .pdp-seg-meta {
  font-family: var(--font-mono); font-size: 10px; color: var(--muted-2);
  letter-spacing: .04em; margin-top: 2px;
}
.pdp-seg-card button {
  width: 26px; height: 26px; border-radius: 5px;
  background: transparent; color: var(--muted-2);
  display: grid; place-items: center; flex: none;
  transition: background 160ms var(--ease), color 160ms var(--ease);
}
.pdp-seg-card button:hover { background: var(--red-soft); color: var(--red); }
.pdp-seg-card select {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); padding: 4px 8px;
  font-family: var(--font); font-size: 11.5px; color: var(--ink-soft);
  cursor: pointer; flex: none;
}

.pdp-footer {
  padding: 12px 20px; border-top: 1px solid var(--border);
  background: var(--surface); display: flex; gap: 8px;
}
.pdp-proceed {
  width: 100%; padding: 11px 16px;
  background: var(--ink); color: #fff; border: 1px solid var(--ink);
  border-radius: var(--r); font-size: 13px; font-weight: 600;
  letter-spacing: -.005em; cursor: pointer;
  transition: background 180ms var(--ease), border-color 180ms var(--ease);
}
.pdp-proceed:hover { background: var(--green); border-color: var(--green); }
.pdp-proceed:disabled { background: var(--muted-2); border-color: var(--muted-2); opacity: .6; cursor: not-allowed; }

/* Crop modal */
.pdp-crop-canvas-wrap {
  position: relative; background: var(--bg);
  display: grid; place-items: center; min-height: 320px;
  padding: 14px;
}
.pdp-crop-selection {
  position: absolute; border: 2px dashed var(--flame);
  background: rgba(99,199,106,.08);
  pointer-events: none;
}

/* ────────────────────────────────────────────────────────────────── *
 *  Plan-form modal (markup / annotate canvas) — Guide-x skin
 *  We do not touch geometry/layout in plan-builder.css; we override
 *  the cosmetic surfaces so it reads in the Guide-x palette.
 * ────────────────────────────────────────────────────────────────── */
.plan-form-box { background: var(--bg); }
.pf-header {
  border-bottom: 1px solid var(--border); background: var(--surface);
  padding: 14px 20px;
}
.pf-title {
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .14em; color: var(--ink); font-weight: 700;
}
.pf-project-name {
  font-family: var(--font); font-size: 13.5px;
  font-weight: 600; color: var(--ink); letter-spacing: -.005em;
}
.pf-close {
  width: 30px; height: 30px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--surface);
  color: var(--muted); font-size: 18px;
  display: grid; place-items: center;
  transition: background 160ms var(--ease), color 160ms var(--ease), border-color 160ms var(--ease);
}
.pf-close:hover { background: var(--red-soft); color: var(--red); border-color: rgba(212,77,77,.30); }
.pf-meta-label {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.pf-meta-input,
.pf-field input[type=text],
.pf-field select,
.pf-field textarea {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); color: var(--ink);
  font-family: var(--font); font-size: 13px; padding: 9px 12px;
  transition: border-color 160ms var(--ease), box-shadow 160ms var(--ease);
}
.pf-meta-input:focus,
.pf-field input[type=text]:focus,
.pf-field select:focus,
.pf-field textarea:focus {
  border-color: var(--ink-soft); box-shadow: 0 0 0 3px rgba(20,14,4,.05);
}
.pf-meta-input::placeholder,
.pf-field input[type=text]::placeholder,
.pf-field textarea::placeholder { color: var(--muted-2); }

.pf-sidebar {
  background: var(--surface); border-right: 1px solid var(--border);
}
.pf-tabs-section-head {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.pf-tab {
  border-radius: var(--r); transition: background 160ms var(--ease);
  font-family: var(--font); font-size: 13px;
}
.pf-tab:hover { background: var(--hover); }
.pf-tab.active { background: var(--ink); }
.pf-tab.active .pf-tab-label { color: #fff; }
.pf-tab-dot { background: var(--ink-soft); }
.pf-tab.active .pf-tab-dot { background: var(--flame); }
.pf-tab-count {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .04em;
  color: var(--muted-2);
}
.pf-tab.active .pf-tab-count { color: rgba(255,255,255,.7); }
.pf-tab-sub-item {
  font-size: 12.5px; color: var(--ink-soft);
  transition: background 160ms var(--ease), color 160ms var(--ease);
}
.pf-tab-sub-item::before { color: var(--muted-2); }
.pf-tab-sub-item:hover { background: var(--hover); color: var(--ink); }
.pf-tab-sub-item.active { background: var(--hover); color: var(--ink); font-weight: 600; }

.pf-canvas-toolbar {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
}
.pf-canvas-tool-btn {
  background: transparent; border: 1px solid transparent; color: var(--muted);
  border-radius: var(--r-sm); transition: all 160ms var(--ease);
}
.pf-canvas-tool-btn:hover { color: var(--ink); border-color: var(--border); background: var(--hover); }
.pf-canvas-tool-btn.active { background: var(--flame); border-color: var(--flame); color: #fff; }

/* Plan-builder primary action (Save) and cancel — bridge to Guide-x CTA */
.pb-cta-primary, .pb-cta-primary.save,
#planFormSaveBtn {
  background: var(--ink); color: #fff; border: 1px solid var(--ink);
  border-radius: var(--r); padding: 9px 16px;
  font-family: var(--font); font-size: 12.5px; font-weight: 600;
  transition: background 180ms var(--ease), border-color 180ms var(--ease);
  letter-spacing: -.005em;
}
.pb-cta-primary:hover, .pb-cta-primary.save:hover,
#planFormSaveBtn:hover { background: var(--green); border-color: var(--green); }

.pb-close, .bs-close {
  width: 30px; height: 30px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--surface); color: var(--muted);
  display: grid; place-items: center;
  transition: background 160ms var(--ease), color 160ms var(--ease), border-color 160ms var(--ease);
}
.pb-close:hover, .bs-close:hover {
  background: var(--red-soft); color: var(--red); border-color: rgba(212,77,77,.30);
}

/* Plan-form dropzone (the "Upload PDF or image" empty state inside the markup modal) */
.pf-dropzone {
  border: 1px dashed var(--border-strong); background: var(--surface);
  border-radius: var(--r-lg);
  transition: border-color 160ms var(--ease), background 160ms var(--ease);
}
.pf-dropzone:hover, .pf-dropzone.dragover { border-color: var(--ink-soft); background: var(--hover); }
.pf-dropzone .title { color: var(--ink); font-weight: 600; }
.pf-dropzone .hint { color: var(--muted); font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; }

/* Plan-form RAG-preview drawer / inspector text */
.pf-preview, .pf-preview * { color: var(--ink-soft); }

/* ────────────────────────────────────────────────────────────────── *
 *  source-citations / citations: dedicated files (kept linked)
 *  chat-plan-pane: also kept linked for its toolbar/zoom internals
 * ────────────────────────────────────────────────────────────────── */

/* Make absolutely sure no legacy decorative skin styles bleed through */
@keyframes gxBlink { 0%,50% { opacity: 1; } 50.01%,100% { opacity: 0; } }

/* ════════════════════════════════════════════════════════════════════════
 * MOVQAE10 REFERENCE OVERRIDES — these rules MUST win over earlier blocks.
 * Components below match the visual contract of movqae10-guidex-start-
 * screen-5.html (the reference). Earlier rules in this file are kept for
 * compatibility but get overridden here.
 * ════════════════════════════════════════════════════════════════════════ */

/* ─── gx-mark — Guidex terminal-style >_ avatar for AI messages ─────── */
.gx-mark {
  width: 32px; height: 32px; border-radius: 0;
  background: transparent; border: 0; color: var(--flame);
  display: inline-flex; align-items: center; justify-content: center; gap: 0;
  flex: none; user-select: none;
  font-family: var(--font-mono); font-size: 15px; font-weight: 600;
  line-height: 1; letter-spacing: -.5px;
}
.gx-mark__prompt { display: inline-block; line-height: 1; }
.gx-mark__cursor { display: inline-block; line-height: 1; width: 7px; text-align: left; color: var(--flame); }
.gx-mark.loading .gx-mark__cursor { animation: gxBlink .58s step-end infinite; }
@media (prefers-reduced-motion: reduce) { .gx-mark .gx-mark__cursor { animation: none !important; } }

/* ─── Message layout — both user AND assistant on LEFT side ────────── */
.message {
  display: flex; gap: 14px; align-items: flex-start;
  width: 100%; max-width: none; min-width: 0;
  align-self: flex-start;
  animation: msgIn 360ms var(--ease) both;
}
.message > .gx-mark { flex: none; }

/* (User-bubble rules consolidated at the earlier .message.user block —
   that block sets display:flex on the row and flex:0 0 auto on .bubble,
   with overflow-wrap:break-word so short text doesn't collapse to 1ch.) */

/* ASSISTANT — gx-mark on the left, prose bubble fills the rest. */
.message.assistant {
  background: transparent; padding: 0; border: 0;
  max-width: none; overflow-x: clip;
}
.message.assistant > .bubble {
  background: transparent; padding: 6px 0 0;
  border-radius: 0; font-size: 14.5px; line-height: 1.65;
  color: var(--ink-soft);
  flex: 1 1 auto; min-width: 0; max-width: 760px;
  overflow-wrap: anywhere; word-break: break-word;
}
.message.assistant > .bubble strong,
.message.assistant > .bubble b { color: var(--ink); font-weight: 600; }
.message.assistant > .bubble em { color: var(--ink); font-style: italic; }
.message.assistant > .bubble h1,
.message.assistant > .bubble h2,
.message.assistant > .bubble h3,
.message.assistant > .bubble h4 {
  font-family: var(--font-display); font-weight: 500;
  letter-spacing: -.01em; color: var(--ink); margin: 18px 0 10px;
}
.message.assistant > .bubble h1 { font-size: 22px; }
.message.assistant > .bubble h2 { font-size: 19px; }
.message.assistant > .bubble h3 { font-size: 17px; }
.message.assistant > .bubble h4 { font-size: 15px; }
.message.assistant > .bubble > *:first-child { margin-top: 0; }
.message.assistant > .bubble p { margin: 0 0 12px; }
.message.assistant > .bubble ul,
.message.assistant > .bubble ol { margin: 0 0 12px; padding-left: 20px; }
.message.assistant > .bubble li { margin-bottom: 5px; }
.message.assistant > .bubble li::marker { color: var(--muted-2); }
.message.assistant > .bubble li strong,
.message.assistant > .bubble li b { color: var(--ink); font-weight: 600; }

/* Reset legacy direct-child stagger now that the children live inside .bubble.
   We re-apply the stagger on .bubble's children with a CSS-only fallback +
   JS-set --i for the typewriter caret. */
.message.assistant > *:nth-child(1),
.message.assistant > *:nth-child(2),
.message.assistant > *:nth-child(3),
.message.assistant > *:nth-child(4),
.message.assistant > *:nth-child(5),
.message.assistant > *:nth-child(6),
.message.assistant > *:nth-child(7),
.message.assistant > *:nth-child(8),
.message.assistant > *:nth-child(9),
.message.assistant > *:nth-child(n+10) { animation: none; animation-delay: 0ms; }

.message.assistant > .bubble > * {
  position: relative;
  animation: aiType 520ms var(--ease) both;
  animation-delay: calc(var(--i, 0) * 220ms);
}
/* Brief flame caret trailing the newest block — disappears on the last child */
.message.assistant > .bubble > *::after {
  content: ""; position: absolute; right: -10px; bottom: 6px;
  width: 6px; height: 14px; background: var(--flame);
  opacity: 0;
  animation: aiCaret 520ms var(--ease) both;
  animation-delay: calc(var(--i, 0) * 220ms);
  pointer-events: none;
}
.message.assistant > .bubble > *:last-child::after { display: none; }
@keyframes aiCaret {
  0%, 40% { opacity: 0; }
  50%, 80% { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .message.assistant > .bubble > *,
  .message.assistant > .bubble > *::after { animation: none !important; }
}

/* Header / list / code rules — keep the previously-tuned typography. */
.message.assistant strong { color: var(--ink); font-weight: 600; }
.message.assistant > .bubble h1,
.message.assistant > .bubble h2,
.message.assistant > .bubble h3,
.message.assistant > .bubble h4 {
  font-family: var(--font-display); font-weight: 500;
  letter-spacing: -.01em; color: var(--ink); margin: 18px 0 10px;
}
.message.assistant > .bubble > *:first-child { margin-top: 0; }
.message.assistant > .bubble p { margin: 0 0 12px; }
.message.assistant > .bubble ul,
.message.assistant > .bubble ol { margin: 0 0 12px; padding-left: 20px; }
.message.assistant > .bubble ul li,
.message.assistant > .bubble ol li { margin-bottom: 6px; }

/* Streaming bubble — same shape as finalized assistant. */
.message.assistant.gf-streaming { display: flex; gap: 14px; align-items: flex-start; }
.message.assistant.gf-streaming > .bubble { background: transparent; padding: 6px 0 0; }
.message.assistant.gf-streaming > .bubble .gf-stream-text { display: inline; color: var(--ink-soft); font: inherit; }

/* Optimistic answer: markdown renders live, so completed blocks must NOT
   re-animate or "flip" on each re-render / finalize. Suppress the staggered
   reveal + trailing per-block caret for the whole gf-live message. The
   .gf-stream-md wrapper is transparent so its children ARE the bubble's
   prose blocks (same typography as a finalized answer). */
.message.assistant.gf-live > .bubble > .gf-stream-md { display: block; }
.message.assistant.gf-live > .bubble > *,
.message.assistant.gf-live > .bubble > .gf-stream-md > *,
.message.assistant.gf-live > .bubble > *::after,
.message.assistant.gf-live > .bubble > .gf-stream-md > *::after {
  animation: none !important;
}
.message.assistant.gf-live > .bubble > .gf-stream-md > *:first-child { margin-top: 0; }
.message.assistant.gf-live > .bubble > .gf-stream-md > *:last-child { margin-bottom: 0; }

/* Soft blinking caret trailing the live answer while it streams. */
.message.assistant.gf-streaming > .bubble .gf-stream-cursor {
  display: inline-block; width: 7px; height: 13px;
  background: var(--flame); margin: 2px 0 0 1px; vertical-align: text-bottom;
  animation: gxBlink 1.05s step-end infinite;
}
.message.assistant:not(.gf-streaming) > .bubble .gf-stream-cursor { display: none; }

/* ─── gx-loader (thinking pattern) — replaces the orb + bar entirely ── */
.gf-thinking { /* override earlier block-level style */
  display: flex; gap: 14px; align-items: flex-start;
  padding: 0; max-width: none; color: inherit;
  animation: msgIn 360ms var(--ease) both;
}
.gf-thinking-orbs,
.gf-thinking-body,
.gf-thinking-row,
.gf-thinking-label,
.gf-thinking-sep,
.gf-thinking-time,
.gf-thinking-bar,
.gf-thinking-bar-fill,
.gf-thinking-trail { display: none !important; }

.gx-loader {
  display: flex; align-items: center;
  color: var(--muted); font-family: var(--font-mono);
  font-size: 12.5px; line-height: 1.4; min-height: 32px; min-width: 0;
}
.gx-loader__line { display: inline-flex; align-items: baseline; white-space: nowrap; min-height: 18px; max-width: 100%; overflow: hidden; }
.gx-loader__text { display: inline-block; white-space: nowrap; }
.gx-loader__caret {
  display: inline-block; width: 7px; height: 13px;
  margin-left: 3px; background: var(--flame); flex-shrink: 0;
  transform: translateY(2px);
  animation: gxBlink 1.05s step-end infinite;
}
.gx-loader[data-busy="1"] .gx-loader__caret { animation: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .gx-loader__caret { animation: none !important; } }

/* ─── Mode-seg — segmented Default / Concise control with slide ──────── */
.mode-seg {
  position: relative; grid-area: mode;
  display: inline-flex; align-items: center;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--r-pill, 999px);
  padding: 2px; cursor: pointer; user-select: none;
  transition: border-color 200ms var(--ease);
}
.mode-seg:hover { border-color: var(--border-strong); }
.mode-seg .indicator {
  position: absolute; top: 2px; bottom: 2px; left: 2px;
  width: calc(50% - 2px); background: var(--ink);
  border-radius: 999px;
  transition: transform 360ms var(--ease), background 280ms var(--ease);
  box-shadow: 0 1px 3px rgba(40,30,14,.18);
}
.mode-seg[data-mode="concise"] .indicator { transform: translateX(100%); background: var(--green); }
.mode-seg .opt {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px 3px 8px;
  font-size: 10.5px; font-weight: 500; color: var(--muted);
  letter-spacing: -.005em;
  transition: color 280ms var(--ease);
  cursor: pointer;
}
.mode-seg[data-mode="default"] .opt[data-opt="default"] { color: #fff; }
.mode-seg[data-mode="concise"] .opt[data-opt="concise"] { color: #fff; }
.mode-seg .opt svg { width: 9px; height: 9px; }

/* Hide the legacy dropdown trigger — replaced by .mode-seg in HTML. */
.gf-chat-mode,
.gf-chat-mode-menu,
.gf-chat-mode-wrap { display: none !important; }

/* Composer grid: re-map so .mode-seg sits in the mode area. */
.gf-chat-pill {
  grid-template-areas:
    "textarea textarea textarea"
    ".        mode      send";
}
.mode-seg { grid-area: mode; }

/* ─── Topbar tightening — match reference cta + status pill ─────────── */
.btn-new-project { display: none !important; } /* removed — not in reference */

.cta-assess {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: var(--r);
  background: var(--ink); color: var(--bg);
  font-size: 13px; font-weight: 600; letter-spacing: -.005em;
  border: 0; cursor: pointer;
  transition: background 280ms var(--ease), box-shadow 280ms var(--ease),
              transform 120ms var(--ease), opacity 220ms var(--ease);
  flex: none; white-space: nowrap;
}
.cta-assess:hover { background: var(--green); box-shadow: 0 1px 2px rgba(20,14,4,.08); }
.cta-assess:active { transform: translateY(1px); }
.cta-assess svg { width: 14px; height: 14px; }

/* "Markup" + "Plans" topbar buttons reuse .cta-assess as-is (black var(--ink)
   background, white var(--bg) text, green hover), with no re-skin. */

/* Status pill inside the topbar — mono uppercase, flame dot with halo. */
.topbar-status {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 0 4px; min-width: 0;
}
.topbar-status .pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 500; color: var(--muted);
}
.topbar-status .pill .dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: var(--flame); box-shadow: 0 0 0 3px rgba(99,199,106,.16);
}
.topbar-status .modeword { color: var(--ink); font-weight: 600; }
.topbar-status .active-badges { display: inline-flex; align-items: center; gap: 6px; }

/* ─── Sidebar brand-rect — static brand logo, no project coupling.
   Content is the shared .gx-lockup (see guide-x.css). ── */
.brand-rect {
  margin: 14px 14px 10px; display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; background: transparent; border: 0;
  border-radius: var(--r);
}

/* Send button — match reference: dark, no border, flame on hover. */
.send-btn {
  width: 30px; height: 30px; border-radius: var(--r);
  background: var(--bg); border: 1px solid var(--border);
  color: var(--muted); display: grid; place-items: center;
  transition: background 180ms var(--ease), color 180ms var(--ease),
              border-color 180ms var(--ease), transform 120ms var(--ease);
}
.send-btn:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.send-btn:active { transform: scale(.94); }
.send-btn.armed { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.send-btn svg { width: 13px; height: 13px; }

/* ────────────────────────────────────────────────────────────────── *
 *  Bulletproof welcome-hide — the welcome panel must disappear the
 *  moment a message exists in the chat. Multiple selectors so we win
 *  regardless of which JS path the app took to add the message.
 * ────────────────────────────────────────────────────────────────── */
.chat-messages:has(> .message) > .welcome,
.chat-messages:has(> .gf-streaming) > .welcome,
.chat-messages:has(> .gf-thinking) > .welcome,
body.gf-has-messages .welcome,
body.gf-chat-started .welcome { display: none !important; }

/* ────────────────────────────────────────────────────────────────── *
 *  Source slideout — split the window instead of overlaying chat.
 *  source-citations.css ships a position:fixed slideout that uses
 *  body.padding-right to make room — but our .app grid is width:100vw
 *  with overflow:hidden, so body padding has no effect. Reskin the
 *  slideout to live inside the 3rd grid column instead, and expand
 *  --pdf-w when it opens.
 * ────────────────────────────────────────────────────────────────── */
.gf-source-slideout {
  /* Full viewport height, flush to the top. The earlier `top: 56px` tried
     to clear the topbar, but the topbar never reaches the slide-out: since
     19 Oct 2026 it spans grid columns 2 and 3, and the app narrows when the
     slide-out opens, so the topbar ends at its left edge. That 56px just
     showed as an empty gap above the slide-out header. */
  position: fixed; top: 0; right: 0; height: 100vh;
  width: 0; max-width: 56vw;
  background: var(--bg); color: var(--ink);
  border-left: 1px solid var(--border);
  box-shadow: -2px 0 0 var(--border);
  transform: none;
  transition: width 320ms var(--ease);
  display: flex; flex-direction: column;
  font-family: var(--font);
  overflow: hidden;
  z-index: 30;
}
/* Track the shared --gf-source-w var (source-citations.css) instead of a
   hardcoded width. Single-pane it resolves to the same min(56vw,720px); in the
   three-pane state (source + plan both open) it is 32.5vw, matching the .app
   shrink so the fixed slideout no longer overlaps the floor-plan column. */
.gf-source-slideout.open { width: var(--gf-source-w); transform: none; }

/* Body padding-right would normally push the .app grid in; but .app is
   100vw + overflow:hidden. Shrink the app width when the slideout is open
   so chat sits beside it instead of underneath. */
body { transition: none; }
body.gf-source-open { padding-right: 0; }
body.gf-source-open .app {
  width: calc(100vw - var(--gf-source-w));
  transition: width 320ms var(--ease);
}
.app { transition: width 320ms var(--ease), grid-template-columns 420ms var(--ease); }

/* Repaint the slideout chrome to Guide-x cream */
.gf-source-slideout-header {
  background: var(--surface); border-bottom: 1px solid var(--border);
  color: var(--ink); padding: 12px 16px;
}
.gf-source-slideout-title {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.gf-source-slideout-close {
  width: 28px; height: 28px; border-radius: var(--r);
  background: transparent; color: var(--muted);
  border: 1px solid transparent;
  display: grid; place-items: center;
  transition: background 160ms var(--ease), color 160ms var(--ease), border-color 160ms var(--ease);
}
.gf-source-slideout-close:hover { background: var(--hover); color: var(--ink); border-color: var(--border); }
.gf-source-slideout-body { background: var(--bg); color: var(--ink); }

/* ── Guidex Reader: a project's own file that is not a PDF ──────────────
 * Opened from the Knowledge hub into the panel above (owner, 5 Oct 2026;
 * js/pages/workspace/file-reader.js). Each file sits on a white page; the
 * panel's zoom buttons scale the type through --gx-reader-zoom. */
.gx-reader {
  --gx-reader-zoom: 1;
  font-family: var(--font); font-size: calc(13px * var(--gx-reader-zoom));
  line-height: 1.6; color: var(--ink);
}
.gx-reader-page {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
  padding: 1.6em 1.9em; margin: 0 0 12px;
}
.gx-reader-word > :first-child { margin-top: 0; }
.gx-reader-word h1, .gx-reader-word h2, .gx-reader-word h3,
.gx-reader-word h4, .gx-reader-word h5, .gx-reader-word h6 {
  font-weight: 600; line-height: 1.3; margin: 1.2em 0 .5em; color: var(--ink);
}
.gx-reader-word h1 { font-size: 1.5em; }
.gx-reader-word h2 { font-size: 1.3em; }
.gx-reader-word h3 { font-size: 1.15em; }
.gx-reader-word h4, .gx-reader-word h5, .gx-reader-word h6 { font-size: 1em; }
.gx-reader-word p { margin: 0 0 .8em; }
.gx-reader-word ul, .gx-reader-word ol { margin: 0 0 .8em; padding-left: 1.6em; }
.gx-reader-word table, .gx-reader-table {
  border-collapse: collapse; width: 100%; margin: 0 0 1em; font-size: .92em;
}
.gx-reader-word td, .gx-reader-word th, .gx-reader-table td, .gx-reader-table th {
  border: 1px solid var(--border); padding: .35em .6em; text-align: left; vertical-align: top;
}
.gx-reader-word th, .gx-reader-table th { background: var(--bg); font-weight: 600; }
.gx-reader-word td p, .gx-reader-word th p { margin: 0; }
.gx-reader-pic {
  display: inline-block; font-size: .85em; color: var(--muted);
  border: 1px dashed var(--border-strong); border-radius: var(--r-sm); padding: .15em .6em;
}
/* A spreadsheet may be wider than the panel: it scrolls sideways on its page. */
.gx-reader-sheet-page { padding: 0; overflow-x: auto; }
.gx-reader-table { margin: 0; }
.gx-reader-table td, .gx-reader-table th { white-space: nowrap; }
.gx-reader-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.gx-reader-tab {
  font: inherit; font-size: .92em; padding: .3em .8em; cursor: pointer;
  border-radius: var(--r-sm); border: 1px solid var(--border);
  background: transparent; color: var(--muted);
}
.gx-reader-tab[aria-selected="true"] {
  background: var(--surface); border-color: var(--border-strong); color: var(--ink); font-weight: 500;
}
.gx-reader-text {
  white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: var(--font); font-size: 1em; color: var(--ink);
}
.gx-reader-mail-head {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: .3em 1.2em;
  margin: 0 0 1em; padding: 0 0 1em; border-bottom: 1px solid var(--border); font-size: .95em;
}
.gx-reader-mail-head dt { color: var(--muted); }
.gx-reader-mail-head dd { margin: 0; overflow-wrap: anywhere; }
.gx-reader-mail-head strong { font-weight: 600; }
.gx-reader-mail-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.gx-reader-muted { color: var(--muted); }
.gx-reader-note { font-size: .9em; color: var(--muted); margin: 0 0 10px; }
.gx-reader-empty { color: var(--muted); font-style: italic; }

/* Chat-plan panel + source both open → three-way split:
   chat 35vw | plan 32.5vw | standard 32.5vw.
   .app width = 100vw - --gf-source-w (32.5vw, set on body in
   source-citations.css) = 67.5vw, inherited from the rule above. Here we
   only fix the plan column to 32.5vw; the chat column is `1fr`, so it
   absorbs the rest: 67.5 - 32.5 (sidebar is collapsed to 0) = 35vw. */
body.gf-plan-pane-open.gf-source-open .app {
  --pdf-w: 32.5vw;
}

/* ────────────────────────────────────────────────────────────────── *
 *  Knowledge hub pane — the project screen's right-hand column (owner,
 *  17 Oct 2026), redrawn after the owner's notes of 19 Oct 2026: ONE box
 *  under the top bar, as tall as what it holds (a long list scrolls inside
 *  it), with nothing beside Markup. Inside it, one order of importance:
 *  the box's title, then each section's small grey name with its arrow,
 *  count and +, then the files, one line each (icon, name, date). The
 *  plan viewer (also column 3) and the reader (the fixed slideout) take
 *  the right side over it while they are open; the hub hides, and comes
 *  back the moment they close. Its width, like the sidebar's, is set by
 *  dragging its edge (js/pages/workspace/pane-resize.js writes --hub-w and
 *  --side-w on :root).
 * ────────────────────────────────────────────────────────────────── */
:root { --hub-w: 320px; }
.app { --pdf-w: var(--hub-w); }
body.gf-source-open:not(.gf-plan-pane-open) .app { --pdf-w: 0px; }
body.gf-source-open .gx-hub-pane,
body.gf-plan-pane-open .gx-hub-pane { display: none; }

/* Plans and Markup in the top-right corner (owner, 19 Oct 2026): the top
   bar runs the full width, its right edge in line with the hub box's, and
   whatever holds the right-hand column (the hub, or the plan viewer)
   starts under it, so neither ever covers the two buttons. */
.topbar { grid-column: 2 / 4; padding-right: 16px; }
.chat-plan-panel { grid-row: 2; }

.gx-hub-pane {
  grid-column: 3; grid-row: 2;
  position: relative; min-width: 0; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 16px 16px 16px 8px;
  background: var(--bg);
}
.gx-hub-box {
  flex: 0 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-xl);
  box-shadow: 0 1px 2px rgba(40,30,14,.04), 0 6px 20px rgba(40,30,14,.05);
}
.gx-hub-box-head { flex: none; display: flex; align-items: baseline; gap: 8px; padding: 14px 16px 4px; }
.gx-hub-box-head > span:first-child { font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -.01em; }
.gx-hub-box-head .count { margin-left: auto; font-size: 12px; color: var(--muted-2); }
.gx-hub-budget { --gx-hub-bar: var(--green); position: relative; flex: none; margin: 6px 16px 8px; font-size: 11px; line-height: 1.5; color: var(--muted); }
/* Green up to 70%, yellow to 90%, red above (owner, 2 Nov 2026). */
.gx-hub-budget.is-mid { --gx-hub-bar: #e0a800; }
.gx-hub-budget.is-high { --gx-hub-bar: var(--red); }
.gx-hub-budget-total { display: flex; align-items: center; gap: 5px; font-variant-numeric: tabular-nums; }
.gx-hub-budget-info { flex: none; width: 13px; height: 13px; padding: 0; display: grid; place-items: center; border: 1px solid var(--border-strong); border-radius: 50%; background: transparent; color: var(--muted); font: 600 9px/1 var(--font); cursor: help; transition: color 160ms var(--ease), border-color 160ms var(--ease); }
.gx-hub-budget-info:hover, .gx-hub-budget-info:focus-visible { color: var(--ink); border-color: var(--muted); outline: none; }
.gx-hub-budget-tip { display: none; position: absolute; z-index: 20; top: 21px; left: 0; right: 0; padding: 8px 10px; border-radius: var(--r); background: var(--ink); color: #fff; font-size: 11.5px; line-height: 1.45; box-shadow: 0 6px 20px rgba(40,30,14,.18); pointer-events: none; }
.gx-hub-budget-info:hover + .gx-hub-budget-tip, .gx-hub-budget-info:focus + .gx-hub-budget-tip { display: block; }
.gx-hub-budget-meter { display: block; width: 100%; height: 5px; margin: 4px 0; border: 0; border-radius: 999px; background: var(--border); accent-color: var(--gx-hub-bar); -webkit-appearance: none; appearance: none; }
.gx-hub-budget-meter::-webkit-meter-bar { height: 5px; background: var(--border); border: 0; border-radius: 999px; }
.gx-hub-budget-meter::-webkit-meter-optimum-value { background: var(--gx-hub-bar); border-radius: 999px; transition: width 200ms var(--ease); }
.gx-hub-budget-meter::-moz-meter-bar { background: var(--gx-hub-bar); border-radius: 999px; }
.gx-hub-budget-total[hidden], .gx-hub-budget-meter[hidden], .gx-hub-budget-remaining[hidden] { display: none; }
.gx-hub-budget-remaining { color: var(--muted-2); }
.gx-hub-budget.is-full .gx-hub-budget-remaining { color: #b45309; }
.gx-hub-budget.is-over-limit .gx-hub-budget-remaining { color: var(--red, #b42318); }
.gx-hub-add:disabled, .gx-hub-empty:disabled { opacity: .4; cursor: not-allowed; }
/* Only an empty hub says what it is for. */
.gx-hub-intro { display: none; margin: 2px 16px 4px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.gx-hub-pane.is-empty .gx-hub-intro { display: block; }
.gx-hub-pane-body {
  flex: 0 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 2px 10px 10px;
}
.gx-hub-pane-body::-webkit-scrollbar { width: 6px; }
.gx-hub-pane-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }

/* A section: its small grey name, the arrow that folds it, its count and its
   +. An empty one is its name and its + alone; nothing opens. */
.gx-hub-pane .gx-hub-section { margin: 0; padding-top: 8px; }
.gx-hub-pane .gx-hub-row,
.gx-hub-pane .gx-hub-row:hover,
.gx-hub-pane .gx-hub-section.is-open > .gx-hub-row { background: transparent; }
.gx-hub-pane .gx-hub-row {
  gap: 3px; height: 28px; padding: 0 6px;
  font-size: 12px; font-weight: 500; color: var(--muted); letter-spacing: 0;
}
.gx-hub-pane .gx-hub-name { order: 1; flex: 0 1 auto; }
.gx-hub-pane .gx-hub-chev { order: 2; width: 12px; height: 12px; color: var(--muted-2); }
.gx-hub-pane .gx-hub-chev svg { width: 11px; height: 11px; }
.gx-hub-pane .gx-hub-count { order: 3; margin-left: auto; padding-right: 4px; font-family: var(--font); font-size: 12px; color: var(--muted-2); }
.gx-hub-pane .gx-hub-add { order: 4; width: 22px; height: 22px; border: 0; border-radius: 6px; background: transparent; color: var(--muted-2); }
.gx-hub-pane .gx-hub-add:hover { background: var(--hover); color: var(--ink); }
.gx-hub-pane .gx-hub-add svg { width: 14px; height: 14px; }
.gx-hub-pane .gx-hub-section.is-empty > .gx-hub-row { cursor: default; color: var(--muted-2); }
.gx-hub-pane .gx-hub-section.is-empty .gx-hub-chev,
.gx-hub-pane .gx-hub-section.is-empty .gx-hub-count { display: none; }
.gx-hub-pane .gx-hub-section.is-empty .gx-hub-add { margin-left: auto; }
.gx-hub-pane .gx-hub-body { padding: 0; }
.gx-hub-pane .gx-hub-hint,
.gx-hub-pane .gx-hub-empty { display: none; }
.gx-hub-pane .gx-hub-section.is-drop-target > .gx-hub-drop-note { padding: 2px 6px 8px; }

/* A file: one line. Its icon, its name, and on the right its date or
   "No text"; pointed at or tabbed into, the move and remove buttons take
   the date's place. */
.gx-hub-pane .gx-hub-files .doc-item { gap: 10px; height: 30px; padding: 0 6px; margin: 0; border-radius: 7px; }
.gx-hub-pane .doc-item .doc-icon { width: 16px; height: 16px; }
.gx-hub-pane .doc-item .doc-icon svg { width: 15px; height: 15px; }
.gx-hub-pane .doc-item .doc-name { font-size: 13px; font-weight: 400; color: var(--ink); }
.gx-hub-pane .doc-item .doc-meta,
.gx-hub-pane .doc-item .doc-chip-warn { display: none; }
.doc-when { display: none; }
.gx-hub-pane .doc-when { display: block; flex: none; font-size: 12px; color: var(--muted-2); white-space: nowrap; }
.gx-hub-pane .doc-when.is-warn { color: #b45309; }
.gx-hub-pane .doc-item .doc-delete { display: none; font-size: 11px; color: var(--muted-2); }
.gx-hub-pane .doc-item .doc-delete:hover { color: var(--red); }
.gx-hub-pane .doc-item:hover .doc-when,
.gx-hub-pane .doc-item:focus-within .doc-when,
.gx-hub-pane .doc-item.is-menu-open .doc-when { display: none; }
.gx-hub-pane .doc-item:hover .doc-delete,
.gx-hub-pane .doc-item:focus-within .doc-delete,
.gx-hub-pane .doc-item.is-menu-open .doc-delete { display: grid; opacity: 1; transform: none; }
/* A section's first files; the rest behind "Show N more" (gxHubRefresh). */
.gx-hub-more { display: none; }
.gx-hub-pane .doc-item.is-over { display: none; }
.gx-hub-pane .gx-hub-more { display: block; margin: 0 0 2px 32px; padding: 4px 0; font-size: 12.5px; color: var(--muted); }
.gx-hub-pane .gx-hub-more:hover { color: var(--ink); }

/* A file row picked up to move it to another section (_gxHubWireMove). */
.gx-hub-pane .gx-hub-files .doc-item[draggable="true"] { cursor: grab; }
.gx-hub-pane .doc-item.is-dragging { opacity: .45; }
body.gx-hub-moving .gx-hub-pane .gx-hub-row,
body.gx-hub-moving .gx-hub-pane .doc-item { cursor: grabbing; }

/* ── Drag to resize: the sidebar's right edge and the hub's left edge ── */
.sidebar { position: relative; }
.gx-pane-resize {
  position: absolute; top: 0; bottom: 0; width: 8px; z-index: 6;
  cursor: col-resize; touch-action: none;
}
.gx-pane-resize::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 2px;
  background: transparent; transition: background 160ms var(--ease);
}
.gx-pane-resize-side { right: 0; }
.gx-pane-resize-side::after { right: 0; }
.gx-pane-resize-hub { left: 0; }
.gx-pane-resize-hub::after { left: 0; }
.gx-pane-resize:hover::after,
.gx-pane-resize.is-active::after { background: var(--green); }
.gx-pane-resize:focus-visible { outline: none; }
.gx-pane-resize:focus-visible::after { background: var(--green); }
/* While dragging: no column animation (the edge must follow the pointer),
   no text selection, and the resize cursor everywhere. */
body.gx-pane-resizing { cursor: col-resize; user-select: none; }
body.gx-pane-resizing .app { transition: none; }
body.gx-pane-resizing iframe, body.gx-pane-resizing canvas { pointer-events: none; }

/* ────────────────────────────────────────────────────────────────── *
 *  PDF-prep modal — force big modal + ensure footer buttons clickable
 *  The base pdf-prep.css declares 90vw / 1100px / 78vh — but a few CSS
 *  layer / specificity edges meant the modal could render at the default
 *  modal-box size (360px). Lock in explicit dimensions here so the
 *  modal-box surely matches the reference shape.
 * ────────────────────────────────────────────────────────────────── */
.modal-box.pdp-modal-box {
  width: 92vw !important;
  max-width: 1200px !important;
  height: 86vh !important;
  max-height: 840px !important;
  padding: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.modal-box.pdp-crop-box {
  width: min(94vw, 1040px) !important;
  max-width: 1040px !important;
  height: min(90vh, 760px) !important;
  max-height: 760px !important;
  padding: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}

/* PDP body fills the modal between header and footer. */
.modal-box.pdp-modal-box .pdp-body { flex: 1; min-height: 0; display: flex; }
.modal-box.pdp-modal-box .pdp-left { flex: 1; min-width: 0; overflow-y: auto; padding: 20px 24px; }
.modal-box.pdp-modal-box .pdp-right {
  width: 340px; flex-shrink: 0;
  display: flex; flex-direction: column;
  border-left: 1px solid var(--border);
  background: var(--surface);
  min-height: 0;
}
.modal-box.pdp-modal-box .pdp-segments-head { padding: 16px 18px 8px; flex: none; }
.modal-box.pdp-modal-box .pdp-segments-list { flex: 1; overflow-y: auto; padding: 0 14px 12px; min-height: 0; }
.modal-box.pdp-modal-box .pdp-footer {
  padding: 14px 18px; border-top: 1px solid var(--border);
  background: var(--surface);
  flex: none;
}

/* Crop modal — bigger canvas, footer always reachable. */
.modal-box.pdp-crop-box .pdp-crop-canvas-wrap {
  flex: 1; min-height: 360px; padding: 20px;
  background: var(--bg);
}
.modal-box.pdp-crop-box .pdp-crop-canvas-wrap canvas {
  max-width: 100%; max-height: 100%;
}
.modal-box.pdp-crop-box .pdp-footer {
  flex: none; padding: 14px 18px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  display: flex; gap: 10px; justify-content: flex-end;
  /* Guarantee clickable — clear any inherited pointer-events:none */
  pointer-events: auto;
}
.modal-box.pdp-crop-box .pdp-footer .modal-btn { pointer-events: auto; }

/* Make sure the modal backdrop sits on top of everything and centers
   the box. */
.modal-backdrop#pdpBackdrop,
.modal-backdrop#pdpCropBackdrop {
  align-items: center; justify-content: center;
}

/* ────────────────────────────────────────────────────────────────── *
 *  Source / doc / plan ticks — match the design-assets `.tick`
 *  component exactly: 16px rounded box, ink fill when on, white
 *  SVG check, click feedback on press.
 * ────────────────────────────────────────────────────────────────── */
.source-checkbox {
  width: 16px; height: 16px; border-radius: 4px;
  border: 1.5px solid var(--border-strong); background: var(--surface);
  flex: none; display: grid; place-items: center;
  transition: background 160ms var(--ease), border-color 160ms var(--ease), transform 160ms var(--ease);
  position: relative; cursor: pointer;
}
/* Tick glyph — rotated L drawn in pure CSS so we don't depend on JS
   injecting an SVG into the box. Stays consistent with the design-assets
   tick which uses an SVG check. */
.source-checkbox::after {
  content: ""; width: 8px; height: 4px;
  border-left: 1.7px solid #fff; border-bottom: 1.7px solid #fff;
  transform: rotate(-45deg) translate(0, -1px) scale(.6);
  opacity: 0;
  transition: opacity 160ms var(--ease), transform 200ms var(--ease);
}
.source-checkbox.checked {
  background: var(--ink); border-color: var(--ink);
}
.source-checkbox.checked::after {
  opacity: 1;
  transform: rotate(-45deg) translate(0, -1px) scale(1);
}
.source-checkbox:hover { border-color: var(--ink-soft); }
.source-checkbox.checked:hover { background: var(--ink); border-color: var(--ink); }
.source-item:active .source-checkbox { transform: scale(.92); }

/* Document rows have no tick: every document is sent to the AI (owner,
   5 Oct 2026). */

/* ─── Cool-grey palette: kill warm overlay residue ───────────────────
 * The Guide-x stylesheet was authored against a warm-parchment palette
 * (rgba(253,250,243,*) and saturate(140%) backdrop-filters). The user's
 * v3 reference and our :root tokens are cool grey (#fafbfc / #ffffff /
 * #e5e7eb). Those warm overlays leak orange chroma into the page —
 * particularly the sticky .status-row gradient at the top of the chat
 * column, where saturate(140%) actively amplifies whatever chroma the
 * cream rgba contributes. Repaint every warm rgba surface in cool
 * equivalents and drop the saturate() so the bg stays neutral. */
.status-row {
  background: linear-gradient(
    to bottom,
    var(--bg) 0%,
    var(--bg) 60%,
    rgba(250, 251, 252, .88) 100%
  ) !important;
  backdrop-filter: blur(8px) !important;
  -webkit-backdrop-filter: blur(8px) !important;
}
.pb-assessed-loader {
  background: rgba(250, 251, 252, .85) !important;
}
.cta-assess[data-locked="true"] .lock { color: rgba(255, 255, 255, .78); }
.pb-tool.active .pb-tool-key { color: rgba(255, 255, 255, .55); }

/* Belt-and-braces: any leftover legacy stylesheet that defined a warm
   --bg / --paper at :root before our adapter loads gets overridden here.
   Adapter is the last linked sheet so this wins. */
:root, :root.theme-light, html, body {
  --bg: #fafbfc !important;
  --surface: #ffffff !important;
  --sidebar: #f2f4f3 !important; /* keep in lockstep with guide-x.css :root */
  --paper: #f9fafb !important;
}
body { background: var(--bg) !important; }

/* ────────────────────────────────────────────────────────────────── *
 *  Upload wizard ("Prepare Plan — Area of work") — Guide-x skin
 *  Two modals: page-pick (.gf-wizard-thumbs) and crop (.gf-crop-viewport).
 *  Base sheet declares .gf-wizard .modal-box at 95vw/1100px but the
 *  adapter's generic .modal-box override and modal-box base in
 *  modals.css narrow it. Force big size with !important and reskin
 *  every wizard surface in Guide-x vocabulary.
 * ────────────────────────────────────────────────────────────────── */
.gf-wizard.modal-backdrop {
  background: rgba(20, 18, 14, 0.45);
  backdrop-filter: blur(14px) saturate(1.05);
  -webkit-backdrop-filter: blur(14px) saturate(1.05);
  padding: 24px;
}
.gf-wizard .modal-box {
  width: 95vw !important;
  max-width: 1100px !important;
  height: auto !important;
  max-height: 92vh !important;
  padding: 22px 26px 18px !important;
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 12px !important;
  box-shadow: 0 24px 56px rgba(20, 14, 4, .20) !important;
  display: flex !important; flex-direction: column !important;
  gap: 10px !important;
  color: var(--ink) !important;
}

/* Wizard title: mono uppercase + flame accent on the EM-dash word. */
.gf-wizard .modal-title {
  font-family: var(--font-mono, 'JetBrains Mono', ui-monospace, monospace) !important;
  font-size: 11px !important;
  letter-spacing: .18em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  font-weight: 700 !important;
  margin: 0 0 4px !important;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

/* Wizard hint line — quiet body copy, ink-soft. */
.gf-wizard-hint {
  font-size: 13px !important;
  line-height: 1.55 !important;
  color: var(--ink-soft, #5b6470) !important;
  padding: 10px 2px 6px !important;
  margin: 0 !important;
}
.gf-wizard-hint b {
  color: var(--ink) !important;
  font-weight: 600 !important;
}

/* Page-pick grid */
.gf-wizard-thumbs {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)) !important;
  gap: 14px !important;
  padding: 4px !important;
  max-height: 64vh !important;
}
.gf-wizard-thumb {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  padding: 10px !important;
  transition: border-color 160ms var(--ease), transform 160ms var(--ease), box-shadow 160ms var(--ease) !important;
  box-shadow: none !important;
}
.gf-wizard-thumb:hover {
  border-color: var(--ink) !important;
  transform: translateY(-2px) !important;
  box-shadow: 0 8px 22px rgba(20, 14, 4, .08) !important;
}
.gf-wizard-thumb canvas {
  border-radius: 4px !important;
  background: #fff !important;
}
.gf-wizard-thumb-label {
  font-family: var(--font-mono, 'JetBrains Mono', monospace) !important;
  font-size: 10.5px !important;
  letter-spacing: .14em !important;
  color: var(--ink-soft, #5b6470) !important;
  font-weight: 600 !important;
}
.gf-wizard-spinner {
  font-family: var(--font-mono, 'JetBrains Mono', monospace) !important;
  font-size: 11px !important;
  letter-spacing: .12em !important;
  color: var(--ink-soft, #5b6470) !important;
}

/* Crop viewport — calm grey backdrop, hairline border, big canvas. */
.gf-crop-viewport {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  margin: 6px 0 14px !important;
  max-height: 70vh !important;
  cursor: crosshair;
}
.gf-crop-viewport canvas {
  background: #fff !important;
  box-shadow: 0 1px 3px rgba(20, 14, 4, .06) !important;
}

/* The drag rectangle — flame stroke + flame-soft fill (Guide-x accent). */
.gf-crop-rect {
  border: 2px dashed var(--flame, #63c76a) !important;
  background: rgba(99, 199, 106, .10) !important;
  border-radius: 2px !important;
}

/* Wizard footer buttons — Guide-x modal-btn vocabulary. */
.gf-wizard .modal-actions {
  padding-top: 6px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
  display: flex !important;
  justify-content: flex-end !important;
  gap: 8px !important;
}
.gf-wizard .modal-btn {
  display: inline-flex !important;
  align-items: center !important;
  height: 34px !important;
  padding: 0 16px !important;
  font-family: var(--font, -apple-system, 'Inter', system-ui, sans-serif) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0 !important;
  border-radius: 6px !important;
  border: 1px solid var(--border) !important;
  background: var(--surface) !important;
  color: var(--ink) !important;
  cursor: pointer !important;
  transition: background 160ms var(--ease), border-color 160ms var(--ease), color 160ms var(--ease), transform 80ms ease !important;
  pointer-events: auto !important;
}
.gf-wizard .modal-btn:hover {
  background: var(--hover, rgba(20, 14, 4, .04)) !important;
  border-color: var(--ink-soft, #5b6470) !important;
}
.gf-wizard .modal-btn:active { transform: translateY(1px); }
.gf-wizard .modal-btn.cancel {
  background: transparent !important;
  color: var(--ink-soft, #5b6470) !important;
}
.gf-wizard .modal-btn.cancel:hover {
  color: var(--ink) !important;
  background: var(--hover, rgba(20, 14, 4, .04)) !important;
}
.gf-wizard .modal-btn.confirm {
  background: var(--ink) !important;
  border-color: var(--ink) !important;
  color: #fff !important;
}
.gf-wizard .modal-btn.confirm:hover:not(:disabled) {
  background: var(--green, #16a34a) !important;
  border-color: var(--green, #16a34a) !important;
}
.gf-wizard .modal-btn:disabled,
.gf-wizard .modal-btn.confirm:disabled {
  opacity: .42 !important;
  cursor: not-allowed !important;
  transform: none !important;
}

/* ──────────────────────────────────────────────────────────────────
 * Brief modal — clamp to viewport, scroll inside, no overflow
 * The default `.gf-brief-box` rule earlier in this sheet sets it to
 * `max-width:640px;padding:28px`, but doesn't bound the height — so
 * with the residential/commercial questionnaire (8–10 questions) the
 * modal grows past the bottom of the viewport, hiding the footer and
 * pushing Save / Skip out of frame. Re-declare the box here so it:
 *   1) always sizes within the viewport
 *   2) splits into head (fixed) + body (scroll) + foot (fixed)
 *   3) adapts gracefully on narrow screens (single-column type picker)
 * ────────────────────────────────────────────────────────────────── */
#projectBriefModal .gf-brief-box,
.gf-brief-box {
  width: min(760px, 92vw) !important;
  max-width: min(760px, 92vw) !important;
  max-height: min(86vh, 820px) !important;
  display: flex !important;
  flex-direction: column !important;
  padding: 0 !important;
  overflow: hidden !important;
  gap: 0;
}
.gf-brief-box .gf-brief-head {
  padding: 22px 26px 16px;
  margin: 0;
  border-bottom: 1px solid var(--border);
  flex: none;
}
.gf-brief-box .gf-brief-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 22px 26px;
}
.gf-brief-box .gf-brief-foot {
  flex: none;
  margin: 0;
  padding: 14px 22px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.gf-brief-box #gfBriefLoader {
  padding: 32px 26px;
}
.gf-brief-box .gf-brief-types {
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 640px) {
  .gf-brief-box .gf-brief-types { grid-template-columns: 1fr; }
  .gf-brief-box .gf-brief-head,
  .gf-brief-box .gf-brief-body { padding-left: 18px; padding-right: 18px; }
  .gf-brief-box .gf-brief-foot { padding-left: 14px; padding-right: 14px; }
}
@media (max-height: 640px) {
  #projectBriefModal .gf-brief-box,
  .gf-brief-box { max-height: 94vh !important; }
}

/* Anchor the brief modal to the top of the viewport (topbar level) instead
   of centered vertically. Sits ~16px below the topbar's bottom edge.
   Max-height is reduced to account for the new top padding so the modal
   still fits within the viewport without scrolling the page itself. */
#projectBriefModal {
  align-items: flex-start !important;
  justify-content: center !important;
  padding-top: 72px;
  overflow-y: auto;
}
#projectBriefModal .gf-brief-box {
  max-height: calc(100vh - 96px) !important;
  margin: 0;
}
@media (max-height: 720px) {
  #projectBriefModal { padding-top: 56px; }
  #projectBriefModal .gf-brief-box { max-height: calc(100vh - 72px) !important; }
}

/* ──────────────────────────────────────────────────────────────────
 * Chat column — slightly indented from the left, slightly wider AI
 * Default `.main-scroll` padding is `0 32px 32px 28px` and the
 * assistant bubble caps at 760px. Per the v3 reference the chat
 * column starts ~64px in from the sidebar edge, and the AI prose
 * sits at ~880px so paragraphs breathe. When the PDF pane is open
 * we pull the gutters back in so both columns stay readable.
 * ────────────────────────────────────────────────────────────────── */
.main-scroll {
  padding-left: 340px !important;
  padding-right: 56px !important;
}
.main-inner { max-width: 920px; margin: 0 0 0 auto !important; }
.app[data-pdf="open"] .main-scroll {
  padding-left: 96px !important;
  padding-right: 36px !important;
}
.app[data-pdf="open"] .main-inner { max-width: none; margin: 0 !important; }

/* AI prose — slightly wider measure (≈ 88ch) */
.message.assistant { max-width: 880px !important; }
.message.assistant > .bubble { max-width: 880px !important; }

/* User bubble — wider cap so longer queries don't break early */
.message.user > .bubble { max-width: min(86%, 760px) !important; }

/* Composer spans the full width of the chat column (not capped) */
.chat-input-area { padding-left: 28px !important; padding-right: 32px !important; }
.composer, .gf-chat-pill { max-width: none !important; width: 100% !important; }
.app[data-pdf="open"] .chat-input-area,
.app[data-spatial="open"] .chat-input-area {
  padding-left: 20px !important; padding-right: 20px !important;
}

@media (max-width: 1100px) {
  .main-scroll {
    padding-left: 160px !important;
    padding-right: 32px !important;
  }
  .main-inner { margin: 0 0 0 auto !important; }
  .message.assistant,
  .message.assistant > .bubble { max-width: 100% !important; }
}

/* Tables in a Projects chat answer use the chat's full width (owner,
   29 Oct 2026). The 880px measure above is for reading prose; tables were
   held to it too and came out crushed, with empty space to their right.
   And the answer's overflow-wrap:anywhere let the browser shrink a column
   to one letter, so a header like "Page" split into "Pa / ge".
   Now: an answer that holds a table may widen to the chat column, its
   prose keeps the 880px measure, cells break only between words, and a
   table too wide for even the full column scrolls sideways instead of
   squeezing. Scoped to .chat-messages: the Fire Strategy report chats share
   these message classes and keep their own table rules. */
.chat-messages .message.assistant:has(table),
.chat-messages .message.assistant:has(table) > .bubble { max-width: none !important; }
.chat-messages .message.assistant > .bubble:has(table) :is(p, ul, ol, h1, h2, h3, h4, blockquote, pre, hr) {
  max-width: 880px;
}
.chat-messages .message.assistant table {
  display: block; width: max-content; max-width: 100%;
  overflow-x: auto;
}
.chat-messages .message.assistant th,
.chat-messages .message.assistant td {
  overflow-wrap: normal; word-break: normal;
  vertical-align: top;
}
/* The trailing flame caret is drawn just past a block's right edge; inside a
   table that scrolls, it would add a scrollbar of its own. */
.chat-messages .message.assistant > .bubble table::after { display: none; }

/* Calmer chips in a Projects chat answer (owner, 29 Oct 2026). Every
   citation was darker and bolder than its sentence, with a dashed line and a
   ↗; every plan space bold with a black dot and a black line. In an answer
   full of them the eye stopped at each one. Picked from a preview of options:
   - Standards citations (option A): the sentence's own colour and weight with
     a faint solid line under it; the ↗ and the darker ink come on hover.
   - Plan spaces (option C): no dot, no bold, a faint green line under the name.
   Geometry is the same at rest, hover and active (only paint changes), so a
   chip near a line break never rewraps under the cursor (see the base rule).
   Scoped to .chat-messages: the Fire Strategy report chats keep their own. */
.chat-messages .message.assistant .gf-citation,
.chat-messages .message.assistant .gf-citation-anchor {
  position: relative;
  color: inherit !important;
  font-weight: 400 !important;
  border-bottom: 1px solid rgba(55,65,81,.22) !important;
  border-radius: 3px !important;
  padding: 0 0 1px !important;
  margin: 0 !important;
}
/* The ↗ takes no room (owner, 29 Oct 2026). Hidden but still in the line, it
   left a blank, underlined gap after every citation: "(ADB · Vol 2, clause
   2.1 )". It now floats just past the chip's last character, so the line and
   the hover highlight end on the reference itself, and showing it on hover
   still moves nothing. Small enough to sit inside a table cell's padding. */
.chat-messages .message.assistant .gf-citation::after,
.chat-messages .message.assistant .gf-citation-anchor::after {
  position: absolute; left: 100%; top: 0;
  margin-left: 1px;
  font-size: .72em;
  line-height: 1 !important;
  opacity: 0;
  pointer-events: none;
}
.chat-messages .message.assistant .gf-citation:hover,
.chat-messages .message.assistant .gf-citation-anchor:hover,
.chat-messages .message.assistant .gf-citation.active,
.chat-messages .message.assistant .gf-citation-anchor.active {
  color: var(--ink) !important;
  background: var(--hover) !important;
  border-bottom: 1px solid var(--ink) !important;
}
.chat-messages .message.assistant .gf-citation:hover::after,
.chat-messages .message.assistant .gf-citation-anchor:hover::after,
.chat-messages .message.assistant .gf-citation.active::after,
.chat-messages .message.assistant .gf-citation-anchor.active::after { opacity: .7; }
/* Not yet verified against the page: the same faint line, dashed. */
.chat-messages .message.assistant .gf-citation.gf-citation-unverified {
  border-bottom-style: dashed !important;
}

.chat-messages .message.assistant .gf-pin-link {
  display: inline !important;
  color: var(--ink) !important;
  font-weight: 500 !important;
  font-size: inherit !important;
  line-height: inherit !important;
  white-space: nowrap;
  border-bottom: 1px solid rgba(47,156,88,.45) !important;
  border-radius: 3px !important;
  padding: 0 0 1px !important;
  margin: 0 !important;
}
.chat-messages .message.assistant .gf-pin-link::before { display: none !important; }
.chat-messages .message.assistant .gf-pin-link:hover,
.chat-messages .message.assistant .gf-pin-link.active {
  color: var(--ink) !important;
  background: var(--hover) !important;
  border-bottom-color: var(--green-deep) !important;
  padding: 0 0 1px !important;
  margin: 0 !important;
}

/* ═══════════════════════════════════════════════════════════════════
 *  3-stage wizard (Pages → Crop → Markup) — shared chrome + stepper
 *  Matches the movqae10 reference. Used by _wizardPickPage,
 *  _wizardCropStep, and the planFormModal (stage 3).
 * ═══════════════════════════════════════════════════════════════════ */

/* Full-viewport backdrop with quiet ink scrim */
.modal-backdrop.gx-wizard {
  background: rgba(20, 18, 14, 0.45) !important;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  padding: 0 !important;
  align-items: stretch !important;
  justify-content: stretch !important;
}

/* Wizard box is full-screen, flex column */
.modal-box.gx-wizard-box {
  width: 100vw !important;
  height: 100vh !important;
  max-width: none !important;
  max-height: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  background: var(--bg, #fafbfc) !important;
  overflow: hidden !important;
  box-shadow: none !important;
  border: none !important;
  gap: 0 !important;
}

/* Chrome header */
.gx-chrome {
  flex: none;
  display: flex !important;
  align-items: center;
  justify-content: space-between !important;
  gap: 12px;
  padding: 18px 22px !important;
  border-bottom: 1px solid var(--border, #e5e7eb) !important;
  background: var(--bg, #fafbfc);
  min-height: 64px;
}
.gx-chrome-left {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  flex: 1;
}
.gx-chrome-right {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: none;
}

.gx-chrome-mark {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-weight: 700;
  font-size: 16px;
  color: var(--ink, #1a1d20);
  line-height: 1;
  letter-spacing: -0.02em;
}
.gx-chrome-mark > .gx-blink,
.gx-chrome-mark i.gx-blink {
  color: var(--flame, #63c76a);
  font-style: normal;
  animation: none;
  opacity: 1;
}

.gx-chrome-title {
  font-family: var(--font-display, 'Inter', system-ui, sans-serif);
  font-weight: 600;
  font-size: 17px;
  color: var(--ink, #1a1d20);
  margin: 0;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.gx-chrome-pill {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft, #6b7280);
  padding: 0;
  border: 0;
  border-radius: 0;
  white-space: nowrap;
  background: transparent;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0;
}
.gx-chrome-pill::before { content: '· '; opacity: .6; margin-right: 2px; }

.gx-chrome-close {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: none;
  border: none;
  color: var(--ink-soft, #6b7280);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 160ms, color 160ms;
  padding: 0;
}
.gx-chrome-close:hover {
  background: var(--hover, rgba(0,0,0,0.04));
  color: var(--ink, #1a1d20);
}

/* Stepper pill */
.gx-stepper {
  display: inline-flex;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}
.gx-step {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 6px;
  border-radius: 999px;
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft, #6b7280);
  background: transparent;
  border: none;
  cursor: default;
  user-select: none;
  transition: background 220ms cubic-bezier(.4, 0, .2, 1), color 220ms;
  line-height: 1;
}
.gx-step.is-active {
  background: var(--ink, #1a1d20);
  color: #fff;
}
.gx-step.is-active .gx-step-num {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}
.gx-step.is-done .gx-step-num {
  background: rgba(34, 167, 95, 0.16);
  color: rgb(34, 132, 76);
}
.gx-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--hover, rgba(0,0,0,0.05));
  color: var(--ink-soft, #6b7280);
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-weight: 600;
  font-size: 11px;
  line-height: 1;
  flex: none;
}
.gx-step-label { line-height: 1; }

/* Wizard body flexes between chrome and footbar */
.gx-wizard-body {
  flex: 1;
  display: flex;
  min-height: 0;
  overflow: hidden;
}

/* ── Stage 1 — Pages ─────────────────────────────────────────────── */
.gx-pages-side {
  width: 300px;
  flex: none;
  border-right: 1px solid var(--border, #e5e7eb);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden;
  background: var(--bg, #fafbfc);
}
.gx-pages-head {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-soft, #6b7280);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0 4px 2px;
}
.gx-pages-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-right: 4px;
}
.gx-pages-loading {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 11px;
  color: var(--ink-soft, #6b7280);
  padding: 12px;
  letter-spacing: 0.1em;
}
.gx-page-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border-radius: 8px;
  border: 1px solid var(--border, #e5e7eb);
  background: var(--surface, #fff);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  transition: border-color 160ms, box-shadow 160ms;
  appearance: none;
}
.gx-page-row:hover {
  border-color: var(--ink-soft, #6b7280);
}
.gx-page-row.is-selected {
  border: 2px solid var(--ink, #1a1d20);
  padding: 10px 11px;
  box-shadow: 0 6px 14px -8px rgba(0, 0, 0, 0.1);
}
.gx-page-thumb {
  width: 44px;
  height: 30px;
  flex: none;
  border: 1px solid var(--ink-soft, #6b7280);
  border-radius: 3px;
  overflow: hidden;
  background: var(--bg, #fafbfc);
  display: flex;
  align-items: center;
  justify-content: center;
}
.gx-page-thumb canvas {
  max-width: 100%;
  max-height: 100%;
  display: block;
}
.gx-page-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gx-page-title {
  font-family: var(--font-display, 'Inter', system-ui, sans-serif);
  font-weight: 600;
  font-size: 13px;
  color: var(--ink, #1a1d20);
  letter-spacing: -0.005em;
}
.gx-tick {
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1.5px solid var(--ink-soft, #6b7280);
  background: var(--surface, #fff);
  position: relative;
  transition: background 200ms, border-color 200ms;
}
.gx-page-row.is-selected .gx-tick {
  background: var(--ink, #1a1d20);
  border-color: var(--ink, #1a1d20);
}
.gx-page-row.is-selected .gx-tick::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 1px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.gx-pages-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  background: var(--paper, #f9fafb);
  overflow: auto;
}
.gx-paper {
  position: relative;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e5e7eb);
  padding: 28px;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 18px -10px rgba(0, 0, 0, 0.1);
}
.gx-paper-pgnum {
  position: absolute;
  top: 10px;
  right: 14px;
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 11px;
  color: var(--ink-soft, #6b7280);
  letter-spacing: 0.14em;
}
.gx-paper-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 320px;
  min-height: 240px;
}
.gx-paper-preview canvas {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 240px);
}
.gx-paper-spinner {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 11px;
  color: var(--ink-soft, #6b7280);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ── Stage 2 — Crop ──────────────────────────────────────────────── */
.gx-crop-main {
  flex: 1;
  min-width: 0;
  background: rgba(20, 18, 14, 0.18);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.gx-crop-main .gx-crop-viewport,
.gf-crop-viewport.gx-crop-viewport {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: crosshair;
  user-select: none;
  padding: 32px;
  box-sizing: border-box;
  background: transparent;
}
.gx-crop-main canvas {
  display: block;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
  box-shadow: 0 12px 36px -10px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  max-width: 100%;
  max-height: 100%;
}
.gx-crop-rect.gf-crop-rect,
.gf-crop-rect.gx-crop-rect {
  position: absolute;
  display: none;
  /* Neutral ink-soft selection — dashed grey border, near-transparent fill
     so the cropped content stays fully legible inside the box. The dim scrim
     OUTSIDE the box still darkens (via the box-shadow), which gives the
     contrast against the inside surface. */
  border: 1.5px dashed rgba(20, 14, 4, 0.55) !important;
  background: rgba(255, 255, 255, 0.04) !important;
  pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(20, 18, 14, 0.42);
  z-index: 2;
}
.gx-crop-rect.gf-crop-rect::before,
.gx-crop-rect.gf-crop-rect::after,
.gf-crop-rect.gx-crop-rect::before,
.gf-crop-rect.gx-crop-rect::after {
  content: '';
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--surface, #fff);
  border: 1.5px solid rgba(20, 14, 4, 0.65);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.gx-crop-rect.gf-crop-rect::before,
.gf-crop-rect.gx-crop-rect::before {
  top: -6px;
  left: -6px;
}
.gx-crop-rect.gf-crop-rect::after,
.gf-crop-rect.gx-crop-rect::after {
  bottom: -6px;
  right: -6px;
}

.gx-crop-side {
  width: 340px;
  flex: none;
  border-left: 1px solid var(--border, #e5e7eb);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  overflow-y: auto;
  background: var(--bg, #fafbfc);
}
.gx-crop-title {
  margin: 0;
  font-family: var(--font-display, 'Inter', system-ui, sans-serif);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink, #1a1d20);
  letter-spacing: -0.005em;
}
.gx-crop-blurb {
  margin: 0;
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-soft, #6b7280);
}
.gx-crop-meta {
  margin: 8px 0 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.gx-crop-meta > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.gx-crop-meta dt {
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 12px;
  color: var(--ink-soft, #6b7280);
  margin: 0;
}
.gx-crop-meta dd {
  margin: 0;
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 12.5px;
  color: var(--ink, #1a1d20);
}
.gx-crop-tip {
  margin-top: auto;
  border: 1px solid var(--border, #e5e7eb);
  background: var(--surface, #fff);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-soft, #6b7280);
}
.gx-crop-tip b {
  color: var(--ink, #1a1d20);
  font-weight: 600;
}

/* ── Footbar (shared) ────────────────────────────────────────────── */
.gx-footbar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 22px;
  border-top: 1px solid var(--border, #e5e7eb);
  background: var(--bg, #fafbfc);
}
.gx-footbar-status {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 11px;
  color: var(--ink-soft, #6b7280);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.gx-footbar-btns {
  display: inline-flex;
  gap: 8px;
}
.gx-btn {
  appearance: none;
  border: 1px solid var(--border, #e5e7eb);
  background: var(--surface, #fff);
  color: var(--ink, #1a1d20);
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 13px;
  font-weight: 500;
  padding: 9px 16px;
  border-radius: 6px;
  cursor: pointer;
  line-height: 1.2;
  transition: background 160ms, color 160ms, border-color 160ms, transform 80ms;
  letter-spacing: -0.005em;
}
.gx-btn:hover {
  background: var(--hover, rgba(0,0,0,0.04));
  border-color: var(--ink-soft, #6b7280);
}
.gx-btn:active { transform: scale(0.98); }
.gx-btn-ghost {
  background: transparent;
  color: var(--ink-soft, #6b7280);
}
.gx-btn-ghost:hover {
  background: var(--hover, rgba(0,0,0,0.04));
  color: var(--ink, #1a1d20);
}
.gx-btn-primary {
  background: var(--ink, #1a1d20);
  color: #fff;
  border-color: var(--ink, #1a1d20);
}
.gx-btn-primary:hover {
  background: oklch(38% 0.13 145);
  border-color: oklch(38% 0.13 145);
}
.gx-btn-primary:disabled {
  background: var(--ink-soft, #6b7280);
  border-color: var(--ink-soft, #6b7280);
  color: rgba(255, 255, 255, 0.7);
  cursor: not-allowed;
  transform: none;
}

/* ── Stage 3 — Markup (planFormModal wears the wizard chrome) ────── */

/* Plan-form modal becomes full-viewport, flex column */
#planFormModal { background: rgba(20, 18, 14, 0.45) !important; }
#planFormModal .plan-form-box.gx-wizard-box {
  width: 100vw !important;
  height: 100vh !important;
  max-width: none !important;
  max-height: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  background: var(--bg, #fafbfc) !important;
}

/* Override pf-header centered-title layout to chrome row */
#planFormModal .pf-header { padding: 0 !important; background: transparent; border-bottom: none !important; }
#planFormModal .pf-header-row.gx-chrome {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding: 18px 22px !important;
  border-bottom: 1px solid var(--border, #e5e7eb) !important;
  background: var(--bg, #fafbfc) !important;
  min-height: 64px;
}
/* The original .pf-project-name styling pulled it large + centered; override
 * inside the chrome-pill grouping. */
#planFormModal .pf-project-name.gx-chrome-pill {
  font-size: 12px !important;
  font-weight: 500 !important;
  color: var(--ink-soft, #6b7280) !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  border-radius: 0 !important;
  margin: 0 !important;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
}
#planFormModal .pf-close.gx-chrome-close {
  position: static !important;
  width: 32px !important;
  height: 32px !important;
  border-radius: 50% !important;
  background: none !important;
  border: none !important;
  color: var(--ink-soft, #6b7280) !important;
  font-size: 22px !important;
}
#planFormModal .pf-close.gx-chrome-close:hover {
  background: var(--hover, rgba(0,0,0,0.04)) !important;
  color: var(--ink, #1a1d20) !important;
}

/* FLOOR meta lives below the chrome — show it as the small label + pill
 * row exactly like the reference. The grid is populated by renderPlanForm()
 * so we only theme the wrapper here. */
#planFormModal .pf-meta-grid {
  padding: 12px 22px !important;
  border-bottom: 1px solid var(--border, #e5e7eb) !important;
  background: var(--bg, #fafbfc) !important;
}

/* Hidden in adapter — kbd hints conflict with the wizard status row */
#planFormModal .pf-kbd-hints { opacity: .55; }

/* Footer buttons (combined .modal-btn + .gx-btn) — prefer gx-btn vocabulary */
#planFormModal .pf-footer-buttons .modal-btn.gx-btn {
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: 13px;
  font-weight: 500;
  padding: 9px 16px !important;
  border-radius: 6px !important;
  letter-spacing: -0.005em;
  line-height: 1.2;
  text-transform: none !important;
}
#planFormModal .pf-footer-buttons .modal-btn.gx-btn-ghost {
  background: transparent !important;
  border: 1px solid var(--border, #e5e7eb) !important;
  color: var(--ink-soft, #6b7280) !important;
}
#planFormModal .pf-footer-buttons .modal-btn.gx-btn-ghost:hover {
  background: var(--hover, rgba(0,0,0,0.04)) !important;
  color: var(--ink, #1a1d20) !important;
}
#planFormModal .pf-footer-buttons .modal-btn.gx-btn-primary {
  background: oklch(45% 0.14 145) !important;
  border: 1px solid oklch(45% 0.14 145) !important;
  color: #fff !important;
}
#planFormModal .pf-footer-buttons .modal-btn.gx-btn-primary:hover {
  background: oklch(40% 0.14 145) !important;
  border-color: oklch(40% 0.14 145) !important;
}

/* ── Responsive: narrower screens ────────────────────────────────── */
@media (max-width: 1100px) {
  .gx-pages-side { width: 240px; padding: 14px; }
  .gx-crop-side  { width: 280px; padding: 20px; }
  .gx-chrome-title { font-size: 15px; }
  .gx-chrome { padding: 14px 18px !important; }
  .gx-footbar { padding: 12px 18px; }
}
@media (max-width: 880px) {
  .gx-stepper { display: none; }
  .gx-chrome-pill { max-width: 160px; }
}

/* ── Markup window close-path hardening ──────────────────────────── *
 *  Save-flow confirm modals (discard / no-spaces / unnamed-rooms /
 *  assessment-loss) must render ABOVE #planFormModal. The natural
 *  z-index allowlist in modals.css lives inside `@layer base` and is
 *  defeated by the unlayered `.modal-backdrop { z-index: 100 }` rule
 *  earlier in this file — so this defensive override is what actually
 *  governs the stacking. Also re-asserts pointer-events and visibility
 *  so the buttons are always clickable.
 * ────────────────────────────────────────────────────────────────── */
#planDiscardModal,
#planNoSpacesModal,
#planUnnamedRoomsModal {
  z-index: 3000 !important;
}
#planDiscardModal.open,
#planNoSpacesModal.open,
#planUnnamedRoomsModal.open {
  display: flex !important;
  pointer-events: auto !important;
  opacity: 1 !important;
}
#planDiscardModal .modal-box,
#planNoSpacesModal .modal-box,
#planUnnamedRoomsModal .modal-box {
  pointer-events: auto !important;
  position: relative;
  z-index: 1;
}
#planDiscardModal .modal-actions .modal-btn,
#planNoSpacesModal .modal-actions .modal-btn,
#planUnnamedRoomsModal .modal-actions .modal-btn {
  pointer-events: auto !important;
  cursor: pointer !important;
}

/* Force the X (top-right) and Back/Save (bottom-right) buttons to always
 * be clickable, even if a future style accidentally inherits pointer-events:
 * none from a parent. */
#planFormModal .pf-close,
#planFormModal .pf-close.gx-chrome-close,
#planFormModal .pf-footer-buttons .modal-btn {
  pointer-events: auto !important;
  cursor: pointer !important;
  position: relative;
  z-index: 2;
}
#planFormModal .pf-header-row.gx-chrome,
#planFormModal .pf-footer-buttons {
  pointer-events: auto !important;
}

/* ─────────────────────────────────────────────────────────────────
   Markup window — right-rail categories + radial pin picker
   Reskin to match the reference (movqae10-guidex-start-screen-5):
     - sidebar tabs render as soft, collapsible category sections
       with rounded-square swatches and a per-category --cat hue;
     - radial picker uses 50px colored circles with a label pill
       underneath instead of small ringed badge buttons.
   No JS changes — wins purely on CSS specificity.
   ───────────────────────────────────────────────────────────────── */

/* Per-category color tokens. Bound by selector so the working
   software's pin palette (mint/gold/sky/purple/red) is reused — only
   the SHAPE matches the reference; the hues stay native. */
.pf-tab-group[data-tab="rooms"],      .pf-tab[data-tab="rooms"]      { --cat: #5FD9A3; --cat-soft: rgba(95,217,163,.16); }
.pf-tab-group[data-tab="openareas"],  .pf-tab[data-tab="openareas"]  { --cat: #2DD4BF; --cat-soft: rgba(45,212,191,.16); }
.pf-tab-group[data-tab="corridors"],  .pf-tab[data-tab="corridors"]  { --cat: #F5B04D; --cat-soft: rgba(245,176,77,.16); }
.pf-tab-group[data-tab="stairwells"], .pf-tab[data-tab="stairwells"] { --cat: #5AA9FF; --cat-soft: rgba(90,169,255,.16); }
.pf-tab-group[data-tab="lifts"],      .pf-tab[data-tab="lifts"]      { --cat: #B57DFF; --cat-soft: rgba(181,125,255,.16); }
.pf-tab-group[data-tab="exits"],      .pf-tab[data-tab="exits"]      { --cat: #FF6B6B; --cat-soft: rgba(255,107,107,.16); }

/* ── Sidebar tabs — match .pb-cat-section + .pb-cat-head ────────── */
.pf-tabs {
  background: var(--sidebar) !important;
  padding: 0 !important;
}
.pf-tabs-section-head {
  padding: 16px 18px 12px !important;
  border-bottom: 1px solid var(--border) !important;
  font-family: var(--font-mono) !important;
  font-size: 10.5px !important; letter-spacing: .14em !important;
  text-transform: uppercase !important; color: var(--muted) !important;
  font-weight: 600 !important;
}
.pf-tab-group {
  border-bottom: 1px solid var(--border) !important;
  background: transparent !important;
}
.pf-tab {
  display: flex !important; align-items: center !important;
  gap: 10px !important;
  padding: 11px 18px !important;
  cursor: pointer !important; user-select: none !important;
  border-left: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  transition: background 180ms var(--ease) !important;
}
.pf-tab { position: relative !important; }
.pf-tab:hover { background: var(--hover) !important; }
/* Active section — quiet flat fill. No gradient, no inset ring, no outer glow.
   Just a single soft category-tint that reads as selected without any aura. */
.pf-tab.active {
  background: var(--cat-soft, var(--hover)) !important;
  box-shadow: none !important;
  transition: background 200ms var(--ease) !important;
}
.pf-tab.active::before { content: none !important; }
.pf-tab.active .pf-tab-label { color: var(--ink) !important; font-weight: 600 !important; }

/* Swatch — colored rounded square holding a pin-glyph SVG (lucide map-pin).
   Same glyph as the canvas pins and the radial options. */
.pf-tab-dot {
  width: 22px !important; height: 22px !important;
  border-radius: 5px !important;
  background: var(--cat, var(--ink-soft)) !important;
  color: #fff !important;
  display: grid !important; place-items: center !important;
  font-size: 0 !important; /* hide any legacy letter content */
  letter-spacing: 0 !important;
  box-shadow:
    inset 0 -1px 0 rgba(0,0,0,.10),
    0 1px 2px rgba(20,14,4,.10) !important;
  border: 0 !important;
  flex: none !important;
  transition: transform 200ms var(--ease), box-shadow 200ms var(--ease) !important;
}
.pf-tab-dot .pf-tab-pin {
  width: 13px !important; height: 13px !important;
  color: #fff !important;
  display: block !important;
}
.pf-tab:hover .pf-tab-dot {
  transform: none !important;
  box-shadow:
    inset 0 -1px 0 rgba(0,0,0,.08),
    0 1px 2px rgba(20,14,4,.10) !important;
}
.pf-tab.active .pf-tab-dot {
  background: var(--cat, var(--ink-soft)) !important;
  box-shadow:
    inset 0 -1px 0 rgba(0,0,0,.08),
    0 1px 2px rgba(20,14,4,.10) !important;
}

/* Name — softer, sentence-cased weight */
.pf-tab-label {
  flex: 1 !important; min-width: 0 !important;
  font-family: var(--font) !important;
  font-size: 12.5px !important; font-weight: 600 !important;
  color: var(--ink) !important;
  letter-spacing: -.005em !important;
  text-transform: none !important;
}

/* Count — quiet mono number, no rounded pill background */
.pf-tab-count {
  background: transparent !important;
  font-family: var(--font-mono) !important;
  font-size: 11px !important; font-weight: 500 !important;
  font-variant-numeric: tabular-nums !important;
  color: var(--muted-2) !important;
  padding: 0 !important; min-width: 0 !important;
}
.pf-tab.active .pf-tab-count { color: var(--cat, var(--muted-2)) !important; }

/* Chevron — small muted arrow that rotates when expanded */
.pf-tab-chevron {
  width: 14px !important; height: 14px !important;
  color: var(--muted-2) !important;
  font-size: 11px !important;
  transition: transform 220ms var(--ease) !important;
}
.pf-tab-group.expanded .pf-tab-chevron {
  color: var(--muted-2) !important;
  transform: rotate(180deg) !important;
}

/* Items list — collapsible padding 4px 12px 10px when expanded */
.pf-tab-items {
  display: none;
  padding: 4px 12px 10px !important;
  border-top: 0 !important;
  background: transparent !important;
}
.pf-tab-group.expanded .pf-tab-items { display: block !important; }
.pf-tab-items-empty {
  padding: 6px 12px !important;
  font-size: 11px !important; color: var(--muted-2) !important;
  font-style: italic !important;
}

/* Item row — dot + name + meta */
.pf-tab-item {
  display: flex !important; align-items: center !important;
  gap: 9px !important;
  padding: 6px 8px !important;
  border-radius: 5px !important;
  background: transparent !important;
  cursor: pointer !important;
  font-size: 12px !important; color: var(--ink-soft) !important;
  transition: background 180ms var(--ease), color 180ms var(--ease) !important;
}
.pf-tab-item:hover {
  background: var(--hover) !important;
  color: var(--ink) !important;
}
.pf-tab-item-dot {
  width: 8px !important; height: 8px !important;
  border-radius: 999px !important;
  flex: none !important;
  /* hide the badge letter inside the dot for the small list-row variant */
  font-size: 0 !important;
  color: transparent !important;
  box-shadow: none !important;
  border: 0 !important;
  background: var(--cat) !important;
}
.pf-tab-item-name {
  flex: 1 !important; min-width: 0 !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
.pf-tab-item-flag {
  font-family: var(--font-mono) !important;
  font-size: 9.5px !important; letter-spacing: .08em !important;
  text-transform: uppercase !important;
  color: var(--muted-2) !important;
  background: transparent !important;
  padding: 0 !important;
}
.pf-tab-item.unplaced .pf-tab-item-name { color: var(--muted-2) !important; }

/* Sub-types (corridor sub-list) — reference shape: letter chip + label */
.pf-tab-sub {
  background: transparent !important;
  border-left: 0 !important;
  padding: 4px 12px 8px 30px !important;
}
.pf-tab-sub-item {
  display: flex !important; align-items: center !important;
  gap: 8px !important;
  padding: 6px 10px !important;
  border-radius: 5px !important;
  font-family: var(--font) !important;
  font-size: 12px !important; font-weight: 500 !important;
  color: var(--ink-soft) !important;
  background: transparent !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  transition: background 180ms var(--ease), color 180ms var(--ease) !important;
}
.pf-tab-sub-item::before { content: none !important; }
.pf-tab-sub-item:hover {
  background: var(--cat-soft) !important;
  color: var(--cat) !important;
}
.pf-tab-sub-item.active {
  background: var(--cat-soft) !important;
  color: var(--cat) !important;
  font-weight: 600 !important;
}

/* ── Radial pin picker — verbatim match of reference .pb-radial ──── */

/* Picker container — fade-in like reference.
   Base sheet sets z-index: var(--z-popover) and opacity: 0 → 1 via .open class.
   Do NOT override z-index here — picker is body-appended and the plan-builder
   modal sits at z-index 1000; a low z-index hides the picker behind the modal. */
.pf-pin-picker.open {
  animation: pickerRadialIn 220ms var(--ease) both !important;
}
@keyframes pickerRadialIn {
  0%   { opacity: 0; transform: scale(.85); }
  100% { opacity: 1; transform: scale(1); }
}

/* Center: 36×36 ink-filled close-X button. Hover → red. */
.pf-pin-picker-dot {
  position: absolute !important;
  left: 50% !important;
  top: 50% !important;
  width: calc(36px * var(--pf-picker-scale)) !important;
  height: calc(36px * var(--pf-picker-scale)) !important;
  border: 0 !important;
  border-radius: 999px !important;
  background: var(--ink) !important;
  color: #fff !important;
  display: grid !important;
  place-items: center !important;
  pointer-events: auto !important;
  cursor: pointer !important;
  transform: translate(-50%, -50%) !important;
  transition: background 200ms var(--ease) !important;
  box-shadow: 0 4px 12px rgba(20,14,4,.22) !important;
}
.pf-pin-picker-dot:hover {
  background: var(--red, #d44d4d) !important;
}
.pf-pin-picker-dot svg {
  width: calc(11px * var(--pf-picker-scale)) !important;
  height: calc(11px * var(--pf-picker-scale)) !important;
  display: block !important;
}

/* Ring: hidden — reference doesn't show a dashed ring around the picker */
.pf-pin-picker-ring {
  display: none !important;
}

/* Buttons: 50×50 colored circles, sit on a transparent stack so the
   label can render BELOW the dot rather than overlapping it.
   Background is set inline by JS from the tab color. */
.pf-pin-picker-btn {
  position: absolute !important;
  width: calc(50px * var(--pf-picker-scale)) !important;
  height: calc(50px * var(--pf-picker-scale)) !important;
  border: 0 !important;
  border-radius: 999px !important;
  color: #fff !important;
  font-family: var(--font-mono) !important;
  font-weight: 700 !important;
  font-size: calc(15px * var(--pf-picker-scale)) !important;
  line-height: 1 !important;
  letter-spacing: 0 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 0 !important;
  cursor: pointer !important;
  pointer-events: auto !important;
  box-shadow: 0 4px 12px rgba(20,14,4,.22) !important;
  transform: translate(-50%, -50%) !important;
  transition: box-shadow 220ms var(--ease), opacity 220ms var(--ease) !important;
}
/* Reference hover: shadow gets LIGHTER, no scale-up. */
.pf-pin-picker-btn:hover {
  transform: translate(-50%, -50%) !important;
  box-shadow: 0 2px 6px rgba(20,14,4,.10) !important;
}
/* Soft press feedback only */
.pf-pin-picker-btn:active {
  box-shadow: 0 1px 3px rgba(20,14,4,.10) !important;
}
/* When another sibling is hovered, dim this one (reference: .dim) */
.pf-pin-picker:hover .pf-pin-picker-btn { opacity: 1 !important; }

/* Inner badge glyph */
.pf-pin-picker-ic {
  font-family: var(--font-mono) !important;
  font-weight: 700 !important;
  font-size: calc(15px * var(--pf-picker-scale)) !important;
  line-height: 1 !important;
  color: #fff !important;
  pointer-events: none !important;
}

/* has-subs chevron — bottom-right pill on the corridors dot */
.pf-pin-picker-btn.has-subs::after {
  content: "›";
  position: absolute;
  right: calc(-2px * var(--pf-picker-scale));
  bottom: calc(-2px * var(--pf-picker-scale));
  width: calc(14px * var(--pf-picker-scale));
  height: calc(14px * var(--pf-picker-scale));
  border-radius: 999px;
  background: #fff;
  color: var(--cat, #7a9874);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: calc(11px * var(--pf-picker-scale));
  display: grid;
  place-items: center;
  box-shadow: 0 1px 2px rgba(20,14,4,.12);
  pointer-events: none;
}

/* Label pill — white surface chip below the colored circle.
   Translates UP +1 on parent hover (reference quirk). */
.pf-pin-picker-label {
  position: absolute !important;
  top: 100% !important;
  left: 50% !important;
  transform: translateX(-50%) !important;
  margin-top: calc(6px * var(--pf-picker-scale)) !important;
  font-family: var(--font) !important;
  font-size: calc(11px * var(--pf-picker-scale)) !important;
  font-weight: 600 !important;
  color: var(--ink) !important;
  background: rgba(255,255,255,.94) !important;
  padding: 2px 8px !important;
  border-radius: 3px !important;
  white-space: nowrap !important;
  letter-spacing: -.005em !important;
  text-transform: none !important;
  box-shadow: 0 1px 3px rgba(20,14,4,.10) !important;
  transition: transform 180ms var(--ease), box-shadow 180ms var(--ease) !important;
  pointer-events: none !important;
}
.pf-pin-picker-btn:hover .pf-pin-picker-label {
  transform: translateX(-50%) translateY(1px) !important;
  box-shadow: 0 2px 5px rgba(20,14,4,.16) !important;
}

/* Pin-glyph SVG sits inside the option circle. Lucide map-pin in white. */
.pf-pin-picker-ic .pf-pin-glyph {
  width: calc(22px * var(--pf-picker-scale)) !important;
  height: calc(22px * var(--pf-picker-scale)) !important;
  color: #fff !important;
  display: block !important;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.18));
}

/* Smooth pick-one micro-animation:
   .picked = chosen option blooms (scale up + halo) before commit.
   .dim    = siblings fade back so the eye lands on the chosen option. */
.pf-pin-picker-btn.picked {
  transform: translate(-50%, -50%) scale(1.18) !important;
  box-shadow:
    0 0 0 6px var(--cat-soft, rgba(20,14,4,.10)),
    0 10px 24px rgba(20,14,4,.22) !important;
  z-index: 2 !important;
  transition:
    transform 220ms cubic-bezier(.22,1,.36,1),
    box-shadow 220ms cubic-bezier(.22,1,.36,1) !important;
}
.pf-pin-picker-btn.picked .pf-pin-picker-label {
  transform: translateX(-50%) translateY(-2px) !important;
  box-shadow: 0 3px 8px rgba(20,14,4,.18) !important;
  background: #fff !important;
}
.pf-pin-picker-btn.dim {
  opacity: .25 !important;
  filter: saturate(.6) !important;
  transition:
    opacity 180ms var(--ease),
    filter 180ms var(--ease) !important;
}
.pf-pin-picker-btn.dim .pf-pin-picker-label {
  opacity: 0 !important;
}
/* Center X also fades out during pick so the chosen option owns the stage. */
.pf-pin-picker.pf-pin-picker-busy .pf-pin-picker-dot {
  opacity: 0 !important;
  transform: translate(-50%, -50%) scale(.6) !important;
  transition: opacity 180ms var(--ease), transform 180ms var(--ease) !important;
  pointer-events: none !important;
}

/* ─── Pin EDIT context menu — reference vibe ─── */
.pf-pin-ctx-menu {
  position: absolute !important;
  width: 252px !important;
  padding: 14px 14px 12px !important;
  background: var(--surface, #ffffff) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  box-shadow:
    0 1px 0 rgba(20,14,4,.04),
    0 18px 40px -16px rgba(20,14,4,.22),
    0 4px 14px -8px rgba(20,14,4,.16) !important;
  color: var(--ink) !important;
  font-family: var(--font-body, var(--font-sans), system-ui, sans-serif) !important;
  z-index: 30 !important;
  animation: ctxMenuIn 180ms var(--ease) both;
}
@keyframes ctxMenuIn {
  from { opacity: 0; transform: translateY(-4px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.pf-pin-ctx-menu__head {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  margin: 0 0 12px !important;
  padding: 0 !important;
}
.pf-pin-ctx-menu__swatch {
  display: inline-block !important;
  width: 10px !important;
  height: 10px !important;
  border-radius: 50% !important;
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--cat, var(--ink)) 18%, transparent) !important;
  flex: none !important;
}
.pf-pin-ctx-menu__title {
  font-family: var(--font-mono, ui-monospace, monospace) !important;
  font-size: 10.5px !important;
  font-weight: 700 !important;
  letter-spacing: .18em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  margin: 0 !important;
}
.pf-pin-ctx-menu__label {
  display: block !important;
  font-family: var(--font-mono, ui-monospace, monospace) !important;
  font-size: 9.5px !important;
  font-weight: 600 !important;
  letter-spacing: .16em !important;
  text-transform: uppercase !important;
  color: var(--muted, var(--ink-soft, #6b7280)) !important;
  margin: 0 0 6px !important;
}
.pf-pin-ctx-menu__input {
  width: 100% !important;
  box-sizing: border-box !important;
  padding: 9px 11px !important;
  border: 1px solid var(--border) !important;
  border-radius: 7px !important;
  font-size: 13.5px !important;
  font-weight: 500 !important;
  font-family: var(--font-body, system-ui, sans-serif) !important;
  background: var(--bg, #fafbfc) !important;
  color: var(--ink) !important;
  outline: none !important;
  transition: border-color 140ms var(--ease), box-shadow 140ms var(--ease), background-color 140ms var(--ease) !important;
}
.pf-pin-ctx-menu__input::placeholder {
  color: var(--muted, #9ca3af) !important;
  font-weight: 400 !important;
}
.pf-pin-ctx-menu__input:focus {
  background: var(--surface, #ffffff) !important;
  border-color: var(--cat, var(--ink)) !important;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--cat, var(--ink)) 14%, transparent) !important;
}
.pf-pin-ctx-menu__divider {
  height: 1px !important;
  background: var(--border) !important;
  margin: 14px 0 10px !important;
}
.pf-pin-ctx-menu__delete {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  width: 100% !important;
  justify-content: flex-start !important;
  padding: 8px 10px !important;
  border: 1px solid var(--border) !important;
  background: var(--surface, #fff) !important;
  color: var(--ink-soft, #6b7280) !important;
  border-radius: 7px !important;
  font-family: var(--font-mono, ui-monospace, monospace) !important;
  font-size: 10.5px !important;
  font-weight: 700 !important;
  letter-spacing: .14em !important;
  text-transform: uppercase !important;
  cursor: pointer !important;
  transition: border-color 140ms var(--ease), color 140ms var(--ease), background-color 140ms var(--ease) !important;
}
.pf-pin-ctx-menu__delete svg {
  width: 13px !important;
  height: 13px !important;
  stroke: currentColor !important;
  flex: none !important;
}
.pf-pin-ctx-menu__delete:hover {
  color: var(--red, #d44d4d) !important;
  border-color: color-mix(in oklab, var(--red, #d44d4d) 40%, var(--border)) !important;
  background: color-mix(in oklab, var(--red, #d44d4d) 8%, var(--surface, #fff)) !important;
}
.pf-pin-ctx-menu__actions {
  display: flex !important;
  gap: 8px !important;
  margin-top: 12px !important;
}
.pf-pin-ctx-menu__btn {
  flex: 1 1 0 !important;
  padding: 8px 10px !important;
  border: 1px solid var(--border) !important;
  background: var(--surface, #fff) !important;
  color: var(--ink) !important;
  border-radius: 7px !important;
  font-family: var(--font-body, system-ui, sans-serif) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  cursor: pointer !important;
  transition: background-color 140ms var(--ease), border-color 140ms var(--ease), color 140ms var(--ease), transform 90ms var(--ease) !important;
}
.pf-pin-ctx-menu__btn:hover {
  background: var(--hover, color-mix(in oklab, var(--ink) 4%, var(--surface))) !important;
}
.pf-pin-ctx-menu__btn:active { transform: translateY(1px) !important; }
.pf-pin-ctx-menu__btn--primary {
  background: var(--ink) !important;
  border-color: var(--ink) !important;
  color: var(--surface, #fff) !important;
  font-weight: 700 !important;
}
.pf-pin-ctx-menu__btn--primary:hover {
  background: oklch(45% .14 145) !important;
  border-color: oklch(45% .14 145) !important;
}

/* ════════════════════════════════════════════════════════════════════
   AREAS rail (Markup) + radial picker — letter-badge vibe
   Overrides the earlier pin-SVG glyph treatment so badges show the
   single mono letter (R/C/S/L/E) as in the reference image. Appended
   here so it wins via cascade order with no specificity drift.
   ════════════════════════════════════════════════════════════════════ */

/* "Markup" section head — large title + muted hint paragraph.
   Replaces the previous tiny mono-uppercase "Areas" label. */
.pf-tabs-section-head {
  padding: 18px 18px 14px !important;
  border-bottom: 1px solid var(--border) !important;
  background: transparent !important;
  font-family: var(--font) !important;
  font-size: 15px !important; letter-spacing: -.01em !important;
  text-transform: none !important;
  color: var(--ink) !important;
  font-weight: 700 !important;
  display: block !important;
}
.pf-tabs-section-head .pf-tabs-section-title {
  font-size: 17px !important;
  font-weight: 700 !important;
  color: var(--ink) !important;
  letter-spacing: -.012em !important;
  line-height: 1.1 !important;
  margin: 0 0 6px !important;
}
.pf-tabs-section-head .pf-tabs-section-hint {
  font-size: 12.5px !important;
  font-weight: 400 !important;
  color: var(--muted) !important;
  line-height: 1.45 !important;
  margin: 0 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
}

/* Letter tile badge — colored square with white mono letter centered.
   Reverts the earlier font-size:0 (pin-SVG path) so the text glyph
   shows. Reference image 3: 22×22 rounded square, white R/C/S/L/E. */
.pf-tab-dot {
  width: 22px !important; height: 22px !important;
  border-radius: 5px !important;
  background: var(--cat, var(--ink-soft)) !important;
  color: #fff !important;
  display: grid !important; place-items: center !important;
  font-family: var(--font-mono) !important;
  font-weight: 700 !important;
  font-size: 10.5px !important;
  letter-spacing: 0 !important;
  line-height: 1 !important;
  text-transform: uppercase !important;
  box-shadow:
    inset 0 -1px 0 rgba(0,0,0,.10),
    0 1px 2px rgba(20,14,4,.10) !important;
  border: 0 !important;
  flex: none !important;
  transition: transform 200ms var(--ease), box-shadow 200ms var(--ease) !important;
}
/* Legacy SVG inside the dot — hide if present (no longer emitted by JS) */
.pf-tab-dot .pf-tab-pin { display: none !important; }

/* Active row — soft tint, count picks up cat color, badge gets a halo */
.pf-tab.active .pf-tab-dot {
  background: var(--cat, var(--ink-soft)) !important;
  box-shadow:
    inset 0 -1px 0 rgba(0,0,0,.10),
    0 0 0 3px var(--cat-soft, rgba(20,18,14,.05)),
    0 4px 10px rgba(20,14,4,.14) !important;
}

/* Item row dot — small filled circle in cat color (no letter) */
.pf-tab-items .pf-tab-item-dot {
  width: 8px !important; height: 8px !important;
  border-radius: 999px !important;
  flex: none !important;
  font-size: 0 !important;
  color: transparent !important;
  text-indent: -9999px !important;
  overflow: hidden !important;
  background: var(--cat) !important;
}

/* ── Radial picker letter badges ─────────────────────────────────── */

/* Center text glyph in the radial option button — reset font-size
   in case the legacy `font-size: 0` ever propagates. Render the badge
   letter as white mono text. */
.pf-pin-picker-ic {
  font-family: var(--font-mono) !important;
  font-weight: 700 !important;
  font-size: calc(15px * var(--pf-picker-scale, 1)) !important;
  line-height: 1 !important;
  color: #fff !important;
  letter-spacing: 0 !important;
  text-transform: uppercase !important;
  display: grid !important;
  place-items: center !important;
  pointer-events: none !important;
  text-indent: 0 !important;
  overflow: visible !important;
}
/* Hide any legacy pin-glyph SVG that might still render inside the badge */
.pf-pin-picker-ic .pf-pin-glyph,
.pf-pin-picker-ic svg {
  display: none !important;
}

/* Tool-button vibe (image 2): the radial circle reads as a clean,
   solid filled disc with the letter centered and the label pill below.
   Press feedback uses a quiet scale-down + slightly heavier shadow,
   echoing the "Pin" card's dark-fill rest state. */
.pf-pin-picker-btn:active {
  transform: translate(-50%, -50%) scale(.96) !important;
  box-shadow:
    inset 0 -1px 0 rgba(0,0,0,.15),
    0 1px 3px rgba(20,14,4,.16) !important;
}

/* ───────────────────────────────────────────────────────────────
   Tools rail (PIN / LINK / ERASE / LABEL / ZONE) — kill brand glow

   plan-builder.css paints the active tool with flame fill +
   `box-shadow: 0 3px 12px rgba(99,199,106,.45)`. That's the loud
   glowing shadow the user flagged. Reskinned here to match the
   Guide-x tool-card vibe: rest is surface card with hairline
   border + mono caps label, hover lifts gently with a quieter
   shadow, active is a flat ink fill with white icon + label
   (no flame, no orange glow). Press scales down 1px.
   ─────────────────────────────────────────────────────────────── */
.pf-tools {
  display: grid !important;
  grid-template-columns: 1fr 1fr 1fr !important;
  gap: 8px !important;
  padding: 14px 12px !important;
  background: var(--sidebar) !important;
  border-bottom: 1px solid var(--border) !important;
}
.pf-tool-vbtn {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 5px !important;
  padding: 10px 4px !important;
  background: var(--surface) !important;
  color: var(--ink-soft) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  font-family: var(--font-mono, 'JetBrains Mono', ui-monospace, monospace) !important;
  font-size: 9.5px !important;
  font-weight: 600 !important;
  letter-spacing: .12em !important;
  cursor: pointer !important;
  box-shadow: 0 1px 2px rgba(20,14,4,.04) !important;
  transition: transform .14s ease, background .15s, border-color .15s, color .15s, box-shadow .18s ease !important;
}
.pf-tool-vbtn:hover {
  transform: translateY(-1px) !important;
  background: var(--surface) !important;
  border-color: var(--ink-soft) !important;
  color: var(--ink) !important;
  box-shadow: 0 3px 10px -4px rgba(20,14,4,.18) !important;
}
.pf-tool-vbtn:active {
  transform: translateY(0) !important;
  box-shadow: 0 1px 2px rgba(20,14,4,.04), inset 0 1px 2px rgba(20,14,4,.06) !important;
}
.pf-tool-vbtn .pf-tool-vbtn-icon {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 16px !important;
  height: 16px !important;
  color: inherit !important;
  font-size: 0 !important;
}
.pf-tool-vbtn .pf-tool-vbtn-icon i[data-lucide] svg,
.pf-tool-vbtn .pf-tool-vbtn-icon svg {
  width: 16px !important;
  height: 16px !important;
  stroke: currentColor !important;
}
.pf-tool-vbtn.active {
  background: var(--ink) !important;
  border-color: var(--ink) !important;
  color: #fff !important;
  /* No flame, no orange. Just a quiet inset highlight + soft neutral lift. */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    0 6px 14px -8px rgba(20,14,4,.32) !important;
}
.pf-tool-vbtn.active .pf-tool-vbtn-icon { color: #fff !important; }
.pf-tool-vbtn.active:hover {
  transform: translateY(-1px) !important;
  background: var(--ink) !important;
  border-color: var(--ink) !important;
  color: #fff !important;
}

/* ═══════════════════════════════════════════════════════════════════
   Initial Design Assessment — plan picker modal
   Was styled in the now-unlinked theme.css with --el-* tokens that
   no longer exist; rendered as a near-blank box. Repainting in
   Guide-x vocabulary so it matches the rest of the chrome.
   ═══════════════════════════════════════════════════════════════════ */
/* Top-anchored: pin the picker just below the topbar (same treatment as the
   Project Brief modal) instead of centering it in the viewport. */
#gfAssessmentPicker {
  z-index: 1500 !important;
  align-items: flex-start !important;
  justify-content: center !important;
  padding-top: 72px;
  overflow-y: auto;
}
@media (max-height: 720px) {
  #gfAssessmentPicker { padding-top: 56px; }
}
#gfAssessmentPicker .modal-box.gf-assess-pick-box {
  width: min(560px, 92vw) !important;
  max-width: 560px !important;
  max-height: calc(100vh - 96px) !important;
  margin: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  padding: 0 !important;
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 14px !important;
  box-shadow:
    0 24px 60px -20px rgba(20,14,4,.32),
    0 6px 16px -8px rgba(20,14,4,.18) !important;
  overflow: hidden !important;
}
#gfAssessmentPicker .modal-title {
  font-family: var(--font-mono) !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: .18em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  padding: 20px 24px 6px !important;
  margin: 0 !important;
  flex: none !important;
}
#gfAssessmentPicker .gf-assess-pick-hint {
  font-size: 13px !important;
  color: var(--muted) !important;
  padding: 0 24px 14px !important;
  margin: 0 !important;
  border-bottom: 1px solid var(--border) !important;
  flex: none !important;
}
#gfAssessmentPicker .gf-assess-pick-list {
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
  padding: 16px 20px !important;
  margin: 0 !important;
  max-height: none !important;
  flex: 1 !important;
  min-height: 0 !important;
  overflow-y: auto !important;
}
#gfAssessmentPicker .gf-assess-pick-list::-webkit-scrollbar { width: 6px; }
#gfAssessmentPicker .gf-assess-pick-list::-webkit-scrollbar-thumb {
  background: var(--border-strong, var(--border)); border-radius: 999px;
}
#gfAssessmentPicker .gf-assess-pick-row {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  gap: 14px !important;
  padding: 14px 16px !important;
  border: 1px solid var(--border) !important;
  background: var(--surface) !important;
  color: var(--ink) !important;
  border-radius: 8px !important;
  font-family: inherit !important;
  font-size: 13.5px !important;
  cursor: pointer !important;
  text-align: left !important;
  transition: background 160ms ease, border-color 160ms ease, transform 120ms ease !important;
  box-shadow: 0 1px 2px rgba(20,14,4,.04) !important;
}
#gfAssessmentPicker .gf-assess-pick-row:hover {
  background: var(--hover) !important;
  border-color: var(--ink-soft) !important;
  transform: translateY(-1px) !important;
  box-shadow: 0 4px 12px -6px rgba(20,14,4,.18) !important;
}
#gfAssessmentPicker .gf-assess-pick-row:active { transform: translateY(0) !important; }
#gfAssessmentPicker .gf-assess-pick-name {
  font-weight: 600 !important;
  color: var(--ink) !important;
  font-size: 13.5px !important;
  letter-spacing: -.005em !important;
}
#gfAssessmentPicker .gf-assess-pick-meta {
  font-family: var(--font-mono) !important;
  font-size: 11px !important;
  color: var(--muted-2) !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 10px !important;
  font-variant-numeric: tabular-nums !important;
}
#gfAssessmentPicker .gf-assess-pick-badge {
  background: var(--ink) !important;
  color: #fff !important;
  font-family: var(--font-mono) !important;
  font-size: 9.5px !important;
  font-weight: 700 !important;
  letter-spacing: .14em !important;
  padding: 3px 8px !important;
  border-radius: 4px !important;
  text-transform: uppercase !important;
}
#gfAssessmentPicker .gf-assess-pick-badge-done {
  background: oklch(62% 0.14 150) !important;
  color: #fff !important;
  box-shadow: 0 1px 2px rgba(20,14,4,.10), inset 0 -1px 0 rgba(0,0,0,.10) !important;
}
#gfAssessmentPicker .gf-assess-pick-empty {
  font-size: 13px !important;
  color: var(--muted) !important;
  font-style: normal !important;
  padding: 32px 16px !important;
  text-align: center !important;
  background: var(--bg) !important;
  border: 1px dashed var(--border-strong, var(--border)) !important;
  border-radius: 10px !important;
}
#gfAssessmentPicker .modal-actions {
  padding: 14px 20px 18px !important;
  margin: 0 !important;
  border-top: 1px solid var(--border) !important;
  background: var(--bg) !important;
  display: flex !important;
  justify-content: flex-end !important;
  gap: 10px !important;
  flex: none !important;
}
#gfAssessmentPicker .modal-actions .modal-btn {
  height: 34px !important;
  padding: 0 18px !important;
  border-radius: 6px !important;
  border: 1px solid var(--border) !important;
  background: var(--surface) !important;
  color: var(--ink) !important;
  font-family: inherit !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  cursor: pointer !important;
  transition: background 160ms ease, border-color 160ms ease !important;
}
#gfAssessmentPicker .modal-actions .modal-btn:hover {
  background: var(--hover) !important;
  border-color: var(--ink-soft) !important;
}

/* ── Assessment modal — footer button styling ──
   Export PDF / Edit markup / Close buttons inside #assessmentModal.
   Uses the Guide-x wizard-footbar button vocabulary. */
.pf-assess-btn-export,
.pf-assess-btn-edit,
.pf-assess-btn-close {
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  letter-spacing: -0.005em !important;
  height: 36px !important;
  padding: 0 18px !important;
  border-radius: 7px !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  transition:
    background 160ms ease,
    border-color 160ms ease,
    color 160ms ease,
    box-shadow 200ms ease,
    transform 120ms ease !important;
  user-select: none !important;
  white-space: nowrap !important;
}

/* Edit markup — ghost surface (secondary action) */
.pf-assess-btn-edit {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  color: var(--ink) !important;
  box-shadow: 0 1px 2px rgba(20, 14, 4, 0.04) !important;
}
.pf-assess-btn-edit:hover {
  background: var(--hover) !important;
  border-color: var(--ink-soft) !important;
  box-shadow: 0 3px 10px -4px rgba(20, 14, 4, 0.18) !important;
  transform: translateY(-1px) !important;
}
.pf-assess-btn-edit:active {
  transform: translateY(0) !important;
  box-shadow: inset 0 1px 2px rgba(20, 14, 4, 0.08) !important;
}

/* Export PDF — primary ink CTA, flips to green on hover (matches ✓ Save vocab) */
.pf-assess-btn-export {
  background: var(--ink) !important;
  border: 1px solid var(--ink) !important;
  color: #fff !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 2px 6px -2px rgba(20, 14, 4, 0.32) !important;
}
.pf-assess-btn-export:hover {
  background: oklch(45% 0.14 145) !important;
  border-color: oklch(45% 0.14 145) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 6px 14px -6px oklch(45% 0.14 145 / 0.45) !important;
  transform: translateY(-1px) !important;
}
.pf-assess-btn-export:active {
  transform: translateY(0) !important;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15) !important;
}

/* Close — quiet tertiary ghost (no flame) */
.pf-assess-btn-close {
  background: transparent !important;
  border: 1px solid var(--border) !important;
  color: var(--muted) !important;
  box-shadow: none !important;
}
.pf-assess-btn-close:hover {
  background: var(--hover) !important;
  border-color: var(--ink-soft) !important;
  color: var(--ink) !important;
  box-shadow: 0 2px 6px -3px rgba(20, 14, 4, 0.14) !important;
  transform: translateY(-1px) !important;
}
.pf-assess-btn-close:active {
  transform: translateY(0) !important;
  box-shadow: inset 0 1px 2px rgba(20, 14, 4, 0.06) !important;
}

/* Footer row spacing for the standalone assessment modal */
.plan-form-box.assessment-box .pf-footer-buttons {
  gap: 10px !important;
  padding: 14px 22px !important;
}

/* ───────────────────────────────────────────────────────────────────────────
   #assessmentModal — standalone assessment view modal.
   Inherits all the .plan-form-box chrome, sizing, fonts. The .assessment-box
   modifier hides the markup-specific meta-grid (used by the wizard), gives
   the canvas a read-only cursor, and widens the summary sidebar so the
   building-description paragraphs read comfortably without horizontal
   cramping. The markup modal's 300px sidebar is tools+tabs vocabulary;
   assessment is mostly prose so it needs more room.
   ─────────────────────────────────────────────────────────────────────────── */
.plan-form-box.assessment-box .pf-meta-grid {
  display: none !important;
}
.plan-form-box.assessment-box.has-canvas .pf-body {
  grid-template-columns: 400px 1fr !important;
}
.plan-form-box.assessment-box .pf-canvas-wrap {
  cursor: default !important;
}
.plan-form-box.assessment-box #assessmentCanvasWrap {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.plan-form-box.assessment-box #assessmentPlanCanvas,
.plan-form-box.assessment-box #assessmentOverlayCanvas {
  position: absolute;
  inset: 0;
  display: block;
  pointer-events: none;
}
.plan-form-box.assessment-box #assessmentCanvasWrap {
  pointer-events: auto;
}

/* "How to update findings" hint at the bottom of the assessment sidebar.
   Muted, dashed border so it reads as advisory text rather than another
   summary section. */
.pf-assess-hint {
  margin: 16px 20px 4px;
  padding: 12px 14px;
  border: 1px dashed var(--border);
  border-radius: 8px;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--muted);
  background: var(--paper);
}
.pf-assess-hint strong {
  color: var(--ink);
  font-weight: 600;
}

/* ───────────────────────────────────────────────────────────────────────────
   Pin-finding hover popover — reference `.pb-note-card` vocabulary.
   Cream-tinted translucent paper with flame left-accent, mono tag,
   ink title, ink-soft body, dashed-underline cite. Wins over plan-builder.css.
   ─────────────────────────────────────────────────────────────────────────── */
.pf-pin-popover {
  position: fixed !important;
  z-index: 1500 !important;
  /* Fixed size — does NOT respond to canvas zoom. Earlier turns made it
     scale with --pf-popover-scale; user found that constantly-changing size
     disorienting, so it's now stable regardless of zoom level. */
  width: 300px !important;
  max-width: 300px !important;
  /* Grow to fit the content (a lone big finding grows as a single column);
     overflow-y below only scrolls as a last resort past the screen edge. */
  max-height: calc(100vh - 16px) !important;
  overflow-y: auto !important;
  background: #ffffff !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: 1px solid rgba(20, 14, 4, 0.10) !important;
  border-left: 1px solid rgba(20, 14, 4, 0.10) !important;
  border-radius: 8px !important;
  padding: 12px 14px !important;
  box-shadow: 0 6px 18px rgba(20, 14, 4, 0.10), 0 1px 2px rgba(20, 14, 4, 0.06) !important;
  font-family: var(--font-body, 'Inter', system-ui, -apple-system, sans-serif) !important;
  font-size: 13px !important;
  line-height: 1.55 !important;
  color: var(--ink, #1a1d20) !important;
  transform-origin: top left;
  /* pointer-events: none so the popover never intercepts mouse events while
     the user is moving between pins. */
  pointer-events: none !important;
  user-select: none !important;
  -webkit-user-select: none !important;
  cursor: default;
  opacity: 0;
  transition: opacity 70ms linear;
}
.pf-pin-popover.open {
  opacity: 1 !important;
}
/* Tall content (2+ findings) → landscape layout: wider box, two columns
   whose findings ALIGN row-by-row. JS adds .tall when the natural height
   would exceed ~360px or 70vh AND there are 2+ findings (a lone finding
   stays a single growing column). */
.pf-pin-popover.tall {
  width: min(560px, 92vw) !important;
  max-width: min(560px, 92vw) !important;
  /* Grow the two-column card down to fit extra/big findings; the shared
     overflow-y: auto only scrolls if it has grown to the screen edge. */
  max-height: calc(100vh - 16px) !important;
}
/* Two-column grid: heading N on the left lines up with heading N on the
   right (row-by-row alignment). Separation is whitespace ONLY — a wide
   column gap and a row gap keep findings clearly apart with no visible
   grid lines. align-items: start top-aligns each finding in its row. */
.pf-pin-popover.tall .pf-pin-popover-list {
  display: grid !important;
  grid-template-columns: 1fr 1fr !important;
  align-items: start !important;
  row-gap: 18px !important;
  column-gap: 28px !important;
  flex-direction: initial !important;
}
.pf-pin-popover.tall .pf-pin-popover-list li {
  margin: 0 !important;
  padding: 0 !important;
}
/* Subtle scrollbar styling inside popover. */
.pf-pin-popover::-webkit-scrollbar { width: 6px; }
.pf-pin-popover::-webkit-scrollbar-thumb {
  background: rgba(212, 200, 176, 0.6);
  border-radius: 999px;
}
/* Selection color matches the flame palette. */
.pf-pin-popover ::selection {
  background: rgba(99, 199, 106, 0.22);
  color: var(--ink, #1a1d20);
}

/* Pin name → reference `.pb-note-title` (ink, 600, 12.5px) */
.pf-pin-popover-name {
  font-family: var(--font-body, 'Inter', system-ui, sans-serif) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  color: var(--ink, #1a1d20) !important;
  letter-spacing: -0.005em !important;
  margin: 0 0 6px 0 !important;
  padding-bottom: 6px !important;
  border-bottom: 1px solid rgba(212, 200, 176, 0.45) !important;
  text-transform: none !important;
}

/* Findings list — stack with gap, no bullets */
.pf-pin-popover-list {
  list-style: none !important;
  margin: 0 !important;
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 10px !important;
}
.pf-pin-popover-list li {
  font-size: 12.5px !important;
  line-height: 1.55 !important;
  color: var(--ink-soft, #5a5346) !important;
}

/* Guidance ref → section title. Bolder + bigger, with a real flame highlighter
   background hugging the text like a marker pen. box-decoration-break keeps the
   highlight wrapping intact when the title spans two lines. */
.pf-pin-popover-ref {
  display: inline !important;
  font-family: var(--font-body, 'Inter', system-ui, -apple-system, sans-serif) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  letter-spacing: -0.005em !important;
  text-transform: none !important;
  color: var(--ink, #1a1d20) !important;
  line-height: 1.4 !important;
  background: none !important;
  -webkit-box-decoration-break: initial !important;
  box-decoration-break: initial !important;
  padding: 0 !important;
  margin: 0 0 6px 0 !important;
  border-bottom: none !important;
  border-radius: 0 !important;
  overflow-wrap: break-word !important;
  word-break: break-word !important;
}
/* Sit the ref on its own line above the issue body. */
.pf-pin-popover-list li .pf-pin-popover-ref { display: inline-block !important; }

/* Finding body — slightly larger than the section title above so prose is
   the comfortable reading element and the ref reads as a quiet heading. */
.pf-pin-popover-issue {
  font-family: var(--font-body, 'Inter', system-ui, sans-serif) !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  line-height: 1.55 !important;
  color: var(--ink, #1a1d20) !important;
  margin: 0 !important;
  overflow-wrap: break-word !important;
  word-break: break-word !important;
}

/* No-findings state — quiet ink-soft body, not italic */
.pf-pin-popover-empty {
  font-family: var(--font-body, 'Inter', system-ui, sans-serif) !important;
  font-size: 12.5px !important;
  font-style: normal !important;
  color: var(--ink-soft, #5a5346) !important;
  line-height: 1.55 !important;
  margin: 0 !important;
  padding: 4px 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  .pf-pin-popover { transition: none !important; transform: none !important; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Popover white-card hardening — overrides any cascading dark background
   from legacy plan-builder.css (which set `background: var(--bg)` and used
   white text), forced-colors mode, or any future drift. Every child element
   inside the popover paints transparent so the container's white surface
   shows through cleanly. Belt-and-braces — should not be required, but
   bulletproofs the popover against environmental rendering quirks.
   ─────────────────────────────────────────────────────────────────────────── */
.pf-pin-popover,
#gfPinPopover.pf-pin-popover {
  background: #ffffff !important;
  background-color: #ffffff !important;
  background-image: none !important;
  filter: none !important;
  mix-blend-mode: normal !important;
  isolation: isolate !important;
  forced-color-adjust: none;
}
.pf-pin-popover > *,
.pf-pin-popover .pf-pin-popover-name,
.pf-pin-popover .pf-pin-popover-list,
.pf-pin-popover .pf-pin-popover-list li,
.pf-pin-popover .pf-pin-popover-ref,
.pf-pin-popover .pf-pin-popover-issue,
.pf-pin-popover .pf-pin-popover-empty {
  background: transparent !important;
  background-color: transparent !important;
  background-image: none !important;
}
/* Pin name lives on the white card surface — ensure ink, not the legacy
   `color: #fff` from plan-builder.css that would render invisible. */
.pf-pin-popover .pf-pin-popover-name {
  color: var(--ink, #1a1d20) !important;
}
.pf-pin-popover .pf-pin-popover-issue {
  color: var(--ink, #1a1d20) !important;
}
.pf-pin-popover .pf-pin-popover-ref {
  color: var(--ink, #1a1d20) !important;
}

/* ───────────────────────────────────────────────────────────────────────────
   PDF-Prep queue step bar — paints in the modern brand palette and gives the
   "Cancel queue" button a visible destructive treatment so users have a clear
   escape if a queued plan stalls. The label / dot / hover states all unify
   to #63c76a (the brand green) rather than the legacy oranges.
   ─────────────────────────────────────────────────────────────────────────── */
.pdp-step-bar {
  gap: 12px !important;
  padding: 6px 8px 6px 14px !important;
  border-radius: 999px !important;
  background: rgba(99, 199, 106, 0.06) !important;
  border: 1px solid rgba(99, 199, 106, 0.20) !important;
  font-size: 11.5px !important;
  font-family: var(--font-mono, ui-monospace, 'JetBrains Mono', monospace) !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
}
.pdp-step-label {
  color: rgba(99, 199, 106, 0.95) !important;
  font-weight: 700 !important;
  letter-spacing: 0.08em !important;
}
.pdp-step-dot { background: rgba(20, 14, 4, 0.15) !important; }
.pdp-step-dot.done { background: rgba(99, 199, 106, 0.45) !important; }
.pdp-step-dot.active { background: #63c76a !important; }
.pdp-step-cancel {
  /* Was a tiny text link in muted ink-soft — easy to miss when the queue
     stalls. Now a proper destructive pill: red text + red hairline border,
     padded, sitting on a subtle red-tinted background that intensifies on
     hover. Aligned to the right of the dots inside the bar. */
  display: inline-flex !important;
  align-items: center !important;
  gap: 5px !important;
  padding: 5px 11px !important;
  margin: 0 !important;
  background: rgba(212, 77, 77, 0.08) !important;
  color: rgba(180, 50, 50, 0.92) !important;
  border: 1px solid rgba(212, 77, 77, 0.30) !important;
  border-radius: 999px !important;
  font-family: var(--font-mono, ui-monospace, 'JetBrains Mono', monospace) !important;
  font-size: 10.5px !important;
  font-weight: 700 !important;
  letter-spacing: 0.10em !important;
  text-transform: uppercase !important;
  cursor: pointer;
  transition: background 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease);
}
.pdp-step-cancel::before {
  content: "✕";
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  opacity: 0.8;
}
.pdp-step-cancel:hover {
  background: rgba(212, 77, 77, 0.18) !important;
  color: #b43232 !important;
  border-color: rgba(212, 77, 77, 0.55) !important;
}
.pdp-step-cancel:active {
  transform: translateY(1px);
}

/* ───────────────────────────────────────────────────────────────────────────
   Sidebar upload progress — gx-loader vocabulary.
   Replaces the legacy SVG ring with a slim shimmer bar + mono uppercase phase
   text + ✕ cancel button, matching the chat thinking-state loader vibe.
   ─────────────────────────────────────────────────────────────────────────── */
.gx-upload-loader.upload-progress {
  display: none;
  flex-direction: column !important;
  align-items: stretch !important;
  gap: 8px !important;
  padding: 10px 12px !important;
  margin: 6px 0 !important;
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  box-shadow: 0 1px 2px rgba(20, 14, 4, 0.04);
}
.gx-upload-loader.upload-progress.visible { display: flex !important; }

/* Hide the legacy SVG ring entirely — JS no longer touches it but the rule
   is defensive in case a future change tries to re-show it. */
.gx-upload-loader .upload-ring { display: none !important; }

.gx-upload-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.gx-upload-phase {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono, ui-monospace, 'JetBrains Mono', monospace) !important;
  font-size: 10.5px !important;
  font-weight: 700 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Blink the trailing _ on the phase text via JS-added "_" — matches the
     gx-mark cursor vibe of the chat loader. */
  position: relative;
}
/* The trailing "_" is a literal char in the phase text. Animate the whole
   phase line's last character via CSS: we restrict the blink to the final
   underscore by using a pseudo-overlay that paints only that glyph in flame.
   Pure-CSS approach: target the entire string in flame and rely on the JS
   formatter ensuring the string ends with "_". Cleaner: just blink the
   whole text — but that's too noisy. Compromise: paint the last char with
   a flame color shadow via text-shadow-only marker. */
.gx-upload-phase::after {
  content: "";
}

.gx-upload-cancel {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease);
}
.gx-upload-cancel:hover {
  background: rgba(212, 77, 77, 0.10);
  border-color: rgba(212, 77, 77, 0.35);
  color: #b43232;
}
.gx-upload-cancel:active { transform: translateY(1px); }

/* Slim shimmer bar — same 3px-tall slat as the chat loader. */
.gx-upload-bar {
  position: relative;
  width: 100%;
  height: 3px;
  border-radius: 999px;
  background: var(--hover, rgba(20, 14, 4, 0.06));
  overflow: hidden;
}
.gx-upload-bar-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--flame, #63c76a), rgba(99, 199, 106, 0.6));
  transition: width 240ms ease;
}
/* Indeterminate shimmer — the fill becomes a sliding highlight when no
   specific pct is known. Mirrors the chat loader's loaderSlide animation. */
.gx-upload-loader.is-indet .gx-upload-bar-fill {
  width: 36% !important;
  transition: none;
  animation: gxUploadSlide 1.6s ease-in-out infinite;
}
.gx-upload-loader.is-done .gx-upload-bar-fill {
  background: oklch(45% 0.14 145) !important;
}
@keyframes gxUploadSlide {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(280%); }
}
@media (prefers-reduced-motion: reduce) {
  .gx-upload-loader.is-indet .gx-upload-bar-fill {
    animation: none;
    width: 36% !important;
  }
}

/* ───────────────────────────────────────────────────────────────────────────
   PDF-Prep modal crop selection — neutral ink-dashed rectangle with near-
   transparent fill so the user can clearly see the underlying page through
   the selection box. Was painted blue (legacy --blue alias); now matches the
   wizard's gx-crop-rect for a consistent "normal selection vibe" everywhere.
   ─────────────────────────────────────────────────────────────────────────── */
.pdp-crop-selection {
  border: 1.5px dashed rgba(20, 14, 4, 0.55) !important;
  background: rgba(255, 255, 255, 0.04) !important;
}

/* ───────────────────────────────────────────────────────────────────────────
   Send-button cooldown state. When the AI service is rate-limited or wedged,
   js/config.js sets .gf-cooldown on the send button + a `title` attribute
   with the remaining seconds. JS-level isServiceCoolingDown() already
   refuses sends, so we only need the visual cue here — dim + grayscale +
   not-allowed cursor. Leaving pointer-events on so the title tooltip can
   appear on hover.
   ─────────────────────────────────────────────────────────────────────────── */
.send-btn.gf-cooldown {
  opacity: 0.5;
  cursor: not-allowed;
  filter: grayscale(1);
}

/* ── "Add to note" — per-answer action row + floor popover (js/chat-notes.js) ── */
/* The row is appended INSIDE .bubble (last child), so it sits flush-left
   under the answer text with no flex-layout side effects on the
   gx-mark | bubble row. It collapses to zero height when idle: older
   messages reveal it on hover; the NEWEST answer always shows it. */
.gf-answer-actions {
  display: flex; justify-content: flex-start; align-items: center;
  max-height: 0; overflow: hidden;
  transition: max-height 160ms var(--ease), margin-top 160ms var(--ease);
}
.message.assistant:hover .gf-answer-actions,
.chat-messages > .message.assistant:last-child .gf-answer-actions,
.gf-answer-actions:focus-within { max-height: 32px; margin-top: 6px; }
.gf-note-btn {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  padding: 3px 10px; border-radius: 999px;
  background: transparent; border: 1px solid var(--border);
  color: var(--muted); font-family: inherit; font-size: 11px; font-weight: 500;
  letter-spacing: .01em; cursor: pointer;
  opacity: 0;                     /* fades in with the row */
  transition: opacity 140ms var(--ease), color 140ms var(--ease), border-color 140ms var(--ease), background 140ms var(--ease);
}
.message.assistant:hover .gf-note-btn,
.chat-messages > .message.assistant:last-child .gf-note-btn,
.gf-note-btn:focus-visible { opacity: 1; }
.gf-note-btn:hover { color: var(--flame); border-color: var(--flame); background: var(--bg); }
.gf-note-btn svg { width: 13px; height: 13px; }
.gf-note-btn:disabled { opacity: .5; cursor: default; }

/* Saving/summarising state — the wait must be unmissable. The row and the
   button are pinned fully visible (they normally fade unless hovered / last
   message, and :disabled dims to .5), the note icon is swapped for a spinner,
   and the label gently pulses. Transform-only animation — no filters (the
   Chromium GPU-cursor bug rules those out). */
.gf-answer-actions.working { max-height: 32px; margin-top: 6px; }
.gf-note-btn.working,
.gf-note-btn.working:disabled {
  opacity: 1; cursor: progress;
  color: var(--flame); border-color: var(--flame); background: var(--bg);
}
.gf-note-btn.working svg { display: none; }
.gf-note-btn.working::before {
  content: ''; width: 12px; height: 12px; flex: 0 0 12px;
  border-radius: 50%;
  border: 1.5px solid currentColor; border-top-color: transparent;
  animation: gfNoteSpin 700ms linear infinite;
}
@keyframes gfNoteSpin { to { transform: rotate(360deg); } }
.gf-note-btn.working span { animation: gfNotePulse 1.1s ease-in-out infinite; }
@keyframes gfNotePulse { 50% { opacity: .55; } }

.gf-note-pop {
  position: fixed; z-index: 4000; min-width: 180px; max-width: 260px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 6px;
  box-shadow: 0 14px 34px -14px rgba(20,14,4,.30), 0 4px 10px -6px rgba(20,14,4,.14);
}
.gf-note-pop-head {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted-2, var(--muted)); font-weight: 600;
  padding: 4px 8px 6px;
}
.gf-note-pop-item {
  display: block; width: 100%; text-align: left;
  padding: 7px 10px; border: 0; border-radius: 6px;
  background: transparent; color: var(--ink);
  font-family: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
  transition: background 120ms var(--ease);
}
.gf-note-pop-item:hover { background: var(--hover); }
