/* ============================================================
   <PricingEstimator /> — "the bill" as an agent that plans.

   Ask two questions, then run an AgentPlanning-style timeline:
   expandable steps with durations, rich detail panels, status
   icons (pending → active → success) and a final "estimate
   ready" step that reveals the stack + indicative price.
   ============================================================ */

const AIEST_TYPES = ["Mobile app", "Web app", "AI product"];
const AIEST_STAGES = ["Just an idea", "MVP / v1", "Scaling up"];
const AIEST_STACK = {
  "Mobile app": ["Flutter", "Swift", "Kotlin", "Firebase", "Node"],
  "Web app": ["Next.js", "React", "TypeScript", "Postgres", "Vercel"],
  "AI product": ["Python", "Claude", "RAG", "pgvector", "FastAPI"],
};
const AIEST_STAGE = {
  "Just an idea": { team: 2, weeks: 8, weeksLabel: "6–10", milestones: "2–3" },
  "MVP / v1": { team: 3, weeks: 12, weeksLabel: "10–16", milestones: "3–5" },
  "Scaling up": { team: 4, weeks: 20, weeksLabel: "16–28", milestones: "5–8" },
};
const AIEST_URGENCY = { "No rush": 0.95, "This quarter": 1.0, "ASAP": 1.12 };
const AIEST_DESIGN = { "Design from scratch": 8000, "We have designs": 0 };
const AIEST_NICHE = ["Fintech", "Health", "Commerce", "Social", "Logistics", "Productivity", "Other"];
const AIEST_STYLE = ["Minimal", "Bold", "Playful", "Premium", "Editorial"];
const AIEST_PALETTES = [
  { name: "Aurora", colors: ["#0088ff", "#7c5cff", "#0a0e27"] },
  { name: "Coral", colors: ["#f73b20", "#ffb764", "#fff5f3"] },
  { name: "Forest", colors: ["#16c253", "#0a5f3a", "#f0fff7"] },
  { name: "Mono", colors: ["#111111", "#888888", "#f5f5f5"] },
  { name: "Sunset", colors: ["#ff5a5f", "#ffb400", "#3a0ca3"] },
];
// maps a stack entry to its Simple Icons slug (same source as the Technologies screen)
const TECH_LOGO = {
  Flutter: "flutter", Swift: "swift", Kotlin: "kotlin", Firebase: "firebase", Node: "nodedotjs",
  "Next.js": "nextdotjs", React: "react", TypeScript: "typescript", Postgres: "postgresql", Vercel: "vercel",
  Python: "python", Claude: "claude", FastAPI: "fastapi",
};

const AIEST_CSS = `
.aiest-section .aiest { max-width: 1040px; margin: 0 auto; }
.aiest-card {
  background: var(--paper-2, #fff);
  border: 1px solid var(--line, rgba(0,0,0,.1));
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 18px 48px -28px rgba(0,0,0,.4);
}
.aiest-hd {
  display: flex; align-items: center; gap: 12px; padding: 16px 22px;
  background: color-mix(in oklab, var(--ink, #111) 4%, transparent);
  border-bottom: 1px solid var(--line, rgba(0,0,0,.08));
  cursor: pointer; user-select: none;
}
.aiest-hd__ic { width: 22px; height: 22px; display: grid; place-items: center; }
.aiest-hd__t { font-weight: 600; font-size: 16px; letter-spacing: -.01em; color: var(--ink, #111); }
.aiest-hd__status { margin-left: auto; font: 400 12.5px/1 var(--font-mono, ui-monospace); color: var(--ink-mute, #888); }
.aiest-prog { height: 3px; background: color-mix(in oklab, var(--ink,#111) 6%, transparent); }
.aiest-prog span { display: block; height: 100%; width: 0; border-radius: 0 3px 3px 0; background: linear-gradient(90deg, var(--accent,#6d5efc), color-mix(in oklab, var(--accent,#6d5efc) 55%, #10b981)); transition: width .55s var(--ease, ease); }
.aiest-hd__chev { color: var(--ink-mute, #999); display: grid; place-items: center; transition: transform .3s var(--ease, ease); }
.aiest-card.is-collapsed .aiest-hd__chev { transform: rotate(-90deg); }
.aiest-wrap { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .4s var(--ease, ease); }
.aiest-card.is-collapsed .aiest-wrap { grid-template-rows: 0fr; }
.aiest-wrap > div { overflow: hidden; min-height: 0; }
.aiest-body { padding: 26px 24px; }

/* ---- form ---- */
.aiest-q { margin-bottom: 22px; }
.aiest-q__l { font-size: 15px; letter-spacing: -.01em; color: var(--ink-soft, #555); margin-bottom: 11px; }
.aiest-seg { display: flex; gap: 8px; flex-wrap: wrap; }
.aiest-opt {
  font: 500 15px/1 var(--font-sans, system-ui); letter-spacing: -.01em; white-space: nowrap;
  color: var(--ink-soft, #555); background: color-mix(in oklab, var(--ink, #111) 4%, transparent);
  border: 1px solid var(--line, rgba(0,0,0,.12)); border-radius: 11px; padding: 13px 18px; cursor: pointer;
  transition: color .18s, border-color .18s, background .18s, transform .12s;
}
.aiest-opt:hover { color: var(--ink, #111); border-color: var(--line-strong, rgba(0,0,0,.25)); transform: translateY(-1px); }
.aiest-opt:active { transform: translateY(0) scale(.98); }
.aiest-opt.is-on {
  color: var(--ink, #111); border-color: var(--accent, #6d5efc);
  box-shadow: inset 0 0 0 1px var(--accent, #6d5efc);
  background: color-mix(in oklab, var(--accent, #6d5efc) 12%, transparent);
}
.aiest-toggle { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 15px; color: var(--ink-soft, #555); }
.aiest-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.aiest-toggle__box { width: 20px; height: 20px; border-radius: 6px; flex: none; border: 1px solid var(--line-strong, rgba(0,0,0,.25)); display: grid; place-items: center; color: #fff; transition: background .15s, border-color .15s; }
.aiest-toggle input:checked + .aiest-toggle__box { background: var(--accent, #6d5efc); border-color: var(--accent, #6d5efc); }
.aiest-toggle__box svg { opacity: 0; transition: opacity .15s; }
.aiest-toggle input:checked + .aiest-toggle__box svg { opacity: 1; }
.aiest-run { margin-top: 22px; }
.aiest-run[disabled] { opacity: .5; pointer-events: none; }

/* ---- timeline ---- */
.aiplan { display: flex; flex-direction: column; }
.aiplan-step { position: relative; display: flex; gap: 14px; transition: opacity .4s; }
.aiplan-step--pending { opacity: .5; }
.aiplan-step__line { position: absolute; left: 12px; top: 28px; bottom: -6px; width: 2px; background: var(--line, rgba(0,0,0,.14)); z-index: 0; }
.aiplan-step__ic { position: relative; z-index: 1; flex: none; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; box-shadow: 0 0 0 4px var(--paper-2, #fff); transition: background .3s, color .3s; }
.aiic--pending { background: color-mix(in oklab, var(--ink,#111) 8%, transparent); color: var(--ink-mute, #999); }
.aiic--active { background: color-mix(in oklab, var(--accent,#6d5efc) 16%, transparent); color: var(--accent, #6d5efc); animation: aiest-pulse 1.5s ease-in-out infinite; }
@keyframes aiest-pulse { 0%,100% { box-shadow: 0 0 0 4px var(--paper-2,#fff), 0 0 0 0 rgba(109,94,252,.35); } 50% { box-shadow: 0 0 0 4px var(--paper-2,#fff), 0 0 0 8px rgba(109,94,252,0); } }
@media (prefers-reduced-motion: reduce) { .aiic--active { animation: none; } }
.aiic--success { background: rgba(16,185,129,.16); color: #10b981; }
.aiplan-step__body { flex: 1; min-width: 0; padding-bottom: 14px; }
.aiplan-step__hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: -4px -6px 0; padding: 4px 6px; border-radius: 7px; transition: background .18s; }
.aiplan-step--has-content .aiplan-step__hd { cursor: pointer; }
.aiplan-step--has-content .aiplan-step__hd:hover { background: color-mix(in oklab, var(--ink,#111) 4%, transparent); }
.aiplan-step__t { font-size: 15.5px; font-weight: 500; letter-spacing: -.01em; color: var(--ink-soft, #555); }
.aiplan-step--active .aiplan-step__t { color: var(--ink, #111); font-weight: 600; }
.aiplan-step__meta { display: flex; align-items: center; gap: 12px; flex: none; }
.aiplan-step__dur { font: 400 12px/1 var(--font-mono, ui-monospace); color: var(--ink-mute, #888); font-variant-numeric: tabular-nums; }
.aiplan-step__chev { color: var(--ink-mute, #aaa); display: grid; place-items: center; transition: transform .3s var(--ease, ease); }
.aiplan-step.is-open .aiplan-step__chev { transform: rotate(90deg); }
.aiplan-step__panel { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .4s var(--ease, ease), opacity .3s, margin .3s; }
.aiplan-step.is-open .aiplan-step__panel { grid-template-rows: 1fr; opacity: 1; margin-top: 8px; }
.aiplan-step__panel > div { overflow: hidden; min-width: 0; }

/* ---- rich content ---- */
.aimono { font: 400 12.5px/1.6 var(--font-mono, ui-monospace); }
.aikv { display: grid; grid-template-columns: 118px 1fr; gap: 8px 12px; padding: 14px 15px; border-radius: 8px; background: color-mix(in oklab, var(--ink,#111) 4%, transparent); border: 1px solid var(--line, rgba(0,0,0,.08)); }
.aikv dt { color: var(--ink-mute, #888); font-weight: 500; }
.aikv dd { margin: 0; color: var(--ink, #111); }
.aikv dd.warn { color: #d97706; }
.aitool { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border-radius: 6px; font-weight: 600; background: color-mix(in oklab, var(--accent,#6d5efc) 12%, transparent); color: var(--accent, #6d5efc); border: 1px solid color-mix(in oklab, var(--accent,#6d5efc) 28%, transparent); }
.aipanel { padding: 14px 15px; border-radius: 8px; background: color-mix(in oklab, var(--ink,#111) 3%, transparent); border: 1px solid var(--line, rgba(0,0,0,.08)); color: var(--ink-soft, #555); }
.aipanel__ok { color: #059669; font-weight: 600; margin-bottom: 6px; display: flex; align-items: center; gap: 5px; }
.aipanel ul { margin: 0; padding-left: 16px; display: flex; flex-direction: column; gap: 4px; }
.airow { display: flex; align-items: center; justify-content: space-between; }
.airow + .airow { margin-top: 6px; }
.airow strong { color: var(--ink, #111); font-variant-numeric: tabular-nums; }

/* ---- final result ---- */
.aiest-res__k { font: 600 12px/1 var(--font-mono, ui-monospace); letter-spacing: .12em; text-transform: uppercase; color: var(--accent, #6d5efc); }
.aiest-res__stack { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 20px; }
.aiest-chip { font: 500 14px/1 var(--font-sans, system-ui); letter-spacing: -.01em; color: var(--ink, #111); background: color-mix(in oklab, var(--ink,#111) 5%, transparent); border: 1px solid var(--line, rgba(0,0,0,.12)); border-radius: 9px; padding: 10px 13px; transition: transform .12s, border-color .18s; }
.aiest-chip:hover { transform: translateY(-2px); border-color: color-mix(in oklab, var(--accent,#6d5efc) 40%, transparent); }
.aiest-res__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.aiest-stat { background: color-mix(in oklab, var(--accent,#6d5efc) 6%, transparent); border: 1px solid color-mix(in oklab, var(--accent,#6d5efc) 18%, transparent); border-radius: 12px; padding: 15px 16px; }
.aiest-stat__l { font: 400 12.5px/1 var(--font-mono, ui-monospace); color: var(--ink-mute, #888); }
.aiest-stat__v { margin-top: 9px; font-weight: 600; font-size: 31px; letter-spacing: -.035em; color: var(--ink, #111); }
.aiest-stat__v .ac { color: var(--accent, #6d5efc); }
.aiest-stat__v small { font-size: 13.5px; color: var(--ink-mute, #888); font-weight: 500; letter-spacing: -.01em; }
.aiest-res__ft { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }

.aiest-spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent; display: inline-block; animation: aiest-spin .7s linear infinite; }
@keyframes aiest-spin { to { transform: rotate(360deg); } }
.aiest-chip { display: inline-flex; align-items: center; gap: 7px; }
.aiest-chip__logo { width: 16px; height: 16px; display: block; flex: none; }
.aiest-wiz__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.aiest-wiz__count { font: 500 12.5px/1 var(--font-mono, ui-monospace); color: var(--ink-mute,#888); }
.aiest-wiz__count i { font-style: normal; opacity: .55; }
.aiest-dots { display: flex; gap: 7px; }
.aiest-dot { width: 7px; height: 7px; border-radius: 50%; background: color-mix(in oklab, var(--ink,#111) 14%, transparent); transition: background .3s, transform .3s; }
.aiest-dot.is-done { background: #10b981; }
.aiest-dot.is-on { background: var(--accent,#6d5efc); transform: scale(1.3); }
.aiest-wiz__q { animation: aiest-qin .35s var(--ease, ease) both; min-height: 116px; }
@keyframes aiest-qin { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.aiest-wiz__l { font-size: 20px; font-weight: 600; letter-spacing: -.025em; color: var(--ink,#111); margin-bottom: 18px; }
.aiest-input { width: 100%; box-sizing: border-box; font: 500 17px/1.3 var(--font-sans, system-ui); color: var(--ink,#111); background: color-mix(in oklab, var(--ink,#111) 3%, transparent); border: 1px solid var(--line-strong, rgba(0,0,0,.2)); border-radius: 11px; padding: 14px 16px; outline: none; transition: border-color .18s, box-shadow .18s; }
.aiest-input:focus { border-color: var(--accent,#6d5efc); box-shadow: inset 0 0 0 1px var(--accent,#6d5efc); }
.aiest-swatches { display: flex; flex-wrap: wrap; gap: 12px; }
.aiest-swatch { display: flex; flex-direction: column; gap: 9px; padding: 11px; border: 1px solid var(--line, rgba(0,0,0,.12)); border-radius: 13px; cursor: pointer; background: transparent; transition: border-color .18s, transform .12s; }
.aiest-swatch:hover { transform: translateY(-2px); border-color: var(--line-strong, rgba(0,0,0,.25)); }
.aiest-swatch.is-on { border-color: var(--accent,#6d5efc); box-shadow: inset 0 0 0 1px var(--accent,#6d5efc); }
.aiest-swatch__row { display: flex; border-radius: 8px; overflow: hidden; width: 120px; height: 38px; }
.aiest-swatch__row span { flex: 1; }
.aiest-swatch__name { font: 500 12.5px/1 var(--font-sans, system-ui); color: var(--ink-soft,#555); text-align: center; }
.aiest-wiz__nav { display: flex; gap: 10px; margin-top: 26px; }
.aiest-wiz__nav .aiest-run { margin-left: auto; margin-top: 0; }
.aiplan-step--active .aiplan-step__t {
  background: linear-gradient(90deg, var(--ink-mute,#999) 18%, var(--ink,#111) 38%, var(--accent,#6d5efc) 50%, var(--ink,#111) 62%, var(--ink-mute,#999) 82%);
  background-size: 200% 100%; -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: aiest-shimmer 1.8s linear infinite;
}
@keyframes aiest-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.aiplan-step--active .aiplan-step__d { position: relative; overflow: hidden; }
.aiplan-step--active .aiplan-step__d::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--paper-2,#fff) 70%, transparent), transparent);
  transform: translateX(-100%); animation: aiest-sweep 1.5s ease-in-out infinite;
}
@keyframes aiest-sweep { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .aiplan-step--active .aiplan-step__t { animation: none; -webkit-text-fill-color: var(--ink,#111); color: var(--ink,#111); }
  .aiplan-step--active .aiplan-step__d::after { animation: none; }
}
@media (prefers-reduced-motion: reduce) { .aiest-spin { animation-duration: 1.4s; } }
@media (max-width: 560px) { .aiest-res__grid { grid-template-columns: 1fr; } .aikv { grid-template-columns: 80px 1fr; } }
`;

const AiSpin = () => <span className="aiest-spin" aria-hidden="true"></span>;
const AiCheck = ({ s = 14 }) => <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12l4 4 9-10" /></svg>;
const AiBrain = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5a3 3 0 0 0-5.6-1.5A3 3 0 0 0 4 8.5 3 3 0 0 0 6 13M12 5a3 3 0 0 1 5.6-1.5A3 3 0 0 1 20 8.5 3 3 0 0 1 18 13M12 5v14M6 13a3 3 0 0 0 6 0M18 13a3 3 0 0 1-6 0M8 19a2.5 2.5 0 0 0 4 0 2.5 2.5 0 0 0 4 0" /></svg>;
const AiChev = () => <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 6l6 6-6 6" /></svg>;
const AiChevD = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6" /></svg>;

const aiFmt = (n) => "$" + n.toLocaleString();
const aiFmtK = (n) => (n >= 1_000_000 ? "$" + (n / 1_000_000).toFixed(1) + "M" : "$" + Math.round(n / 1000) + "k");

function aiEstimate(type, stage, maintenance, urgency, design) {
  const cfg = AIEST_STAGE[stage];
  const RATE = 8500, DISCOVERY = 12000, RETAINER = 18000;
  const mult = type === "AI product" ? 1.2 : 1.0;
  const uMult = AIEST_URGENCY[urgency] ?? 1;
  const discovery = DISCOVERY + (AIEST_DESIGN[design] ?? 0);
  const build = Math.round((cfg.team * cfg.weeks * RATE * mult * uMult) / 1000) * 1000;
  const maint = maintenance ? RETAINER * 6 : 0;
  const total = discovery + build + maint;
  const low = Math.round((total * 0.85) / 1000) * 1000;
  const high = Math.round((total * 1.15) / 1000) * 1000;
  return { stack: AIEST_STACK[type], priceLabel: `${aiFmtK(low)}–${aiFmtK(high)}`, weeks: cfg.weeksLabel, team: cfg.team, milestones: cfg.milestones, discovery, build, maint };
}

function TechChip({ name }) {
  const slug = TECH_LOGO[name];
  const [bad, setBad] = React.useState(false);
  return (
    <span className="aiest-chip">
      {slug && !bad && <img className="aiest-chip__logo" src={`https://cdn.simpleicons.org/${slug}`} alt="" loading="lazy" onError={() => setBad(true)} />}
      {name}
    </span>
  );
}

function PricingEstimator() {
  const [type, setType] = React.useState(null);
  const [stage, setStage] = React.useState(null);
  const [maintenance, setMaintenance] = React.useState(true);
  const [urgency, setUrgency] = React.useState("This quarter");
  const [design, setDesign] = React.useState("Design from scratch");
  const [name, setName] = React.useState("");
  const [niche, setNiche] = React.useState(null);
  const [palette, setPalette] = React.useState(null);
  const [styleAns, setStyleAns] = React.useState(null);
  const [step, setStep] = React.useState(0);
  const [phase, setPhase] = React.useState("form"); // form | running | done
  const [done, setDone] = React.useState(0);
  const [collapsed, setCollapsed] = React.useState(false);
  const [open, setOpen] = React.useState({});
  const runId = React.useRef(0);

  const start = () => {
    if (!type || !stage) return;
    const id = ++runId.current;
    setPhase("running"); setDone(0); setOpen({ 0: true });
    let i = 0;
    const tick = () => {
      if (id !== runId.current) return;
      i += 1; setDone(i);
      setOpen((o) => ({ ...o, [i - 1]: false, [Math.min(i, 4)]: true }));
      if (i < 5) setTimeout(tick, 1650);
      else setPhase("done");
    };
    setTimeout(tick, 1200);
  };
  const reset = () => { runId.current++; setPhase("form"); setDone(0); setOpen({}); setStep(0); };
  const toggle = (i) => setOpen((o) => ({ ...o, [i]: !o[i] }));

  const r = type && stage ? aiEstimate(type, stage, maintenance, urgency, design) : null;
  const statusText = phase === "form" ? "awaiting input" : phase === "running" ? "studying your answers…" : "estimate ready";

  const STEPS = r ? [
    {
      title: "Reading your brief", duration: "0.9s",
      content: (
        <dl className="aikv aimono">
          <dt>App</dt><dd>{name || "Untitled"}</dd>
          <dt>Niche</dt><dd>{niche || "—"}</dd>
          <dt>Type</dt><dd>{type}</dd>
          <dt>Stage</dt><dd>{stage}</dd>
          <dt>Palette</dt><dd>{palette || "—"}</dd>
          <dt>Style</dt><dd>{styleAns || "—"}</dd>
          <dt>Maintenance</dt><dd className={maintenance ? "" : "warn"}>{maintenance ? "6-month retainer" : "Not included"}</dd>
        </dl>
      ),
    },
    {
      title: "Matching the Innoveev stack", duration: "2.3s",
      content: (
        <div className="aimono" style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8, color: "var(--ink-mute,#888)" }}>
            Running tool: <span className="aitool"><AiCheck s={11} /> stack_match</span>
          </div>
          <div className="aipanel">
            <div className="aipanel__ok"><AiCheck s={12} /> Best-fit stack for a {type.toLowerCase()}</div>
            <ul>{r.stack.map((s) => <li key={s}>{s}</li>)}</ul>
          </div>
        </div>
      ),
    },
    {
      title: "Sizing the squad & milestones", duration: "1.9s",
      content: (
        <div className="aipanel aimono">
          <div className="airow"><span>Senior squad</span><strong>{r.team} engineers + PM + design</strong></div>
          <div className="airow"><span>Delivery window</span><strong>{r.weeks} weeks</strong></div>
          <div className="airow"><span>Milestones</span><strong>{r.milestones}</strong></div>
        </div>
      ),
    },
    {
      title: "Pricing the engagement", duration: "1.4s",
      content: (
        <div className="aipanel aimono">
          <div className="airow"><span>Discovery sprint</span><strong>{aiFmt(r.discovery)}</strong></div>
          <div className="airow"><span>Build phase ({r.team} eng)</span><strong>{aiFmt(r.build)}</strong></div>
          {r.maint > 0 && <div className="airow"><span>Maintenance (6 mo)</span><strong>{aiFmt(r.maint)}</strong></div>}
        </div>
      ),
    },
    {
      title: "Estimate ready", duration: null, final: true,
      content: (
        <div className="aiest-res">
          <div className="aiest-res__k">Recommended stack</div>
          <div className="aiest-res__stack">{r.stack.map((s) => <TechChip key={s} name={s} />)}</div>
          <div className="aiest-res__grid">
            <div className="aiest-stat">
              <div className="aiest-stat__l">Indicative price</div>
              <div className="aiest-stat__v"><span className="ac">{r.priceLabel}</span></div>
            </div>
            <div className="aiest-stat">
              <div className="aiest-stat__l">Timeline</div>
              <div className="aiest-stat__v">{r.weeks} <small>wks · {r.milestones} milestones</small></div>
            </div>
          </div>
          <div className="aiest-res__ft">
            <a href="contact.html" className="btn btn--primary">Get a firm quote <Arrow /></a>
            <button type="button" className="btn btn--secondary" onClick={reset}>Re-estimate</button>
          </div>
        </div>
      ),
    },
  ] : [];

  const headIcon = phase === "running" ? <span style={{ color: "var(--accent,#6d5efc)" }}><AiSpin /></span>
    : phase === "done" ? <span style={{ color: "#10b981" }}><AiCheck s={16} /></span>
    : <span style={{ color: "var(--accent,#6d5efc)" }}><AiBrain /></span>;

  return (
    <section className="section section--tight aiest-section">
      <style>{AIEST_CSS}</style>
      <div className="container">
        <div className="section-head">
          <div>
            <span className="eyebrow">Estimator · AI-assisted</span>
            <h2 className="h2 section-head__title">Answer a few questions. <em>See the bill.</em></h2>
          </div>
          <p className="lede section-head__lede">
            Tell us what you're building and how far along you are. Our estimator studies it live, then
            proposes a stack and an indicative price — firmed up after a 2-week discovery.
          </p>
        </div>

        <div className="aiest">
          <div className={`aiest-card ${collapsed ? "is-collapsed" : ""}`}>
            <div className="aiest-hd" onClick={() => phase !== "form" && setCollapsed((c) => !c)}>
              <span className="aiest-hd__ic">{headIcon}</span>
              <span className="aiest-hd__t">{phase === "done" ? "Here's our estimate" : "Innoveev AI"}</span>
              <span className="aiest-hd__status">{statusText}</span>
              {phase !== "form" && <span className="aiest-hd__chev"><AiChevD /></span>}
            </div>
            {phase !== "form" && <div className="aiest-prog"><span style={{ width: `${(done / 5) * 100}%` }}></span></div>}

            <div className="aiest-wrap">
              <div>
                <div className="aiest-body">
                  {phase === "form" && (() => {
                    const WQ = [
                      { key: "name", q: "What's the app called?", kind: "text" },
                      { key: "niche", q: "What's the niche?", kind: "chips", opts: AIEST_NICHE },
                      { key: "type", q: "What type of app is it?", kind: "chips", opts: AIEST_TYPES },
                      { key: "stage", q: "How far along are you?", kind: "chips", opts: AIEST_STAGES },
                      { key: "palette", q: "Pick a colour direction", kind: "swatch", opts: AIEST_PALETTES },
                      { key: "style", q: "What's the visual style?", kind: "chips", opts: AIEST_STYLE },
                      { key: "review", q: "One last thing", kind: "review" },
                    ];
                    const FIELD = { name: [name, setName], niche: [niche, setNiche], type: [type, setType], stage: [stage, setStage], palette: [palette, setPalette], style: [styleAns, setStyleAns] };
                    const cur = WQ[step];
                    const cv = cur.key === "review" ? true : FIELD[cur.key][0];
                    const canNext = cur.kind === "text" ? !!(cv && cv.trim()) : cur.kind === "review" ? true : !!cv;
                    const isLast = step === WQ.length - 1;
                    return (
                      <div className="aiest-form">
                        <div className="aiest-wiz__top">
                          <span className="aiest-wiz__count">Question {step + 1} <i>/ {WQ.length}</i></span>
                          <div className="aiest-dots">{WQ.map((_, i) => <span key={i} className={`aiest-dot ${i === step ? "is-on" : ""} ${i < step ? "is-done" : ""}`}></span>)}</div>
                        </div>
                        <div className="aiest-wiz__q" key={step}>
                          <div className="aiest-wiz__l">{cur.q}</div>
                          {cur.kind === "text" && (
                            <input className="aiest-input" type="text" autoFocus value={name || ""} placeholder="e.g. LedgerFlow"
                              onChange={(e) => setName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && canNext) setStep((s) => s + 1); }} />
                          )}
                          {cur.kind === "chips" && (
                            <div className="aiest-seg">
                              {cur.opts.map((o) => (
                                <button key={o} type="button" className={`aiest-opt ${FIELD[cur.key][0] === o ? "is-on" : ""}`} onClick={() => FIELD[cur.key][1](o)}>{o}</button>
                              ))}
                            </div>
                          )}
                          {cur.kind === "swatch" && (
                            <div className="aiest-swatches">
                              {cur.opts.map((p) => (
                                <button key={p.name} type="button" className={`aiest-swatch ${palette === p.name ? "is-on" : ""}`} onClick={() => setPalette(p.name)}>
                                  <span className="aiest-swatch__row">{p.colors.map((c, j) => <span key={j} style={{ background: c }}></span>)}</span>
                                  <span className="aiest-swatch__name">{p.name}</span>
                                </button>
                              ))}
                            </div>
                          )}
                          {cur.kind === "review" && (
                            <label className="aiest-toggle">
                              <input type="checkbox" checked={maintenance} onChange={(e) => setMaintenance(e.target.checked)} />
                              <span className="aiest-toggle__box" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 14 14" fill="none"><path d="M3 7.5l3 3 5-6" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" /></svg></span>
                              <span>Include 6 months of maintenance</span>
                            </label>
                          )}
                        </div>
                        <div className="aiest-wiz__nav">
                          {step > 0 && <button type="button" className="btn btn--secondary" onClick={() => setStep((s) => s - 1)}>Back</button>}
                          {!isLast && <button type="button" className="btn btn--primary aiest-run" disabled={!canNext} onClick={() => setStep((s) => s + 1)}>Next <Arrow /></button>}
                          {isLast && <button type="button" className="btn btn--primary aiest-run" disabled={!type || !stage} onClick={start}>Estimate with AI <Arrow /></button>}
                        </div>
                      </div>
                    );
                  })()}

                  {phase !== "form" && (
                    <div className="aiplan">
                      {STEPS.map((s, i) => {
                        const visible = i <= done;
                        if (!visible) return null;
                        const st = i < done ? "success" : phase === "running" ? "active" : "success";
                        const last = i === STEPS.length - 1;
                        const isOpen = !!open[i];
                        return (
                          <div key={i} className={`aiplan-step aiplan-step--${st} ${s.content ? "aiplan-step--has-content" : ""} ${isOpen ? "is-open" : ""}`}>
                            {!last && <span className="aiplan-step__line"></span>}
                            <span className={`aiplan-step__ic aiic--${st}`}>
                              {st === "success" ? <AiCheck /> : st === "active" ? <AiSpin /> : <span style={{ width: 6, height: 6, borderRadius: 9, background: "currentColor" }}></span>}
                            </span>
                            <div className="aiplan-step__body">
                              <div className="aiplan-step__hd" onClick={() => s.content && toggle(i)}>
                                <span className="aiplan-step__t">{s.title}</span>
                                <span className="aiplan-step__meta">
                                  {s.duration && <span className="aiplan-step__dur">{s.duration}</span>}
                                  {s.content && !s.final && <span className="aiplan-step__chev"><AiChev /></span>}
                                </span>
                              </div>
                              {s.content && (
                                <div className="aiplan-step__panel"><div>{s.content}</div></div>
                              )}
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

window.PricingEstimator = PricingEstimator;
