// qualify.jsx - multi-step qualification form + Cal.com embed
// Triggered by every primary CTA on the page. Renders as a full-screen
// modal. Steps: pain → stack → timeline+budget → contact details
// → qualification result + live Cal.com inline widget (prefilled).

// ─────────────────────────────────────────────────────────────────
// 👇 CONFIGURE THIS: paste your Cal.com event link (just the path part).
// If your full URL is https://cal.com/skybridgesystems/30min,
// then CAL_LINK = "skybridgesystems/30min"
// If you only have the username (which lists all event types),
// use CAL_LINK = "skybridgesystems"
// ─────────────────────────────────────────────────────────────────
const CAL_LINK = "skybridgesystems";
const CAL_NAMESPACE = "skybridge";
const FORM_STEPS = 4;
const CAL_BOOKING_ACTIONS = ["bookingSuccessfulV2", "bookingSuccessful"];

function dispatchBookingOk(detail) {
  window.dispatchEvent(new CustomEvent("__skybridge_booking_ok", { detail: detail || {} }));
}

function isCalBookingMessage(data) {
  if (!data || typeof data !== "object") return false;
  const type = data.type || data.fullType || data.action || (data.detail && data.detail.type);
  if (!type) return false;
  const s = String(type);
  return s === "bookingSuccessfulV2" || s === "bookingSuccessful" || s.includes("bookingSuccessful");
}

function registerCalBookingListeners(namespace) {
  if (!window.Cal) return;
  CAL_BOOKING_ACTIONS.forEach(function (action) {
    const handler = function (e) { dispatchBookingOk(e && e.detail); };
    try { window.Cal("on", { action: action, callback: handler }); } catch (err) {}
    try {
      if (window.Cal.ns && window.Cal.ns[namespace]) {
        window.Cal.ns[namespace]("on", { action: action, callback: handler });
      }
    } catch (err) {}
  });
}

function QualifyModal({ open, onClose }) {
  const [step, setStep] = React.useState(0);
  const [data, setData] = React.useState({
    pain: "",
    stack: [],
    timeline: "",
    budget: "",
    name: "",
    email: "",
    company: "",
    notes: "",
  });
  const update = (k, v) => setData((d) => ({ ...d, [k]: v }));
  const toggle = (k, v) => setData((d) => ({
    ...d,
    [k]: d[k].includes(v) ? d[k].filter((x) => x !== v) : [...d[k], v],
  }));
  const leadTrackedRef = React.useRef(false);

  React.useEffect(() => {
    if (!open) {
      leadTrackedRef.current = false;
      return;
    }
    if (step < FORM_STEPS || leadTrackedRef.current) return;
    leadTrackedRef.current = true;
    window.sbTrack?.("generate_lead", {
      pain: data.pain,
      timeline: data.timeline,
      budget: data.budget,
    });
  }, [open, step, data.pain, data.timeline, data.budget]);

  React.useEffect(() => {
    function onMessage(event) {
      if (!String(event.origin || "").includes("cal.com")) return;
      if (isCalBookingMessage(event.data)) {
        const payload = event.data.data || event.data.detail || event.data;
        dispatchBookingOk(payload);
      }
    }
    window.addEventListener("message", onMessage);
    return () => window.removeEventListener("message", onMessage);
  }, []);

  React.useEffect(() => {
    if (open) {
      setStep(0);
      document.body.style.overflow = "hidden";
      window.sbTrack?.("qualify_form_start");
    } else {
      document.body.style.overflow = "";
    }
    return () => { document.body.style.overflow = ""; };
  }, [open]);

  // If the form was already open when the visitor accepts cookies, sbTrack was
  // skipped on open — fire again once consent is granted.
  React.useEffect(() => {
    function onConsent(e) {
      if (e.detail?.consent === "all" && open) {
        window.sbTrack?.("qualify_form_start");
      }
    }
    window.addEventListener("sb-consent-changed", onConsent);
    return () => window.removeEventListener("sb-consent-changed", onConsent);
  }, [open]);

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    if (open) window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  if (!open) return null;

  const steps = [
    {
      id: "pain",
      label: "What's the biggest pain right now?",
      sub: "Pick the one that's costing you the most sleep.",
      render: () => (
        <div className="qf-options">
          {[
            ["ci_slow", "CI/CD is slow or broken", "Releases pile up on Friday, manual deploys, scary hotfixes"],
            ["legacy", "Stuck on legacy .NET", ".NET Framework, WCF, IIS, can't hire"],
            ["azure", "No Azure infrastructure yet", "Need to migrate, or starting fresh on Azure"],
            ["mix", "All of the above", "Honestly, it's everywhere"],
            ["other", "Something else", "I'll explain on the call"],
          ].map(([v, label, sub]) => (
            <button key={v}
              type="button"
              className={"qf-opt " + (data.pain === v ? "is-active" : "")}
              onClick={() => { update("pain", v); next(); }}
            >
              <span className="qf-opt-label">{label}</span>
              <span className="qf-opt-sub">{sub}</span>
            </button>
          ))}
        </div>
      ),
      canNext: () => !!data.pain,
    },
    {
      id: "stack",
      label: "What's running today?",
      sub: "Multi-select. Helps us prep before the call.",
      render: () => (
        <div className="qf-chips">
          {[
            ".NET Framework 4.x",
            ".NET 5 /6 / 7 / 8 / 9 / 10",
            "WCF / Web API",
            "WebForms / MVC 5",
            "Azure (already)",
            "AWS / GCP",
            "On-prem / self-hosted",
            "Azure DevOps",
            "GitHub Actions",
            "Jenkins / GitLab / Bamboo",
            "SQL Server",
            "Other",
          ].map((s) => (
            <button key={s}
              type="button"
              className={"qf-chip " + (data.stack.includes(s) ? "is-active" : "")}
              onClick={() => toggle("stack", s)}
            >
              {data.stack.includes(s) ? "✓ " : "+ "}{s}
            </button>
          ))}
        </div>
      ),
      canNext: () => data.stack.length > 0,
    },
    {
      id: "timeline_budget",
      label: "Timeline and budget?",
      sub: "Rough is fine - we sort the specifics on the call.",
      render: () => (
        <div className="qf-two-col">
          <div>
            <span className="kicker" style={{ marginBottom: 10, display: "block" }}>When do you want this fixed?</span>
            <div className="qf-options">
              {[
                ["asap", "ASAP - this month", "Production fire, can't wait"],
                ["q", "Next 1-3 months", "Have budget, planning the work"],
                ["h", "Within 6 months", "On the roadmap, evaluating"],
                ["unknown", "Just exploring", "Want to understand options"],
              ].map(([v, label, sub]) => (
                <button key={v}
                  type="button"
                  className={"qf-opt qf-opt--compact " + (data.timeline === v ? "is-active" : "")}
                  onClick={() => update("timeline", v)}
                >
                  <span className="qf-opt-label">{label}</span>
                  <span className="qf-opt-sub">{sub}</span>
                </button>
              ))}
            </div>
          </div>
          <div>
            <span className="kicker" style={{ marginBottom: 10, display: "block" }}>Budget range for this work?</span>
            <div className="qf-options">
              {[
                ["s", "Under €2,500", "Audit only, no implementation"],
                ["m", "€2,500 - €10,000", "Single-engagement scope"],
                ["l", "€10,000 - €30,000", "Multi-engagement, modernization"],
                ["xl", "€30,000+ or not sure", "Larger scope, or recommend"],
              ].map(([v, label, sub]) => (
                <button key={v}
                  type="button"
                  className={"qf-opt qf-opt--compact " + (data.budget === v ? "is-active" : "")}
                  onClick={() => update("budget", v)}
                >
                  <span className="qf-opt-label">{label}</span>
                  <span className="qf-opt-sub">{sub}</span>
                </button>
              ))}
            </div>
          </div>
        </div>
      ),
      canNext: () => !!data.timeline && !!data.budget,
    },
    {
      id: "details",
      label: "Last thing - how do we reach you?",
      sub: "We respond within 4 business hours. No newsletters, ever.",
      render: () => (
        <div className="qf-form">
          <div className="qf-form-row">
            <Field label="Your name" value={data.name} onChange={(v) => update("name", v)} placeholder="Jane Doe" />
            <Field label="Work email" type="email" value={data.email} onChange={(v) => update("email", v)} placeholder="jane@company.com" />
          </div>
          <Field label="Company" value={data.company} onChange={(v) => update("company", v)} placeholder="Acme GmbH" />
          <Field
            label="Anything specific we should know?"
            value={data.notes}
            onChange={(v) => update("notes", v)}
            placeholder="Optional - links, repos, deadlines, team size…"
            multiline
          />
        </div>
      ),
      canNext: () => /.+@.+\..+/.test(data.email) && data.name.trim().length > 1,
    },
  ];

  const next = () => {
    setStep((s) => Math.min(s + 1, FORM_STEPS));
  };
  const prev = () => setStep((s) => Math.max(s - 1, 0));

  // After all steps, show qualification result
  const showResult = step >= steps.length;
  const qualified = qualifyLead(data);

  const cur = steps[step];

  return (
    <div className="qf-overlay" onClick={(e) => { if (e.target.classList.contains("qf-overlay")) onClose(); }} id="qualify">
      <div className="qf-modal" role="dialog" aria-modal="true" aria-labelledby="qf-title">
        <header className="qf-head">
          <div className="qf-head-left">
            <span className="kicker">Skybridge · Free audit booking</span>
            <span className="qf-head-sub">~45 seconds · 4 quick questions</span>
          </div>
          <button className="qf-close" onClick={onClose} aria-label="Close">
            <svg width="18" height="18" viewBox="0 0 18 18"><path d="M4 4l10 10M14 4 4 14" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
          </button>
        </header>

        {!showResult && (
          <>
            <div className="qf-progress" aria-hidden>
              {steps.map((_, i) => (
                <span key={i} className={"qf-pdot " + (i <= step ? "is-on" : "")} />
              ))}
              <span className="qf-pcount mono">{String(step + 1).padStart(2, "0")} / {String(steps.length).padStart(2, "0")}</span>
            </div>

            <div className="qf-body">
              <span className="qf-step-num mono">- Step {step + 1}</span>
              <h2 id="qf-title" className="h1" style={{ fontSize: "clamp(28px, 3.4vw, 40px)", margin: "8px 0 6px" }}>
                {cur.label}
              </h2>
              <p className="qf-sub">{cur.sub}</p>

              <div className="qf-step-content">
                {cur.render()}
              </div>
            </div>

            <footer className="qf-foot">
              <button className="btn btn--ghost btn--sm" onClick={prev} disabled={step === 0}>← Back</button>
              <div className="qf-foot-right">
                <span className="qf-foot-hint mono">↵ to continue</span>
                <button className="btn btn--primary btn--sm" disabled={!cur.canNext()} onClick={next}>
                  {step === steps.length - 1 ? "See if we're a fit" : "Continue"}
                  <svg className="arrow" viewBox="0 0 16 16" fill="none" aria-hidden><path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                </button>
              </div>
            </footer>
          </>
        )}

        {showResult && <ResultScreen data={data} qualified={qualified} onClose={onClose} />}
      </div>
    </div>
  );
}

function qualifyLead(d) {
  return { ok: !!d.pain };
}

function ResultScreen({ data, qualified, onClose }) {
  const [booked, setBooked] = React.useState(null);
  const bookTrackedRef = React.useRef(false);

  // Listen for Cal.com booking-success event (dispatched from CalComEmbed)
  React.useEffect(() => {
    const onBook = (e) => {
      setBooked(e.detail || {});
      if (bookTrackedRef.current) return;
      bookTrackedRef.current = true;
      window.sbTrack?.("book_call");
    };
    window.addEventListener("__skybridge_booking_ok", onBook);
    return () => window.removeEventListener("__skybridge_booking_ok", onBook);
  }, []);

  if (qualified.ok === false) {
    return (
      <div className="qf-result">
        <span className="qf-badge qf-badge--soft">↻ Incomplete</span>
        <h2 className="h1" style={{ fontSize: "clamp(28px, 3.4vw, 40px)" }}>Almost there.</h2>
        <p className="qf-sub">Please go back and complete the questions so we can prep properly.</p>
      </div>
    );
  }

  if (booked) {
    return (
      <div className="qf-result qf-confirmed">
        <span className="qf-badge qf-badge--ok">✓ Booked</span>
        <h2 className="h1" style={{ fontSize: "clamp(28px, 3.4vw, 40px)", margin: "12px 0 14px" }}>
          You're on the calendar, <em>{data.name.split(" ")[0] || "there"}</em>.
        </h2>
        <p className="qf-sub" style={{ maxWidth: "52ch" }}>
          Calendar invite + Google Meet link sent to <strong>{data.email}</strong>.
          Reply to that email if anything changes - I respond within a few hours
          during CET business days.
        </p>
        <div className="qf-summary mono">
          <span>- Booking summary</span>
          <span>For   · {data.name}{data.company ? " · " + data.company : ""}</span>
          <span>About · {prettyPain(data.pain)}</span>
          <span>Stack · {data.stack.slice(0,3).join(", ")}{data.stack.length > 3 ? ` +${data.stack.length-3}` : ""}</span>
          <span>Ref   · SKY-{(Math.random()*99999|0).toString().padStart(5,"0")}</span>
        </div>
        <div className="qf-result-actions">
          <button className="btn btn--ink" onClick={onClose}>Done</button>
          <a className="btn btn--ghost" href="mailto:hello@skybridgesystems.io">Email instead</a>
        </div>
      </div>
    );
  }

  return (
    <div className="qf-result qf-result--cal">
      <span className="qf-badge qf-badge--ok">✓ You're a fit - pick a slot</span>
      <h2 className="h1" style={{ fontSize: "clamp(28px, 3.4vw, 40px)", margin: "12px 0 6px" }}>
        Great. Let's get you on the calendar, <em>{data.name.split(" ")[0] || "there"}</em>.
      </h2>
      <p className="qf-sub" style={{ maxWidth: "56ch" }}>
        30-minute call with Saba. No sales - we'll go through your stack,
        sketch the work, and give you a price range. Recording on request.
      </p>

      <CalComEmbed data={data} />

      <p className="mono" style={{ fontSize: 11, color: "var(--muted)", marginTop: 14 }}>
        Times shown in your local zone. Need to reschedule? Email{" "}
        <a href="mailto:hello@skybridgesystems.io" style={{ color: "var(--bridge-red)" }}>hello@skybridgesystems.io</a>.
      </p>
    </div>
  );
}

function CalComEmbed({ data }) {
  const ref = React.useRef(null);
  const [status, setStatus] = React.useState("loading"); // loading | ready | error
  const isMobile = typeof window !== "undefined" && window.matchMedia("(max-width: 640px)").matches;

  React.useEffect(() => {
    let cancelled = false;
    let attempts = 0;

    const tryInit = () => {
      if (cancelled) return;
      attempts++;
      if (window.Cal && ref.current) {
        try {
          ref.current.innerHTML = "";
          // Initialize Cal namespace (idempotent)
          window.Cal("init", CAL_NAMESPACE, { origin: "https://app.cal.com" });
          // Inline embed
          window.Cal.ns[CAL_NAMESPACE]("inline", {
            elementOrSelector: ref.current,
            calLink: CAL_LINK,
            layout: isMobile ? "column_view" : "month_view",
            config: {
              name: data.name || "",
              email: data.email || "",
              notes: buildNotes(data),
              theme: document.documentElement.getAttribute("data-theme") === "technical" ? "dark" : "light",
              useSlotsViewOnSmallScreen: "true",
              "ui.autoscroll": "false",
            },
          });
          registerCalBookingListeners(CAL_NAMESPACE);
          setStatus("ready");
        } catch (e) {
          console.error("Cal.com init error:", e);
          setStatus("error");
        }
      } else if (attempts < 30) {
        setTimeout(tryInit, 200);
      } else {
        setStatus("error");
      }
    };

    tryInit();
    return () => { cancelled = true; };
  }, [data.name, data.email]);

  return (
    <div className="qf-cal">
      {status === "loading" && (
        <div className="qf-cal-loading">
          <span className="qf-cal-spinner" aria-hidden />
          <span className="mono">Loading available times…</span>
        </div>
      )}
      {status === "error" && (
        <div className="qf-cal-error">
          <p>
            We couldn't load the live calendar (it may be blocked by an ad
            blocker or network). Email{" "}
            <a href={"mailto:hello@skybridgesystems.io?subject=Booking%20-%20" + encodeURIComponent(data.name)}>
              hello@skybridgesystems.io
            </a>{" "}
            and we'll send slots manually within a few hours.
          </p>
        </div>
      )}
      <div ref={ref} className="qf-cal-embed" aria-live="polite" />
    </div>
  );
}

function buildNotes(data) {
  const lines = [];
  if (data.company) lines.push("Company: " + data.company);
  if (data.pain) lines.push("Pain: " + prettyPain(data.pain));
  if (data.stack?.length) lines.push("Stack: " + data.stack.join(", "));
  if (data.timeline) lines.push("Timeline: " + prettyTimeline(data.timeline));
  if (data.budget) lines.push("Budget: " + prettyBudget(data.budget));
  if (data.notes) lines.push("\nNotes:\n" + data.notes);
  return lines.join("\n");
}

function prettyPain(p) {
  return {
    ci_slow: "Slow / broken CI/CD",
    legacy: "Legacy .NET modernization",
    azure: "Azure infrastructure",
    mix: "All of the above",
    other: "Other (TBD on call)",
  }[p] || "TBD";
}

function prettyTimeline(t) {
  return {
    asap: "ASAP - this month",
    q: "Next 1-3 months",
    h: "Within 6 months",
    unknown: "Just exploring",
  }[t] || t;
}

function prettyBudget(b) {
  return {
    s: "Under €2,500",
    m: "€2,500 - €10,000",
    l: "€10,000 - €30,000",
    xl: "€30,000+ or not sure",
  }[b] || b;
}

function Field({ label, value, onChange, placeholder, type = "text", multiline }) {
  return (
    <label className="qf-field">
      <span className="qf-field-label kicker">{label}</span>
      {multiline ? (
        <textarea
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder={placeholder}
          rows={3}
        />
      ) : (
        <input
          type={type}
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder={placeholder}
        />
      )}
    </label>
  );
}

// Big inline CTA section, used near footer
function CTASection({ onCTA }) {
  return (
    <section className="section sb-cta-band">
      <div className="wrap sb-cta-inner">
        <div>
          <span className="eyebrow" style={{ color: "var(--paper)" }}>Free 30-min audit · no obligation</span>
          <h2 className="h-display" style={{ color: "var(--paper)", marginTop: 24, fontSize: "clamp(40px, 6vw, 80px)" }}>
            Book a free audit.<br />
            <em className="brush" style={{ color: "var(--bridge-red)" }}>Leave with a plan.</em>
          </h2>
          <p className="lede sb-cta-lede" style={{ marginTop: 24 }}>
            Six questions, 60 seconds - then pick a slot on my calendar.
            We'll go through your stack live, sketch the work, and give you
            a fixed-fee range. No follow-up sales sequence, ever.
          </p>
        </div>
        <div className="sb-cta-card">
          <span className="kicker" style={{ color: "var(--muted)" }}>What you get on the call</span>
          <ul className="sb-cta-list">
            <li><span className="dot" /> Honest read on whether we can help</li>
            <li><span className="dot" /> Sketch of the recommended approach</li>
            <li><span className="dot" /> Fixed-fee range with a delivery date</li>
            <li><span className="dot" /> A written summary, even if you don't hire us</li>
          </ul>
          <button className="btn btn--primary" onClick={onCTA} style={{ width: "100%", justifyContent: "center", marginTop: 8 }}>
            Start the 60-second form
            <svg className="arrow" viewBox="0 0 16 16" fill="none" aria-hidden><path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
          </button>
          <span className="mono" style={{ fontSize: 11, color: "var(--muted)", display: "block", textAlign: "center", marginTop: 4 }}>
            Or email hello@skybridgesystems.io
          </span>
        </div>
      </div>
    </section>
  );
}

const qfStyles = document.createElement("style");
qfStyles.textContent = `
  /* CTA band */
  .sb-cta-band { background: var(--surface-invert); color: var(--surface-invert-fg); }
  .sb-cta-lede { color: var(--surface-invert-muted); }
  .sb-cta-inner {
    display: grid; grid-template-columns: 1.3fr 1fr;
    gap: clamp(32px, 5vw, 72px);
    align-items: center;
  }
  @media (max-width: 900px) { .sb-cta-inner { grid-template-columns: 1fr; } }
  .sb-cta-card {
    background: var(--paper); color: var(--ink);
    border-radius: var(--radius);
    padding: 28px;
    display: flex; flex-direction: column; gap: 18px;
  }
  .sb-cta-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
  .sb-cta-list li { display: flex; gap: 10px; align-items: center; font-size: 14px; color: var(--ink-2); }
  .sb-cta-list .dot {
    width: 6px; height: 6px; border-radius: 50%; background: var(--bridge-red);
    flex-shrink: 0;
  }

  /* Modal */
  .qf-overlay {
    position: fixed; inset: 0; z-index: 100;
    background: rgba(15, 12, 8, 0.62);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    display: flex; align-items: center; justify-content: center;
    padding: 16px;
    animation: qf-fade .2s var(--ease);
  }
  @keyframes qf-fade { from { opacity: 0; } to { opacity: 1; } }
  .qf-modal {
    width: 100%; max-width: 860px;
    max-height: calc(100dvh - 32px);
    background: var(--paper);
    border-radius: var(--radius);
    display: flex; flex-direction: column;
    overflow: hidden;
    box-shadow: 0 30px 80px rgba(0,0,0,0.32);
    animation: qf-rise .25s var(--ease);
  }
  @media (max-width: 640px) {
    .qf-overlay {
      padding: 0;
      align-items: stretch;
    }
    .qf-modal {
      max-height: 100dvh;
      border-radius: 0;
    }
    .qf-head { padding: 14px 16px; }
  }
  @keyframes qf-rise { from { transform: translateY(20px); opacity: 0; } to { transform: none; opacity: 1; } }

  .qf-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 18px 24px;
    border-bottom: 1px solid var(--line);
  }
  .qf-head-left { display: flex; flex-direction: column; gap: 2px; }
  .qf-head-sub { font-family: var(--f-mono); font-size: 11px; color: var(--muted); }
  .qf-close {
    background: none; border: 1px solid var(--line); border-radius: 50%;
    width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
    color: var(--ink);
  }
  .qf-close:hover { background: var(--paper-2); }

  .qf-progress {
    display: flex; align-items: center; gap: 6px;
    padding: 14px 24px 0;
  }
  .qf-pdot {
    flex: 1; height: 3px; border-radius: 999px;
    background: var(--line);
    transition: background .25s var(--ease);
  }
  .qf-pdot.is-on { background: var(--bridge-red); }
  .qf-pcount { font-size: 10px; color: var(--muted); margin-left: 8px; }

  .qf-body { padding: 28px 24px; overflow-y: auto; flex: 1; min-height: 0; -webkit-overflow-scrolling: touch; }
  .qf-step-num { font-size: 11px; color: var(--bridge-red); letter-spacing: 0.08em; }
  .qf-sub { color: var(--muted); margin: 0 0 24px; font-size: 14.5px; }
  .qf-step-content { margin-top: 6px; }

  /* Options (large radio cards) */
  .qf-options { display: flex; flex-direction: column; gap: 8px; }
  .qf-opt {
    appearance: none; background: var(--paper); color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 16px 18px;
    text-align: left;
    display: flex; flex-direction: column; gap: 3px;
    transition: border-color .15s var(--ease), background .15s var(--ease), transform .1s var(--ease);
  }
  .qf-opt:hover { border-color: var(--ink); background: var(--paper-2); }
  .qf-opt.is-active { border-color: var(--bridge-red); background: var(--bridge-red-soft); }
  .qf-opt-label { font-size: 15.5px; font-weight: 500; color: var(--ink); }
  .qf-opt-sub { font-size: 13px; color: var(--muted); }
  .qf-opt--compact { padding: 11px 14px; }
  .qf-opt--compact .qf-opt-label { font-size: 14px; }
  .qf-opt--compact .qf-opt-sub { font-size: 12px; }

  /* Two-column step (timeline + budget) */
  .qf-two-col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
  }
  @media (max-width: 640px) { .qf-two-col { grid-template-columns: 1fr; gap: 18px; } }

  /* Form rows (name + email side by side) */
  .qf-form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
  }
  @media (max-width: 560px) { .qf-form-row { grid-template-columns: 1fr; } }

  /* Chips */
  .qf-chips { display: flex; flex-wrap: wrap; gap: 8px; }
  .qf-chip {
    appearance: none; background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 9px 14px;
    font-size: 13px;
    color: var(--ink-2);
    font-family: var(--f-mono);
    transition: all .15s var(--ease);
  }
  .qf-chip:hover { border-color: var(--ink); }
  .qf-chip.is-active { background: var(--bridge-red); color: var(--paper); border-color: var(--bridge-red); }

  /* Form fields */
  .qf-form { display: flex; flex-direction: column; gap: 16px; }
  .qf-field { display: flex; flex-direction: column; gap: 6px; }
  .qf-field-label { font-size: 10px; }
  .qf-field input, .qf-field textarea {
    appearance: none;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 12px 14px;
    font: inherit;
    color: var(--ink);
    transition: border-color .15s var(--ease);
    resize: vertical;
    font-family: var(--f-sans);
  }
  .qf-field input::placeholder, .qf-field textarea::placeholder { color: var(--muted-2); }
  .qf-field input:focus, .qf-field textarea:focus { outline: none; border-color: var(--bridge-red); }

  .qf-foot {
    display: flex; justify-content: space-between; align-items: center;
    padding: 16px 24px;
    border-top: 1px solid var(--line);
    background: var(--paper-2);
    gap: 12px;
  }
  .qf-foot-right { display: flex; gap: 12px; align-items: center; }
  .qf-foot-hint { font-size: 10px; color: var(--muted); letter-spacing: 0.06em; }
  .qf-foot .btn--ghost:disabled { opacity: 0.4; }
  .qf-foot .btn--primary:disabled {
    background: var(--paper-3); color: var(--muted-2); cursor: not-allowed;
  }
  .qf-foot .btn--primary:disabled:hover { transform: none; background: var(--paper-3); }
  @media (max-width: 480px) { .qf-foot-hint { display: none; } }

  /* Result screen */
  .qf-result {
    padding: 36px 28px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  @media (max-width: 640px) {
    .qf-result { padding: 20px 16px 28px; }
    .qf-result--cal .qf-sub { margin-bottom: 16px; }
    .qf-result--cal .h1 { font-size: clamp(24px, 6vw, 32px) !important; }
  }
  .qf-badge {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px;
    border-radius: 999px;
    font-family: var(--f-mono); font-size: 11px;
    letter-spacing: 0.06em;
  }
  .qf-badge--ok   { background: rgba(43,174,92,0.12); color: #1A8A4D; }
  .qf-badge--soft { background: var(--sky-blue-soft); color: var(--sky-blue); }

  .qf-result-actions { display: flex; gap: 12px; margin-top: 24px; flex-wrap: wrap; }

  /* Cal.com embed */
  .qf-cal {
    margin-top: 22px;
    border-radius: 12px;
    border: 1px solid var(--line);
    background: var(--paper);
    min-height: 80px;
  }
  .qf-cal-embed { width: 100%; min-height: 420px; }
  .qf-cal-embed iframe {
    display: block;
    width: 100% !important;
    border: 0;
  }
  .qf-cal-loading {
    display: flex; align-items: center; justify-content: center; gap: 12px;
    padding: 40px 20px;
    color: var(--muted);
    font-size: 12px;
  }
  .qf-cal-spinner {
    width: 16px; height: 16px;
    border: 2px solid var(--line-strong);
    border-top-color: var(--bridge-red);
    border-radius: 50%;
    animation: qf-spin 0.8s linear infinite;
  }
  @keyframes qf-spin { to { transform: rotate(360deg); } }
  .qf-cal-error {
    padding: 28px 24px;
    color: var(--ink-2);
    font-size: 14px;
  }
  .qf-cal-error a { color: var(--bridge-red); border-bottom: 1px solid currentColor; }

  /* Confirmed */
  .qf-summary {
    display: flex; flex-direction: column;
    background: var(--paper-2);
    border: 1px dashed var(--line-strong);
    border-radius: 10px;
    padding: 18px;
    margin-top: 22px;
    font-size: 12px;
    color: var(--ink-2);
    gap: 4px;
  }
  .qf-summary span:first-child { color: var(--bridge-red); margin-bottom: 6px; }
`;
document.head.appendChild(qfStyles);

Object.assign(window, { QualifyModal, CTASection });
