:root{
  --bg:#F0EEE6;
  --surface:#FAF9F5;
  --surface-2:#E7E2D5;
  --ink:#1F1B16;
  --ink-muted:#6B6358;
  --accent:#D97757;
  --accent-deep:#BD5B3A;
  --accent-soft:rgba(217,119,87,0.12);
  --line:#DAD5C7;
  --frozen:#AEA99D;
  --frozen-bg:#E3DFD3;

  --font-display:'Fraunces', serif;
  --font-body:'Inter', sans-serif;
  --font-mono:'IBM Plex Mono', monospace;

  --maxw:1120px;
}

*{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
img,svg{ display:block; max-width:100%; }
a{ color:inherit; }
:focus-visible{ outline:2px solid var(--accent-deep); outline-offset:3px; border-radius:4px; }

.wrap{ max-width:var(--maxw); margin:0 auto; padding:0 28px; }
.eyebrow{
  font-family:var(--font-mono);
  font-size:12px;
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--accent-deep);
  font-weight:500;
}
h1,h2,h3{ font-family:var(--font-display); font-weight:600; margin:0; color:var(--ink); }
p{ margin:0; }
.muted{ color:var(--ink-muted); }

/* ---------- NAV ---------- */
header.site{
  position:sticky; top:0; z-index:50;
  background:rgba(240,238,230,0.92);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
}
nav.bar{
  display:flex; align-items:center; justify-content:space-between;
  padding:18px 28px; max-width:var(--maxw); margin:0 auto;
}
.logo{
  display:flex; align-items:center; gap:8px;
  font-family:var(--font-mono); font-weight:500; font-size:15px;
  letter-spacing:0.02em;
}
.logo-mark{ width:18px; height:18px; }
.nav-links{ display:flex; gap:32px; font-size:14px; }
.nav-links a{ text-decoration:none; color:var(--ink-muted); }
.nav-links a:hover{ color:var(--ink); }
.nav-cta{ display:flex; align-items:center; gap:18px; }
@media (max-width:720px){ .nav-links{ display:none; } }

.btn{
  font-family:var(--font-body); font-weight:600; font-size:14px;
  padding:11px 20px; border-radius:8px; border:1px solid transparent;
  cursor:pointer; text-decoration:none; display:inline-flex; align-items:center; gap:8px;
  transition:transform .15s ease, box-shadow .15s ease;
}
.btn-primary{ background:var(--accent); color:#FAF6F1; }
.btn-primary:hover{ background:var(--accent-deep); }
.btn-ghost{ background:transparent; color:var(--ink); border-color:var(--line); }
.btn-ghost:hover{ border-color:var(--ink-muted); }
.btn:disabled{ opacity:.5; cursor:not-allowed; transform:none !important; }
@media (prefers-reduced-motion:no-preference){ .btn:hover{ transform:translateY(-1px); } }

/* Reusable across every button that shows a "working…" text state while
   waiting on a request — Save, Restore, Evaluate, Steal This, Export,
   the paste-idea submit, all of it. Same ::before pseudo-element
   technique as .canvas-busy-indicator's spinner, for the same reason:
   it's generated by CSS, not real DOM content, so nothing that changes
   the button's text can ever accidentally remove it. Disabled buttons
   already drop to 0.5 opacity above — bumped back up here specifically,
   since a barely-visible spinner defeats the point of adding one. */
.btn-loading{ opacity:.85 !important; }
.btn-loading::before{
  content:''; flex-shrink:0; width:13px; height:13px; border-radius:50%;
  border:2px solid rgba(255,255,255,0.35); border-top-color:currentColor;
  animation:canvasBusySpin .7s linear infinite;
}
.btn-ghost.btn-loading::before{ border-color:rgba(31,27,22,0.25); border-top-color:var(--ink); }

/* ---------- HERO ---------- */
.hero{ padding:88px 0 40px; }
.hero-inner{ text-align:center; max-width:760px; margin:0 auto; }
.hero h1{
  font-size:clamp(34px, 5.4vw, 58px);
  line-height:1.06;
  margin:18px 0 20px;
  letter-spacing:-0.01em;
}
.hero .sub{ font-size:18px; color:var(--ink-muted); max-width:560px; margin:0 auto 30px; }
.hero-ctas{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; margin-bottom:64px; }
.hint-link{ font-size:14px; color:var(--ink-muted); text-decoration:none; align-self:center; }
.hint-link:hover{ color:var(--ink); }

/* ---------- GRAPH DEMO ---------- */
.graph-demo{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:20px;
  padding:36px 24px 28px;
  max-width:920px; margin:0 auto;
  box-shadow:0 1px 0 rgba(0,0,0,0.02);
}
.graph-canvas{ position:relative; }
.graph-lines{ position:absolute; top:0; left:0; width:100%; height:100%; overflow:visible; pointer-events:none; }
.graph-lines path{
  fill:none; stroke:var(--accent); stroke-width:1.6; stroke-linecap:round;
}
.node-row{ display:flex; gap:10px; justify-content:center; flex-wrap:wrap; position:relative; z-index:2; }
.node-pill{
  font-family:var(--font-mono); font-size:13px;
  background:var(--surface); border:1px solid var(--line); color:var(--ink);
  padding:9px 16px; border-radius:999px; cursor:pointer;
  transition:border-color .15s ease, background .15s ease, color .15s ease;
}
.node-pill:hover{ border-color:var(--accent); }
.node-pill.active{ background:var(--accent); border-color:var(--accent); color:#FAF6F1; }
.child-row{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; margin-top:56px; min-height:64px; position:relative; z-index:2; }
.child-card{
  background:var(--surface); border:1px solid var(--accent); border-radius:10px;
  padding:10px 14px; width:168px; text-align:left;
  opacity:0; transform:translateY(6px);
}
.child-card.in{ opacity:1; transform:translateY(0); transition:opacity .35s ease, transform .35s ease; }
.child-card .k{ font-family:var(--font-mono); font-size:10px; letter-spacing:.08em; color:var(--accent-deep); text-transform:uppercase; }
.child-card .v{ font-size:13.5px; margin-top:3px; }
.frozen-lane{ display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-top:14px; min-height:0; }
.frozen-pill{
  font-family:var(--font-mono); font-size:11.5px;
  background:var(--frozen-bg); border:1px dashed var(--frozen); color:var(--ink-muted);
  padding:6px 12px; border-radius:999px; cursor:pointer;
}
.frozen-pill:hover{ color:var(--ink); border-color:var(--ink-muted); }
.frozen-pill span{ color:var(--frozen); margin:0 2px; }
.graph-caption{ text-align:center; font-size:13px; color:var(--ink-muted); margin-top:22px; }

@media (prefers-reduced-motion:reduce){
  .child-card{ transition:none !important; opacity:1; transform:none; }
}

/* ---------- STEPS ---------- */
.section{ padding:84px 0; }
.section-head{ max-width:560px; margin-bottom:48px; }
.section-head h2{ font-size:clamp(26px,3.4vw,36px); margin-top:14px; }

.steps{ display:grid; grid-template-columns:repeat(4,1fr); gap:28px; }
@media (max-width:900px){ .steps{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:560px){ .steps{ grid-template-columns:1fr; } }
.step{ border-top:1px solid var(--line); padding-top:18px; }
.step .num{ font-family:var(--font-mono); font-size:12px; color:var(--frozen); }
.step h3{ font-size:18px; margin:10px 0 8px; }
.step p{ font-size:14.5px; color:var(--ink-muted); }
.step svg{ width:32px; height:32px; margin-bottom:14px; }

/* ---------- FEATURES ---------- */
.features{ background:var(--surface); border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.feature-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--line); border:1px solid var(--line); border-radius:14px; overflow:hidden; }
@media (max-width:860px){ .feature-grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:560px){ .feature-grid{ grid-template-columns:1fr; } }
.feature{ background:var(--surface); padding:28px 24px; }
.feature .eyebrow{ display:block; margin-bottom:10px; }
.feature h3{ font-size:17px; margin-bottom:8px; }
.feature p{ font-size:14px; color:var(--ink-muted); }

/* ---------- IDEA CARD ---------- */
.idea-wrap{ display:grid; grid-template-columns:1.1fr 0.9fr; gap:40px; align-items:start; }
@media (max-width:860px){ .idea-wrap{ grid-template-columns:1fr; } }
.idea-card{
  background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:28px;
}
.idea-tag{ font-family:var(--font-mono); font-size:11px; color:var(--accent-deep); text-transform:uppercase; letter-spacing:.08em; }

.idea-card h3{ font-size:22px; margin:8px 0 4px; }
.idea-oneliner{ color:var(--ink-muted); font-size:14.5px; margin-bottom:18px; }
.idea-block{ margin-bottom:16px; }
.idea-block .lbl{ font-family:var(--font-mono); font-size:11px; color:var(--ink-muted); text-transform:uppercase; letter-spacing:.06em; margin-bottom:4px; }
.idea-block p{ font-size:14px; }
.idea-note{ font-size:12px; color:var(--frozen); font-family:var(--font-mono); margin-top:18px; }

.radar-panel{ background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:24px; text-align:center; }
.radar-panel h4{ font-family:var(--font-mono); font-size:12px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-muted); margin-bottom:18px; }
.radar-legend{ display:flex; flex-wrap:wrap; gap:8px 14px; justify-content:center; margin-top:14px; }
.radar-legend span{ font-size:11.5px; color:var(--ink-muted); font-family:var(--font-mono); }
.radar-legend b{ color:var(--ink); }

/* ---------- PRICING ---------- */
.pricing-grid{ display:grid; grid-template-columns:1fr 1fr; gap:24px; }
@media (max-width:700px){ .pricing-grid{ grid-template-columns:1fr; } }
/* Applied when a signed-in user is already pro (see applyPricingProState
   in script.js) — the free card is hidden via inline display:none, and
   this switches the grid to a single centered column instead of leaving
   an empty column where the free card used to be. */
.pricing-grid.pro-only{ grid-template-columns:1fr; max-width:420px; margin:0 auto; }
.plan{ border:1px solid var(--line); border-radius:16px; padding:30px; background:var(--surface); }
.plan.pro{ border-color:var(--accent); position:relative; }
.plan .ptag{ font-family:var(--font-mono); font-size:11px; color:var(--ink-muted); text-transform:uppercase; letter-spacing:.08em; }
.plan h3{ font-size:22px; margin:10px 0 2px; }
.plan .price{ font-family:var(--font-display); font-size:36px; margin:10px 0 18px; }
.plan .price sup{ font-family:var(--font-body); font-size:14px; color:var(--ink-muted); font-weight:500; }
.plan ul{ list-style:none; padding:0; margin:0 0 22px; display:flex; flex-direction:column; gap:9px; }
.plan li{ font-size:14px; color:var(--ink-muted); padding-left:20px; position:relative; }
.plan li::before{ content:"—"; position:absolute; left:0; color:var(--accent-deep); }
.plan .btn{ width:100%; justify-content:center; }

/* ---------- CTA / FOOTER ---------- */
.cta-band{ text-align:center; padding:90px 0; }
.cta-band h2{ font-size:clamp(26px,4vw,38px); margin:14px 0 26px; max-width:600px; margin-inline:auto; }
footer{ border-top:1px solid var(--line); padding:36px 0; }
.foot-row{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:16px; }
.foot-links{ display:flex; gap:22px; font-size:13px; color:var(--ink-muted); }
.foot-links a{ text-decoration:none; }
.foot-links a:hover{ color:var(--ink); }
.foot-fine{ font-size:12px; color:var(--frozen); margin-top:18px; }

/* ---------- API STATUS (footer) ---------- */
.api-status{
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--font-mono); font-size:11px; color:var(--ink-muted);
}
.api-status .dot{
  width:7px; height:7px; border-radius:50%;
  background:var(--frozen);
  transition:background .25s ease;
}
.api-status.online .dot{ background:#5C8A5C; }
.api-status.offline .dot{ background:#C24A3D; }

/* ---------- AUTH PAGE ---------- */
.auth-main{ min-height:calc(100vh - 140px); display:flex; align-items:center; justify-content:center; padding:60px 20px; }
.auth-card{
  width:100%; max-width:400px;
  background:var(--surface); border:1px solid var(--line); border-radius:16px;
  padding:36px 32px;
}
.auth-tabs{ display:flex; gap:4px; background:var(--surface-2); border-radius:10px; padding:4px; margin-bottom:26px; }
.auth-tab{
  flex:1; font-family:var(--font-body); font-weight:600; font-size:14px;
  padding:9px 0; border:none; border-radius:8px; background:transparent; color:var(--ink-muted);
  cursor:pointer; transition:background .15s ease, color .15s ease;
}
.auth-tab.active{ background:var(--surface); color:var(--ink); box-shadow:0 1px 2px rgba(0,0,0,0.04); }

.auth-form{ display:none; flex-direction:column; gap:16px; }
.auth-form.active{ display:flex; }
.auth-form label{
  display:flex; flex-direction:column; gap:6px;
  font-family:var(--font-mono); font-size:11px; letter-spacing:.04em; text-transform:uppercase; color:var(--ink-muted);
}
.auth-form input{
  font-family:var(--font-body); font-size:15px; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:11px 13px; outline:none;
  transition:border-color .15s ease;
}
.auth-form input:focus{ border-color:var(--accent); }
.auth-form .btn{ justify-content:center; margin-top:4px; }
.auth-error{ font-size:13px; color:#C24A3D; min-height:16px; margin:0; }

.auth-pending{ text-align:center; padding:8px 4px; }
.auth-pending h3{ font-size:18px; margin-bottom:10px; }
.auth-pending strong{ color:var(--ink); }

.auth-banner{
  background:var(--accent-soft); border:1px solid var(--accent); color:var(--accent-deep);
  font-size:13px; border-radius:8px; padding:10px 14px; margin-bottom:20px; text-align:center;
}

/* ---------- OTP form (#otpForm — signup and login both route through
   this one shared step now, see initAuthPage/handleOtpSubmit in
   script.js). Reuses every base .auth-form/.auth-form input rule above
   as-is; these are just the code-entry-specific touches on top —
   centered, spaced-out digits so it reads as "a code," not a normal
   text field, plus a resend affordance since email delivery can lag. ---------- */
#otpCodeInput{
  text-align:center;
  font-family:var(--font-mono);
  font-size:22px;
  letter-spacing:0.5em;
  padding-left:10px; /* offsets the letter-spacing so it doesn't push the last digit visually off-center */
}
#otpEmailLabel{ color:var(--ink); font-weight:600; }
.otp-resend{
  background:none; border:none; padding:0; margin-top:-4px;
  font-family:var(--font-body); font-size:13px; color:var(--accent-deep);
  cursor:pointer; text-decoration:underline; align-self:center;
}
.otp-resend:hover{ color:var(--accent); }
.otp-resend:disabled{ color:var(--ink-muted); text-decoration:none; cursor:default; }

/* ---------- MODAL (shared) ---------- */
/* Used by the "name your blueprint" dialog. Generic enough to reuse for
   any future confirm/input dialog without writing new modal CSS. */
.modal-overlay{
  position:fixed; top:0; left:0; width:100%; height:100%;
  background:rgba(31,27,22,0.45);
  display:flex; align-items:center; justify-content:center;
  z-index:200; padding:20px;
}
.modal-card{
  background:var(--surface); border:1px solid var(--line); border-radius:16px;
  padding:28px; max-width:420px; width:100%;
  box-shadow:0 8px 30px rgba(0,0,0,0.12);
}
.modal-card h3{ font-size:19px; margin-bottom:8px; }
.modal-card .muted{ font-size:13.5px; margin-bottom:18px; }
.modal-card input{
  width:100%; font-family:var(--font-body); font-size:15px; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:11px 13px; outline:none; margin-bottom:6px;
  transition:border-color .15s ease;
}
.modal-card input:focus{ border-color:var(--accent); }
.modal-actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:18px; }

/* ---------- Pro plan modal (showProPlanModal in script.js) ---------- */
/* .plan already has its own border/padding/background (see the pricing
   section rules below) — nested directly inside .modal-card, which has
   the exact same properties, that would double up into a visible
   border-within-a-border. This strips .plan's own box styling only
   inside this specific context, letting .modal-card be the one visual
   container instead of stacking two. */
.modal-plan-card{ border:none; padding:0; background:transparent; }
.modal-plan-card .btn{ width:100%; display:block; text-align:center; }
.modal-close-btn{ width:100%; margin-top:10px; }

/* ---------- DASHBOARD ---------- */
.dashboard-main{ padding:60px 0 100px; }
.dashboard-main h1{ font-size:clamp(26px,3.4vw,34px); margin-bottom:28px; }

.pro-banner{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  background:var(--surface); border:1px solid var(--line); border-radius:12px;
  padding:16px 20px; margin-bottom:36px; font-size:14px; color:var(--ink-muted);
}
.pro-banner .eyebrow{ margin-right:4px; }
.pro-banner.pro{ border-color:var(--accent); }
.pro-banner .btn{ margin-left:auto; }

.empty-state{
  background:var(--surface); border:1px solid var(--line); border-radius:16px;
  padding:48px 36px; text-align:center; max-width:480px; margin:0 auto;
}
.empty-state h3{ font-size:20px; margin-bottom:10px; }
.empty-state p{ margin-bottom:22px; }

.blueprint-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); gap:20px; margin-bottom:24px; }
.blueprint-card{
  position:relative;
  background:var(--surface); border:1px solid var(--line); border-radius:14px;
  padding:22px; display:flex; flex-direction:column; gap:6px;
}
.blueprint-card h3{ font-size:17px; padding-right:20px; } /* room for the delete button so it never overlaps the title */
.blueprint-card .status-label{ font-family:var(--font-mono); font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--accent-deep); margin-bottom:10px; }
.blueprint-card.locked{ border-color:var(--frozen); background:var(--frozen-bg); }
.blueprint-card.locked .status-label{ color:var(--frozen); }
.blueprint-card .btn{ align-self:flex-start; }

/* Pro-only delete control (renderBlueprintArea in script.js) — small,
   quiet, top-right corner, deliberately not competing visually with the
   card's real action (Open blueprint). Free-tier cards never render
   this at all, since those blueprints already self-delete on schedule. */
.btn-delete-blueprint{
  position:absolute; top:14px; right:14px;
  width:22px; height:22px; border-radius:50%;
  background:transparent; border:none; color:var(--ink-muted);
  font-size:13px; line-height:1; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
}
.btn-delete-blueprint:hover{ background:rgba(194,74,61,0.12); color:#C24A3D; }

/* ---------- APP / CANVAS ---------- */
.app-header .bar{ display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:20px; }
.app-header .bar .logo-spacer{ visibility:hidden; pointer-events:none; }
.app-blueprint-title{
  font-family:var(--font-mono); font-size:13px; color:var(--ink-muted); flex:1; text-align:center;
  cursor:pointer; border-radius:6px; padding:4px 10px; transition:background-color .15s ease;
}
.app-blueprint-title:hover{ background:var(--surface-2); }
.app-blueprint-title-input{
  font-family:var(--font-mono); font-size:13px; color:var(--ink);
  background:var(--bg); border:1px solid var(--accent); border-radius:6px;
  padding:3px 8px; outline:none; text-align:center; width:100%; max-width:280px;
}
.locked-banner{
  background:var(--frozen-bg); color:var(--ink-muted); text-align:center;
  font-size:13px; padding:8px 16px; border-top:1px solid var(--frozen);
}
.locked-banner a{ color:var(--accent-deep); font-weight:600; text-decoration:none; }

/* Progress + breadcrumb bar — sits between the header and the canvas.
   Hidden entirely until at least one option has ever been activated
   (computeClientPathTrail returns nothing to show before that), so a
   brand new blueprint doesn't show an empty bar with nothing in it.
   Deliberately NOT using the mono font the rest of the app reserves for
   bold uppercase labels (card headers, block titles) — this is meant to
   read as quiet ambient context, not another loud heading, so it uses
   the regular body font at a smaller size and a much lighter border. */
.path-progress-bar{
  display:flex; align-items:stretch; justify-content:space-between; gap:16px;
  min-height:34px; box-sizing:border-box;
  padding:7px 28px; background:var(--bg); border-bottom:1px solid var(--line);
  font-family:var(--font-body); font-size:12px;
}
.path-breadcrumb{
  flex:1; min-width:0; overflow-x:auto; white-space:nowrap; color:var(--ink-muted);
  display:flex; align-items:center;
}
.path-breadcrumb::-webkit-scrollbar{ height:4px; }
.path-breadcrumb .crumb{ color:var(--ink-muted); }
.path-breadcrumb .crumb-sep{ color:var(--ink-muted); margin:0 6px; opacity:0.6; }
.path-progress-count{
  flex-shrink:0; color:var(--ink-muted); display:flex; align-items:center; gap:8px;
}
@media (max-width:640px){
  .path-progress-bar{ padding:7px 14px; }
  .path-breadcrumb{ display:none; } /* counter survives on mobile; the trail itself doesn't fit well at this width */
}

body.canvas-page{
  display:flex; flex-direction:column; height:100vh; margin:0; overflow:hidden;
}
body.canvas-page header.site{ flex-shrink:0; }
body.canvas-page .path-progress-bar{ flex-shrink:0; }

.canvas-viewport{
  position:relative; overflow:hidden; flex:1; min-height:0;
  background-color:var(--bg);
  background-image: radial-gradient(circle, var(--line) 1px, transparent 1.4px);
  background-size: 22px 22px;
  cursor:grab;
  touch-action:none; user-select:none;
}
.canvas-viewport.panning{ cursor:grabbing; }
.canvas-viewport.busy{ pointer-events:none; }

/* Fullscreen API targets this element directly (not the whole page) — it
   needs to fill the screen and keep its own background/pattern once it's
   the fullscreen root, since none of its normal page chrome comes with it. */
.canvas-viewport:fullscreen{ width:100vw; height:100vh; }
.canvas-viewport:-webkit-full-screen{ width:100vw; height:100vh; }

.canvas-world{
  position:absolute; top:0; left:0; transform-origin:0 0; will-change:transform;
  backface-visibility:hidden;
}
/* Added only for the one-time "look what you built" auto-frame when a
   path first reaches its terminal Generate Ideas card — removed right
   after, so ordinary panning/zooming stays instant the rest of the time. */
.canvas-world.auto-framing{ transition:transform 0.8s cubic-bezier(0.22, 1, 0.36, 1); }
.canvas-connector{
  position:absolute; height:2px; background:var(--accent);
  transform-origin:0 50%; pointer-events:none;
}
.canvas-connector.frozen{ background:var(--frozen); }
.canvas-connector.drag-preview{
  height:0; border-top:2px dashed var(--accent); background:none;
}
.canvas-connector.dotted{
  height:0; background:none;
  border-top:1.5px dotted var(--ink-muted);
  opacity:0.6;
}
.canvas-connector.dotted.frozen{
  border-top-color:var(--frozen);
  opacity:0.4;
}
.canvas-connector.dimmed{ opacity:0.15; }

.canvas-group{
  position:absolute; width:220px;
  background:var(--surface); border:1px solid var(--line); border-radius:12px;
  box-shadow:0 2px 6px rgba(0,0,0,0.05);
  user-select:none;
  transition:opacity .15s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease, filter .15s ease;
}

/* Per-block territory dot — see BLOCK_COLORS in script.js. Deliberately
   not on the border (that's already on-path/frozen's signal); just a
   small recognition cue in the header that's always visible regardless
   of selection state. */
.block-color-dot{ width:7px; height:7px; border-radius:50%; flex-shrink:0; margin-right:5px; }

/* The idea-checkpoint card — the one deliberately dramatic, forced
   2-option fork in the whole path. Heavier border + warm header tint +
   a visible shadow lift, all within the SAME 220px footprint as every
   other card (changing the footprint itself would need the backend's
   spider-web layout math to also know about it, to avoid overlapping a
   neighbor sized for the normal width). Placed BEFORE .frozen and
   .batch-unpicked below on purpose: equal specificity here falls back to
   source order, and a checkpoint that's also frozen or faded needs THOSE
   states to win, not this one. */
.canvas-group.checkpoint-node{
  border-width:2px; border-color:var(--accent);
  box-shadow:0 6px 20px rgba(217,119,87,0.22);
}
.canvas-group.checkpoint-node .canvas-group-header{ background:var(--accent-soft); }
.checkpoint-intro{
  padding:10px 14px 2px; font-size:11.5px; color:var(--accent-deep);
  font-style:italic; line-height:1.4; text-align:center;
}
.canvas-group.checkpoint-node .canvas-option{ padding:14px 12px; font-size:13px; font-weight:500; }
.canvas-group.checkpoint-node .canvas-option.root-clickable:hover{ background:var(--accent-soft); }

.combined-pick-note{
  padding:6px 14px; font-size:11px; color:var(--accent-deep); background:var(--accent-soft);
  line-height:1.4;
}

/* Frozen — grayed out by definition (no longer the active branch). Stays
   grayed out PERMANENTLY regardless of any render/animation timing, since
   it's driven purely by group.is_frozen on every render, never a transient
   class. The ONLY thing that lifts the gray is the mouse actually hovering
   the card — a deliberate "peek at a frozen branch without un-freezing it"
   affordance, not a bug. Moving the mouse away always re-grays it; there is
   no other state in between. */
.canvas-group.frozen{ background:var(--frozen-bg); border-color:var(--frozen); opacity:0.75; }
.canvas-group.frozen:hover{
  opacity:1; background:var(--surface); border-color:var(--line);
  box-shadow:0 4px 14px rgba(0,0,0,0.10);
  z-index:5;
}
.canvas-group.frozen .canvas-group-header{ color:var(--frozen); background:transparent; }
.canvas-group.frozen:hover .canvas-group-header{ color:var(--ink); background:var(--surface-2); }
.canvas-group.frozen:hover .canvas-option{ opacity:1; }

/* Batch-unpicked — a brother group spawned in the SAME batch (same
   activation) has a pick inside it, and this one doesn't. Strong fade,
   on purpose: background swap (not opacity alone — that measured an
   imperceptible luminance gap of 3.6/255 the one time it was tried)
   PLUS a real opacity drop on top, since this needs to read as clearly
   "you moved on from this one" rather than a light hint. Hover lifts it
   to full clarity to peek without losing the cue once the mouse leaves. */
.canvas-group.batch-unpicked{ background:var(--frozen-bg); opacity:0.7; }
.canvas-group.batch-unpicked .canvas-group-header{ background:#DCD7C8; color:var(--ink-muted); }
.canvas-group.batch-unpicked:hover{
  background:var(--surface); opacity:1;
  box-shadow:0 4px 14px rgba(0,0,0,0.10);
  z-index:5;
}
.canvas-group.batch-unpicked:hover .canvas-group-header{ background:var(--surface-2); color:var(--ink); }

/* "on-path" — this group currently holds the option that was picked to
   continue onward; the orange outline marks the live trail through the
   graph at a glance. Never applied together with .frozen (see script.js —
   a frozen group's selected option is a STALE choice from before an
   ancestor branch got deprioritized, not the current path), so there's no
   conflicting style to resolve between the two. */
.canvas-group.on-path{ box-shadow:0 0 0 2px var(--accent); }

.canvas-group-header{
  display:grid; grid-template-columns:auto 1fr auto; align-items:center;
  min-height:40px; height:auto; padding:8px 8px 6px 12px; border-bottom:1px solid var(--line);
  background:var(--surface-2); border-radius:12px 12px 0 0; cursor:grab;
  font-family:var(--font-mono); font-size:11.5px; font-weight:600; color:var(--ink);
  letter-spacing:.03em; text-transform:uppercase; gap:6px;
}
.canvas-group-header .header-spacer{ visibility:hidden; pointer-events:none; display:flex; align-items:center; gap:4px; min-width:0; }
.header-controls{ display:flex; align-items:center; gap:4px; min-width:0; }
/* Centering done in two layers on purpose: this flex wrapper centers the
   title block as a WHOLE within the grid's middle column — that part
   doesn't depend on the title's own width at all, so it can't fail the
   way relying on the inner span filling 100% did. The inner span (below)
   only has to handle centering each individual wrapped line within
   ITSELF once text actually clamps to 2 lines. */
.canvas-group-title{
  display:flex; align-items:center; justify-content:center;
  width:100%; min-width:0; overflow:hidden;
}
.canvas-group-title span{
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
  overflow:hidden; line-height:1.25; text-align:center;
}
.remove-btn{
  border:none; background:transparent; color:var(--ink-muted); font-size:16px;
  line-height:1; cursor:pointer; padding:2px 4px; border-radius:4px; flex-shrink:0;
}
.remove-btn:hover{ color:#C24A3D; background:rgba(194,74,61,0.1); }
.canvas-group-header:active{ cursor:grabbing; }

.version-nav{ display:flex; align-items:center; gap:4px; font-family:var(--font-mono); font-size:11px; color:var(--ink-muted); flex-shrink:0; }
.version-nav button{ border:none; background:none; cursor:pointer; color:var(--ink-muted); font-size:13px; padding:0 2px; }
.version-nav button:hover:not(:disabled){ color:var(--ink); }
.version-nav button:disabled{ opacity:.3; cursor:not-allowed; }

.canvas-option{
  display:flex; align-items:center; gap:8px; min-height:38px; height:auto; padding:8px 12px;
  border-bottom:1px solid var(--line); font-size:13px; cursor:pointer;
}
.canvas-option:last-child{ border-bottom:none; }
.canvas-option.selected{ cursor:default; }
.canvas-option.selected .opt-dot{ background:var(--accent); cursor:grab; }
.canvas-option.selected .opt-dot:hover{ box-shadow:0 0 0 4px var(--accent-soft); }
.canvas-option.selected .opt-dot:active{ cursor:grabbing; }
/* The non-primary picks in a combined activation — selected, but not
   the option the line was actually dragged to. Blended from --accent
   itself rather than a plain gray, so it still reads as "a version of
   the selected color," just visually quieter than the primary pick. */
.canvas-option.selected.selected-secondary .opt-dot{ background:color-mix(in srgb, var(--accent) 50%, var(--ink-muted) 50%); }
.canvas-option.root-clickable{ cursor:pointer; }
.canvas-option.root-clickable:hover{ background:var(--accent-soft); }
.canvas-option.inert{ cursor:default; }
/* Staged for a combined activation (ctrl+click). Deliberately an INSET
   box-shadow, not a real border — a real border would change this row's
   box height slightly, and the server's layout math (estimateOptionHeight)
   assumes a fixed, predictable row height for every state. Works on top
   of .selected, .root-clickable, or .inert; never replaces them. */
.canvas-option.multi-staged{ background:var(--accent-soft); box-shadow:inset 0 0 0 2px var(--accent); }
.canvas-option.multi-staged .opt-dot{ background:var(--accent); }
.canvas-option .opt-dot{ width:12px; height:12px; border-radius:50%; background:var(--line); flex-shrink:0; }
.canvas-option .opt-label{
  flex:1; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
  overflow:hidden; line-height:1.3; text-align:center;
}

/* Live feedback while dragging a connecting line */
.canvas-group.drop-eligible{ box-shadow:0 0 0 2px var(--accent); }
.canvas-option.drop-hover{ background:var(--accent-soft); outline:2px dashed var(--accent); outline-offset:-2px; }



.canvas-group-footer{ display:flex; gap:4px; padding:8px; border-top:1px solid var(--line); }
.mini-btn{
  flex:1; font-family:var(--font-mono); font-size:10px; text-transform:uppercase;
  background:transparent; border:1px solid var(--line); border-radius:6px;
  padding:6px 0; cursor:pointer; color:var(--ink-muted);
}
.mini-btn:hover:not(:disabled){ border-color:var(--accent); color:var(--ink); }
.mini-btn:disabled{ opacity:.4; cursor:not-allowed; }

/* Terminal node at the end of a 15-deep path — no options, no
   Retry/Random/Custom, just a clear stop sign with one button. The
   slightly heavier border + tinted top edge is a deliberate, gentle
   "this one's different" cue, distinct from both the plain default card
   and the orange on-path/frozen-gray treatments used everywhere else. */
.canvas-group.generate-ideas-node{ border-color:var(--accent); border-width:2px; }
.canvas-generate-ideas-body{
  padding:18px 16px; text-align:center; display:flex; flex-direction:column; gap:14px; align-items:center;
}
.canvas-generate-ideas-body p{ font-size:13px; color:var(--ink-muted); line-height:1.4; margin:0; }
.canvas-generate-ideas-body .btn{ width:100%; justify-content:center; }

.canvas-custom-row{ display:flex; gap:6px; padding:8px; border-top:1px solid var(--line); align-items:flex-end; }
.canvas-custom-row textarea{
  flex:1; font-family:var(--font-body); font-size:12px; line-height:1.4;
  border:1px solid var(--line); border-radius:6px; padding:6px 8px;
  background:var(--bg); color:var(--ink); outline:none;
  resize:none; overflow:hidden; min-height:30px; max-height:140px;
  white-space:pre-wrap; word-wrap:break-word;
}
.canvas-custom-row textarea:focus{ border-color:var(--accent); }

.canvas-controls{ position:absolute; bottom:20px; right:20px; display:flex; flex-direction:column; gap:6px; z-index:5; }
.zoom-btn{
  width:32px; height:32px; border-radius:8px; border:1px solid var(--line);
  background:var(--surface); color:var(--ink); font-size:15px; cursor:pointer;
}
.zoom-btn:hover{ border-color:var(--accent); }

.canvas-empty-message{ position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:var(--ink-muted); }
.canvas-busy-indicator{
  position:absolute; top:16px; left:50%; transform:translateX(-50%);
  background:var(--ink); color:var(--bg); font-family:var(--font-mono); font-size:12px;
  padding:6px 14px; border-radius:14px; z-index:6;
  max-width:min(520px, 90%); min-width:120px;
  transition:max-width .3s ease, padding .2s ease;
  text-align:center;
  display:flex; align-items:center; gap:9px;
}
/* Generated by CSS, not real DOM content — this is deliberate. The
   streaming-label renderer does a full innerHTML replacement of this
   element's content on every token (see updateStreamingLabelDisplay),
   which would wipe out any spinner added as an actual child element.
   A pseudo-element can't be touched by that at all, so the spinner
   stays visible through the ENTIRE busy period — including the gap
   after streaming stops but before the request has actually finished
   (a semantic dedup check, a DB write) — which is exactly the moment
   that was reading as "frozen" before this existed. */
.canvas-busy-indicator::before{
  content:''; flex-shrink:0; width:13px; height:13px; border-radius:50%;
  border:2px solid rgba(250,246,241,0.35); border-top-color:var(--bg);
  animation:canvasBusySpin .7s linear infinite;
}
@keyframes canvasBusySpin{
  to{ transform:rotate(360deg); }
}

/* ---------- Streaming label preview (inside canvas-busy-indicator) ---------- */
.stream-label-list{
  display:flex; flex-direction:column; gap:4px; max-height:260px;
  overflow:hidden; /* no scrollbar — older labels just scroll out of view */
}
.stream-label-placeholder{ white-space:nowrap; }
.stream-label{
  display:block; font-size:11.5px; line-height:1.45; white-space:pre-wrap;
  word-break:break-word;
}
.stream-label-done{
  /* Fade in when a label completes — the pop from nothing to full
     opacity is what makes each new option feel "typed in" rather than
     just appearing. A very short animation so it's subtle, not distracting. */
  animation:labelFadeIn .18s ease both;
}
.stream-label-typing{
  opacity:.85; /* slightly dimmer to distinguish from finished labels */
}
.stream-cursor{
  display:inline-block; margin-left:1px; color:var(--accent-soft);
  animation:cursorBlink .65s step-start infinite;
}
@keyframes labelFadeIn{
  from{ opacity:0; transform:translateY(3px); }
  to{ opacity:1; transform:translateY(0); }
}
@keyframes cursorBlink{
  0%, 100%{ opacity:1; }
  50%{ opacity:0; }
}

/* ---------- IDEATE PAGE ---------- */
.ideate-main{ padding:60px 0 100px; }
.ideate-wrap{ max-width:640px; }

/* confirm.html's result page is much richer than a single question —
   idea fields, two-column competitor/persona grids, risk cards — and
   feels cramped at the same 640px ideate.html uses for one question and
   6 options at a time. Scoped to #confirmRoot specifically so this
   doesn't widen the simpler 45-question flow, which shares the same
   .ideate-wrap class but doesn't need the extra room. */
#confirmRoot .ideate-wrap{ max-width:880px; }
.ideate-meta{ display:flex; justify-content:space-between; align-items:baseline; margin-bottom:10px; }
.ideate-progress{ font-family:var(--font-mono); font-size:12px; color:var(--ink-muted); }
.ideate-progress-track{ height:4px; background:var(--line); border-radius:999px; margin-bottom:40px; overflow:hidden; }
.ideate-progress-fill{ height:100%; background:var(--accent); border-radius:999px; transition:width .3s ease; width:0%; }

/* Shown above every confirmation question so answering "which
   monetization model fits" (or any of the other 4 pressure-test
   questions) has actual context behind it, rather than the person
   confirming or changing parts of an idea they were never shown.
   Deliberately lighter-weight than .ideate-card below it (dashed border,
   smaller type, less padding) — this is supporting context, not the
   main focus of the screen. */
.idea-draft-context{
  background:var(--surface); border:1px dashed var(--line); border-radius:14px;
  padding:20px 24px; margin-bottom:24px;
}
.idea-draft-name{ font-size:19px; margin:8px 0 4px; }
.idea-draft-oneliner{ color:var(--ink-muted); font-size:13.5px; margin-bottom:14px; }
.idea-draft-fields{ display:grid; grid-template-columns:repeat(2, 1fr); gap:12px 20px; }
.idea-draft-fields .lbl{ font-family:var(--font-mono); font-size:10px; color:var(--ink-muted); text-transform:uppercase; letter-spacing:.06em; margin-bottom:2px; }
.idea-draft-fields p{ font-size:13px; color:var(--ink); margin:0; line-height:1.4; }
@media (max-width:640px){
  .idea-draft-fields{ grid-template-columns:1fr; }
}

.ideate-card{ background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:36px; }
.ideate-question{ font-family:var(--font-display); font-size:24px; line-height:1.35; margin-bottom:28px; }
.ideate-options{ display:flex; flex-direction:column; gap:10px; }
.ideate-option{
  text-align:left; font-family:var(--font-body); font-size:15px; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:10px;
  padding:14px 18px; cursor:pointer; transition:border-color .15s ease, background .15s ease;
}
.ideate-option:hover:not(:disabled){ border-color:var(--accent); background:var(--accent-soft); }
.ideate-option:disabled{ opacity:.5; cursor:default; }
/* Briefly applied to whichever option the AI picked, so there's a
   visible link between pressing "Let AI Answer" and what got chosen,
   instead of jumping straight to the next question with no feedback. */
.ideate-option.ai-picked{ border-color:var(--accent); background:var(--accent-soft); opacity:1; }

.ai-answer-btn{ display:table; margin:18px auto 0; }

.ideate-result{ background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:36px; }
.ideate-result h2{ font-size:26px; margin:10px 0 8px; }

/* ---------- CONFIRMATION PAGE ---------- */
.confirm-researching{
  background:var(--surface); border:1px solid var(--line); border-radius:16px;
  padding:48px 36px; text-align:center;
}
.confirm-researching h3{ font-size:18px; margin:18px 0 8px; }
.confirm-researching p{ max-width:380px; margin:0 auto; }
.confirm-spinner{
  width:32px; height:32px; margin:0 auto;
  border:3px solid var(--line); border-top-color:var(--accent); border-radius:50%;
  animation:confirm-spin 0.8s linear infinite;
}
@keyframes confirm-spin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){
  .confirm-spinner{ animation:none; border-top-color:var(--line); }
}

.confirm-result{ background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:36px; }

/* Scoped to these specific buttons, not .btn/.btn-primary generally —
   those classes are used inline in plenty of other places (nav, hero,
   pricing) that need to stay exactly as they are. display:table sizes
   to content width like inline-block does, while still letting
   margin:auto center it — display:block would work for centering too
   but would stretch the button to its container's full width, which
   isn't wanted here. */
#deeperAnalysisSection > button,
#deeperFixesSection > button,
#buildBriefSection > button,
#reviseIdeaSection > button,
#deeperAnalysisSection > .pro-gate,
#deeperFixesSection > .pro-gate,
#buildBriefSection > .pro-gate,
#reviseIdeaSection > .pro-gate,
.confirm-result > a.btn-primary,
.ideate-result > a.btn-primary{
  display:table;
  margin:24px auto 0;
}
.confirm-result h2{ font-size:26px; margin:10px 0 8px; }
.confirm-section-title{ font-size:16px; margin:28px 0 14px; padding-top:20px; border-top:1px solid var(--line); }

/* ---------- Pro-gated action buttons (renderProGatedButton) ---------- */
.pro-gate{ display:flex; align-items:center; gap:10px; }
.pro-gate button:disabled{ opacity:.55; cursor:not-allowed; }
.pro-gate-badge{
  font-family:var(--font-mono); font-size:10px; font-weight:700; letter-spacing:.06em;
  color:var(--accent-deep); background:var(--accent-soft); padding:3px 7px; border-radius:5px;
}
.pro-gate-link{ font-size:13px; color:var(--accent-deep); font-weight:500; white-space:nowrap; }
.pro-gate-link:hover{ text-decoration:underline; }

.competitors-list{ display:flex; flex-direction:column; gap:16px; margin-bottom:8px; }
.competitor-block{ background:var(--bg); border:1px solid var(--line); border-radius:10px; padding:16px 18px; }
.competitor-name{ font-family:var(--font-mono); font-size:13px; font-weight:600; margin-bottom:10px; }
.competitor-cols{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.competitor-cols .lbl{ font-family:var(--font-mono); font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; margin-bottom:6px; }
.lbl-pro{ color:#5C8A5C; }
.lbl-con{ color:#C24A3D; }
.competitor-cols ul{ margin:0; padding-left:16px; font-size:13px; color:var(--ink-muted); display:flex; flex-direction:column; gap:4px; }
@media (max-width:560px){ .competitor-cols{ grid-template-columns:1fr; } }

.solutions-list{ display:flex; flex-direction:column; gap:10px; }
.solution-block{
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:12px;
  background:var(--bg); border:1px solid var(--line); border-radius:10px; padding:12px 16px; font-size:13px;
}
.solution-problem{ color:var(--ink-muted); }
.solution-arrow{ color:var(--accent); font-weight:600; }
.solution-fix{ color:var(--ink); }
@media (max-width:640px){
  .solution-block{ grid-template-columns:1fr; gap:6px; }
  .solution-arrow{ display:none; }
}

.confirm-full-description{ font-size:14.5px; line-height:1.7; color:var(--ink); white-space:pre-line; }

.btn-secondary{
  background:var(--bg); color:var(--ink); border:1px solid var(--line);
}
.btn-secondary:hover{ border-color:var(--accent); color:var(--accent-deep); }

.idea-block-p{ font-size:14px; color:var(--ink-muted); line-height:1.6; margin-bottom:14px; }

.confirm-error{ color:#C24A3D; font-size:14px; }

/* Market intel pricing */
.pricing-list{ display:flex; flex-direction:column; gap:8px; margin-bottom:16px; }
.pricing-row{
  display:flex; justify-content:space-between; align-items:center;
  background:var(--bg); border:1px solid var(--line); border-radius:8px; padding:10px 14px;
  font-size:13px;
}
.pricing-competitor{ color:var(--ink); font-weight:500; }
.pricing-amount{ font-family:var(--font-mono); color:var(--ink-muted); }

/* This is the one place in the whole app a model output could plausibly
   get mistaken for real validation data — deliberately the LOUDEST visual
   treatment on the page, breaking from the calm neutral palette used
   everywhere else on purpose. Shown once as a section banner and again
   directly above the persona grid (see script.js), not just once at the
   top where it's easy to scroll past. */
.simulated-disclaimer{
  background:#FBEFD9; border:1.5px solid #D9A33E; color:#7A5418;
  border-radius:8px; padding:10px 14px; font-size:13px; font-weight:600;
  margin-bottom:16px;
}

.personas-grid{ display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-bottom:8px; }
@media (max-width:640px){ .personas-grid{ grid-template-columns:1fr; } }
.persona-card{
  background:var(--bg); border:1px solid var(--line); border-radius:10px; padding:16px 18px;
}
.persona-name{ font-family:var(--font-mono); font-size:13px; font-weight:600; margin-bottom:4px; }
.persona-background{ font-size:12.5px; color:var(--ink-muted); margin-bottom:12px; line-height:1.5; }
.persona-row{ margin-bottom:8px; }
.persona-row .lbl{ font-family:var(--font-mono); font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); display:block; margin-bottom:2px; }
.persona-row p{ font-size:13px; color:var(--ink); margin:0; line-height:1.5; }

.risks-list{ display:flex; flex-direction:column; gap:12px; }
.risk-card{
  background:var(--bg); border:1px solid var(--line); border-left:4px solid var(--line);
  border-radius:8px; padding:14px 16px;
}
.risk-card.risk-high{ border-left-color:#C24A3D; }
.risk-card.risk-medium{ border-left-color:#D9A33E; }
.risk-card.risk-low{ border-left-color:#5C8A5C; }
.risk-header{ display:flex; align-items:baseline; gap:10px; margin-bottom:8px; }
.risk-severity-tag{
  font-family:var(--font-mono); font-size:10px; font-weight:700; letter-spacing:.05em;
  padding:2px 7px; border-radius:5px; background:var(--surface-2); color:var(--ink-muted); flex-shrink:0;
}
.risk-card.risk-high .risk-severity-tag{ background:rgba(194,74,61,0.15); color:#C24A3D; }
.risk-card.risk-medium .risk-severity-tag{ background:rgba(217,163,62,0.18); color:#9A7320; }
.risk-card.risk-low .risk-severity-tag{ background:rgba(92,138,92,0.15); color:#5C8A5C; }
.risk-assumption{ font-size:14px; font-weight:500; color:var(--ink); }
.risk-addressed{ font-size:13px; color:var(--ink-muted); margin:0 0 6px; line-height:1.5; }
.risk-next-step{ font-size:13px; color:var(--ink); margin:0; line-height:1.5; }
.risk-addressed strong, .risk-next-step strong{ color:var(--ink); font-weight:600; }

/* ---------- Suggest Changes (feedback-driven revision + preview) ---------- */
.revise-form{
  display:flex; flex-direction:column; gap:10px;
  background:var(--surface); border:1px solid var(--line); border-radius:10px;
  padding:16px; margin:18px 0;
}
.revise-textarea{
  width:100%; box-sizing:border-box; resize:vertical; min-height:90px;
  font-family:var(--font-body); font-size:14px; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:8px; padding:10px 12px;
}
.revise-textarea:focus{ outline:none; border-color:var(--accent); }
.revise-textarea.input-error{ border-color:#C24A3D; }
.revise-form-actions{ display:flex; gap:10px; }
.revise-validation-error{ margin:0; }

.revise-preview{
  border:1px solid var(--accent); border-radius:10px; padding:18px;
  background:var(--accent-soft); margin:18px 0;
}
.revise-preview h3{ margin:10px 0 4px; }
.idea-tag-preview{ background:var(--accent); color:#FAF6F1; padding:2px 8px; border-radius:5px; }
.revise-feedback-echo{
  font-size:13px; color:var(--ink-muted); font-style:italic;
  margin:8px 0 16px; line-height:1.5;
}

/* ---------- Build Brief ---------- */
.mvp-list{ display:flex; flex-direction:column; gap:14px; }
.mvp-item{
  background:var(--surface); border:1px solid var(--line); border-radius:10px;
  padding:14px 16px;
}
.mvp-item-title{ font-size:14px; font-weight:600; color:var(--ink); margin-bottom:6px; }
.mvp-item-description{ font-size:13.5px; color:var(--ink-muted); line-height:1.6; margin:0; }
.build-brief-actions{ display:flex; gap:10px; margin-top:20px; }

/* ---------- Shareable link ---------- */
.confirm-final-actions{
  display:flex; align-items:center; justify-content:center;
  flex-wrap:wrap; gap:16px; margin-top:28px; padding-top:20px; border-top:1px solid var(--line);
}
.share-link-row{ display:flex; gap:8px; align-items:center; max-width:420px; width:100%; }
.share-link-input{
  flex:1; min-width:0; font-family:var(--font-mono); font-size:12.5px; color:var(--ink-muted);
  background:var(--surface); border:1px solid var(--line); border-radius:7px; padding:9px 11px;
}

/* ---------- Public one-pager (share.html) ---------- */
.share-wrap{ max-width:680px; padding:48px 24px 80px; margin:0 auto; }
.share-onepager{ background:var(--surface); border:1px solid var(--line); border-radius:14px; padding:40px; }
.share-idea-name{ font-family:var(--font-display); font-size:32px; margin:10px 0 8px; }
.share-footer{ font-size:13px; color:var(--ink-muted); margin-top:24px; }
.share-onepager .btn-primary{ margin-top:24px; }

@media print{
  .no-print{ display:none !important; }
  body{ background:#fff; }
  .share-onepager{ border:none; box-shadow:none; padding:0; }
  .share-wrap{ max-width:100%; padding:0; }
}

@media (max-width:640px){
  .confirm-final-actions{ flex-direction:column; align-items:stretch; }
  .share-link-row{ max-width:none; }
  .share-onepager{ padding:24px; }
}

/* ---------- CLICK FEEDBACK (feedback.js) ---------- */
/* Applied as a temporary class by feedback.js to whatever was just
   clicked — a button, a canvas option, anything actionable. The overshoot
   in the cubic-bezier (the 1.4 value pushing past 1.0 on the way back up)
   is what makes this read as a little springy "pop" rather than a flat
   press-down. Pairs with, doesn't fight, the existing .btn hover
   transition on transform — an animation always takes priority over a
   transition on the same property for as long as it's running, so this
   only ever shows up for the brief moment right after a click. */
@keyframes satisfying-pop{
  0%{ transform:scale(1); }
  35%{ transform:scale(0.93); }
  100%{ transform:scale(1); }
}
.pop-effect{
  animation:satisfying-pop 0.22s cubic-bezier(0.34, 1.4, 0.64, 1);
}

/* Floating sound toggle — injected into the DOM by feedback.js itself,
   not present in any page's own markup, so adding sound to every page
   only ever needed one <script> tag added per page, nothing else.
   Bottom-LEFT specifically: the existing pan/zoom controls
   (.canvas-controls) already occupy bottom-right, and this used to sit
   at that exact same spot, fighting it for the same corner. */
/* ---------- App-wide toast (showToast in script.js) ---------- */
.app-toast{
  position:fixed; left:50%; bottom:32px; transform:translate(-50%, 12px);
  background:var(--ink); color:var(--bg); font-size:13.5px; font-weight:500;
  padding:11px 20px; border-radius:10px; box-shadow:0 6px 20px rgba(0,0,0,0.18);
  opacity:0; transition:opacity .2s ease, transform .2s ease; z-index:1000;
  max-width:80vw; text-align:center;
}
.app-toast.app-toast-visible{ opacity:1; transform:translate(-50%, 0); }

/* ============================================================
   MOBILE OVERHAUL — three parts:
   1. Floating multi-select status bar (renderMultiSelectStatusBar in
      script.js) — the discoverable UI for the long-press staging
      gesture that replaces ctrl+click on touch devices.
   2. A (hover:none)/(pointer:coarse) pass widening every tap target on
      the canvas — option rows, footer buttons, zoom controls, header
      controls — since the desktop sizing throughout this file was
      tuned for a mouse cursor's precision, not a fingertip's.
   3. A real responsive pass over the ideation/confirmation screens:
      bigger comfortable type on small viewports, tighter but not
      cramped spacing, a sticky progress header so position in the
      flow is never scrolled out of view, and smoother state-change
      animations so the whole thing feels considered rather than just
      "the desktop layout, shrunk."
   ============================================================ */

/* ---------- 1. Multi-select status bar ---------- */
.multi-select-status-bar{
  position:fixed; left:50%; bottom:24px; transform:translateX(-50%);
  z-index:900; max-width:min(560px, 92vw);
  display:flex; align-items:center; gap:14px;
  background:var(--ink); color:var(--bg);
  border-radius:14px; padding:12px 16px 12px 18px;
  box-shadow:0 10px 30px rgba(0,0,0,0.28);
  animation:multiSelectBarIn .18s ease both;
}
@keyframes multiSelectBarIn{
  from{ opacity:0; transform:translateX(-50%) translateY(10px); }
  to{ opacity:1; transform:translateX(-50%) translateY(0); }
}
.multi-select-status-text{
  font-size:13px; line-height:1.4; flex:1;
}
.multi-select-cancel-btn{
  flex-shrink:0; font-family:var(--font-mono); font-size:11px; font-weight:600;
  text-transform:uppercase; letter-spacing:.04em;
  background:rgba(250,246,241,0.14); color:var(--bg);
  border:1px solid rgba(250,246,241,0.28); border-radius:8px;
  padding:8px 12px; cursor:pointer;
}
.multi-select-cancel-btn:hover{ background:rgba(250,246,241,0.24); }
/* Give the status bar room above the canvas's own zoom controls on
   narrow screens instead of the two stacking on top of each other. */
@media (max-width:640px){
  .multi-select-status-bar{ bottom:18px; max-width:94vw; padding:11px 14px 11px 16px; gap:10px; }
  .multi-select-status-text{ font-size:12.5px; }
}

/* ---------- 2. Bigger touch targets on coarse-pointer devices ----------
   (hover:none) is the real signal for "this is a touch input" — better
   than a viewport-width media query alone, since a touch laptop or a
   tablet in landscape can be wide but still needs finger-sized targets,
   while a narrow desktop browser window still has mouse precision. */
@media (hover:none) and (pointer:coarse){
  .canvas-option{
    min-height:48px; padding:11px 14px; font-size:14px;
  }
  .canvas-option .opt-dot{
    width:16px; height:16px; /* the drag-to-activate handle — was tuned for a mouse's pixel precision */
  }
  .canvas-group-footer{ padding:10px; gap:6px; }
  .mini-btn{ padding:10px 0; font-size:11px; }
  .remove-btn{ font-size:19px; padding:6px 8px; }
  .version-nav button{ font-size:16px; padding:4px 6px; }
  .zoom-btn{ width:42px; height:42px; font-size:18px; }
  .canvas-controls{ bottom:28px; right:16px; gap:10px; }
  .canvas-group-header{ min-height:46px; padding:10px 10px 8px 14px; }
  .canvas-generate-ideas-body .btn{ padding:14px 20px; }
  /* Cards get a touch more breathing room since fingers are less
     precise than a cursor at judging where one card ends and the next
     begins — a wider card reduces accidental mis-taps between them. */
  .canvas-group{ width:230px; }
  .fullscreen-btn, #fullscreenBtn{ width:42px; height:42px; font-size:18px; }
}

/* ---------- 3. Ideation & confirmation screen responsive pass ---------- */
@media (max-width:640px){
  .ideate-main{ padding:20px 0 80px; }
  .wrap{ padding:0 16px; }

  /* Sticky progress header — keeps "where am I in this flow" visible
     even mid-scroll through a long confirmation result, instead of it
     living only at the very top where a single swipe hides it. */
  .ideate-meta{
    position:sticky; top:0; z-index:40;
    background:var(--bg); padding:14px 0 8px; margin-bottom:0;
    border-bottom:1px solid var(--line);
  }
  .ideate-progress-track{ margin-bottom:0; }

  .ideate-card, .confirm-result, .ideate-result{
    padding:22px 18px; border-radius:14px;
  }
  .ideate-question{
    font-size:19px; line-height:1.3; margin-bottom:20px;
  }
  .ideate-option{
    padding:15px 16px; font-size:14.5px; border-radius:12px;
    transition:border-color .15s ease, background .15s ease, transform .1s ease;
  }
  .ideate-option:active{ transform:scale(0.98); }
  .ideate-options{ gap:9px; }

  .idea-draft-context{ padding:16px 18px; border-radius:12px; }
  .idea-draft-name{ font-size:17px; }
  .idea-draft-fields{ gap:10px 14px; }

  .confirm-result h2, .ideate-result h2{ font-size:21px; }
  .confirm-section-title{ font-size:14.5px; margin:22px 0 12px; padding-top:16px; }

  .competitor-block{ padding:14px 15px; }
  .competitor-cols{ gap:12px; }
  .solution-block{ padding:11px 14px; font-size:12.5px; }
  .persona-card{ padding:14px 15px; }
  .risk-card{ padding:12px 14px; }

  .revise-form{ padding:14px; }
  .revise-textarea{ min-height:110px; font-size:16px; } /* 16px prevents iOS Safari's auto-zoom-on-focus for inputs under 16px */
  .mvp-item{ padding:12px 14px; }

  .confirm-researching{ padding:32px 20px; }
  .confirm-researching h3{ font-size:16px; }

  .auth-card{ padding:28px 22px; }
  .auth-form input{ font-size:16px; padding:13px 14px; } /* same iOS zoom-prevention reasoning as the textarea above */
}

/* Gentle entrance animation for freshly-rendered result sections —
   applied via a class script.js can add to a freshly-populated
   container, so a new section (deeper analysis, build brief, a
   revision preview) reads as something that just arrived rather than
   snapping into place with no transition at all. Respects
   prefers-reduced-motion via the existing global rule pattern already
   used elsewhere in this file. */
@keyframes resultSectionIn{
  from{ opacity:0; transform:translateY(8px); }
  to{ opacity:1; transform:translateY(0); }
}
.result-section-enter{
  animation:resultSectionIn .3s ease both;
}
@media (prefers-reduced-motion:reduce){
  .result-section-enter{ animation:none; }
}

/* ---------- Step-based researching indicator (confirm.html Q4 flow) ----------
   Replaces a single spinner + one line of swapped text with a real
   checklist that fills in as each SSE progress event arrives, so the
   30-40 second wait during final idea synthesis reads as visible
   forward motion instead of an ambiguous "is this stuck?" spinner. */
.research-steps-list{
  display:flex; flex-direction:column; gap:10px;
  max-width:380px; margin:22px auto 0; text-align:left;
}
.research-step{
  display:flex; align-items:center; gap:12px;
  font-size:13.5px; color:var(--ink-muted);
  opacity:0.5; transition:opacity .25s ease, color .25s ease;
}
.research-step.active{ opacity:1; color:var(--ink); font-weight:600; }
.research-step.done{ opacity:1; color:var(--ink-muted); }
.research-step-marker{
  flex-shrink:0; width:20px; height:20px; border-radius:50%;
  border:2px solid var(--line); display:flex; align-items:center; justify-content:center;
  font-size:11px; color:transparent; transition:all .2s ease;
}
.research-step.active .research-step-marker{
  border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft);
}
.research-step.active .research-step-marker::after{
  content:''; width:8px; height:8px; border-radius:50%; background:var(--accent);
  animation:researchStepPulse 1s ease-in-out infinite;
}
@keyframes researchStepPulse{
  0%, 100%{ opacity:0.4; transform:scale(0.8); }
  50%{ opacity:1; transform:scale(1); }
}
.research-step.done .research-step-marker{
  border-color:#5C8A5C; background:#5C8A5C; color:#FAF6F1;
}
.research-step.done .research-step-marker::before{ content:'✓'; }
@media (prefers-reduced-motion:reduce){
  .research-step-marker::after{ animation:none; }
}

/* ---------- Dashboard feedback button (renderFeedbackButton in script.js) ----------
   Bottom-RIGHT specifically: this only ever renders on dashboard.html,
   which has no canvas/zoom controls or multi-select status bar competing
   for that corner (those only exist on app.html), so there's no clash
   to route around the way feedback.js's sound toggle had to avoid
   .canvas-controls by going bottom-left instead. */
.feedback-fab{
  position:fixed; right:24px; bottom:24px; z-index:150;
  width:52px; height:52px; border-radius:50%;
  background:var(--accent); color:#FAF6F1; border:none;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; box-shadow:0 6px 18px rgba(217,119,87,0.35);
  transition:transform .15s ease, background .15s ease, box-shadow .15s ease;
}
.feedback-fab:hover{
  background:var(--accent-deep); transform:translateY(-2px);
  box-shadow:0 10px 24px rgba(217,119,87,0.42);
}
.feedback-fab:active{ transform:translateY(0) scale(0.96); }
@media (hover:none) and (pointer:coarse){
  .feedback-fab{ width:56px; height:56px; right:18px; bottom:18px; }
}

/* ---------- User icon button (nav) ----------
   Used two places: the marketing nav (index.html, injected by
   initNavAuthState next to the Dashboard button) and dashboard.html's
   own nav, where it replaced the old text "Log out" button — both link
   straight to settings.html, which is where logging out actually lives
   now. Circular, same accent-on-cream treatment as the rest of the nav's
   interactive elements. */
.user-icon-btn{
  width:36px; height:36px; border-radius:50%; flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); color:var(--ink);
  border:1px solid var(--line);
  transition:background .15s ease, border-color .15s ease, color .15s ease;
}
.user-icon-btn:hover{
  background:var(--accent-soft); border-color:var(--accent); color:var(--accent-deep);
}

/* ---------- SETTINGS PAGE (settings.html) ---------- */
.settings-main{ padding:56px 0 100px; }
.settings-wrap{ max-width:640px; }
.settings-head{ margin-bottom:36px; }
.settings-head h1{ font-size:clamp(26px, 3.4vw, 32px); margin:8px 0 6px; }

.settings-section{ margin-bottom:28px; }
.settings-section-head{ margin-bottom:10px; }
.settings-section-head h2{ font-size:15px; font-family:var(--font-mono); text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); font-weight:600; }

.settings-card{
  background:var(--surface); border:1px solid var(--line); border-radius:14px;
  padding:22px 24px;
}
.settings-danger-card{ border-color:#E8B8AE; background:#FBF3F1; }

.settings-row{ display:flex; align-items:center; justify-content:space-between; gap:16px; }
.settings-avatar-row{ display:flex; align-items:center; gap:16px; }
.settings-avatar{
  width:44px; height:44px; border-radius:50%; flex-shrink:0;
  background:var(--accent); color:#FAF6F1;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-display); font-size:19px; font-weight:600;
}
.settings-avatar-row > div:nth-child(2){ flex:1; min-width:0; }

.settings-field-label{
  font-family:var(--font-mono); font-size:11px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--ink-muted); margin-bottom:3px;
}
.settings-field-value{ font-size:15px; color:var(--ink); word-break:break-word; }
.settings-field-value.muted{ font-size:13.5px; color:var(--ink-muted); max-width:360px; line-height:1.5; }

.settings-edit-btn{ flex-shrink:0; font-size:13px; padding:8px 14px; }

.settings-divider{ height:1px; background:var(--line); margin:20px 0; }

.settings-inline-form{
  display:flex; flex-direction:column; gap:10px; margin-top:14px;
}
.settings-inline-form input{
  font-family:var(--font-body); font-size:14.5px; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:11px 13px; outline:none; transition:border-color .15s ease;
}
.settings-inline-form input:focus{ border-color:var(--accent); }
.settings-inline-actions{ display:flex; justify-content:flex-end; gap:8px; margin-top:2px; }
.settings-inline-actions .btn{ font-size:13px; padding:9px 16px; }

.settings-danger-btn{
  background:#C24A3D; color:#FAF6F1; border:none;
}
.settings-danger-btn:hover{ background:#A83D32; }

.settings-logout-row{ display:flex; justify-content:center; margin-top:8px; }

@media (max-width:640px){
  .settings-main{ padding:32px 0 80px; }
  .settings-card{ padding:18px 18px; }
  .settings-row{ flex-direction:column; align-items:flex-start; gap:12px; }
  .settings-row .btn{ align-self:stretch; text-align:center; }
  .settings-avatar-row{ width:100%; }
  .settings-danger-card .settings-field-value.muted{ max-width:none; }
}

/* =====================================================================
   IDEA TOOLKIT — 9 features built on the hardened idea (confirm.html)
   ===================================================================== */
.idea-toolkit{ margin-top:8px; }
.idea-toolkit-intro{ font-size:13.5px; margin:-6px 0 20px; }
.toolkit-grid{ display:flex; flex-direction:column; gap:20px; }
.toolkit-card{
  background:var(--surface); border:1px solid var(--line); border-radius:14px;
  padding:22px 24px;
}
.toolkit-card-head{ margin-bottom:14px; }
.toolkit-card-head h4{ font-size:17px; margin-bottom:4px; }
.toolkit-card-actions{ display:flex; gap:10px; flex-wrap:wrap; margin-top:18px; }
.toolkit-locked-note{ font-size:13px; margin-top:4px; }

/* ---------- Strength Score ---------- */
.strength-score-layout{ display:grid; grid-template-columns:200px 1fr; gap:24px; align-items:start; }
.strength-radar-wrap{ position:relative; display:flex; align-items:center; justify-content:center; }
.strength-radar-svg{ width:100%; max-width:200px; }
.strength-overall{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  font-family:var(--font-display); font-size:30px; font-weight:800;
  background:var(--strength-overall-bg, var(--surface));
  border-radius:50%;
  width:84px; height:84px; display:flex; flex-direction:column; align-items:center; justify-content:center;
  box-shadow:0 3px 12px rgba(0,0,0,0.16), 0 0 0 4px var(--bg);
  line-height:1.05;
}
.strength-overall span{ font-size:12px; color:var(--ink-muted); font-weight:600; }
.strength-dims-list{ display:flex; flex-direction:column; gap:14px; }
.strength-dim-header{ display:flex; justify-content:space-between; align-items:baseline; margin-bottom:4px; }
.strength-dim-label{ font-family:var(--font-mono); font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-muted); }
.strength-dim-score{
  font-family:var(--font-mono); font-weight:800; font-size:12.5px;
  padding:3px 9px; border-radius:6px;
}
.strength-dim-explanation{ font-size:13.5px; line-height:1.6; color:var(--ink); margin:0; }
.strength-dim-action{ font-size:12.5px; color:var(--accent-deep); margin:6px 0 0; }
.strength-fit-note{ font-size:12px; margin-top:16px; }
@media (max-width:640px){
  .strength-score-layout{ grid-template-columns:1fr; }
  .strength-radar-wrap{ max-width:180px; margin:0 auto; }
}

/* ---------- Pivot Generator ---------- */
.pivots-accordion{ display:flex; flex-direction:column; gap:10px; }
.pivot-item{
  border:1px solid var(--line); border-radius:10px; background:var(--bg); overflow:hidden;
}
.pivot-item summary{
  display:flex; align-items:center; gap:10px; padding:13px 16px; cursor:pointer;
  font-weight:600; list-style:none;
}
.pivot-item summary::-webkit-details-marker{ display:none; }
.pivot-type-badge{
  font-family:var(--font-mono); font-size:10px; text-transform:uppercase; letter-spacing:.05em;
  padding:3px 8px; border-radius:5px; flex-shrink:0; font-weight:700;
}
.pivot-type-audience{ background:rgba(62,124,168,0.15); color:#3E7CA8; }
.pivot-type-monetization{ background:rgba(168,138,62,0.15); color:#A88A3E; }
.pivot-type-scope{ background:rgba(138,92,168,0.15); color:#8A5CA8; }
.pivot-concept-name{ font-family:var(--font-display); font-size:15px; }
.pivot-item-body{ padding:0 16px 18px; }
.pivot-oneliner{ font-size:13.5px; color:var(--ink-muted); margin:0 0 14px; }
.pivot-build-btn{ margin-top:8px; }

/* ---------- Persona Cards ---------- */
.personas-scroll-row{
  display:flex; gap:16px; overflow-x:auto; padding-bottom:6px; -webkit-overflow-scrolling:touch;
}
.persona-full-card{
  flex:0 0 260px; background:var(--bg); border:1px solid var(--line); border-radius:12px;
  padding:18px;
}
.persona-full-avatar{
  width:40px; height:40px; border-radius:50%; background:var(--accent); color:#FAF6F1;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-display); font-weight:600; font-size:15px; margin-bottom:10px;
}
.persona-full-name{ font-weight:600; font-size:15px; }
.persona-full-occupation{ font-size:12.5px; color:var(--ink-muted); margin-bottom:12px; }
.persona-full-routine{ font-size:13px; line-height:1.6; margin-bottom:10px; }
.persona-full-card ul{ margin:4px 0 12px; padding-left:18px; font-size:12.5px; }
.persona-full-card li{ margin-bottom:3px; }
.persona-full-tried, .persona-full-wouldpay{ font-size:12.5px; line-height:1.5; margin-bottom:10px; }
.persona-full-quote{
  font-family:var(--font-display); font-style:italic; font-size:13.5px; color:var(--accent-deep);
  margin-top:12px; padding-top:12px; border-top:1px solid var(--line);
}
@media (hover:none) and (pointer:coarse){
  .persona-full-card{ flex-basis:82vw; }
}

/* ---------- Landing Page Copy ---------- */
.landing-copy-preview{ display:flex; flex-direction:column; gap:16px; }
.lc-section .lbl{ margin-bottom:6px; }
.lc-hero{ font-family:var(--font-display); font-size:19px; font-weight:600; }
.lc-cta-options{ display:flex; gap:8px; flex-wrap:wrap; }
.lc-cta-pill{
  font-size:12px; background:var(--accent-soft); color:var(--accent-deep);
  padding:6px 11px; border-radius:999px;
}

/* ---------- Red Team ("Challenge This Idea") ---------- */
.red-team-angles{ display:flex; flex-direction:column; gap:10px; }
.red-team-angle{
  border:1px solid #E8D5B8; border-radius:10px; background:#FDF8F0; overflow:hidden;
}
.red-team-angle summary{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:13px 16px; cursor:pointer; font-weight:600; list-style:none;
}
.red-team-angle summary::-webkit-details-marker{ display:none; }
.red-team-angle-label{ font-size:14px; }
.red-team-verdict{
  font-family:var(--font-mono); font-size:10px; text-transform:uppercase; font-weight:700;
  padding:3px 8px; border-radius:5px; flex-shrink:0;
}
.red-team-verdict-solid{ background:rgba(92,138,92,0.18); color:#5C8A5C; }
.red-team-verdict-partial{ background:rgba(217,163,62,0.2); color:#9A7320; }
.red-team-verdict-dodge{ background:rgba(194,74,61,0.18); color:#C24A3D; }
.red-team-angle-body{ padding:0 16px 18px; }
.red-team-critique{ font-size:13.5px; line-height:1.6; margin:0 0 10px; }
.red-team-question{ font-size:13px; color:var(--ink-muted); margin:0 0 14px; }
.red-team-rebuttal-box{ display:flex; flex-direction:column; gap:8px; }
.red-team-response{
  font-size:13px; line-height:1.6; background:var(--surface); border-radius:8px;
  padding:12px 14px; margin-top:4px;
}

/* ---------- Spy Mode ---------- */
.spy-mode-tab-buttons{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:16px; }
.spy-mode-tab-btn{
  font-size:13px; font-weight:600; padding:8px 14px; border-radius:8px;
  background:var(--bg); border:1px solid var(--line); color:var(--ink-muted); cursor:pointer;
}
.spy-mode-tab-btn.active{ background:var(--accent); border-color:var(--accent); color:#FAF6F1; }
.spy-mode-tab-panel{ display:none; }
.spy-mode-tab-panel.active{ display:block; }
.spy-mode-confirmed-date{ font-weight:400; text-transform:none; letter-spacing:0; color:var(--frozen); font-size:10px; }

/* ---------- Launch Checklist ---------- */
.checklist-progress-header{ font-size:12.5px; color:var(--ink-muted); margin-bottom:16px; }
.checklist-progress-track{ height:6px; background:var(--line); border-radius:999px; margin-top:6px; overflow:hidden; }
.checklist-progress-fill{ height:100%; background:var(--accent); transition:width .3s ease; }
.checklist-weeks{ display:flex; flex-direction:column; gap:10px; }
.checklist-week{ border:1px solid var(--line); border-radius:10px; background:var(--bg); overflow:hidden; }
.checklist-week summary{
  padding:13px 16px; cursor:pointer; font-weight:600; font-size:14px; list-style:none;
}
.checklist-week summary::-webkit-details-marker{ display:none; }
.checklist-week-body{ padding:0 16px 18px; display:flex; flex-direction:column; gap:10px; }
.checklist-task{
  display:flex; flex-wrap:wrap; align-items:flex-start; gap:4px 10px; cursor:pointer; padding:8px 0;
  border-bottom:1px solid var(--line);
}
.checklist-task:last-of-type{ border-bottom:none; }
.checklist-task input[type="checkbox"]{ margin-top:3px; flex-shrink:0; width:16px; height:16px; accent-color:var(--accent); }
.checklist-task-text{ font-size:13.5px; flex:1; min-width:200px; }
.checklist-task-criterion{
  font-size:11.5px; color:var(--ink-muted);
  flex-basis:100%; margin-left:26px; /* lines up under the task text, not the checkbox */
}
.checklist-metrics{ margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
.checklist-metric-row{ font-size:13px; margin-bottom:10px; }
.checklist-pivot-link{ display:inline-block; margin-top:6px; font-size:12.5px; }

/* =====================================================================
   EXPORT PAGE (export.html) — print-first, screen-friendly too
   ===================================================================== */
.export-wrap{ max-width:720px; padding:48px 24px 80px; margin:0 auto; }
.export-cover{ text-align:center; padding:40px 0 32px; border-bottom:2px solid var(--accent); margin-bottom:32px; }
.export-cover-eyebrow{ font-family:var(--font-mono); font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--accent-deep); }
.export-cover-title{ font-family:var(--font-display); font-size:36px; margin:14px 0 8px; }
.export-cover-oneliner{ font-size:16px; color:var(--ink-muted); }
.export-cover-date{ font-size:12px; color:var(--frozen); margin-top:14px; }
.export-section{ margin-bottom:32px; page-break-inside:avoid; }
.export-section h2{ font-family:var(--font-display); font-size:20px; border-bottom:1px solid var(--line); padding-bottom:8px; margin-bottom:14px; }
.export-section p{ font-size:14px; line-height:1.7; margin-bottom:10px; }
.export-competitor{ margin-bottom:14px; }
.export-landing-page{
  border:1px solid var(--line); border-radius:12px; padding:28px; text-align:center; background:var(--surface);
}
.export-landing-page h1{ font-family:var(--font-display); font-size:24px; margin-bottom:10px; }
.export-landing-sub{ color:var(--ink-muted); margin-bottom:16px; }
.export-landing-page ul{ list-style:none; padding:0; margin-bottom:20px; }
.export-landing-page li{ padding:6px 0; font-size:14px; }
.export-landing-cta{
  display:inline-block; background:var(--accent); color:#FAF6F1; padding:10px 22px;
  border-radius:8px; font-weight:600; font-size:14px;
}
.export-footer{ text-align:center; font-size:12px; color:var(--frozen); margin-top:40px; }

.export-persona-page{
  page-break-after:always; padding:40px 0; border-bottom:1px dashed var(--line); margin-bottom:24px;
}
.export-persona-page:last-child{ page-break-after:auto; border-bottom:none; }
.export-persona-header{ display:flex; align-items:center; gap:16px; margin-bottom:24px; }
.export-persona-avatar{
  width:56px; height:56px; border-radius:50%; background:var(--accent); color:#FAF6F1;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-display); font-weight:600; font-size:20px; flex-shrink:0;
}
.export-persona-header h1{ font-family:var(--font-display); font-size:24px; margin:0; }
.export-persona-occupation{ color:var(--ink-muted); margin:2px 0 0; }
.export-persona-page h2{ font-size:15px; font-family:var(--font-mono); text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); margin:20px 0 6px; }
.export-persona-page p, .export-persona-page ul{ font-size:14px; line-height:1.7; }
.export-persona-page blockquote{
  font-family:var(--font-display); font-style:italic; font-size:17px; color:var(--accent-deep);
  border-left:3px solid var(--accent); padding-left:16px; margin:20px 0 0;
}

@media print{
  .no-print{ display:none !important; }
  body{ background:#fff; }
  .export-wrap{ max-width:100%; padding:0; }
  .export-section, .export-persona-page{ page-break-inside:avoid; }
}

/* =====================================================================
   PRO BLUEPRINT UPGRADE — richer generation hint, snapshots, and a
   genuinely different premium feel to the canvas itself for Pro users.
   ===================================================================== */

/* ---------- Rationale hint (Pro-only "why this fits" tooltip) ---------- */
.opt-rationale-dot{
  flex-shrink:0; font-size:10px; color:var(--accent); opacity:0.6; cursor:help;
  margin-left:2px; transition:opacity .15s ease;
}
.canvas-option:hover .opt-rationale-dot{ opacity:1; }

/* ---------- Snapshots button (canvas-controls cluster) ---------- */
.snapshots-btn{ font-size:15px; }
.pro-glow-btn{
  box-shadow:0 0 0 1px rgba(217,163,62,0.4), 0 0 10px rgba(217,163,62,0.25);
}

/* ---------- Snapshots modal ---------- */
.snapshots-modal-card{ max-width:480px; }
.snapshot-save-row{ display:flex; gap:8px; margin:14px 0 4px; }
.snapshot-save-row input{
  flex:1; font-family:var(--font-body); font-size:14px; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:10px 12px; outline:none;
}
.snapshot-save-row input:focus{ border-color:var(--accent); }
.snapshots-list{ max-height:280px; overflow-y:auto; margin-top:16px; display:flex; flex-direction:column; gap:8px; }
.snapshots-empty{ text-align:center; padding:20px 0; font-size:13px; }
.snapshot-row{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:10px 12px;
}
.snapshot-row-info{ min-width:0; }
.snapshot-row-name{ display:block; font-size:13.5px; font-weight:600; color:var(--ink); }
.snapshot-row-meta{ display:block; font-size:11.5px; color:var(--ink-muted); margin-top:2px; }
.snapshot-row-actions{ display:flex; gap:6px; flex-shrink:0; }
.snapshot-restore-btn{ font-size:12px; padding:7px 12px; }
.snapshot-delete-btn{ font-size:13px; padding:7px 10px; color:var(--ink-muted); }
.snapshot-delete-btn:hover{ color:#C24A3D; border-color:#C24A3D; }

/* ---------- Premium Pro canvas theme ----------
   A genuinely different feel for the workspace itself, not just a badge
   bolted on somewhere — a warm gold-tinted glow behind the dot-grid
   background and a subtle ring around the blueprint title, both purely
   additive on top of the existing canvas styling (nothing here overrides
   base colors, so a free-tier canvas is completely unaffected). */
.canvas-viewport.pro-canvas{
  background-image:
    radial-gradient(circle, var(--line) 1px, transparent 1.4px),
    radial-gradient(ellipse 900px 500px at 20% 15%, rgba(217,163,62,0.05), transparent 60%),
    radial-gradient(ellipse 700px 500px at 85% 80%, rgba(217,119,87,0.045), transparent 60%);
  background-size: 22px 22px, 100% 100%, 100% 100%;
}
.app-blueprint-title.pro-title{
  position:relative;
}
.app-blueprint-title.pro-title::after{
  content:'PRO';
  font-family:var(--font-mono); font-size:9px; font-weight:700; letter-spacing:.06em;
  color:#9A7320; background:rgba(217,163,62,0.16);
  padding:2px 5px; border-radius:4px; margin-left:8px; vertical-align:middle;
}





/* ---------- Show/hide password toggle ---------- */
.password-field-wrap{ position:relative; display:flex; }
.password-field-wrap .password-toggle-input{ flex:1; padding-right:44px !important; }
.password-toggle-btn{
  position:absolute; right:4px; top:50%; transform:translateY(-50%);
  background:none; border:none; font-size:16px; line-height:1; cursor:pointer;
  padding:8px; border-radius:6px; opacity:0.7;
}
.password-toggle-btn:hover{ opacity:1; background:var(--surface-2); }

/* ---------- Mobile dashboard header + pro-banner arrangement ---------- */
@media (max-width:640px){
  nav.bar{ padding:14px 16px; }
  .dashboard-main{ padding:32px 0 80px; }
  .dashboard-main h1{ margin-bottom:18px; font-size:22px; }

  .pro-banner{
    flex-direction:column; align-items:flex-start; gap:10px;
    padding:14px 16px; margin-bottom:24px;
  }
  .pro-banner .btn{ margin-left:0; width:100%; text-align:center; justify-content:center; }
}

/* ---------- Click-to-expand truncated canvas text ---------- */
/* Applied by setupTruncatedTextExpansion in script.js. Removes the
   2-line clamp entirely and lets the text wrap to however many lines
   it actually needs. Cursor stays a pointer so it's clear this text is
   interactive even before the first click. */
.canvas-group-title span,
.opt-label{ cursor:pointer; }
.canvas-group-title span.text-expanded,
.opt-label.text-expanded{
  -webkit-line-clamp:unset; display:block; overflow:visible;
}
/* The card containing an expanded label needs to render ABOVE its
   siblings — otherwise the now-taller content just gets visually
   clipped by whatever neighboring card happens to overlap it, which
   would make "click to see the full text" not actually show the full
   text. A stronger shadow also helps it read as "temporarily lifted
   out," not just a layout glitch. */
.canvas-group.card-popped{
  z-index:50; box-shadow:0 10px 28px rgba(0,0,0,0.18);
}

/* ---------- Pro features "See everything" modal ---------- */
.pro-more-btn{
  background:none; border:none; padding:0; margin:2px 0 14px; text-align:left;
  font-family:var(--font-body); font-size:12.5px; color:var(--accent-deep);
  cursor:pointer; text-decoration:underline;
}
.pro-more-btn:hover{ color:var(--accent); }
.pro-features-modal-card{ max-width:520px; max-height:85vh; overflow-y:auto; }
.pro-features-group{ margin:18px 0; }
.pro-features-group-label{
  font-family:var(--font-mono); font-size:11px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--ink-muted); margin-bottom:8px;
}
.pro-features-group ul{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:7px; }
.pro-features-group li{
  font-size:13.5px; color:var(--ink); line-height:1.5; padding-left:18px; position:relative;
}
.pro-features-group li::before{ content:"—"; position:absolute; left:0; color:var(--accent-deep); }
.pro-features-modal-actions{ justify-content:space-between; margin-top:22px; }

/* ---------- Checkout confirmation modal (username copy step) ---------- */
.checkout-confirmation-card{ max-width:440px; }
.checkout-username-display{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  background:var(--bg); border:1px solid var(--accent); border-radius:10px;
  padding:14px 16px; margin:14px 0;
}
.checkout-username-display span{
  font-family:var(--font-mono); font-size:16px; font-weight:600; color:var(--accent-deep);
  word-break:break-all;
}
.checkout-email-note{ font-size:12.5px; margin-bottom:6px; }

/* ---------- Stolen competitive edges (Spy Mode -> Build Brief) ---------- */
.stolen-edges-block{ border-color:var(--accent); }
.stolen-edges-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.stolen-edges-list li{ font-size:13.5px; line-height:1.5; }
.stolen-edge-source{ font-size:11.5px; color:var(--ink-muted); font-style:italic; }

/* ---------- Flash highlight (draws the eye to a section that just updated off-screen) ---------- */
@keyframes flashHighlight{
  0%{ box-shadow:0 0 0 3px var(--accent); }
  100%{ box-shadow:0 0 0 0 transparent; }
}
.flash-highlight{ animation:flashHighlight 2s ease-out; border-radius:14px; }

/* ---------- Expanded landing page copy sections ---------- */
.lc-how-it-works{ margin:0; padding-left:20px; display:flex; flex-direction:column; gap:6px; }
.lc-how-it-works li{ font-size:13.5px; line-height:1.5; }
.lc-faq{ display:flex; flex-direction:column; gap:12px; }
.lc-faq-item{ background:var(--bg); border-radius:8px; padding:10px 12px; }
.lc-faq-question{ font-weight:600; font-size:13.5px; margin:0 0 4px; }
.lc-faq-answer{ font-size:13px; color:var(--ink-muted); margin:0; line-height:1.5; }
.lc-footer-cta{ font-family:var(--font-display); font-style:italic; font-size:15px; color:var(--accent-deep); }

/* ---------- Landing copy per-section copy buttons + Carrd explainer ---------- */
.lc-section-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:6px; }
.lc-section-head .lbl{ margin-bottom:0; }
.lc-copy-btn{
  background:none; border:1px solid var(--line); border-radius:6px;
  font-size:11px; font-family:var(--font-mono); color:var(--ink-muted);
  padding:3px 9px; cursor:pointer; flex-shrink:0;
}
.lc-copy-btn:hover{ border-color:var(--accent); color:var(--accent-deep); }
.lc-carrd-explainer{ font-size:12px; margin-top:10px; line-height:1.5; }

/* =====================================================================
   GUIDED TOURS — spotlight + coach-mark caption system
   ===================================================================== */
.tour-spotlight{
  z-index:10000 !important;
  box-shadow:0 0 0 4px var(--accent) !important;
  border-radius:inherit;
  animation:tourPulseGlow 1.5s ease-in-out infinite;
}
@keyframes tourPulseGlow{
  0%, 100%{ box-shadow:0 0 0 4px var(--accent), 0 0 14px 2px rgba(217,119,87,0.45) !important; }
  50%{ box-shadow:0 0 0 5px var(--accent), 0 0 26px 6px rgba(217,119,87,0.75) !important; }
}
/* Only applied via JS, and only when the target's own computed position
   is 'static' (the default — meaning it has no positioning of its own
   yet) — a truly static element needs SOME position value for the
   z-index/box-shadow spotlight to actually take effect at all. Anything
   that already has fixed/absolute/relative positioning (like
   .canvas-controls, deliberately anchored to a screen corner) keeps
   its own position completely untouched. */
.tour-needs-position{ position:relative; }
.tour-caption{
  position:fixed; z-index:10001; max-width:340px;
  background:var(--surface); border:2px solid var(--accent); border-radius:14px;
  padding:18px 20px; box-shadow:0 12px 36px rgba(0,0,0,0.35);
}
.tour-caption-centered{
  max-width:380px; text-align:center;
}
.tour-caption-progress{
  font-family:var(--font-mono); font-size:11px; text-transform:uppercase;
  letter-spacing:.05em; color:var(--accent-deep); margin-bottom:8px;
}
.tour-caption h4{ font-size:16px; margin-bottom:6px; }
.tour-caption p{ font-size:13.5px; line-height:1.55; color:var(--ink); margin-bottom:14px; }
.tour-caption-actions{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
.tour-skip-btn{
  background:none; border:none; font-size:12px; color:var(--ink-muted);
  cursor:pointer; text-decoration:underline; padding:0;
}
.tour-skip-btn:hover{ color:var(--ink); }
.tour-nav-btns{ display:flex; gap:8px; }
.tour-nav-btns .btn{ padding:8px 16px; font-size:13px; }

/* ---------- Toolkit tour header + reopen button ---------- */
.idea-toolkit-header-row{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-bottom:4px;
}
.toolkit-tour-reopen-btn{ font-size:12.5px; padding:8px 14px; white-space:nowrap; flex-shrink:0; }

@media (max-width:640px){
  .tour-caption{ max-width:calc(100vw - 32px); }
}

/* =====================================================================
   TOUR DEMONSTRATION SYSTEM — ghost cursor + click ripple
   The actual "show, don't tell" layer: an animated cursor moves across
   real page elements, clicks them (ripple), and cards visibly react
   (a brief press/select state) — genuinely demonstrating the gesture
   on the live page, not narrating it in a caption alone.
   ===================================================================== */
.tour-ghost-cursor{
  position:fixed; z-index:10002; width:22px; height:22px;
  margin-left:-4px; margin-top:-2px;
  pointer-events:none; opacity:0;
  transition:left .6s cubic-bezier(.4,0,.2,1), top .6s cubic-bezier(.4,0,.2,1);
}
.tour-ghost-cursor::before{
  content:'';
  display:block; width:100%; height:100%;
  background:var(--ink);
  clip-path:polygon(0 0, 0 70%, 25% 55%, 40% 90%, 55% 84%, 40% 50%, 70% 50%);
  filter:drop-shadow(0 2px 4px rgba(0,0,0,0.35));
}
.tour-ghost-cursor.tour-cursor-grabbing::before{
  background:var(--accent-deep);
}

.tour-click-ripple{
  position:fixed; z-index:10001; width:14px; height:14px; margin:-7px;
  border-radius:50%; border:2px solid var(--accent);
  pointer-events:none;
  animation:tourRippleExpand .65s ease-out forwards;
}
@keyframes tourRippleExpand{
  0%{ transform:scale(0.4); opacity:0.9; }
  100%{ transform:scale(3.2); opacity:0; }
}

.tour-ctrl-badge{
  position:fixed; z-index:10002; pointer-events:none;
  background:var(--ink); color:var(--surface);
  font-family:var(--font-mono); font-size:10px; font-weight:600;
  padding:3px 8px; border-radius:5px;
  transition:left .6s ease, top .6s ease;
}

.tour-demo-pressed{
  transform:scale(0.94) !important;
  transition:transform .12s ease !important;
}
.tour-demo-selected{
  outline:2px solid var(--accent) !important;
  outline-offset:2px;
  background:rgba(217,119,87,0.08) !important;
}

.tour-drag-line{
  position:fixed; z-index:10001; height:0;
  border-top:2px dashed var(--accent-deep);
  transform-origin:0 50%;
  pointer-events:none;
}

.tour-connector-line{
  position:fixed; z-index:9999; height:0;
  border-top:2px dashed var(--accent);
  opacity:0.6;
  transform-origin:0 50%;
  pointer-events:none;
}

.tour-mandatory-note{
  font-size:11.5px !important; color:var(--ink-muted) !important;
  font-style:italic; margin-top:-6px !important; margin-bottom:14px !important;
}

/* ---------- Pricing page one-time-payment notes ---------- */
.pricing-subhead{ font-size:13px; margin-top:6px; max-width:520px; }
.pricing-expiry-note{ font-size:12.5px; text-align:center; margin-top:20px; }

/* ---------- Dashboard/settings "manage plan" modal ---------- */
.modal-plan-card{ margin:0; }
.modal-plan-expiry-note{ font-size:12px; text-align:center; margin-bottom:16px; }
.pro-features-expiry-note{ font-size:12px; margin:14px 0; }

/* ---------- Canvas reset button ---------- */
.reset-blueprint-btn{ font-size:16px; }
.reset-blueprint-btn.reset-btn-targeted{
  background:var(--accent); color:#FAF6F1; border-color:var(--accent);
}

/* The group currently selected as the Reset target — same accent
   treatment already used elsewhere on the canvas for "this is the thing
   an action will apply to" (matches the tour spotlight's own color),
   so it reads consistently rather than introducing a new visual language. */
.canvas-group.reset-target-selected{
  outline:2px solid var(--accent);
  outline-offset:2px;
  box-shadow:0 0 0 5px rgba(217,119,87,0.15);
}
.canvas-group.reset-target-selected .canvas-group-title{ cursor:pointer; }

/* ---------- Paste-idea FAB (stacked above the feedback FAB) ---------- */
.paste-idea-fab{
  bottom:86px; /* feedback-fab's 24px + its own 52px + a real gap */
  text-decoration:none;
  background:var(--ink);
}
.paste-idea-fab:hover{ background:#3A342C; }
@media (hover:none) and (pointer:coarse){
  .paste-idea-fab{ bottom:86px; right:18px; }
}

/* ---------- Paste Your Own Idea page ---------- */
.paste-idea-wrap{ max-width:640px; }
.pro-gate-block{
  text-align:center; padding:32px 20px;
  display:flex; flex-direction:column; align-items:center; gap:10px;
}
.pro-gate-block .ptag{ margin-bottom:4px; }
.pro-gate-block h3{ font-size:20px; }
.pro-gate-block p{ max-width:420px; margin-bottom:8px; }
.paste-idea-label{
  display:block; font-family:var(--font-mono); font-size:11px;
  text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted);
  margin-bottom:8px;
}
.paste-idea-textarea{
  width:100%; min-height:220px; resize:vertical;
  padding:14px 16px; border:1px solid var(--line); border-radius:10px;
  background:var(--surface); font-family:var(--font-body); font-size:14.5px;
  line-height:1.6; color:var(--ink);
}
.paste-idea-textarea:focus{ outline:none; border-color:var(--accent); }
.paste-idea-char-count{
  text-align:right; font-family:var(--font-mono); font-size:11px;
  color:var(--ink-muted); margin-top:6px; margin-bottom:22px;
}
.paste-idea-mode-choice{ display:flex; flex-direction:column; gap:10px; margin-bottom:20px; }
.paste-idea-mode-option{
  display:flex; align-items:flex-start; gap:12px; padding:14px 16px;
  border:1px solid var(--line); border-radius:10px; cursor:pointer;
  transition:border-color .15s ease, background .15s ease;
}
.paste-idea-mode-option:has(input:checked){
  border-color:var(--accent); background:rgba(217,119,87,0.06);
}
.paste-idea-mode-option input[type="radio"]{ margin-top:3px; flex-shrink:0; accent-color:var(--accent); }
.paste-idea-mode-option strong{ font-size:14px; display:block; margin-bottom:3px; }
.paste-idea-mode-option p{ margin:0; font-size:12.5px; }
.paste-idea-submit-btn{ width:100%; }
