/* ============================================================
   Synthesize (Reflect phase / Coach surface)
   Local vars are aliases onto /design-system/platform-tokens.css
   (Red Unification: red IS the platform brand color, not an
   exception). Hex appears only where no platform token exists.
   Everything is scoped under .synth.
   ============================================================ */
.synth,
.synth-topbar { /* ds-lint-disable-line — palette intentionally uses hardcoded colors where no platform tokens exist */
  /* Accent — unified brand red (--phase-learn family) */
  --accent: var(--phase-learn);
  --accentD: var(--phase-learn-dark);
  /* ds-lint-disable-next-line */
  --accentL: #FCA5A5; /* red-300 step between light and main — no platform token */
  --accentVL: var(--phase-learn-light);
  --ctaShadow: 0 4px 14px rgba(229, 77, 77, .28);

  /* Ink / text — platform warm ink ramp */
  --ink: var(--color-ink);
  --ink2: var(--color-ink-secondary);
  --muted: var(--color-ink-muted);
  --faint: var(--color-ink-faint);
  /* ds-lint-disable-next-line */
  --hair: #C4BCB0; /* hairline between faint ink and border — no platform token */

  /* Surfaces / backgrounds */
  --bgPage: var(--bg-page);
  --surface: var(--bg-surface);
  /* ds-lint-disable-next-line */
  --subtle: var(--bg-subtle, #FAFAF9);
  /* ds-lint-disable-next-line */
  --subtleP: #FBF6FF; /* faint lilac hover wash — no platform token */

  /* Borders — warm; platform only defines a cool border token */
  --border: #E8E3DC;
  --inner: #F0EBE4;

  /* Priority colors */
  --p1: var(--color-primary-on-white);
  --p2: var(--color-warning-dark);
  --p3: #0369A1;
  --park: var(--color-ink-muted);
  --ok: #047857; /* agreed / done / decision green (no exact platform token) */
  /* ds-lint-disable-next-line */
  --sticky: #FEF9C3;        /* rendered sticky-note yellow (functional, no token) */
  /* ds-lint-disable-next-line */
  --statusPlanBg: #FFFBEB;  /* roadmap status washes (no platform token) */
  /* ds-lint-disable-next-line */
  --statusBacklogBg: #EFF6FF;

  /* Shadows */
  --shCard: var(--shadow-sm, 0 1px 3px rgba(0, 0, 0, .06));
  --shDrop: 0 12px 24px rgba(0, 0, 0, .16);   /* drag lift — heavier than platform ramp */
  --shModal: 0 20px 25px rgba(0, 0, 0, .18);  /* modal — heavier than --shadow-xl */

  /* Radii */
  --rBadge: var(--radius-sm, 4px);
  --rChip: 7px; /* between --radius-md and --radius-lg; kept for chip density */
  --rCard: var(--radius-xl, 12px);
  --rModal: var(--radius-2xl, 16px);
}

.synth {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--bgPage);
  min-height: 70vh;
  -webkit-font-smoothing: antialiased;
}

.synth-body { background: var(--bg-page); }

.synth *, .synth *::before, .synth *::after { box-sizing: border-box; }

.synth .material-symbols-outlined, .synth-topbar .material-symbols-outlined {
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
  vertical-align: middle;
  line-height: 1;
}

/* ---------- Typography ---------- */
.synth h1, .synth h2, .synth h3, .synth .ff {
  font-family: var(--font-heading);
  font-optical-sizing: auto;
  letter-spacing: -.02em;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
.synth .kicker {
  font-size: calc(11px * var(--tscale, 1));
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}

/* ---------- Boot ---------- */
.synth-boot { display: grid; place-items: center; min-height: 50vh; }
.synth-spinner {
  width: 56px; height: 56px; border-radius: 50%;
  border: 3px solid var(--accentL);
  border-top-color: var(--accent);
  animation: synth-spin .9s linear infinite;
}
@keyframes synth-spin { to { transform: rotate(360deg); } }

/* ---------- Buttons ----------
   Buttons are the platform's: .ws-btn from includes/components/components.css,
   which includes/header.php already loads on every page. Only the Material
   Symbols sizing is Synthesize's, because ws_button ships inline SVG icons and
   the app emits ligature spans. */
.synth .ws-btn .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }

.synth .iconbtn, .synth-topbar .iconbtn {
  width: 34px; height: 34px; display: inline-grid; place-items: center;
  border-radius: 9px; border: 1px solid var(--border); background: var(--surface);
  color: var(--ink2); cursor: pointer; transition: background var(--duration-base) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.synth .iconbtn:hover, .synth-topbar .iconbtn:hover { background: var(--inner); }
.synth .iconbtn:active, .synth-topbar .iconbtn:active { transform: scale(.98); }
.synth .iconbtn .material-symbols-outlined, .synth-topbar .iconbtn .material-symbols-outlined { font-size: calc(20px * var(--tscale, 1)); }

.synth .linkback {
  background: none; border: 0; color: var(--accent); font: inherit; font-weight: 600;
  cursor: pointer; padding: 4px 0; display: inline-flex; align-items: center; gap: 4px;
}
.synth .linkback:hover { color: var(--accentD); }

/* ---------- Layout containers ---------- */
.synth .wrap { max-width: 840px; margin: 0 auto; padding: 56px 24px 110px; }
.synth .wrap--wide { max-width: 1120px; }
.synth .wrap--kanban { max-width: 1180px; }
.synth .wrap--doc { max-width: 820px; }

/* ============================================================
   HOME
   ============================================================ */
/* Workspace-scale headings: the app chrome carries identity, so screen titles
   read as section labels, not marketing heroes. */
.synth .home-h1 { font-size: calc(30px * var(--tscale, 1)); line-height: 1.15; margin: 4px 0 10px; max-width: 24ch; }
.synth .home-sub { font-size: calc(16.5px * var(--tscale, 1)); color: var(--ink2); max-width: 52ch; margin-bottom: 36px; }

/* Home gallery — a card per saved synthesis, with the New-synthesis card
   sitting alongside them as the last cell. Card min width matches the 200px
   comp; the New card spans two rows so it reads as a distinct destination. */
.synth .sy-gallery-h {
  font-family: var(--font-heading); font-size: calc(20px * var(--tscale, 1));
  font-weight: 600; letter-spacing: -.02em; margin: 0 0 16px;
}
/* Cards on the left, New synthesis as a persistent right column — it stays put
   regardless of how many syntheses exist, rather than drifting to wherever the
   grid happens to end. Stacks on narrow viewports. */
.synth .sy-home-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 200px;
  gap: var(--space-8); align-items: start; margin-bottom: var(--space-10);
}
.synth .sy-gallery {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-4); align-items: start;
}
@media (max-width: 720px) {
  .synth .sy-home-grid { grid-template-columns: 1fr; gap: var(--space-4); }
}

.synth .sy-card {
  display: flex; flex-direction: column; gap: 8px;
  min-height: 184px; padding: 16px; cursor: pointer; text-align: left;
  font: inherit; color: inherit;
  border: 1px solid var(--border); background: var(--surface); border-radius: var(--rCard);
  transition: transform var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
.synth .sy-card:hover { transform: translateY(-2px); box-shadow: var(--shCard); border-color: var(--accentL, var(--border)); }
.synth .sy-card:active { transform: translateY(1px); }
.synth .sy-card__name {
  font-family: var(--font-heading); font-weight: 600;
  font-size: calc(15px * var(--tscale, 1)); line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.synth .sy-card__count { font-size: calc(12px * var(--tscale, 1)); font-style: italic; color: var(--muted); }

/* Source-type row: lit = present, dim = absent. Fixed slots keep the rows
   aligned across cards so the pattern is scannable down a column. */
.synth .sy-card__kinds { display: flex; gap: 10px; margin-top: 2px; }
.synth .sy-kind { color: var(--hair); line-height: 0; }
.synth .sy-kind.is-on { color: var(--accent); }
.synth .sy-kind .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }

.synth .sy-card__foot {
  margin-top: auto; padding-top: var(--space-2-5); text-align: right;
  font-size: calc(11px * var(--tscale, 1)); font-style: italic; color: var(--muted);
}

.synth .sy-new {
  display: flex; flex-direction: column; gap: 6px;
  min-height: 380px; padding: 20px; cursor: pointer; text-align: left; font: inherit;
  background: var(--accent); color: var(--text-inverse);
  border: 1px solid var(--accent); border-radius: var(--rCard); box-shadow: var(--ctaShadow);
  transition: transform var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out);
}
.synth .sy-new:hover { transform: translateY(-2px); box-shadow: var(--shCard); }
.synth .sy-new:active { transform: translateY(1px); }
.synth .sy-new__icon { font-size: calc(26px * var(--tscale, 1)); margin-bottom: 4px; }
.synth .sy-new__title {
  font-family: var(--font-heading); font-weight: 600;
  font-size: calc(19px * var(--tscale, 1)); letter-spacing: -.02em;
}
.synth .sy-new__desc { font-size: calc(13px * var(--tscale, 1)); color: rgba(255,255,255,.85); }

.synth .sy-gallery-empty { font-size: calc(14px * var(--tscale, 1)); color: var(--muted); margin: -28px 0 44px; }

/* Loading: platform skeletons (.ws-skeleton), which bring their own shimmer. */
.synth .sy-card--skel { cursor: default; pointer-events: none; }

.synth .recent-h { font-size: calc(13px * var(--tscale, 1)); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; }


/* ============================================================
   MODALS
   ============================================================ */
.synth-overlay {
  position: fixed; inset: 0; background: rgba(44, 36, 22, .42);
  display: grid; place-items: center; padding: 24px; z-index: 1000;
  animation: synth-fade var(--duration-base) var(--ease-out);
}
.synth-overlay--top { z-index: 1100; }
@keyframes synth-fade { from { opacity: 0; } }
.synth-modal {
  position: relative;
  background: var(--surface); border-radius: var(--rModal); box-shadow: var(--shModal);
  width: 100%; max-width: 560px; max-height: 86vh; overflow: auto;
  animation: synth-pop var(--duration-enter) var(--ease-spring);
}
.synth-modal--wide { max-width: 720px; }
@keyframes synth-pop { from { opacity: 0; transform: translateY(8px) scale(.98); } }
/* Already on screen before this render rebuilt it (see snapshotOverlays) — the
   entry animation belongs to opening, not to every state change behind it. */
.synth-overlay--settled,
.synth-overlay--settled > .synth-modal { animation: none; }
/* Red gradient header matching the Planner's modal/topbar chrome
   (--planner-topbar-bg): white title + white-on-translucent close button. */
.synth-modal-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 52px 14px 24px;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accentD) 100%);
  color: #fff;
}
.synth-modal-icon {
  width: 32px; height: 32px; flex-shrink: 0;
  background: rgba(255, 255, 255, .2); border-radius: var(--radius-md, 8px);
  display: flex; align-items: center; justify-content: center;
}
.synth-modal-icon .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); color: #fff; }
.synth-modal-title { font-family: var(--font-heading); font-size: calc(18px * var(--tscale, 1)); font-weight: 600; letter-spacing: -.02em; color: #fff; }
.synth-modal-close {
  position: absolute; top: 12px; right: 12px;
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: rgba(255, 255, 255, .15); border: 0; border-radius: var(--radius-md, 6px);
  color: #fff; cursor: pointer;
  transition: background-color .15s var(--ease-out), color .15s var(--ease-out),
              transform .2s var(--ease-out);
}
.synth-modal-close:hover { background: rgba(255, 255, 255, .28); color: #fff; transform: rotate(90deg); }
.synth-modal-close:active { transform: rotate(90deg) scale(.92); }
.synth-modal-close .material-symbols-outlined { font-size: calc(20px * var(--tscale, 1)); }
@media (prefers-reduced-motion: reduce) {
  .synth-modal-close { transition: background-color .15s var(--ease-out), color .15s var(--ease-out); }
  .synth-modal-close:hover, .synth-modal-close:active { transform: none; }
}
.synth-modal-body { padding: 20px 24px 22px; }
.synth-modal-foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 16px 24px; border-top: 1px solid var(--inner);
}

.synth .field { margin-bottom: 16px; }
.synth .field label { display: block; font-size: calc(13px * var(--tscale, 1)); font-weight: 600; color: var(--ink2); margin-bottom: 6px; }
/* .hint had only ever been styled inside .field, so the three modals using it
   as a standalone sibling rendered explanatory text at full body size and ink
   colour. This is the base; .field .hint just tightens the margin. */
.synth .hint { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); line-height: 1.55; }
.synth .field .hint { margin-top: 4px; }
/* Spacing for the blocks that sat on inline margin-top styles. */
.synth .modal-note { margin-top: var(--space-2); }
.synth .modal-actions { margin-top: var(--space-3); }
.synth .modal-inline-actions { display: flex; gap: var(--space-2-5); }
.synth .fig-toggle {
  margin: 0 0 var(--space-1-5); font-size: calc(13px * var(--tscale, 1));
}
.synth .fig-guide { background: var(--subtleP); border: 1px solid var(--border); border-radius: var(--rChip); padding: 10px 14px 10px 6px; margin-bottom: 6px; }
.synth .fig-guide ol { margin: 0; padding-left: 22px; }
.synth .fig-guide ul { margin: 4px 0 0; padding-left: 22px; }
.synth .fig-guide li { font-size: calc(13px * var(--tscale, 1)); color: var(--ink2); line-height: 1.55; margin: 2px 0; }
.synth .fig-guide strong { color: var(--ink); font-weight: 600; }
.synth input[type=text], .synth input[type=url], .synth input[type=date], .synth textarea, .synth select {
  width: 100%; font: inherit; font-size: calc(14px * var(--tscale, 1)); color: var(--ink);
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); resize: vertical;
}
/* Date inputs ship with UA chrome that ignores the rules above: Safari adds an
   inner inset and both engines size the picker glyph off the UA font. */
.synth input[type=date] { -webkit-appearance: none; appearance: none; min-height: 41px; }
.synth input[type=date]::-webkit-date-and-time-value { text-align: left; margin: 0; }
.synth input[type=date]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .55; }
.synth input[type=date]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
.synth textarea { min-height: 120px; line-height: 1.5; }
.synth input:focus, .synth textarea:focus, .synth select:focus {
  /* Sky-blue ring: the platform's one sanctioned non-red accent (focus visibility) */
  outline: none; border-color: var(--focus-ring-color); box-shadow: 0 0 0 3px var(--focus-ring-color);
}

/* Video upload: consent row + run progress */
.synth .vid-meta { font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); }
.synth .consent-row {
  display: flex; align-items: flex-start; gap: var(--space-2);
  margin-top: var(--space-3); padding: var(--space-3);
  border: 1px solid var(--border); border-radius: var(--rChip); background: var(--subtle);
  font-size: calc(13px * var(--tscale, 1)); line-height: 1.5; cursor: pointer;
}
/* Sized to be as easy to reach as the button it gates — a consent control that
   is harder to hit than the action it authorises is a dark pattern. */
.synth .consent-row input[type=checkbox] { flex: none; width: 18px; height: 18px; margin-top: 1px; cursor: pointer; }
.synth .vid-progress { padding: var(--space-2) 0; }
.synth .vid-progress__bar {
  height: 8px; border-radius: 9999px; background: var(--inner); overflow: hidden; margin-bottom: var(--space-3);
}
/* No transition on width. The value comes straight from XHR progress events, so
   it is already continuous — easing it only makes the bar lag behind the real
   upload, and animating a layout property thrashes on every event. scaleX would
   be the performant alternative but squashes the pill's rounded ends. */
.synth .vid-progress__bar span {
  display: block; height: 100%; background: var(--accent); border-radius: 9999px;
}
.synth .vid-progress__line { font-size: calc(14px * var(--tscale, 1)); font-weight: 600; color: var(--ink); }

/* dropzone */
.synth .dropzone {
  /* display is load-bearing: a <label> is inline by default, so without this the
     28px padding overflows instead of shaping a box, text-align can't apply, and
     the block-level icon inside forces a block-in-inline split that renders a
     stray fragment of the label's own background beside the border. */
  display: block;
  border: 1.5px dashed var(--hair); border-radius: 12px; padding: 28px;
  text-align: center; color: var(--muted); background: var(--subtle); cursor: pointer;
  transition: border-color var(--duration-base) var(--ease-out), background var(--duration-base) var(--ease-out);
}
.synth .dropzone:hover { border-color: var(--accent); background: var(--subtleP); }
.synth .dropzone .material-symbols-outlined { font-size: calc(30px * var(--tscale, 1)); color: var(--accent); display: block; margin-bottom: 8px; }
.synth .charcount { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); text-align: right; margin-top: 6px; }
.synth .charcount.over { color: var(--p1); font-weight: 600; }
.synth .thumbs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.synth .thumb { position: relative; width: 72px; height: 72px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.synth .thumb img { width: 100%; height: 100%; object-fit: cover; }
.synth .thumb .x { position: absolute; top: 2px; right: 2px; background: rgba(0,0,0,.6); color: var(--bg-surface); border: 0; border-radius: 6px; width: 20px; height: 20px; cursor: pointer; display: grid; place-items: center; }
.synth .thumb .x .material-symbols-outlined { font-size: calc(14px * var(--tscale, 1)); }
/* Advisory capture-quality badge (blur/glare/dark/low-res) — warns, never blocks. */
.synth .thumb-warn {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  font-size: calc(10px * var(--tscale, 1)); font-weight: 600; padding: 2px 4px;
  background: var(--color-warning-very-light); color: var(--color-warning-ink);
}
.synth .thumb-warn .material-symbols-outlined { font-size: calc(12px * var(--tscale, 1)); }

/* ============================================================
   INPUT (artifact tray)
   ============================================================ */
.synth .input-h1 { font-size: calc(22px * var(--tscale, 1)); line-height: 1.25; margin: 8px 0 18px; max-width: 44ch; }
/* The app frame, worn by every working screen: the sources you gathered on the
   left, the working surface in the middle, the Synthesizer AI panel on the
   right when it's open. The rail sticks so it stays reachable while the middle
   scrolls. Collapses to one column under 1080px. */
/* Column layouts run the full viewport width. Prose inside them keeps its own
   measure cap (.home-h1 / .home-sub), so only the columns widen. */
.synth .wrap--app,
.synth .wrap--full { max-width: none; }
/* The app frame sits directly under the doc-bar, which already provides the
   separation a top pad would. min-height + a trimmed bottom pad are what let the
   rail inside actually reach full height; .wrap's 110px bottom was dead space
   the frame would otherwise have to stop short of. */
.synth .wrap--app {
  /* Edge to edge: no side padding, so the rail meets the left window edge and
     the working surface reaches the right one. margin:0 is load-bearing — the
     base .wrap sets `margin: 0 auto`, and auto cross-axis margins on a flex
     item suppress the stretch that makes this full width. */
  padding: 0 0 var(--space-6);
  margin: 0;
  display: flex; flex-direction: column;
}
.synth .wrap--app > .sy-app { flex: 1; }
.synth .sy-app {
  display: grid; grid-template-columns: var(--app-rail-width) minmax(0, 1fr);
  /* No gutter: rail and working surface are adjacent panels, separated by the
     surface's own left border rather than by empty page. */
  gap: 0;
  /* stretch, not start: the rail runs the full height of the frame rather than
     ending as a card wherever its content stops. */
  align-items: stretch;
}
/* The middle column is the working surface, so it wears the drafting grid over
   the platform page background (--bg-page) rather than the warmer --bg-paper —
   the page and the work surface read as one sheet. --grid-line-color and the
   24px cell are the canonical platform pair; none of it is literal here so a
   change to the tokens propagates. */
.synth .sy-main {
  background-color: var(--bg-page);
  background-image:
    linear-gradient(var(--grid-line-color) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line-color) 1px, transparent 1px);
  background-size: 24px 24px;
  /* Square, and bordered only where it meets the rail — a radius or a right
     border would read as a card floating on the page rather than a panel that
     runs to the window edge. */
  border: 0;
  border-left: 1px solid var(--border);
  border-radius: 0;
  /* The panel itself runs edge to edge; its content doesn't. 24px all round so
     cards clear the left seam and the window edge. */
  padding: var(--space-6);
  min-width: 0;
}
/* Row one of the working surface: where you are on the left (back link or
   tabs), how to add material on the right. */
.synth .sy-main__bar {
  display: flex; align-items: flex-end; gap: var(--space-4);
  margin-bottom: var(--space-5); flex-wrap: wrap;
}
/* The tab row keeps a real minimum: rather than squeezing the tabs into a
   horizontal scroller when the AI panel opens, the add-source icons wrap to
   their own line. */
.synth .sy-main__bar > .ws-tabs { flex: 1 1 400px; min-width: 0; margin-bottom: 0; }
.synth .sy-main__bar > .linkback { flex: 1 1 200px; margin: 0; }
.synth .sy-main__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-5);
}
.synth .sy-main__foot .hint { font-size: calc(13px * var(--tscale, 1)); color: var(--muted); }

/* Add-source icon rail. Labels live in the tooltip — five spelled-out buttons
   crowded the surface they sit above. */
/* In the rail, not the canvas bar: the row spreads across the 280px column. */
.synth .sy-tools {
  display: flex; gap: var(--space-1-5); flex: none;
  margin-bottom: var(--space-4);
}
.synth .sy-rail .sy-tools { justify-content: space-between; }
.synth .sy-rail .sy-tool { flex: 1; }
.synth .sy-tool {
  position: relative; display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface); color: var(--ink);
  cursor: pointer; padding: 0;
  transition: border-color var(--duration-base) var(--ease-out), background var(--duration-base) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.synth .sy-tool:hover { border-color: var(--accent); background: var(--subtleP); }
.synth .sy-tool:active { transform: scale(.96); }
.synth .sy-tool .material-symbols-outlined { font-size: calc(20px * var(--tscale, 1)); color: var(--accent); }
.synth .sy-tool__tip {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 5;
  white-space: nowrap; font-size: calc(12px * var(--tscale, 1)); font-weight: 600;
  padding: 4px 8px; border-radius: var(--rBadge);
  background: var(--ink); color: var(--bg-surface);
  opacity: 0; pointer-events: none; transition: opacity var(--duration-base) var(--ease-out);
}
.synth .sy-tool:hover .sy-tool__tip, .synth .sy-tool:focus-visible .sy-tool__tip { opacity: 1; }

/* The stage dropzone: the centre of the empty state, not a slim strip. */
.synth .sy-drop {
  display: grid; place-content: center; gap: var(--space-2);
  min-height: 300px; padding: var(--space-8);
}
.synth .sy-drop__text { font-size: calc(13.5px * var(--tscale, 1)); line-height: 1.6; max-width: 52ch; }
.synth .sy-drop__text strong { color: var(--ink); font-size: calc(16px * var(--tscale, 1)); }

/* Rail and AI panel are panels of the same family as the working surface: one
   hairline --border, one --rCard radius. Only the fill tells them apart. */
/* A full-height column, not a card: no border, no radius, and the tint runs the
   whole height of the frame.

   The rail also owns its own scrolling. `align-self: start` opts it out of the
   grid's stretch so it can be sticky and so max-height can bind — a stretched
   item is sized by the row and neither would take effect. min-height keeps the
   full-height tint when the source list is short, max-height caps it at the
   viewport, and overflow-y only produces a bar once the sources actually pass
   that point. Sticky top:0 is relative to .synth-stage, the scroll container,
   so the rail stays put while a long board scrolls beside it. */
.synth .sy-rail {
  border: 0;
  border-radius: 0;
  padding: var(--space-5);
  background: var(--bg-paper-dark);
  align-self: start;
  position: sticky;
  top: 0;
  min-height: 100%;
  max-height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.synth .sy-rail__h {
  display: flex; align-items: center; gap: 8px;
  font-size: calc(15px * var(--tscale, 1)); font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 14px;
}
.synth .sy-rail__count {
  font-size: calc(13px * var(--tscale, 1)); font-weight: 700; padding: 2px 9px;
  border-radius: 9999px; background: var(--accentVL); color: var(--accentD); letter-spacing: 0;
}
.synth .sy-rail__empty {
  display: flex; flex-direction: column; align-items: flex-start; gap: 12px;
  border: 1px dashed var(--hair); border-radius: var(--rCard); padding: 18px;
  font-size: calc(13px * var(--tscale, 1)); color: var(--muted); background: var(--subtle);
}
/* Rail cards stack vertically and wrap their labels — the horizontal tray row
   does not survive a 280px column. */
.synth .tray--rail .tray-item { flex-wrap: wrap; }
/* Titles wrap to two lines in the rail rather than truncating mid-word — a
   source is identified by its name, so clipping it defeats the rail. */
.synth .tray--rail .tray-title {
  white-space: normal; overflow: hidden; text-overflow: clip;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.synth .add-bar--rail { flex-direction: column; flex-wrap: nowrap; margin-bottom: 0; }
.synth .add-bar--rail .add-btn { width: 100%; justify-content: flex-start; }

@media (max-width: 1080px) {
  .synth .sy-app { grid-template-columns: 1fr; gap: 28px; }
  .synth .sy-rail { position: static; order: 3; }
}

.synth .add-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 24px; }
.synth .add-btn {
  display: inline-flex; align-items: center; gap: 8px; font: inherit; font-size: calc(14px * var(--tscale, 1)); font-weight: 600;
  padding: 11px 15px; border: 1px solid var(--border); border-radius: 11px; background: var(--surface);
  color: var(--ink); cursor: pointer; transition: border-color var(--duration-base) var(--ease-out), background var(--duration-base) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.synth .add-btn:hover { border-color: var(--accent); background: var(--subtleP); }
.synth .add-btn:active { transform: scale(.98); }
.synth .add-btn .material-symbols-outlined { font-size: calc(19px * var(--tscale, 1)); color: var(--accent); }

.synth .uni-demo { margin-bottom: var(--space-4); }

.synth .tray { display: flex; flex-direction: column; gap: 10px; }
.synth .tray-item {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border: 1px solid var(--border); background: var(--surface); border-radius: 11px;
}
.synth .tray-tile {
  width: 42px; height: 42px; border-radius: 10px; background: var(--accentVL);
  color: var(--accentD); display: grid; place-items: center; flex: none;
}
/* The card body is a real <button>, so opening a source is keyboard-reachable
   and announced, not a click handler on a div. It resets the button chrome and
   inherits the row layout the card used to own. */
.synth .tray-open {
  display: flex; align-items: center; gap: 14px;
  flex: 1; min-width: 0;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  border-radius: var(--rChip);
}
.synth .tray-open:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }
.synth .tray-open .tray-title,
.synth .tray-open .tray-meta { display: block; }
.synth .tray-main { flex: 1; min-width: 0; }
.synth .tray-title { font-weight: 600; font-size: calc(14.5px * var(--tscale, 1)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.synth .tray-meta { font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); margin-top: 2px; }

/* Live-session-record artifact card (Workshop Record import) */
.synth .tray-item--session { border-color: var(--accentL); background: var(--accentVL); }
.synth .tray-item--session .tray-tile { background: var(--surface); }


/* Workshop picker ("Which workshop is this from?") */
.synth .wk-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
  padding: 12px 14px; margin-bottom: 8px; cursor: pointer; font: inherit; color: var(--ink);
}
.synth .wk-row:hover { border-color: var(--accent); background: var(--subtleP); }
.synth .wk-row .wk-ico { color: var(--accent); flex: none; }
.synth .wk-row > .material-symbols-outlined:last-child { color: var(--faint); flex: none; }
.synth .wk-main { flex: 1; min-width: 0; display: block; }
.synth .wk-name { display: block; font-weight: 600; font-size: calc(14.5px * var(--tscale, 1)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.synth .wk-meta { display: block; font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); margin-top: 2px; }
.synth .wk-badge {
  display: inline-block; padding: 1px 8px; border-radius: 9999px;
  font-size: calc(11px * var(--tscale, 1)); font-weight: 700; letter-spacing: .04em; text-transform: capitalize;
  background: var(--inner); color: var(--muted);
}
.synth .wk-badge--delivered { background: var(--accentVL); color: var(--accentD); }
.synth .wk-badge--synthesized { background: var(--accent); color: var(--text-inverse); }

/* Alerts are the platform's (.ws-alert). Only the spacing an inline alert needs
   inside a modal body is Synthesize's. */
.synth .ws-alert { margin-top: var(--space-4); }
.synth .synth-alert--spaced { margin-top: 0; margin-bottom: var(--space-3-5); }
.synth .input-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  margin-top: var(--space-6); flex-wrap: wrap;
}
.synth .toggle { display: inline-flex; align-items: center; gap: 8px; font-size: calc(13px * var(--tscale, 1)); color: var(--ink2); cursor: pointer; }
.synth .toggle input { width: auto; }

/* ============================================================
   LOADING
   ============================================================ */
.synth .loading { display: grid; place-items: center; min-height: 56vh; text-align: center; gap: 22px; }
.synth .load-steps { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.synth .load-step { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: calc(14px * var(--tscale, 1)); transition: color .3s; }
.synth .load-step.done { color: var(--ink); }
.synth .load-step.done .material-symbols-outlined { color: var(--ok); }
.synth .load-step .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); color: var(--faint); }
.synth .load-hint { font-style: italic; color: var(--muted); font-size: calc(13.5px * var(--tscale, 1)); }

/* ============================================================
   REVIEW
   ============================================================ */
.synth .review-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface); margin-bottom: 8px;
}
.synth .review-row .conf { font-size: calc(18px * var(--tscale, 1)); }
.synth .review-row .conf.low { color: var(--p2); }
.synth .review-row .conf.ok { color: var(--ok); }
.synth .review-text { flex: 1; }
.synth .src-chip {
  display: inline-flex; align-items: center; gap: 5px; font-size: calc(11.5px * var(--tscale, 1)); font-weight: 600;
  padding: 3px 9px; border-radius: 9999px; background: var(--accentVL); color: var(--accentD);
  cursor: pointer; border: 0; flex: none;
}
.synth .src-chip .material-symbols-outlined { font-size: calc(14px * var(--tscale, 1)); }
/* Cross-photo dedupe marker: informational (not clickable), so neutral gray
   rather than the accent the src-chip uses. */
.synth .dupe-chip {
  display: inline-flex; align-items: center; gap: 5px; font-size: calc(11.5px * var(--tscale, 1)); font-weight: 600;
  padding: 3px 9px; border-radius: 9999px; background: var(--subtle); color: var(--muted); flex: none;
}
.synth .dupe-chip .material-symbols-outlined { font-size: calc(14px * var(--tscale, 1)); }
.synth .low-pill {
  display: inline-flex; align-items: center; gap: 6px; font-size: calc(12px * var(--tscale, 1)); font-weight: 600;
  padding: var(--space-1) var(--space-2-5); border-radius: 9999px; background: var(--color-warning-very-light); color: var(--color-warning-ink); margin-bottom: var(--space-3-5);
}

/* ----- Grouped review (scannable affinity review for big boards) ----- */
.synth .review-cover {
  display: inline-flex; align-items: center; gap: 7px; font-size: calc(13px * var(--tscale, 1)); font-weight: 600;
  color: var(--accentD); background: var(--accentVL); padding: 5px 12px; border-radius: 9999px; margin-bottom: 14px;
}
.synth .review-cover .material-symbols-outlined { font-size: calc(16px * var(--tscale, 1)); }
.synth .review-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.synth .review-modes { display: inline-flex; border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
.synth .review-modes button {
  display: inline-flex; align-items: center; gap: 5px; font-size: calc(12.5px * var(--tscale, 1)); font-weight: 600;
  padding: 6px 12px; border: 0; background: var(--surface); color: var(--muted); cursor: pointer;
}
.synth .review-modes button + button { border-left: 1px solid var(--border); }
.synth .review-modes button.on { background: var(--accentVL); color: var(--accentD); }
.synth .review-modes .material-symbols-outlined { font-size: calc(15px * var(--tscale, 1)); }

.synth .rg-card { border: 1px solid var(--border); border-radius: 12px; background: var(--surface); margin-bottom: 10px; overflow: hidden; }
.synth .rg-card.accepted { background: var(--subtleP); }
.synth .rg-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; }
.synth .rg-chev { border: 0; background: transparent; cursor: pointer; color: var(--muted); display: inline-flex; padding: 0; }
.synth .rg-title { flex: 1; font-family: var(--font-heading); font-size: calc(16px * var(--tscale, 1)); font-weight: 600; color: var(--ink); }
.synth .rg-count {
  font-size: calc(12px * var(--tscale, 1)); font-weight: 700; color: var(--muted);
  /* ds-lint-disable-next-line */
  background: var(--subtle, #FBFAF8);
  border: 1px solid var(--border); border-radius: 9999px; padding: 1px 9px; min-width: 24px; text-align: center;
}
.synth .rg-ok { font-size: calc(18px * var(--tscale, 1)); color: var(--ok); }
.synth .rg-mini { border: 0; background: transparent; cursor: pointer; color: var(--muted); display: inline-flex; padding: 4px; border-radius: 6px; }
.synth .rg-mini:hover { background: var(--subtleP); color: var(--accentD); }
.synth .rg-mini.del:hover { color: var(--p1); }
.synth .rg-mini .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }
.synth .rg-body { padding: 0 12px 12px; }
.synth .rg-body .review-row { margin-bottom: 6px; }
.synth .rg-additem { margin-top: 2px; }
.synth .rg-merged { margin-top: 8px; border-top: 1px solid var(--inner); padding-top: 8px; }
.synth .rg-merged-tog { border: 0; background: transparent; cursor: pointer; color: var(--muted); font-size: calc(12.5px * var(--tscale, 1)); display: inline-flex; align-items: center; gap: 4px; padding: 0; }
.synth .rg-merged-tog .material-symbols-outlined { font-size: calc(16px * var(--tscale, 1)); }
.synth .rg-dups { margin-top: 6px; }
.synth .rg-dup { display: flex; align-items: center; gap: 7px; font-size: calc(13px * var(--tscale, 1)); color: var(--muted); padding: 4px 0 4px 6px; }
.synth .rg-dup .material-symbols-outlined { font-size: calc(14px * var(--tscale, 1)); }

/* ----- Assisted keyboard triage ("Sort myself") ----- */
.synth .tr-kbd { font-family: ui-monospace, Menlo, monospace; font-size: calc(13px * var(--tscale, 1)); background: var(--subtle); border: 1px solid var(--border); border-radius: 5px; padding: 1px 7px; color: var(--ink2); }
.synth .tr-prog { display: flex; align-items: center; gap: 12px; margin: 4px 0 16px; }
.synth .tr-prog-n { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); white-space: nowrap; }
.synth .tr-bar { flex: 1; height: 5px; background: var(--inner); border-radius: 3px; overflow: hidden; }
/* fill animates via scaleX (compositor-only) — width transitions cause layout thrash */
.synth .tr-bar > i { display: block; height: 100%; width: 100%; background: var(--accent); transform-origin: left; transition: transform .2s ease; }
.synth .tr-note { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 1px 3px rgba(0,0,0,.05); padding: 28px 22px; text-align: center; margin-bottom: 12px; }
.synth .tr-note-text { font-family: var(--font-heading); font-size: calc(20px * var(--tscale, 1)); font-weight: 600; line-height: 1.4; color: var(--ink); }
.synth .tr-note-by { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); margin-top: 10px; display: inline-flex; align-items: center; gap: 5px; }
.synth .tr-note-by .material-symbols-outlined { font-size: calc(14px * var(--tscale, 1)); }
.synth .tr-sugg { text-align: center; font-size: calc(13px * var(--tscale, 1)); color: var(--accentD); margin-bottom: 12px; display: flex; align-items: center; justify-content: center; gap: 5px; }
.synth .tr-sugg .material-symbols-outlined { font-size: calc(16px * var(--tscale, 1)); }
.synth .tr-sugg--none { color: var(--muted); }
.synth .tr-bkts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.synth .tr-bkt { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); cursor: pointer; font-family: var(--font-body); font-size: calc(13px * var(--tscale, 1)); color: var(--ink); text-align: left; transition: border-color .1s; }
.synth .tr-bkt:hover { border-color: var(--accent); }
.synth .tr-bkt.suggested { border: 2px solid var(--accent); background: var(--accentVL); color: var(--accentD); font-weight: 600; }
.synth .tr-bkt .tr-key { font-family: ui-monospace, Menlo, monospace; font-size: calc(13px * var(--tscale, 1)); width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 5px; color: var(--muted); flex: none; }
.synth .tr-bkt.suggested .tr-key { border-color: var(--accent); color: var(--accentD); }
.synth .tr-bkt-label { flex: 1; min-width: 0; }
.synth .tr-ret { margin-left: auto; font-size: calc(16px * var(--tscale, 1)); color: var(--accent); }
.synth .tr-newbkt { margin-top: 10px; border: 0; background: transparent; cursor: pointer; color: var(--muted); font-size: calc(13px * var(--tscale, 1)); display: inline-flex; align-items: center; gap: 6px; padding: 0; }
.synth .tr-legend { display: flex; flex-wrap: wrap; gap: 16px; justify-content: center; margin-top: 16px; font-size: calc(12px * var(--tscale, 1)); color: var(--muted); }
.synth .tr-legend span { display: inline-flex; align-items: center; gap: 5px; }
.synth .tr-done { text-align: center; padding: 36px 20px; }
.synth .tr-done .material-symbols-outlined { font-size: calc(32px * var(--tscale, 1)); color: var(--ok); }
.synth .tr-done-h { font-family: var(--font-heading); font-size: calc(20px * var(--tscale, 1)); font-weight: 600; margin: 10px 0 4px; }
.synth .tr-done-sub { font-size: calc(13px * var(--tscale, 1)); color: var(--muted); margin-bottom: 18px; }

/* ============================================================
   RESULTS — header
   ============================================================ */
.synth .res-head {
  position: sticky; top: 0; z-index: 40; height: 64px;
  display: flex; align-items: center; gap: 12px; padding: 0 24px;
  background: rgba(254, 247, 241, .9); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.synth .res-wordmark { font-family: var(--font-heading); font-weight: 700; font-size: calc(18px * var(--tscale, 1)); letter-spacing: -.02em; }
.synth .res-pill { font-size: calc(11px * var(--tscale, 1)); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 3px 9px; border-radius: 9999px; background: var(--accentVL); color: var(--accentD); }
.synth .res-spacer { flex: 1; }
.synth .seg, .synth-topbar .seg {
  display: inline-flex; background: var(--inner); border-radius: 9px; padding: 3px;
}
.synth .seg button, .synth-topbar .seg button {
  font: inherit; font-size: calc(13px * var(--tscale, 1)); font-weight: 600; border: 0; background: transparent;
  color: var(--ink2); padding: 6px 12px; border-radius: 7px; cursor: pointer; transition: background .2s, color .2s;
  white-space: nowrap;
}
.synth .seg button.on, .synth-topbar .seg button.on { background: var(--surface); color: var(--ink); box-shadow: var(--shCard); }

/* Layout toggles on the Themes tab. Scoped to .tab-tools so the topbar's own
   .seg (undo/redo, white on red) is untouched.

   Icons carry the brand red rather than ink — these are the one control on the
   tab, and red is what marks them as actionable. The selected state is still
   read from the raised pill behind it, not from the icon colour, so all four
   staying red doesn't cost the affordance. */
.synth .tab-tools.seg button { position: relative; }
.synth .tab-tools.seg button .material-symbols-outlined { color: var(--accent); }
.synth .tab-tools.seg button.on .material-symbols-outlined { color: var(--accentD); }

/* Same tooltip as the add-source rail (.sy-tool__tip) — one tip pattern in this
   app, not two. Right-anchored because these sit at the bar's trailing edge and
   a centred tip would clip outside it. */
.synth .seg__tip {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 5;
  white-space: nowrap; font-size: calc(12px * var(--tscale, 1)); font-weight: 600;
  padding: 4px 8px; border-radius: var(--rBadge);
  background: var(--ink); color: var(--bg-surface);
  opacity: 0; pointer-events: none; transition: opacity var(--duration-base) var(--ease-out);
}
.synth .tab-tools.seg button:hover .seg__tip,
.synth .tab-tools.seg button:focus-visible .seg__tip { opacity: 1; }


/* Tabs, sized up for this app. The component's own sizes are rem tokens
   (--text-small, --text-micro), which under-render inside .synth because the
   app scales its root, so these restate them in the file's calc idiom.
   Hover drops the component's grey fill: a solid block reads as a smudge on the
   drafting grid, so hover is carried by ink and a hairline instead. */
.synth .ws-tabs__btn {
  padding: 14px 18px;
  font-size: calc(15px * var(--tscale, 1));
  gap: 8px;
}
.synth .ws-tabs__btn:hover:not(.is-disabled) {
  background: none;
  color: var(--ink);
  border-bottom-color: var(--hair);
}
.synth .ws-tabs__btn.is-active { border-bottom-width: 3px; }
/* The component ships no focus ring on tabs; keyboard users need one. */
.synth .ws-tabs__btn:focus-visible {
  outline: var(--focus-ring); outline-offset: -3px; border-radius: var(--rBadge);
}
.synth .ws-tabs__count {
  font-size: calc(12px * var(--tscale, 1));
  min-width: 22px; height: 22px; padding: 0 7px;
}

/* ---------- Tabs ----------
   Platform tabs (.ws-tabs--underline). Adopting them also retired the reset
   Synthesize needed against the global `.tab` pill rule, which sat at the same
   specificity and was only losing on source order. */
.synth .tab-tools { margin-left: auto; }

/* ============================================================
   THEMES
   ============================================================ */
.synth .themes-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.synth .themes-list { display: flex; flex-direction: column; gap: 12px; }
.synth .theme-card {
  border: 1px solid var(--border); background: var(--surface); border-radius: var(--rCard);
  padding: var(--space-4); transition: box-shadow .2s, transform .2s;
}
.synth .theme-card:hover { box-shadow: var(--shCard); }
.synth .theme-card.muted { opacity: .55; }
.synth .theme-top { display: flex; align-items: center; gap: 10px; }
.synth .theme-chev { background: none; border: 0; cursor: pointer; color: var(--muted); padding: 0; display: grid; place-items: center; }
.synth .theme-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.synth .theme-title { font-family: var(--font-heading); font-weight: 600; font-size: calc(17px * var(--tscale, 1)); flex: 1; min-width: 0; }
.synth .theme-notes { font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); white-space: nowrap; }
.synth .theme-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; align-items: center; }
.synth .themes-bar { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; align-items: center; }
.synth .themes-bar .tab-tools { margin-left: auto; }
/* A collapsed theme still shows what it's made of — a title alone tells you
   nothing about whether the grouping is right. */
.synth .theme-points {
  list-style: none; margin: 12px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.synth .theme-points li {
  position: relative; padding-left: 16px;
  font-size: calc(13.5px * var(--tscale, 1)); line-height: 1.5; color: var(--ink2);
}
.synth .theme-points li::before {
  content: ''; position: absolute; left: 3px; top: 8px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--hair);
}
.synth .theme-points__more::before { display: none; }
.synth .theme-points__more button {
  font: inherit; font-size: calc(12.5px * var(--tscale, 1)); font-weight: 600;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--accentD); text-decoration: underline; text-underline-offset: 2px;
}

/* Badges and pills are the platform's (.ws-badge / .ws-pill). What stays is
   only the data-driven colouring they can't express: the priority band and the
   category fill are both set inline from app state, so these two just make the
   text legible on top of whatever colour lands there. */
.synth .pri-badge { color: var(--bg-surface); }
.synth .cat-pill { color: var(--bg-surface); border: 0; cursor: pointer; }

/* evidence */
.synth .evidence { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--inner); display: flex; flex-direction: column; gap: 10px; }
.synth .ev-card {
  background: var(--subtle); border: 1px solid var(--inner); border-radius: 10px; padding: 12px 14px;
  position: relative;
}
.synth .ev-quote { color: var(--accent); font-size: calc(16px * var(--tscale, 1)); }
.synth .ev-text { font-size: calc(14px * var(--tscale, 1)); line-height: 1.5; margin: 4px 0; }
.synth .ev-foot { display: flex; align-items: center; gap: 10px; font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); }
.synth .ev-by { font-style: italic; }
.synth .ev-card .del { position: absolute; top: 8px; right: 8px; opacity: 0; }
.synth .ev-card:hover .del { opacity: 1; }


/* card / overflow menu */
.synth .menu-wrap { position: relative; }
.synth .menu {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 60; min-width: 200px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shDrop);
  padding: var(--space-1-5); animation: synth-pop var(--duration-fast) var(--ease-out);
}
.synth .menu button {
  width: 100%; text-align: left; font: inherit; font-size: calc(13.5px * var(--tscale, 1)); color: var(--ink);
  background: none; border: 0; padding: 8px 10px; border-radius: 7px; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
}
.synth .menu button:hover { background: var(--inner); }
.synth .menu button.danger { color: var(--p1); }
.synth .menu-sep { height: 1px; background: var(--inner); margin: 5px 2px; }
.synth .menu-label { font-size: calc(11px * var(--tscale, 1)); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding: 6px 10px 4px; }
.synth .cat-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 10px 8px; }
.synth .cat-chip { font-size: calc(11.5px * var(--tscale, 1)); font-weight: 600; padding: 4px 9px; border-radius: 9999px; border: 1px solid var(--border); background: var(--surface); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
.synth .menu-catcher { position: fixed; inset: 0; z-index: 50; }

/* ---------- Kanban ---------- */
.synth .kanban { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 12px; }
.synth .kan-col { flex: 0 0 280px; background: var(--subtle); border: 1px solid var(--border); border-radius: var(--rCard); padding: 12px; }
.synth .kan-col.dragover { border-color: var(--accent); background: var(--subtleP); }
.synth .kan-col-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-weight: 700; font-size: calc(13px * var(--tscale, 1)); }
.synth .kan-col-dot { width: 9px; height: 9px; border-radius: 50%; }
.synth .kan-col-cnt { margin-left: auto; font-size: calc(12px * var(--tscale, 1)); color: var(--muted); }
.synth .kan-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 12px; margin-bottom: 10px; cursor: grab; }
.synth .kan-card:active { cursor: grabbing; }
.synth .kan-card.dragging { opacity: .4; }
.synth .kan-add-col { flex: 0 0 200px; display: grid; place-items: center; border: 1.5px dashed var(--hair); border-radius: var(--rCard); color: var(--muted); cursor: pointer; }

/* ---------- Outline (Category → Themes → Items) ---------- */
.synth .outline { display: flex; flex-direction: column; gap: 12px; max-width: 820px; }
.synth .ol-cat { border: 1px solid var(--border); background: var(--surface); border-radius: var(--rCard); overflow: hidden; }
.synth .ol-cat-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; cursor: pointer; background: var(--subtle); }
.synth .ol-cat-head:hover { background: var(--inner); }
.synth .ol-cat-head .material-symbols-outlined { color: var(--muted); font-size: calc(20px * var(--tscale, 1)); }
.synth .ol-cat-dot { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.synth .ol-cat-label { font-family: var(--font-heading); font-weight: 600; font-size: calc(17px * var(--tscale, 1)); flex: 1; }
.synth .ol-cat-meta { font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); white-space: nowrap; }
.synth .ol-themes { padding: 6px 10px 10px 16px; display: flex; flex-direction: column; gap: 4px; }
.synth .ol-theme { border-left: 2px solid var(--inner); padding-left: 12px; }
.synth .ol-theme-head { display: flex; align-items: center; gap: 8px; padding: 8px 6px; cursor: pointer; border-radius: 8px; }
.synth .ol-theme-head:hover { background: var(--subtle); }
.synth .ol-theme-head .material-symbols-outlined { color: var(--faint); font-size: calc(18px * var(--tscale, 1)); }
.synth .ol-theme-title { font-weight: 600; font-size: calc(14.5px * var(--tscale, 1)); flex: 1; }
.synth .ol-theme-meta { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); }
.synth .ol-items { display: flex; flex-direction: column; gap: 4px; padding: 2px 0 8px 26px; }
.synth .ol-item { display: flex; gap: 8px; font-size: calc(13.5px * var(--tscale, 1)); line-height: 1.5; color: var(--ink2); }
.synth .ol-item .material-symbols-outlined { color: var(--accent); font-size: calc(15px * var(--tscale, 1)); flex: none; margin-top: 2px; }
.synth .ol-item em { color: var(--muted); font-style: italic; }

/* ============================================================
   PRIORITIZE — 2x2 matrix carousel
   ============================================================ */
.synth .prio-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; row-gap: 10px; }
/* Three named lenses, all visible: which framework you're reading through is a
   choice worth seeing, not a carousel position you have to page toward. */
/* The auto margin sits on the trailing group — the lens is what gets pushed to
   the far edge now, not the tools. */
.synth .prio-fw { flex-wrap: wrap; margin-left: auto; }
/* The selected lens fills red rather than wearing the raised white pill the
   other segmented controls use. This one changes what the whole grid means, so
   it earns a louder selected state than a view toggle does. Scoped to .prio-fw
   so the Themes layout toggles and the topbar segments keep the quiet pill.
   White text, not --ink: this is the same red-with-white-label treatment as the
   platform's primary button, and --ink on --accent fails contrast. */
.synth .prio-fw button.on {
  background: var(--accent); color: var(--text-inverse); box-shadow: none;
}
.synth .prio-tools { display: flex; gap: 8px; flex-wrap: wrap; }
/* The grid highlights while a chip is over it, so a drop that will land reads
   differently from one that won't. */
.synth .matrix.is-target { border-color: var(--accent); background: var(--subtleP); }

/* Queue on the left, grid on the right. The tray is a fixed column so the 2×2
   takes every pixel left over — the grid is the thing being read, the tray is
   just what is still waiting. align-items:start keeps the tray its own height
   rather than stretching it down the side of a tall grid. */
.synth .prio-layout {
  display: grid; grid-template-columns: 480px minmax(0, 1fr);
  gap: var(--space-5); align-items: start;
  margin: var(--space-5) 0 var(--space-4);
}
/* Under 1100px the two columns would each be too narrow to use: the chips lose
   their labels and the grid stops being big enough to place anything precisely.
   Stack, and put the tray back under the grid. */
@media (max-width: 1100px) {
  .synth .prio-layout { grid-template-columns: 1fr; }
  /* Stacked: the tray is full-width under the grid, so a fixed height would be
     mostly empty box. Let it size to its content again. */
  .synth .prio-layout .prio-tray { order: 2; height: auto; min-height: 52px; }
}

/* Themes waiting to be judged under this lens. An empty grid with a full tray
   is the honest starting state — nothing has been positioned yet. */
/* Two columns of chips: twice as many themes stay in view, and short titles
   stop leaving a long ragged gap down the right of the column. auto-fit rather
   than a fixed 1fr 1fr so the stacked layout below 1100px fills the full width
   instead of holding two narrow columns. */
.synth .prio-tray {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-2); align-content: start;
  padding: var(--space-3);
  /* Fixed height, not content height. The tray is the left column, so every
     theme dragged out used to collapse it by one row (~51px) and shift the
     legend and everything below it mid-interaction. A constant box means the
     page holds still while you work, and it scrolls internally when full. */
  height: 560px; overflow-y: auto;
  border: 1px dashed var(--hair); border-radius: var(--rCard); background: var(--subtle);
}
/* The left column is now a stack — queue on top, legend beneath — so the grid
   column still sees a single grid child and the two-column split holds. */
.synth .prio-side { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }

/* The heading and the all-done message are about the tray, not items in it. */
.synth .prio-tray__label,
.synth .prio-tray__done { grid-column: 1 / -1; }
.synth .prio-tray__label {
  font-size: calc(11px * var(--tscale, 1)); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
  margin-bottom: var(--space-1);
}
.synth .prio-tray__done {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: calc(13px * var(--tscale, 1)); color: var(--muted);
}
.synth .prio-tray__done .material-symbols-outlined { font-size: calc(17px * var(--tscale, 1)); color: var(--ok); }
/* Unplaced themes are things you pick up, so they read heavier than the tray
   they sit in: a darker cream against the tray's --subtle, and a visible grip
   rather than a cursor change nobody sees until they hover. */
/* Grid stretches each chip to its column, so the only override needed is
   lifting the 260px cap the horizontal tray relied on. */
.synth .prio-tray .prio-chip { max-width: none; text-align: left; }
.synth .prio-chip {
  /* start, not center: the grip sits with the first line of a wrapped title
     rather than floating halfway down the chip. */
  display: inline-flex; align-items: flex-start; gap: var(--space-1-5);
  font: inherit; font-size: calc(14px * var(--tscale, 1)); font-weight: 600;
  padding: var(--space-2) var(--space-3); max-width: 260px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-paper-dark); color: var(--ink);
  box-shadow: var(--shCard); cursor: grab; touch-action: none;
}
.synth .prio-chip__grip {
  display: inline-flex; flex: none; margin-left: calc(var(--space-1) * -1);
  color: var(--muted);
}
/* The grip is the one part that must not shrink, so the ellipsis moves onto the
   label — the chip itself is now a flex row, not a single text run. */
.synth .prio-chip__grip .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }
/* Wraps rather than truncates. In two 173px columns an ellipsis was cutting
   most titles mid-phrase ("Onboarding is …"), and you can't choose where to
   place a theme you can't read. overflow-wrap catches the single long word an
   ordinary wrap would still overflow. */
.synth .prio-chip__label { min-width: 0; white-space: normal; overflow-wrap: anywhere; }
.synth .prio-chip:hover { border-color: var(--accent); }
.synth .prio-chip:hover .prio-chip__grip { color: var(--accentD); }
.synth .prio-chip:active { cursor: grabbing; }
.synth .prio-chip--ghost {
  position: fixed; z-index: 90; pointer-events: none;
  transform: translate(-50%, -50%); box-shadow: var(--shDrop); opacity: .95;
}
.synth .matrix-wrap { position: relative; }
/* Wider, and no longer centred in its own column — the grid fills the space the
   tray doesn't take. The cap is high enough to stay out of the way on a large
   screen without letting the aspect ratio push the grid below the fold. */
/* Shorter than it is wide by more than the old 1.4: at the 1100px width that
   ratio made the grid 786px tall and pushed the lower quadrants under the fold.
   1.75 brings it back to ~630px without cramping the vertical axis. */
.synth .matrix {
  position: relative; width: 100%; aspect-ratio: 1.75 / 1; max-width: 1100px; margin: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--rCard);
}
.synth #prio-plot { position: absolute; inset: 44px; }
/* The grid's own labels read red, and one step up in size. Two reds, not one:
   the axis names the dimension and the quadrant names the verdict, so the
   darker tone keeps the axis primary the way --muted over --faint used to. */
.synth .axis-label { position: absolute; font-size: calc(13.5px * var(--tscale, 1)); font-weight: 600; color: var(--accentD); }
.synth .axis-top { top: 8px; left: 50%; transform: translateX(-50%); }
.synth .axis-bottom { bottom: 8px; left: 50%; transform: translateX(-50%); }
.synth .axis-left { left: 8px; top: 50%; transform: translateY(-50%) rotate(-90deg); transform-origin: left; }
.synth .axis-right { right: 8px; top: 50%; transform: translateY(-50%) rotate(90deg); transform-origin: right; }
.synth .quad-label { position: absolute; font-size: calc(12.5px * var(--tscale, 1)); font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: .04em; }
.synth .matrix .vline, .synth .matrix .hline { position: absolute; background: var(--inner); }
.synth .matrix .vline { left: 50%; top: 44px; bottom: 44px; width: 1px; }
.synth .matrix .hline { top: 50%; left: 44px; right: 44px; height: 1px; }
/* Same cream as the chip it was dragged from (--bg-paper-dark). A theme that
   changed colour on being placed read as a different kind of object; keeping it
   means the thing you picked up is the thing you put down. */
.synth .dot-card {
  position: absolute; transform: translate(-50%, -50%);
  background: var(--bg-paper-dark); border: 1px solid var(--border); border-radius: 9px;
  padding: var(--space-1-5) var(--space-2-5); font-size: calc(12px * var(--tscale, 1)); font-weight: 600; max-width: 160px;
  box-shadow: var(--shCard); cursor: grab; user-select: none; touch-action: none;
}
.synth .dot-card:active { cursor: grabbing; }
.synth .dot-card .pri-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }

/* A card in the sidebar rather than centred prose under the page. Left-aligned
   and unconstrained in width — it's reference text read a clause at a time
   while placing a theme, not a caption skimmed once. */
.synth .prio-caption {
  margin: 0; text-align: left;
  color: var(--ink2); font-size: calc(13px * var(--tscale, 1)); line-height: 1.6;
  padding: var(--space-3);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--rCard);
}
/* One rule per line. A wrapped rule indents its continuation so the start of
   each condition stays scannable down the left edge. */
.synth .prio-caption span { display: block; padding-left: 1em; text-indent: -1em; }
.synth .prio-caption span + span { margin-top: var(--space-1); }

.synth .lens-section { border-top: 1px solid var(--border); padding-top: 20px; margin-top: 8px; }
.synth .lens-h { font-family: var(--font-heading); font-weight: 600; font-size: calc(18px * var(--tscale, 1)); margin-bottom: 12px; }
.synth .lens-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.synth .lens-card { border: 1px solid var(--border); border-radius: var(--rCard); padding: 14px 16px; background: var(--surface); }
.synth .lens-card h4 { margin: 0 0 8px; font-size: calc(14px * var(--tscale, 1)); font-weight: 700; }
/* These sizes were inline on the markup in lensSection(), as bare 13px/13.5px —
   which meant they alone ignored --tscale and rendered smaller than everything
   around them. In CSS, on the same idiom as the rest of the file. */
.synth .lens-card ul {
  margin: 0; padding-left: 18px;
  font-size: calc(15px * var(--tscale, 1)); line-height: 1.7;
}
.synth .lens-card ul li + li { margin-top: 2px; }
.synth .lens-empty { color: var(--muted); font-size: calc(14px * var(--tscale, 1)); line-height: 1.6; }

.synth .roadmap { margin-top: 22px; }
.synth .road-group { margin-bottom: 16px; }
.synth .road-group h4 { display: flex; align-items: center; gap: 8px; font-size: calc(14px * var(--tscale, 1)); font-weight: 700; margin: 0 0 8px; }
.synth .road-group .dot { width: 9px; height: 9px; border-radius: 50%; }
.synth .road-item { padding: 8px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 9px; margin-bottom: 6px; font-size: calc(14px * var(--tscale, 1)); }

/* ============================================================
   ACTIONS / DECISIONS
   ============================================================ */
/* One card per action. Owner and due date sit on the card rather than in table
   columns, so the two facts that decide whether an action happens survive a
   narrow viewport. */
.synth .act-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--space-3); }
.synth .act-card {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4); border: 1px solid var(--border); border-radius: var(--rCard);
  background: var(--surface); box-shadow: var(--shCard);
}
.synth .act-card.is-done { background: var(--subtle); }
.synth .act-card.is-done .act-text { text-decoration: line-through; color: var(--muted); }
.synth .act-body { flex: 1; min-width: 0; }
.synth .act-text { font-size: calc(14.5px * var(--tscale, 1)); line-height: 1.5; font-weight: 500; }
.synth .act-meta { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-2-5); }
.synth .act-field {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: calc(13px * var(--tscale, 1)); color: var(--ink2);
}
.synth .act-field .material-symbols-outlined { font-size: calc(16px * var(--tscale, 1)); color: var(--faint); }
.synth .act-card .del { flex: none; opacity: 0; }
.synth .act-card:hover .del, .synth .act-card:focus-within .del { opacity: 1; }

.synth .dec-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--space-3); }
.synth .dec-card {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4); border: 1px solid var(--border); border-radius: var(--rCard);
  background: var(--surface); box-shadow: var(--shCard);
}
/* A decision is settled — the filled tick says so at a glance, where the
   actions list uses an open checkbox for work still to do. */
.synth .dec-check {
  flex: none; display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--ok); color: var(--bg-surface);
}
.synth .dec-check .material-symbols-outlined { font-size: calc(17px * var(--tscale, 1)); }
.synth .dec-text { flex: 1; font-size: calc(14.5px * var(--tscale, 1)); line-height: 1.5; }
.synth .dec-card .del { flex: none; opacity: 0; }
.synth .dec-card:hover .del, .synth .dec-card:focus-within .del { opacity: 1; }

/* ============================================================
   QUICK SUMMARY
   ============================================================ */
.synth .sum-head {
  display: flex; align-items: center; gap: var(--space-3);
  flex-wrap: wrap; margin-bottom: var(--space-4);
}
.synth .sum-flag {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: calc(11px * var(--tscale, 1)); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: var(--space-1) var(--space-2-5); border-radius: var(--radius-full);
  background: var(--accentVL); color: var(--accentD);
}
.synth .sum-flag .material-symbols-outlined { font-size: calc(14px * var(--tscale, 1)); }
.synth .sum-note { flex: 1; min-width: 200px; font-size: calc(13px * var(--tscale, 1)); color: var(--muted); }
/* Never shrink: .sum-head wraps, so on a narrow column the button drops to its
   own line at full label rather than being squeezed into an ellipsis. */
.synth .sum-add { flex: none; margin-left: auto; }

/* Empty state, flush variant (Actions, Decisions). The shared component is a
   560px centred card on #F0EBE3; here the empty state stands for the whole
   section, so it runs the section's full width and drops the fill. The dashed
   border stays — it's what still reads as "a slot with nothing in it". */
.synth .ws-empty-state--flush {
  max-width: none; margin: 0;
  background: transparent;
}

/* Right-aligned action row above a list (Actions, Decisions). Above rather than
   below: under the list the button walked further down the page with every item
   added, and on a long list it left the viewport entirely. */
.synth .tab-actions { display: flex; justify-content: flex-end; margin-bottom: var(--space-3); }
.synth .sum-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.synth .sum-card {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--border); border-radius: var(--rCard);
  background: var(--surface); box-shadow: var(--shCard);
}
.synth .sum-num {
  flex: none; display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--accentVL); color: var(--accentD);
  font-size: calc(13px * var(--tscale, 1)); font-weight: 700;
}
.synth .sum-text { flex: 1; font-size: calc(15.5px * var(--tscale, 1)); line-height: 1.55; }
.synth .sum-card .del { flex: none; opacity: 0; margin-top: 2px; }
.synth .sum-card:hover .del, .synth .sum-card:focus-within .del { opacity: 1; }

/* ============================================================
   SYNTHESIZER AI
   ============================================================ */
/* A flyout, at every width: fixed to the right edge, over the board rather than
   beside it. It never takes a grid column, so opening it can't narrow the
   working surface. No scrim either — the board stays live and editable behind
   it, which is the whole reason to prefer a drawer over a modal. `top` comes
   from --synth-stage-top (set on open + resize) because a fixed element can't
   measure the chrome above it. */
.synth .sy-ai {
  position: fixed; top: var(--synth-stage-top, 0px); right: 0; bottom: 0; left: auto;
  width: min(475px, 92vw); z-index: 60;
  display: flex; flex-direction: column;
  border: 0; border-left: 1px solid var(--border); border-radius: 0;
  background: var(--surface); overflow: hidden;
  padding-bottom: var(--space-12);
  box-shadow: var(--shModal);
}
/* No entry animation: the whole screen re-renders on every state change, so an
   `animation` here would replay on each message and read as a flicker. */
/* Same chrome as the Planner side panels (version / suggestions / cleanup /
   schedule in css/planner/components/_history.css): red gradient, white
   Fraunces title, translucent leading icon tile. The translucent whites have no
   token — they only exist as on-red treatments. */
.synth .ai-head {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 20px; flex-shrink: 0;
  background: var(--mainsite-gradient);
  color: var(--text-inverse);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.synth .ai-head__icon {
  width: 36px; height: 36px; flex-shrink: 0;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: var(--radius-lg);
  color: var(--text-inverse);
}
.synth .ai-head__icon .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }
.synth .ai-title {
  flex: 1; min-width: 0; margin: 0;
  font-family: var(--font-heading);
  /* 18px via the file's calc idiom, not var(--text-h4): the app scales its root
     font-size, so the rem token lands at 14.4px here instead of 18. */
  font-size: calc(18px * var(--tscale, 1)); font-weight: 600;
  color: var(--text-inverse);
  letter-spacing: -0.015em; line-height: 1.2;
}
.synth .ai-head .iconbtn {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .3);
  color: var(--text-inverse);
}
.synth .ai-head .iconbtn:hover {
  background: rgba(255, 255, 255, .22);
  border-color: rgba(255, 255, 255, .5);
}
/* The close twists, matching Planner's .recommendations-modal-close. That rule
   hardcodes `all 0.3s` and skips the motion-preference gate; motion.md puts UI
   micro-motion on the 150-300ms tokens and requires the gate, so this is the
   same gesture written on-system rather than a copy. */
@media (prefers-reduced-motion: no-preference) {
  .synth .ai-head .iconbtn {
    transition: background var(--duration-base) var(--ease-out),
                border-color var(--duration-base) var(--ease-out),
                transform var(--duration-base) var(--ease-out);
  }
  .synth .ai-head .iconbtn:hover { transform: rotate(90deg); }
  .synth .ai-head .iconbtn:active { transform: rotate(90deg) scale(.94); }
}
.synth .ai-log { flex: 1; overflow-y: auto; padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
.synth .ai-empty { color: var(--muted); font-size: calc(13.5px * var(--tscale, 1)); line-height: 1.6; }
.synth .ai-empty p { margin: 0 0 var(--space-4); }
.synth .ai-suggestions { display: flex; flex-direction: column; gap: var(--space-2); }
.synth .ai-suggest {
  text-align: left; font: inherit; font-size: calc(13px * var(--tscale, 1));
  padding: 9px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--subtle); color: var(--ink); cursor: pointer;
  transition: border-color var(--duration-base) var(--ease-out), background var(--duration-base) var(--ease-out);
}
.synth .ai-suggest:hover { border-color: var(--accent); background: var(--subtleP); }
.synth .ai-msg { display: flex; align-items: flex-start; gap: var(--space-2); }
.synth .ai-msg--me { justify-content: flex-end; }
.synth .ai-avatar {
  flex: none; display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--accentVL); color: var(--accentD);
}
.synth .ai-avatar .material-symbols-outlined { font-size: calc(15px * var(--tscale, 1)); }
.synth .ai-bubble {
  max-width: 88%; padding: 10px 13px; border-radius: var(--rChip);
  font-size: calc(13.5px * var(--tscale, 1)); line-height: 1.6;
  border: 1px solid var(--inner); background: var(--subtle); color: var(--ink);
}
.synth .ai-msg--me .ai-bubble { background: var(--accentVL); border-color: var(--accentL); }
.synth .ai-bubble.is-error { background: var(--color-danger-very-light, var(--accentVL)); color: var(--p1); border-color: var(--accentL); }
.synth .ai-bubble--typing { display: inline-flex; gap: 4px; padding: 14px 13px; }
.synth .ai-bubble--typing i { width: 5px; height: 5px; border-radius: 50%; background: var(--faint); animation: sy-ai-dot 1.2s infinite; }
.synth .ai-bubble--typing i:nth-child(2) { animation-delay: .15s; }
.synth .ai-bubble--typing i:nth-child(3) { animation-delay: .3s; }
@keyframes sy-ai-dot { 0%, 60%, 100% { opacity: .3; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .synth .ai-bubble--typing i { animation: none; } }
.synth .ai-composer {
  display: flex; align-items: flex-end; gap: var(--space-2);
  padding: var(--space-4); border-top: 1px solid var(--inner); background: var(--subtle);
}
.synth .ai-composer textarea { flex: 1; resize: none; font-size: calc(13.5px * var(--tscale, 1)); }
.synth .ai-composer .ws-btn { flex: none; padding: 10px; }

/* Narrower than the three-column split: the panel leaves the grid and becomes
   a sheet over the right edge, so the board keeps its full width underneath.
   These must sit after the base .sy-ai rule — same specificity, cascade wins. */
@media (max-width: 1080px) {
  /* On phones the right-edge sheet becomes a bottom sheet — a 380px panel on a
     narrow screen leaves nothing of the board visible beside it. */
  .synth .sy-ai {
    top: auto; right: 0; bottom: 0; left: 0; width: auto;
    max-height: 78vh; border-width: 1px 0 0; border-radius: var(--rModal) var(--rModal) 0 0;
  }
}

/* contenteditable affordance */
.synth [contenteditable] { outline: none; border-radius: 5px; padding: 1px 3px; margin: -1px -3px; transition: background .15s, box-shadow .15s; }
.synth [contenteditable]:hover { background: var(--subtle); }
.synth [contenteditable]:focus { background: var(--surface); box-shadow: 0 0 0 2px var(--focus-ring-color); }
.synth [contenteditable]:empty::before { content: attr(data-ph); color: var(--faint); }

.synth .del {
  background: none; border: 0; color: var(--faint); cursor: pointer; padding: 2px; border-radius: 6px;
  display: inline-grid; place-items: center;
}
.synth .del:hover { color: var(--p1); background: var(--accentVL); }
.synth .del .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }

/* Workshop record view: one group per agenda item, signals as pills.
   .ws-pill is built for short tokens (nowrap, line-height 1), so note pills
   relax both — a facilitator note is a sentence, not a label. */
.synth .sess-group + .sess-group { margin-top: var(--space-5); }
.synth .sess-group__h {
  display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap;
  font-family: var(--font-heading); font-weight: 600;
  font-size: calc(15px * var(--tscale, 1)); margin: 0 0 var(--space-2-5);
}
.synth .sess-group__timing {
  font-family: var(--font-body); font-weight: 500;
  font-size: calc(12px * var(--tscale, 1)); color: var(--muted); letter-spacing: 0;
}
.synth .sess-pills { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.synth .sess-pill {
  white-space: normal; line-height: 1.45; text-align: left;
  align-items: flex-start; max-width: 100%;
  padding-top: var(--space-1-5); padding-bottom: var(--space-1-5);
}
.synth .sess-pill--note { font-weight: 500; }
.synth .sess-pill__kind {
  display: inline-block; margin-right: var(--space-1-5);
  font-size: calc(10px * var(--tscale, 1)); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accentD);
}
.synth .sess-pill__emo { margin-right: var(--space-1); font-size: calc(14px * var(--tscale, 1)); }

/* ---------- Source viewer ---------- */
.synth .src-body pre { white-space: pre-wrap; font-family: var(--font-body); font-size: calc(13.5px * var(--tscale, 1)); line-height: 1.6; color: var(--ink2); background: var(--subtle); border: 1px solid var(--inner); border-radius: 10px; padding: 16px; }
.synth .src-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.synth .src-photos img { width: 100%; border-radius: 10px; border: 1px solid var(--border); }
.synth .src-stickies { display: flex; flex-direction: column; gap: 6px; }
.synth .src-sticky { padding: 8px 12px; background: var(--sticky); border-radius: 8px; font-size: calc(13.5px * var(--tscale, 1)); }

/* ---------- Export ---------- */
.synth .export-preview {
  white-space: pre-wrap; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: calc(12.5px * var(--tscale, 1));
  line-height: 1.6; background: var(--subtle); border: 1px solid var(--inner); border-radius: 10px;
  padding: 16px; max-height: 50vh; overflow: auto; color: var(--ink2);
}

/* ---------- Library / error ---------- */
.synth .lib-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px; }
.synth .lib-main { flex: 1; min-width: 0; }
.synth .lib-name { font-family: var(--font-heading); font-weight: 600; font-size: calc(15px * var(--tscale, 1)); }
.synth .lib-meta { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); }
.synth .err-screen { display: grid; place-items: center; min-height: 50vh; text-align: center; gap: 16px; }
.synth .err-screen .material-symbols-outlined { font-size: calc(44px * var(--tscale, 1)); color: var(--p1); }

/* toast */
.synth .toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: var(--text-inverse); padding: 10px 18px; border-radius: 9999px;
  font-size: calc(13px * var(--tscale, 1)); font-weight: 600; z-index: 1200; box-shadow: var(--shDrop);
  animation: synth-pop var(--duration-base) var(--ease-out);
}

@media (max-width: 640px) {
  .synth .wrap { padding: 32px 16px 90px; }
  /* The shorthand above resets padding-top, so the app frame has to restate
     its zero here or it reappears below 640px. */
  .synth .wrap--app { padding-top: 0; }
  .synth .home-h1 { font-size: calc(26px * var(--tscale, 1)); }
  .synth .input-h1 { font-size: calc(20px * var(--tscale, 1)); }
  .synth .res-head { padding: 0 14px; gap: 8px; }
}

/* ============================================================
   PRODUCT ROADMAP DASHBOARD STYLES
   ============================================================ */
.synth .roadmap-intro {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--rCard);
  padding: var(--space-8);
  margin-bottom: var(--space-6);
  gap: var(--space-6);
}
.synth .roadmap-intro h2 {
  font-family: var(--font-heading);
  font-size: calc(28px * var(--tscale, 1));
  margin: 0 0 var(--space-2-5);
}
.synth .roadmap-intro p {
  color: var(--ink2);
  line-height: 1.6;
  margin: 0;
  max-width: 72ch;
  font-size: calc(14.5px * var(--tscale, 1));
}
.synth .ri-stats {
  display: flex;
  gap: var(--space-4);
  flex-shrink: 0;
}
.synth .ri-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--subtle);
  border: 1px solid var(--inner);
  border-radius: var(--radius-xl);
  width: 140px;
  height: 90px;
  text-align: center;
}
.synth .ri-stat .num {
  font-family: var(--font-heading);
  font-size: calc(32px * var(--tscale, 1));
  font-weight: 700;
  color: var(--accent);
  line-height: 1;
}
.synth .ri-stat .lbl {
  font-size: calc(11px * var(--tscale, 1));
  font-weight: 600;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: var(--space-1);
}

@media (max-width: 768px) {
  .synth .roadmap-intro {
    flex-direction: column;
    align-items: flex-start;
    padding: var(--space-6);
  }
  .synth .ri-stats {
    width: 100%;
    justify-content: space-between;
  }
}

/* Strategic Goal Filter Grid */
.synth .roadmap-goals-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-3-5);
  margin-bottom: var(--space-8);
}
.synth .roadmap-goal-card {
  display: flex;
  gap: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--rCard);
  padding: var(--space-4);
  cursor: pointer;
  transition: transform .2s, border-color .2s, box-shadow .2s;
}
.synth .roadmap-goal-card:hover {
  transform: translateY(-2px);
  border-color: var(--goal-color);
  box-shadow: var(--shCard);
}
.synth .roadmap-goal-card.on {
  border-color: var(--goal-color);
  background: var(--bgPage);
  box-shadow: 0 0 0 3px var(--accentVL); /* selection ring, not elevation */
}
.synth .rg-card-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  flex-shrink: 0;
}
.synth .rg-card-icon .material-symbols-outlined {
  font-size: calc(22px * var(--tscale, 1));
}
.synth .rg-card-body h3 {
  margin: 0 0 var(--space-1);
  font-size: calc(14px * var(--tscale, 1));
  font-weight: 700;
}
.synth .rg-card-body p {
  margin: 0;
  font-size: calc(12px * var(--tscale, 1));
  color: var(--muted);
  line-height: 1.4;
}

/* 12-Month Board Board / Columns */
.synth .roadmap-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-10);
  align-items: start;
}
.synth .roadmap-column {
  background: var(--subtle);
  border: 1px solid var(--border);
  border-radius: var(--rCard);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.synth .rc-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--inner);
  padding-bottom: var(--space-2-5);
  margin-bottom: var(--space-1);
}
.synth .rc-header h3 {
  font-family: var(--font-heading);
  font-size: calc(18px * var(--tscale, 1));
  margin: 0;
}
.synth .rc-count {
  font-size: calc(11px * var(--tscale, 1));
  font-weight: 700;
  color: var(--muted);
  background: var(--inner);
  padding: 2px var(--space-2);
  border-radius: 10px;
}
.synth .rc-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Feature Card */
.synth .roadmap-feature-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: var(--space-4);
  box-shadow: var(--shCard);
  transition: transform .2s, border-color .2s;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.synth .roadmap-feature-card:hover {
  transform: translateY(-2px);
  border-color: var(--hair);
}
.synth .rfc-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.synth .quarter-tag {
  font-size: calc(11px * var(--tscale, 1));
  font-weight: 700;
  color: var(--accentD);
  background: var(--accentVL);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--rChip);
}
.synth .status-badge {
  font-size: calc(10px * var(--tscale, 1));
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .02em;
  padding: 2px var(--space-1-5);
  border-radius: var(--rBadge);
}
.synth .status-badge.status--progress {
  color: var(--color-primary-on-white);
  background: var(--color-error-very-light);
}
.synth .status-badge.status--planning {
  color: var(--color-warning-dark);
  background: var(--statusPlanBg);
}
.synth .status-badge.status--backlog {
  color: var(--color-info-dark);
  background: var(--statusBacklogBg);
}
.synth .rfc-title {
  margin: var(--space-1) 0 0;
  font-size: calc(15.5px * var(--tscale, 1));
  font-weight: 700;
  font-family: var(--font-heading);
  line-height: 1.3;
  cursor: pointer;
}
.synth .rfc-title:hover {
  color: var(--accent);
}
.synth .rfc-desc {
  margin: 0;
  font-size: calc(12.5px * var(--tscale, 1));
  color: var(--ink2);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.synth .rfc-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: calc(11px * var(--tscale, 1));
  color: var(--muted);
  border-top: 1px solid var(--inner);
  padding-top: var(--space-2);
  margin-top: var(--space-1);
}
.synth .rfc-time {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.synth .rfc-time .material-symbols-outlined {
  font-size: calc(12px * var(--tscale, 1));
}
.synth .rfc-goal-tag {
  background: var(--inner);
  color: var(--ink2);
  padding: 1px var(--space-1-5);
  border-radius: var(--rChip);
}
.synth .rfc-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-1-5);
}
.synth .rfc-actions .ws-btn {
  padding: var(--space-1) var(--space-2);
  font-size: calc(12px * var(--tscale, 1));
  border-radius: var(--radius-md);
}
.synth .vote-count {
  font-weight: 700;
  margin-left: 2px;
}

/* User Suggestions Layout */
.synth .roadmap-suggestions-section {
  border-top: 1px solid var(--border);
  padding-top: var(--space-8);
}
.synth .rss-header h3 {
  font-family: var(--font-heading);
  font-size: calc(24px * var(--tscale, 1));
  margin: 0 0 var(--space-1-5);
}
.synth .rss-header p {
  color: var(--ink2);
  margin: 0 0 var(--space-6);
  max-width: 72ch;
  font-size: calc(14px * var(--tscale, 1));
  line-height: 1.5;
}
.synth .rss-layout {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-6);
}
@media (max-width: 768px) {
  .synth .rss-layout {
    grid-template-columns: 1fr;
  }
}
.synth .rss-list-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.synth .rss-form-column {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--rCard);
  padding: var(--space-5);
  align-self: start;
}
.synth .rss-form-column h4 {
  margin: 0 0 var(--space-4);
  font-family: var(--font-heading);
  font-size: calc(18px * var(--tscale, 1));
}
.synth .suggestion-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--rCard);
  padding: var(--space-4);
  gap: var(--space-4);
  box-shadow: var(--shCard);
}
.synth .sr-main h4 {
  margin: 0 0 var(--space-1-5);
  font-size: calc(14.5px * var(--tscale, 1));
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.synth .sr-main .goal-badge {
  font-size: calc(11px * var(--tscale, 1));
  font-weight: 600;
  color: var(--accentD);
  background: var(--accentVL);
  padding: 1px var(--space-1-5);
  border-radius: 10px;
}
.synth .sr-main p {
  margin: 0;
  font-size: calc(12.5px * var(--tscale, 1));
  color: var(--ink2);
  line-height: 1.45;
}
.synth .sr-date {
  font-size: calc(11px * var(--tscale, 1));
  color: var(--muted);
  display: block;
  margin-top: var(--space-1-5);
}
.synth .sr-actions {
  flex-shrink: 0;
}

/* Detail Modal Styles */
.synth .detail-status-bar {
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--inner);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-4);
}
.synth .detail-scope-box, .synth .detail-kpis-box {
  background: var(--subtle);
  border: 1px solid var(--inner);
  border-radius: var(--radius-lg);
  padding: var(--space-2-5) var(--space-3);
  font-size: calc(13px * var(--tscale, 1));
  color: var(--ink2);
  line-height: 1.5;
}
.synth .detail-alignment-box {
  background: var(--subtle);
  border: 1px solid var(--border);
  border-radius: var(--rChip);
  padding: var(--space-2-5) var(--space-3);
  font-size: calc(13.5px * var(--tscale, 1));
  line-height: 1.5;
  color: var(--ink2);
}


/* ============================================================
   E3 — undo/redo, grouped-review bulk actions (Jul 2026)
   ============================================================ */

/* Undo/redo segment — matches .seg, adds a disabled state */
.synth .undo-seg button[disabled], .synth-topbar .undo-seg button[disabled] { opacity: .35; cursor: default; }
.synth .undo-seg button .material-symbols-outlined, .synth-topbar .undo-seg button .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); }

/* Drag handle on grouped-review rows */
.synth .rg-drag {
  font-size: calc(18px * var(--tscale, 1));
  color: var(--faint);
  cursor: grab;
  flex-shrink: 0;
  align-self: center;
  user-select: none;
  -webkit-user-drag: element;
}
.synth .rg-drag:hover { color: var(--muted); }
.synth .review-row.dragging { opacity: .45; }

/* Drop target highlight when dragging a note over another group */
.synth .rg-card.dragover {
  outline: 2px dashed var(--accent);
  outline-offset: 2px;
  background: var(--accentVL);
}

/* Select-mode checkboxes */
.synth .rg-check {
  background: none; border: 0; padding: 0;
  color: var(--faint); cursor: pointer;
  flex-shrink: 0; align-self: center;
  display: inline-flex;
}
.synth .rg-check.on, .synth .rg-check:hover { color: var(--accent); }
.synth .rg-check .material-symbols-outlined { font-size: calc(19px * var(--tscale, 1)); }
.synth .review-row.selected { background: var(--accentVL); border-radius: 8px; }

/* Merge menu (per group) + bulk move menu — small anchored dropdowns */
.synth .rg-merge-wrap, .synth .bulk-move-wrap { position: relative; display: inline-flex; }
.synth .rg-menu, .synth .bulk-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  min-width: 220px; max-height: 260px; overflow: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shDrop); padding: 6px;
}
.synth .bulk-menu { top: auto; bottom: calc(100% + 6px); left: 0; right: auto; }
.synth .rg-menu-h {
  font-size: calc(11.5px * var(--tscale, 1)); font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
  padding: var(--space-1-5) var(--space-2) var(--space-1);
}
.synth .rg-menu button, .synth .bulk-menu button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; text-align: left;
  background: none; border: 0; border-radius: 7px;
  padding: 7px 9px; font-size: calc(13.5px * var(--tscale, 1)); color: var(--ink); cursor: pointer;
}
.synth .rg-menu button:hover, .synth .bulk-menu button:hover { background: var(--subtle); }
.synth .bulk-menu-new { color: var(--accent) !important; font-weight: 600; }

/* Sticky bulk-action bar */
.synth .bulk-bar {
  position: sticky; bottom: 14px; z-index: 50;
  display: flex; align-items: center; gap: 10px;
  margin-top: var(--space-3-5); padding: var(--space-2-5) var(--space-3-5);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shDrop);
}
.synth .bulk-count { font-size: calc(13.5px * var(--tscale, 1)); font-weight: 700; color: var(--ink); }
.synth .bulk-del { color: var(--accentD); }

/* Select-mode hint line */
.synth .review-hint {
  display: flex; align-items: center; gap: 6px;
  font-size: calc(13px * var(--tscale, 1)); color: var(--muted); margin: 0 0 12px;
}
.synth .review-hint .material-symbols-outlined { font-size: calc(16px * var(--tscale, 1)); }

/* ============================================================
   E4/E6 — export & share modal (brand, sections, send-to)
   ============================================================ */
.synth .x-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.synth .x-toggles { display: flex; gap: 6px; flex-wrap: wrap; }
.synth .x-toggle {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: 1px solid var(--border); border-radius: 8px;
  padding: 5px 10px; font-size: calc(12.5px * var(--tscale, 1)); font-weight: 600; color: var(--muted); cursor: pointer;
}
.synth .x-toggle.on { color: var(--ink); border-color: var(--hair); background: var(--subtle); }
.synth .x-toggle .material-symbols-outlined { font-size: calc(16px * var(--tscale, 1)); }
.synth .x-toggle.on .material-symbols-outlined { color: var(--accent); }

.synth .x-send { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.synth .x-send-h { font-size: calc(11.5px * var(--tscale, 1)); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.synth .x-dest { display: inline-flex; align-items: center; gap: 8px; }
.synth .x-setup { font-size: calc(10.5px * var(--tscale, 1)); font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: .04em; }
.synth .x-busy { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); }
.synth .x-msg { font-size: calc(12px * var(--tscale, 1)); font-weight: 600; }
.synth .x-msg.ok { color: var(--ok); }
.synth .x-msg.err { color: var(--accentD); }
.synth .x-hint { display: flex; align-items: center; gap: 6px; font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); margin: 8px 0; }
.synth .x-hint .material-symbols-outlined { font-size: calc(15px * var(--tscale, 1)); }

.synth .x-form { display: flex; flex-direction: column; gap: 12px; }
.synth .x-label { display: block; font-size: calc(12px * var(--tscale, 1)); font-weight: 700; color: var(--ink2); }
.synth .x-input {
  /* metrics match the .field input system — one form language app-wide */
  display: block; width: 100%; margin-top: var(--space-1);
  border: 1px solid var(--border); border-radius: 10px;
  padding: var(--space-2-5) var(--space-3); font: inherit; font-size: calc(14px * var(--tscale, 1)); color: var(--ink); background: var(--surface);
}
.synth .x-input:focus { outline: none; border-color: var(--focus-ring-color); box-shadow: 0 0 0 3px var(--focus-ring-color); }
.synth .x-accent-row { display: flex; align-items: center; gap: 8px; }
.synth .x-input--accent { width: 120px; }
.synth .x-swatch { width: 22px; height: 22px; border-radius: 6px; border: 1px solid var(--border); flex-shrink: 0; }
.synth .x-logo-row { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.synth .x-logo { height: 40px; max-width: 160px; object-fit: contain; border: 1px solid var(--border); border-radius: 6px; padding: 3px 6px; background: var(--surface); }
.synth .x-nologo { font-size: calc(12.5px * var(--tscale, 1)); color: var(--faint); }
.synth .x-upload { cursor: pointer; }
.synth .x-conn { border: 1px solid var(--border); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.synth .x-conn-h { display: flex; align-items: center; gap: 7px; font-size: calc(13px * var(--tscale, 1)); font-weight: 700; color: var(--ink); }
.synth .x-conn-h .material-symbols-outlined { font-size: calc(17px * var(--tscale, 1)); color: var(--accent); }
.synth .x-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); display: inline-block; margin: 0 3px 0 8px; }
.synth .x-dot.on { background: var(--ok); }
.synth .x-conn-h { font-size: calc(12px * var(--tscale, 1)); }

/* ============================================================
   E5 — follow-through: action status, continue card, carry-forward
   ============================================================ */
.synth .act-progress { font-size: calc(12.5px * var(--tscale, 1)); font-weight: 700; color: var(--muted); margin-bottom: 10px; }
.synth .act-table th.st, .synth .act-table td.st { width: 34px; }
.synth .act-check { background: none; border: 0; padding: 0; cursor: pointer; color: var(--faint); display: inline-flex; }
.synth .act-check.on, .synth .act-check:hover { color: var(--ok); }
.synth .act-check .material-symbols-outlined { font-size: calc(19px * var(--tscale, 1)); }
.synth .act-table tr.is-done td.what span[contenteditable] { text-decoration: line-through; color: var(--muted); }
.synth .carried-chip {
  display: inline-block; vertical-align: 1px; margin-left: 6px;
  font-size: calc(10px * var(--tscale, 1)); font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); background: var(--accentVL); border-radius: 4px; padding: 1px 6px;
}

.synth .continue-card {
  display: flex; align-items: center; gap: 16px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 18px; margin: 18px 0 8px; box-shadow: var(--shCard);
}
.synth .continue-card .cc-main { flex: 1; min-width: 0; }
.synth .cc-kicker { display: flex; align-items: center; gap: 6px; font-size: calc(11px * var(--tscale, 1)); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--accent); margin-bottom: 4px; }
.synth .cc-kicker .material-symbols-outlined { font-size: calc(15px * var(--tscale, 1)); }
.synth .cc-name { font-size: calc(16px * var(--tscale, 1)); font-weight: 700; color: var(--ink); }
.synth .cc-meta { font-size: calc(12.5px * var(--tscale, 1)); color: var(--muted); margin-top: 2px; }

.synth .carry-panel {
  border: 1px solid var(--border); border-radius: 12px; background: var(--subtle);
  padding: var(--space-3-5) var(--space-4); margin: var(--space-4) 0;
}
.synth .carry-h { display: flex; align-items: center; gap: 8px; font-size: calc(13.5px * var(--tscale, 1)); font-weight: 700; color: var(--ink); margin-bottom: 8px; }
.synth .carry-h .material-symbols-outlined { font-size: calc(17px * var(--tscale, 1)); color: var(--accent); }
.synth .carry-h .ws-btn { margin-left: auto; }
.synth .carry-count { font-size: calc(11.5px * var(--tscale, 1)); font-weight: 700; color: var(--muted); background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1px 8px; }
.synth .carry-row {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; margin: 4px 0; font-size: calc(13px * var(--tscale, 1)); color: var(--ink); cursor: pointer;
}
.synth .carry-row .material-symbols-outlined { font-size: calc(18px * var(--tscale, 1)); color: var(--faint); flex-shrink: 0; }
.synth .carry-row.on { border-color: var(--accent); background: var(--accentVL); }
.synth .carry-row.on .material-symbols-outlined { color: var(--accent); }
.synth .carry-text { flex: 1; min-width: 0; }
.synth .carry-meta { font-size: calc(11.5px * var(--tscale, 1)); font-weight: 700; color: var(--muted); flex-shrink: 0; }
.synth .carry-hint { font-size: calc(12px * var(--tscale, 1)); color: var(--muted); margin-top: 6px; }


/* Dropzone hover state for OS file drags */
.synth .dropzone.dragover {
  border-color: var(--accent);
  background: var(--accentVL);
  color: var(--accentD);
}


/* ════════════════════════════════════════
   APP SHELL (app.php) — locked viewport, facilitator pattern.
   ws_header on top; .synth-shell fills the rest; .synth-stage scrolls.
   ════════════════════════════════════════ */
body.synth-app-body {
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.synth-app-body #main-content {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.synth-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Type scale. Every font-size in this file is `calc(Npx * var(--tscale, 1))`,
   so this one number sets the whole app's reading size.

   Why a multiplier and not the platform's rem tokens: platform-tokens.css sets
   `html { font-size: 80% }` platform-wide, so var(--text-small) paints at
   11.2px here — smaller than what this app already used, and smaller than the
   Planner elements it's being matched to (its cards measure 15.5px / 17px,
   which are literal px in the Planner sheet too). Migrating to rem tokens would
   shrink this app, not grow it.

   1.1 lands the common sizes on Planner's: 13px→14.3, 14.5px→16, 15px→16.5.
   --tscale was the A/A+/A++ preference hook, removed 2026-07-22 and unset since
   (every declaration resolved to its raw px through the fallback), so it is
   free to carry the base scale. Re-adding that control means multiplying this
   value rather than replacing it. */
.synth-shell,
.synth,
.synth-topbar { --tscale: 1.1; }
/* ---------- Topbar ----------
   The bar itself is the shared ws_app_bar component (DESIGN.md §12.8):
   layout, gradient, title, save state, and actions all come from
   includes/components/components.css. What stays here is only what is
   genuinely Synthesize's — the segmented contextual controls it slots into
   the bar's centre, and their on-red treatment. */
.synth-topbar .seg { background: rgba(255, 255, 255, .16); }
.synth-topbar .seg button { color: rgba(255, 255, 255, .8); }
.synth-topbar .seg button.on { background: rgba(255, 255, 255, .92); color: var(--accentD); box-shadow: none; }
.synth-topbar .seg button[disabled] { opacity: .45; }
.synth-topbar .iconbtn {
  background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .3); color: #fff;
}
.synth-topbar .iconbtn:hover { background: rgba(255, 255, 255, .22); border-color: rgba(255, 255, 255, .5); }

/* Title, save state and the controls that act on them read as one group at the
   bar's leading edge. The lead cluster is sized by its content and the bar's
   spacer absorbs the slack, so everything after the title follows it rather
   than scattering to the far edge. */
.synth-topbar .ws-app-bar__lead { flex: 0 1 auto; min-width: 0; }

/* The workshop name still needs real size — the shared component sets
   var(--text-ui), which lands at 12px here because the app scales its root
   font-size. Size and width are separate concerns: this is big enough to read
   as the page's identity, narrow enough that the save chip sits beside it
   instead of a screen away. Scoped to .synth-topbar so Planner, Facilitator
   and Strategist bars are untouched. */
.synth-topbar .ws-app-bar__title-input {
  font-size: calc(18px * var(--tscale, 1));
  flex: 0 1 22ch;
  max-width: min(22ch, 26vw);
}

/* The action cluster stays at the trailing edge — ws_app_bar's own spacer does
   that, so there is deliberately no override here. The title is short and the
   save state sits beside it; the actions belong at the far right. */

.synth-stage {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
/* Flex column, not block: a percentage min-height only resolves against an
   ancestor with a definite height, so the app frame could never reach the
   bottom of the stage while this was a plain block. */
.synth-stage .synth { min-height: 100%; display: flex; flex-direction: column; }
.synth-stage .synth > .wrap--app { flex: 1; }

/* Doc-bar on phones: hub icon + editable title + chip on row one, compact
   icon actions on row two. Text size stays (accessibility); the mode toggle
   hides — Full board remains reachable from the quick-read CTA. This block
   must sit AFTER the base topbar rules (same specificity, cascade decides).
   The title input is the session's identity on phones — never display:none. */
@media (max-width: 640px) {
  .synth-topbar .hide-sm { display: none; }
  .synth-topbar .undo-seg button, .synth .undo-seg button { padding: 6px 8px; }
}
