/* NutriDMS, Enterprise Register / Onboarding flow
   Six steps with side-panel progress (default), top-bar dots, or one-question-per-screen.
   The pattern is exposed as a Tweak so the user can A/B the step layout. */

const { useState: useRgState, useEffect: useRgEffect, useMemo: useRgMemo, useRef: useRgRef } = React;
const _RgCtx = { role: "super-admin", page: "register", setPage: () => { }, lang: "en", setLang: () => { }, openCmd: () => { }, openNotif: () => { } };

const RG_STEPS_ALL = [
  { id: "account", num: 1, t: "Create account", s: "Work email & password" },
  { id: "verify", num: 2, t: "Verify email", s: "Confirm your work address" },
  { id: "workspace", num: 3, t: "Create workspace", s: "Company, region, team size" },
  { id: "plan", num: 4, t: "Choose trial plan", s: "Starter, Growth, Professional, Enterprise" },
  { id: "invite", num: 5, t: "Invite your team", s: "Roles & permissions" },
  { id: "goals", num: 6, t: "Set up goals", s: "First-day workflows" }];

/* ── API trial steps, developer-first onboarding (per PRD §7) ──
   Pricing → Plan → Trial → Account → Verify → Billing+IP → Workspace → Sandbox key → Console */
const RG_STEPS_API = [
  { id: "account", num: 1, t: "Developer account", s: "Name, work email, password" },
  { id: "verify", num: 2, t: "Verify email", s: "Confirm your work address" },
  { id: "api-workspace", num: 3, t: "API workspace", s: "Region, use case, app" },
  { id: "billing", num: 4, t: "Billing & terms", s: "Card + IP agreements" },
  { id: "key", num: 5, t: "Sandbox API key", s: "Generate & test your first call" },
];

function getStepsForPlan(planKind) {
  if (planKind === "api") return RG_STEPS_API;
  return RG_STEPS_ALL;
}


/* ─── Brand panel, left rail with progress + plan deep-dive ─── */
const PLATFORM_PILLARS = [
  { ic: "code-2", t: "API Infrastructure", s: "Developer-first nutrition APIs" },
  { ic: "lightbulb", t: "Loraa.ai", s: "AI nutrition reasoning & QA" },
  { ic: "shield-check", t: "Health Rules Engine", s: "Chronic & dietary validation" },
  { ic: "globe", t: "White-Label", s: "Tenant branding & deployment" },
  { ic: "layers", t: "Multi-Tenant", s: "Isolated workspace boundaries" },
  { ic: "credit-card", t: "Billing & Metering", s: "Stripe-powered usage billing" },
  { ic: "file-clock", t: "Governance", s: "Audit, residency, security" },
];

function RgSidePanel({ stepIdx, jump, planContext, steps }) {
  const isApiPlan = !!planContext?.price;
  return (
    <aside className="rg-side">
      <div className="rg-side-top">
        <a href="../Landing.html" className="back"><Icon name="arrow-left" size={13} stroke={2.4} /> Back to nutridms.com</a>
        <span className="tag">Enterprise</span>
      </div>
      <div style={{ marginBottom: 24 }}>
        <NutriHoriz height={32} forceTheme="dark" />
      </div>

      {planContext && !isApiPlan && (
        <div className="rg-plan-context">
          <div className="rg-plan-context-tag">{planContext.kind}</div>
          <div className="rg-plan-context-t">{planContext.title}</div>
          <div className="rg-plan-context-s">{planContext.sub}</div>
        </div>
      )}

      {planContext && isApiPlan && (
        <div className="rg-plan-card">
          <div className="rg-plan-card-tag">{planContext.kind}</div>
          <div className="rg-plan-card-price">
            <strong>{planContext.price}</strong>
            <span>/mo after 7-day trial</span>
          </div>
          <div className="rg-plan-card-grid">
            <div><span>Requests</span><strong>{planContext.calls}/mo</strong></div>
            <div><span>Rate limit</span><strong>{planContext.rate}</strong></div>
            <div><span>Overage</span><strong>{planContext.overage}</strong></div>
            <div><span>Support</span><strong>{planContext.sla}</strong></div>
          </div>
          {planContext.intendedFor && (
            <div className="rg-plan-card-section">
              <span className="lbl">Intended for</span>
              <div className="rg-plan-card-pills">
                {planContext.intendedFor.map((p) => <span key={p}>{p}</span>)}
              </div>
            </div>
          )}
          {planContext.includes && (
            <div className="rg-plan-card-section">
              <span className="lbl">Includes</span>
              <ul className="rg-plan-card-list">
                {planContext.includes.map((p) => (
                  <li key={p}><Icon name="check" size={10} stroke={3} /> {p}</li>
                ))}
              </ul>
            </div>
          )}
        </div>
      )}

      <div className="rg-steps">
        {steps.map((s, i) => {
          const isActive = i === stepIdx;
          const isComplete = i < stepIdx;
          return (
            <div
              key={s.id}
              className={`rg-step ${isActive ? "active" : ""} ${isComplete ? "complete" : ""}`}
              onClick={() => i <= stepIdx && jump(i)}
              style={i <= stepIdx ? { cursor: "pointer" } : {}}>

              <div className="num">
                {isComplete ? <Icon name="check" size={14} stroke={3} /> : s.num}
              </div>
              <div className="meta">
                <div className="t">{s.t}</div>
                <div className="s">{s.s}</div>
              </div>
            </div>);

        })}
      </div>

      {isApiPlan && (
        <div className="rg-pillars">
          <div className="rg-pillars-h">Platform pillars</div>
          <div className="rg-pillars-grid">
            {PLATFORM_PILLARS.map((p) => (
              <div key={p.t} className="rg-pillar" title={p.s}>
                <Icon name={p.ic} size={11} stroke={2.4} />
                <span>{p.t}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      <div className="rg-side-foot">
        <div><strong>7-day free trial.</strong> Stripe card required · cancel anytime before renewal.</div>
        <div>Need help? <a href="mailto:hello@nutridms.com">hello@nutridms.com</a></div>
      </div>
    </aside>);

}

/* ─── Top-bar progress for non-side patterns ─── */
function RgTopbar({ stepIdx, steps }) {
  return (
    <div className="rg-topbar">
      <a href="../Landing.html" style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
        <NutriHoriz height={26} />
      </a>
      <div className="step-dots">
        {steps.map((s, i) =>
          <div
            key={s.id}
            className={`step-dot ${i < stepIdx ? "complete" : i === stepIdx ? "active" : ""}`} />

        )}
      </div>
      <div className="step-counter">
        <strong>Step {stepIdx + 1}</strong> of {steps.length} · {steps[stepIdx].t}
      </div>
    </div>);

}

/* ─── Step 1, Account ─── */
function StepAccount({ data, set, next, stepNum = 1, total = 6 }) {
  const [showPw, setShowPw] = useRgState(false);
  const pw = data.password || "";
  const strength = useRgMemo(() => {
    let s = 0;
    if (pw.length >= 8) s++;
    if (/[A-Z]/.test(pw)) s++;
    if (/\d/.test(pw)) s++;
    if (/[^A-Za-z0-9]/.test(pw)) s++;
    return s;
  }, [pw]);
  const sLabel = ["", "weak", "fair", "good", "strong"][strength];
  const sText = ["Too short", "Weak", "Fair", "Good", "Strong"][strength];
  const valid =
    (data.firstName || "").trim() &&
    (data.lastName || "").trim() &&
    /^\S+@\S+\.\S+$/.test(data.email || "") &&
    pw.length >= 8 &&
    pw === data.confirmPassword;

  const submit = (e) => { e.preventDefault(); if (valid) next(); };

  return (
    <form onSubmit={submit} noValidate>
      <span className="rg-form-eyebrow"><Icon name="user-plus" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Create your account</h1>
      <p className="rg-form-sub">Start your 7-day free trial. We'll set up a practice workspace right after you verify your email, billing card collected before production access.</p>

      <div className="rg-form-grid">
        <div className="rg-field">
          <label>First name <span className="req">*</span></label>
          <input value={data.firstName || ""} onChange={(e) => set("firstName", e.target.value)} placeholder="Sarah" autoComplete="given-name" />
        </div>
        <div className="rg-field">
          <label>Last name <span className="req">*</span></label>
          <input value={data.lastName || ""} onChange={(e) => set("lastName", e.target.value)} placeholder="Chen" autoComplete="family-name" />
        </div>
        <div className="rg-field full">
          <label>Work email <span className="req">*</span></label>
          <input type="email" value={data.email || ""} onChange={(e) => set("email", e.target.value)} placeholder="you@yourcompany.com" autoComplete="email" />
          <div className="hint">Use your work email so we can route your workspace correctly. Personal addresses (gmail, yahoo) get a Starter trial only.</div>
        </div>
        <div className="rg-field full">
          <label>Password <span className="req">*</span></label>
          <div style={{ position: "relative" }}>
            <input
              type={showPw ? "text" : "password"}
              value={pw}
              onChange={(e) => set("password", e.target.value)}
              placeholder="At least 8 characters" autoComplete="new-password" />

            <button type="button" onClick={() => setShowPw(!showPw)} style={{ position: "absolute", right: 12, top: 12, background: "transparent", color: "var(--gray-500)" }}>
              <Icon name={showPw ? "eye-off" : "eye"} size={16} stroke={2.2} />
            </button>
          </div>
          {pw &&
            <>
              <div className={`rg-pw-strength ${sLabel}`}>
                <i /><i /><i /><i />
              </div>
              <div className="rg-pw-meta">
                <span>Password strength</span>
                <strong className={sLabel}>{sText}</strong>
              </div>
            </>
          }
        </div>
        <div className="rg-field full">
          <label>Confirm password <span className="req">*</span></label>
          <input
            type={showPw ? "text" : "password"}
            value={data.confirmPassword || ""}
            onChange={(e) => set("confirmPassword", e.target.value)}
            placeholder="Re-enter your password" autoComplete="new-password" />

        </div>
      </div>

      <div className="rg-cta-row">
        <div className="spacer" />
        <button type="submit" className="btn primary" disabled={!valid}>
          Continue <Icon name="arrow-right" size={14} stroke={2.4} />
        </button>
      </div>

      <div className="rg-divider">or sign up with</div>
      <div className="rg-sso">
        <button type="button"><span style={{ fontWeight: 800 }}>G</span> Google</button>
        <button type="button"><Icon name="square" size={15} stroke={2.2} /> Microsoft</button>
      </div>

      <p style={{ fontSize: 12.5, color: "var(--gray-500)", textAlign: "center", marginTop: 28, lineHeight: 1.55 }}>
        Already have an account? <a href="../signin.html" style={{ color: "var(--brand-700)", fontWeight: 700 }}>Sign in</a>
        <br />
        By continuing you agree to our <a href="#" style={{ color: "var(--gray-600)", fontWeight: 600 }}>Terms</a> and <a href="#" style={{ color: "var(--gray-600)", fontWeight: 600 }}>Privacy Policy</a>.
      </p>
    </form>);

}

/* ─── Step 2, Verify Email ─── */
function StepVerify({ data, set, next, back, stepNum = 2, total = 6 }) {
  const [countdown, setCountdown] = useRgState(0);
  useRgEffect(() => {
    if (countdown <= 0) return;
    const id = setTimeout(() => setCountdown(countdown - 1), 1000);
    return () => clearTimeout(id);
  }, [countdown]);

  return (
    <div>
      <span className="rg-form-eyebrow"><Icon name="mail" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Check your inbox</h1>
      <p className="rg-form-sub">We sent a verification link to your work email. Click it to confirm and continue setting up your workspace.</p>

      <div className="rg-verify-art">
        <Icon name="mail-check" size={36} stroke={2} />
      </div>

      <div className="rg-verify-mailbox">
        <Icon name="at-sign" size={16} stroke={2.2} style={{ color: "var(--gray-500)" }} />
        <span className="e">{data.email || "you@yourcompany.com"}</span>
        <button type="button" onClick={back}>Change</button>
      </div>

      <div className="rg-resend">
        <span>Didn't get the email? Check your spam folder.</span>
        {countdown > 0 ?
          <span className="countdown">Resend in {countdown}s</span> :

          <a href="#" onClick={(e) => { e.preventDefault(); setCountdown(30); }}>Resend link</a>
        }
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}>
          <Icon name="arrow-left" size={14} stroke={2.4} /> Back
        </button>
        <div className="spacer" />
        <button type="button" className="btn primary" onClick={next}>
          I verified my email <Icon name="arrow-right" size={14} stroke={2.4} />
        </button>
      </div>
    </div>);

}

/* ─── Step 3, Workspace ─── */
const BUSINESS_TYPES = [
  { id: "restaurant", t: "Restaurant", s: "Single or multi-location", ic: "utensils" },
  { id: "qsr", t: "QSR / Fast Casual", s: "Quick-service, chains, drive-thru", ic: "burger" },
  { id: "catering", t: "Catering & Events", s: "B2B catering, corporate dining", ic: "soup" },
  { id: "meal-prep", t: "Meal Prep", s: "Subscription / DTC meal services", ic: "package" },
  { id: "ghost-kitchen", t: "Ghost / Cloud Kitchen", s: "Delivery-only brands, virtual concepts", ic: "chef-hat" },
  { id: "manufacturer", t: "Food Manufacturer", s: "Packaged goods, retail", ic: "factory" },
  { id: "cpg", t: "CPG / DTC Brand", s: "Branded packaged products", ic: "shopping-bag" },
  { id: "beverage", t: "Beverage Producer", s: "Drinks, supplements, RTD", ic: "cup-soda" },
  { id: "clinic", t: "Dietitian Clinic", s: "Health & wellness practices", ic: "stethoscope" },
  { id: "hospital", t: "Hospital / Healthcare", s: "Patient nutrition, foodservice", ic: "heart-pulse" },
  { id: "wellness", t: "Wellness / Fitness", s: "Gyms, coaching, lifestyle programs", ic: "dumbbell" },
  { id: "api", t: "Enterprise API Partner", s: "Building on NutriDMS APIs", ic: "code-2" },
  { id: "pos", t: "POS / Tech Platform", s: "POS, marketplace, delivery platform", ic: "monitor" },
  { id: "edu", t: "Educational Institution", s: "Universities, school nutrition", ic: "graduation-cap" },
  { id: "k12", t: "K–12 / Childcare", s: "School lunch, daycare nutrition", ic: "backpack" },
  { id: "gov", t: "Government / NGO", s: "Public health, food assistance", ic: "landmark" },
  { id: "hotel", t: "Hospitality / Hotel", s: "Hotel F&B, resorts, cruise", ic: "bed" },
  { id: "other", t: "Other", s: "Tell us more in onboarding", ic: "shapes" }];


function StepWorkspace({ data, set, next, back, stepNum = 3, total = 6 }) {
  const valid = (data.companyName || "").trim() && (data.workspaceName || "").trim() && data.businessType && data.region && data.teamSize;
  return (
    <form onSubmit={(e) => { e.preventDefault(); if (valid) next(); }} noValidate>
      <span className="rg-form-eyebrow"><Icon name="building" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Create your workspace</h1>
      <p className="rg-form-sub">Workspaces are isolated environments, recipes, users, and audit logs are scoped to each one. Most teams start with one workspace per business unit.</p>

      <div className="rg-form-grid">
        <div className="rg-field full">
          <label>Company name <span className="req">*</span></label>
          <input value={data.companyName || ""} onChange={(e) => set("companyName", e.target.value)} placeholder="Acme Foods, Inc." />
        </div>
        <div className="rg-field full">
          <label>Workspace name <span className="req">*</span><span className="opt">often the brand or business unit</span></label>
          <input value={data.workspaceName || ""} onChange={(e) => set("workspaceName", e.target.value)} placeholder="Acme, Production" />
          <div className="hint">URL preview: <code style={{ fontFamily: "ui-monospace, monospace", color: "var(--brand-700)" }}>{(data.workspaceName || "your-workspace").toString().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}.nutridms.com</code></div>
        </div>
      </div>

      <div className="rg-field" style={{ marginBottom: 20 }}>
        <label>Business type <span className="req">*</span></label>
        <div className="rg-chip-grid">
          {BUSINESS_TYPES.map((b) =>
            <button key={b.id} type="button" className={`rg-chip ${data.businessType === b.id ? "on" : ""}`} onClick={() => set("businessType", b.id)}>
              <div className="ic"><Icon name={b.ic} size={18} stroke={2.2} /></div>
              <div>
                <div className="nm">{b.t}</div>
                <div className="sm">{b.s}</div>
              </div>
            </button>
          )}
        </div>
      </div>

      <div className="rg-region-row" style={{ marginBottom: 8 }}>
        <div className="rg-field">
          <label>Data region <span className="req">*</span></label>
          <select value={data.region || ""} onChange={(e) => set("region", e.target.value)}>
            <option value="">Select region…</option>
            <option value="us-east">US East (Virginia) · default</option>
            <option value="us-west">US West (Oregon)</option>
            <option value="eu-west">EU West (Ireland) · GDPR</option>
            <option value="ca-central">Canada Central (Toronto)</option>
            <option value="ap-southeast">Asia Pacific (Singapore)</option>
          </select>
          <div className="hint">Where your workspace data is stored. Cannot be changed later.</div>
        </div>
        <div className="rg-field">
          <label>Team size <span className="req">*</span></label>
          <select value={data.teamSize || ""} onChange={(e) => set("teamSize", e.target.value)}>
            <option value="">Select…</option>
            <option value="1-5">1-5 people</option>
            <option value="6-25">6-25 people</option>
            <option value="26-100">26-100 people</option>
            <option value="101-500">101-500 people</option>
            <option value="500+">500+ people</option>
          </select>
        </div>
        <div className="rg-field full">
          <label>Departments <span style={{ fontWeight: 400, color: "var(--gray-400)" }}>· optional, comma-separated</span></label>
          <input value={data.departments || ""} onChange={(e) => set("departments", e.target.value)} placeholder="Editorial, Nutrition, Compliance, Platform" onBlur={(e) => { const v = e.target.value.split(",").map(x => x.trim()).filter(Boolean); if (v.length && typeof saveDepartments === "function") saveDepartments(v); }} />
        </div>
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}>
          <Icon name="arrow-left" size={14} stroke={2.4} /> Back
        </button>
        <div className="spacer" />
        <button type="submit" className="btn primary" disabled={!valid}>
          Continue <Icon name="arrow-right" size={14} stroke={2.4} />
        </button>
      </div>
    </form>);

}

/* ─── API Step 3, Workspace (developer-first, nutrition mobile-apps-aware) ─── */
/* §9 Company Types, the 8 PRD options, paired with §4 primary-market context */
const API_COMPANY_TYPES = [
  { id: "nutrition-app", t: "Nutrition app", s: "Calorie / macro trackers", ic: "smartphone", market: "Nutrition Apps", highlight: true },
  { id: "meal-planner", t: "Meal planner", s: "Weekly menus, grocery lists", ic: "calendar-days", market: "Nutrition Apps" },
  { id: "fitness-app", t: "Fitness app", s: "Workouts + nutrition logging", ic: "dumbbell", market: "Fitness & Wellness" },
  { id: "wellness", t: "Wellness company", s: "Habit, behavior, coaching", ic: "heart-pulse", market: "Fitness & Wellness" },
  { id: "healthcare", t: "Healthcare platform", s: "Clinics, hospitals, dietitians", ic: "stethoscope", market: "Healthcare & Compliance" },
  { id: "restaurant-pos", t: "Restaurant / POS", s: "Menus, allergens, POS partners", ic: "utensils", market: "Enterprise Food Ops" },
  { id: "food-marketplace", t: "Food marketplace", s: "Catalog enrichment at scale", ic: "shopping-bag", market: "Enterprise Food Ops" },
  { id: "school-project", t: "School project", s: "Student / academic non-commercial", ic: "graduation-cap", market: "Education" },
];

function StepApiWorkspace({ data, set, next, back, stepNum, total }) {
  const valid = (data.companyName || "").trim()
    && (data.workspaceName || "").trim()
    && data.region
    && data.businessType
    && (data.appName || "").trim()
    && data.country;
  const slug = (data.workspaceName || "your-workspace").toString().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");

  return (
    <form onSubmit={(e) => { e.preventDefault(); if (valid) next(); }} noValidate>
      <span className="rg-form-eyebrow"><Icon name="code-2" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Set up your API workspace</h1>
      <p className="rg-form-sub">Workspaces are isolated tenants, API keys, usage, billing, and audit logs are all scoped per-workspace. Pick where data should live and what you're building.</p>

      <div className="rg-form-grid">
        <div className="rg-field">
          <label>Company name <span className="req">*</span></label>
          <input value={data.companyName || ""} onChange={(e) => set("companyName", e.target.value)} placeholder="Acme Nutrition, Inc." />
        </div>
        <div className="rg-field">
          <label>App / product name <span className="req">*</span></label>
          <input value={data.appName || ""} onChange={(e) => set("appName", e.target.value)} placeholder="MacroPal" />
        </div>
        <div className="rg-field full">
          <label>Workspace name <span className="req">*</span><span className="opt">used in your dashboard URL</span></label>
          <input value={data.workspaceName || ""} onChange={(e) => set("workspaceName", e.target.value)} placeholder="macropal-prod" />
          <div className="hint">URL preview: <code style={{ fontFamily: "ui-monospace, monospace", color: "var(--brand-700)" }}>api.nutridms.com/v1/<strong>{slug}</strong>/…</code></div>
        </div>
      </div>

      <div className="rg-field" style={{ marginBottom: 20 }}>
        <label>Company type <span className="req">*</span><span className="opt">we tune sample data, docs &amp; rate-limit policy to this</span></label>
        <div className="rg-chip-grid">
          {API_COMPANY_TYPES.map((u) => (
            <button key={u.id} type="button" className={`rg-chip ${data.businessType === u.id ? "on" : ""} ${u.highlight ? "featured" : ""}`} onClick={() => set("businessType", u.id)}>
              <div className="ic"><Icon name={u.ic} size={18} stroke={2.2} /></div>
              <div>
                <div className="nm">{u.t}{u.highlight && <span className="rg-chip-flag">Most common</span>}</div>
                <div className="sm">{u.s}</div>
                <div className="rg-chip-market">{u.market}</div>
              </div>
            </button>
          ))}
        </div>
      </div>

      <div className="rg-region-row" style={{ marginBottom: 8 }}>
        <div className="rg-field">
          <label>Data region <span className="req">*</span></label>
          <select value={data.region || ""} onChange={(e) => set("region", e.target.value)}>
            <option value="">Select region…</option>
            <option value="us-east">US East (Virginia) · default</option>
            <option value="us-west">US West (Oregon)</option>
            <option value="eu-west">EU West (Ireland) · GDPR</option>
            <option value="ca-central">Canada Central (Toronto)</option>
            <option value="ap-southeast">Asia Pacific (Singapore)</option>
          </select>
          <div className="hint">Where API requests + recipes are stored. Locked after creation.</div>
        </div>
        <div className="rg-field">
          <label>Country <span className="req">*</span></label>
          <select value={data.country || ""} onChange={(e) => set("country", e.target.value)}>
            <option value="">Select country…</option>
            <option>United States</option><option>Canada</option><option>United Kingdom</option>
            <option>Germany</option><option>France</option><option>Spain</option>
            <option>Netherlands</option><option>Mexico</option><option>Brazil</option>
            <option>Australia</option><option>Singapore</option><option>India</option><option>Other</option>
          </select>
          <div className="hint">For tax + compliance routing.</div>
        </div>
      </div>

      <div className="rg-api-callout">
        <Icon name="zap" size={14} stroke={2.4} />
        <span><strong>Sandbox access is instant.</strong> You'll get a test key right after you set up billing. Production access unlocks after email + business verification.</span>
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}><Icon name="arrow-left" size={14} stroke={2.4} /> Back</button>
        <div className="spacer" />
        <button type="submit" className="btn primary" disabled={!valid}>Continue <Icon name="arrow-right" size={14} stroke={2.4} /></button>
      </div>
    </form>
  );
}

/* ─── API Step 4, Billing (Stripe) + Terms / IP agreements ─── */
function fmtCard(s) {
  return s.replace(/\D/g, "").slice(0, 19).replace(/(.{4})/g, "$1 ").trim();
}
function fmtExp(s) {
  const n = s.replace(/\D/g, "").slice(0, 4);
  return n.length > 2 ? `${n.slice(0, 2)}/${n.slice(2)}` : n;
}
function detectBrand(num) {
  const n = num.replace(/\s/g, "");
  if (/^4/.test(n)) return "visa";
  if (/^(5[1-5]|2[2-7])/.test(n)) return "mc";
  if (/^3[47]/.test(n)) return "amex";
  if (/^6(011|5)/.test(n)) return "disc";
  return "card";
}

function StepBilling({ data, set, next, back, stepNum, total, planContext }) {
  const card = data.card || {};
  const setCard = (k, v) => set("card", { ...card, [k]: v });
  const validCard = (card.number || "").replace(/\s/g, "").length >= 15
    && /^\d{2}\/\d{2}$/.test(card.exp || "")
    && (card.cvc || "").length >= 3
    && (card.name || "").trim().length > 1
    && (card.line1 || "").trim().length > 2
    && (card.city || "").trim().length > 1
    && (card.state || "").trim().length >= 1
    && (card.postal || "").trim().length >= 3
    && (card.country || "").trim().length >= 1;
  const validAgreements = data.agreeTos && data.agreeIp && data.agreeData;
  const valid = validCard && validAgreements;
  const brand = detectBrand(card.number || "");

  return (
    <form onSubmit={(e) => { e.preventDefault(); if (valid) next(); }} noValidate>
      <span className="rg-form-eyebrow"><Icon name="credit-card" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Add billing &amp; accept terms</h1>
      <p className="rg-form-sub">Your 7-day trial is free, we won't charge this card until {new Date(Date.now() + 7 * 864e5).toLocaleDateString(undefined, { month: "long", day: "numeric" })}. Cancel anytime from your billing dashboard.</p>

      {/* Trial summary, surfaces the per-tier plan details from the PRD */}
      <div className="rg-trial-summary">
        <div className="rg-trial-summary-row">
          <span className="lbl">Plan</span>
          <span className="val">{planContext?.kind || planContext?.title || "API trial"}</span>
        </div>
        {planContext?.price && (
          <>
            <div className="rg-trial-summary-row">
              <span className="lbl">After trial</span>
              <span className="val"><strong>{planContext.price}</strong> /month</span>
            </div>
            <div className="rg-trial-summary-row">
              <span className="lbl">Included calls</span>
              <span className="val">{planContext.calls}/month · {planContext.rate}</span>
            </div>
            <div className="rg-trial-summary-row">
              <span className="lbl">Overage</span>
              <span className="val">{planContext.overage}</span>
            </div>
            <div className="rg-trial-summary-row">
              <span className="lbl">Support</span>
              <span className="val">{planContext.sla}</span>
            </div>
          </>
        )}
        <div className="rg-trial-summary-row">
          <span className="lbl">Trial</span>
          <span className="val">7 days free · cancel anytime before renewal</span>
        </div>
        <div className="rg-trial-summary-row">
          <span className="lbl">Today's charge</span>
          <span className="val accent"><strong>$0.00</strong></span>
        </div>
      </div>

      {/* Add-on Marketplace, PRD §20–§31 (Loraa.ai tiers, Health Rules tiers, Recipe Media, White-label, Dedicated hosting, Regional residency, Encryption keys) */}
      <h3 className="rg-section-h">Add-on marketplace<span className="rg-section-h-meta">activation triggers Stripe + scoped permissions</span></h3>
      <div className="rg-marketplace">

        {/* Loraa.ai, Starter / Growth / Enterprise */}
        <div className="rg-mkt-card">
          <div className="rg-mkt-card-head">
            <div className="rg-mkt-ic ai"><Icon name="lightbulb" size={16} stroke={2.2} /></div>
            <div>
              <div className="rg-mkt-t">Loraa.ai <span className="rg-mkt-tag">AI Engine</span></div>
              <div className="rg-mkt-d">AI nutrition analysis, health insights, recipe intelligence, compliance assistance. <em>Not included</em> in base plans.</div>
            </div>
          </div>
          <div className="rg-mkt-tiers">
            {[
              { id: "laura-starter", t: "Starter", price: "+$149/mo", unit: "50,000 AI tokens" },
              { id: "laura-growth", t: "Growth", price: "+$499/mo", unit: "250,000 AI tokens" },
              { id: "laura-enterprise", t: "Enterprise", price: "Custom", unit: "Volume + dedicated AI", contact: true },
            ].map((tier) => {
              const on = data.addonTiers?.laura === tier.id;
              return (
                <button key={tier.id} type="button" className={`rg-mkt-tier ${on ? "on" : ""}`} onClick={() => {
                  if (tier.contact) return;
                  set("addonTiers", { ...(data.addonTiers || {}), laura: on ? null : tier.id });
                }}>
                  <div className="t">{tier.t}{tier.contact && <span className="rg-mkt-tier-flag">Sales</span>}</div>
                  <div className="p">{tier.price}</div>
                  <div className="u">{tier.unit}</div>
                  {on && <Icon name="check-circle" size={14} stroke={2.6} className="rg-mkt-tier-check" />}
                </button>
              );
            })}
          </div>
          <div className="rg-mkt-meta">
            <span className="rg-mkt-pillar">Endpoints</span>
            <code>/v1/laura/analyze-meal</code>
            <code>/v1/laura/ingredient-insights</code>
            <code>/v1/laura/health-score</code>
            <code>/v1/laura/substitution-engine</code>
          </div>
          <div className="rg-mkt-meta">
            <span className="rg-mkt-pillar">Overage</span>
            <span className="rg-mkt-overage">$0.0025 / AI token request · $0.01 / nutrition analysis</span>
          </div>
        </div>

        {/* Health Rules, Basic / Professional / Enterprise */}
        <div className="rg-mkt-card">
          <div className="rg-mkt-card-head">
            <div className="rg-mkt-ic rules"><Icon name="shield-check" size={16} stroke={2.2} /></div>
            <div>
              <div className="rg-mkt-t">Health Rules API <span className="rg-mkt-tag">Compliance</span></div>
              <div className="rg-mkt-d">Chronic-condition checks, dietary rules, allergen-conflict validation. Used by healthcare &amp; enterprise food.</div>
            </div>
          </div>
          <div className="rg-mkt-tiers">
            {[
              { id: "rules-basic", t: "Basic", price: "+$199/mo", unit: "100,000 validations" },
              { id: "rules-pro", t: "Professional", price: "+$699/mo", unit: "750,000 validations" },
              { id: "rules-enterprise", t: "Enterprise", price: "Custom", unit: "Volume + SLA", contact: true },
            ].map((tier) => {
              const on = data.addonTiers?.rules === tier.id;
              return (
                <button key={tier.id} type="button" className={`rg-mkt-tier ${on ? "on" : ""}`} onClick={() => {
                  if (tier.contact) return;
                  set("addonTiers", { ...(data.addonTiers || {}), rules: on ? null : tier.id });
                }}>
                  <div className="t">{tier.t}{tier.contact && <span className="rg-mkt-tier-flag">Sales</span>}</div>
                  <div className="p">{tier.price}</div>
                  <div className="u">{tier.unit}</div>
                  {on && <Icon name="check-circle" size={14} stroke={2.6} className="rg-mkt-tier-check" />}
                </button>
              );
            })}
          </div>
          <div className="rg-mkt-coverage">
            <div>
              <span className="rg-mkt-pillar">Chronic</span>
              <span>Diabetes T1 · Diabetes T2 · Hypertension · Heart disease · CKD · Liver · Obesity · Cancer support</span>
            </div>
            <div>
              <span className="rg-mkt-pillar">Dietary</span>
              <span>Low sodium · Gluten-free · Dairy-free · Nut-free · Vegan · Vegetarian · Pregnancy-safe · Low carb · High protein</span>
            </div>
            <div>
              <span className="rg-mkt-pillar">Logic</span>
              <span>Sodium / sugar thresholds · Caffeine alerts · Cross-contamination warnings · Allergen conflicts</span>
            </div>
          </div>
          <div className="rg-mkt-meta">
            <span className="rg-mkt-pillar">Endpoints</span>
            <code>/v1/compliance/health-rules</code>
            <code>/v1/compliance/dietary-validation</code>
            <code>/v1/compliance/chronic-condition-check</code>
            <code>/v1/compliance/allergen-risk</code>
          </div>
        </div>

        {/* Recipe Media, single tier */}
        <div className={`rg-mkt-card simple ${(data.addons || []).includes("media") ? "on" : ""}`} onClick={() => {
          const cur = data.addons || [];
          const on = cur.includes("media");
          set("addons", on ? cur.filter(x => x !== "media") : [...cur, "media"]);
        }}>
          <div className="rg-mkt-card-head">
            <div className="rg-mkt-ic media"><Icon name="play-circle" size={16} stroke={2.2} /></div>
            <div>
              <div className="rg-mkt-t">Recipe Media <span className="rg-mkt-tag">Content</span><span className="rg-mkt-price-inline">+$299/mo</span></div>
              <div className="rg-mkt-d">Recipe videos, cooking steps, prep &amp; cook time, serving size, cultural notes, chef notes. 25,000 media requests/mo · $0.01 per extra.</div>
            </div>
            <div className="rg-addon-toggle"><i /></div>
          </div>
        </div>

        {/* Infrastructure tier, 4 add-ons from §31 */}
        <div className="rg-mkt-infra-h">Enterprise infrastructure add-ons<span>contact sales to activate</span></div>
        <div className="rg-mkt-infra-grid">
          {[
            { id: "white-label", ic: "palette", t: "White-Label API", d: "Custom domain (api.yours.com), branded docs, custom webhook signing." },
            { id: "dedicated", ic: "server", t: "Dedicated hosting", d: "Isolated infra · dedicated S3 buckets · multi-domain routing." },
            { id: "residency", ic: "globe", t: "Regional data residency", d: "EU / US / APAC / CA pinned storage. GDPR + audit retention." },
            { id: "encryption", ic: "key-square", t: "Dedicated encryption keys", d: "Per-tenant KMS keys, BYOK / HYOK supported." },
          ].map((a) => (
            <div key={a.id} className="rg-mkt-infra">
              <div className="rg-mkt-ic infra"><Icon name={a.ic} size={14} stroke={2.2} /></div>
              <div className="rg-mkt-infra-body">
                <div className="rg-mkt-infra-t">{a.t}</div>
                <div className="rg-mkt-infra-d">{a.d}</div>
              </div>
              <a href="../book-demo.html" className="rg-mkt-infra-link">Contact <Icon name="arrow-up-right" size={11} stroke={2.4} /></a>
            </div>
          ))}
        </div>
      </div>
      <div className="rg-addons-note">
        <Icon name="info" size={12} stroke={2.4} />
        Add-on activation: Billing → Marketplace → Stripe confirmation → endpoints activated → scoped permissions issued. Locked endpoints return <code>{`{ "error": "subscription_required" }`}</code> until then.
      </div>

      {/* Stripe-style card */}
      <div className="rg-card-mock" data-brand={brand}>
        <div className="rg-card-mock-chip" />
        <div className="rg-card-mock-brand">{brand === "visa" ? "VISA" : brand === "mc" ? "Mastercard" : brand === "amex" ? "AMEX" : brand === "disc" ? "Discover" : "CARD"}</div>
        <div className="rg-card-mock-num">{(card.number || "•••• •••• •••• ••••").padEnd(19, "•")}</div>
        <div className="rg-card-mock-row">
          <div><span>Cardholder</span><strong>{(card.name || "Your name").toUpperCase()}</strong></div>
          <div><span>Expires</span><strong>{card.exp || "MM/YY"}</strong></div>
        </div>
      </div>

      <div className="rg-form-grid">
        <div className="rg-field full">
          <label>Cardholder name <span className="req">*</span></label>
          <input value={card.name || ""} onChange={(e) => setCard("name", e.target.value)} placeholder="Sarah Chen" autoComplete="cc-name" />
        </div>
        <div className="rg-field full">
          <label>Card number <span className="req">*</span></label>
          <div className="rg-input-icon">
            <input value={card.number || ""} onChange={(e) => setCard("number", fmtCard(e.target.value))} placeholder="1234 1234 1234 1234" autoComplete="cc-number" inputMode="numeric" />
            <Icon name="credit-card" size={16} stroke={2.2} />
          </div>
        </div>
        <div className="rg-field">
          <label>Expiry <span className="req">*</span></label>
          <input value={card.exp || ""} onChange={(e) => setCard("exp", fmtExp(e.target.value))} placeholder="MM/YY" autoComplete="cc-exp" inputMode="numeric" />
        </div>
        <div className="rg-field">
          <label>CVC <span className="req">*</span></label>
          <input value={card.cvc || ""} onChange={(e) => setCard("cvc", e.target.value.replace(/\D/g, "").slice(0, 4))} placeholder="123" autoComplete="cc-csc" inputMode="numeric" />
        </div>
        <div className="rg-field full">
          <label>Billing email <span className="req">*</span><span className="opt">where receipts &amp; invoices go</span></label>
          <input type="email" value={card.billingEmail || data.email || ""} onChange={(e) => setCard("billingEmail", e.target.value)} placeholder="billing@yourcompany.com" autoComplete="email" />
        </div>
      </div>

      <div className="rg-stripe-note">
        <Icon name="lock" size={12} stroke={2.4} />
        Card details are tokenized by <strong>Stripe</strong> · we never touch raw card numbers.
      </div>

      {/* Billing address, PRD §10 required during signup */}
      <h3 className="rg-section-h">Billing address</h3>
      <div className="rg-form-grid">
        <div className="rg-field full">
          <label>Street address <span className="req">*</span></label>
          <input value={card.line1 || ""} onChange={(e) => setCard("line1", e.target.value)} placeholder="100 Market Street" autoComplete="address-line1" />
        </div>
        <div className="rg-field full">
          <label>Apt / Suite <span className="opt">optional</span></label>
          <input value={card.line2 || ""} onChange={(e) => setCard("line2", e.target.value)} placeholder="Suite 400" autoComplete="address-line2" />
        </div>
        <div className="rg-field">
          <label>City <span className="req">*</span></label>
          <input value={card.city || ""} onChange={(e) => setCard("city", e.target.value)} placeholder="San Francisco" autoComplete="address-level2" />
        </div>
        <div className="rg-field">
          <label>State / Region <span className="req">*</span></label>
          <input value={card.state || ""} onChange={(e) => setCard("state", e.target.value)} placeholder="CA" autoComplete="address-level1" />
        </div>
        <div className="rg-field">
          <label>Postal code <span className="req">*</span></label>
          <input value={card.postal || ""} onChange={(e) => setCard("postal", e.target.value)} placeholder="94103" autoComplete="postal-code" />
        </div>
        <div className="rg-field">
          <label>Country <span className="req">*</span></label>
          <select value={card.country || ""} onChange={(e) => setCard("country", e.target.value)} autoComplete="country">
            <option value="">Select…</option>
            <option>United States</option><option>Canada</option><option>United Kingdom</option>
            <option>Germany</option><option>France</option><option>Spain</option>
            <option>Netherlands</option><option>Mexico</option><option>Brazil</option>
            <option>Australia</option><option>Singapore</option><option>India</option><option>Other</option>
          </select>
        </div>
      </div>

      {/* Agreements, PRD §13, §14, §15 explicit */}
      <h3 className="rg-section-h">Agreements &amp; policies</h3>
      <div className="rg-agree-list">
        <label className="rg-agree">
          <input type="checkbox" checked={!!data.agreeTos} onChange={(e) => set("agreeTos", e.target.checked)} />
          <span className="box"><Icon name="check" size={11} stroke={3.2} /></span>
          <span className="body">
            <strong>Terms &amp; usage policies</strong>, I agree to NutriDMS's:
            <span className="rg-agree-list-inline">
              <span><a href="#">Terms of Service</a></span>
              <span><a href="#">API Usage Policy</a></span>
              <span><a href="#">Anti-abuse Policy</a></span>
              <span><a href="#">Rate-limit Policy</a></span>
              <span><a href="#">Data Handling Policy</a></span>
            </span>
          </span>
        </label>
        <label className="rg-agree">
          <input type="checkbox" checked={!!data.agreeIp} onChange={(e) => set("agreeIp", e.target.checked)} />
          <span className="box"><Icon name="check" size={11} stroke={3.2} /></span>
          <span className="body">
            <strong>Intellectual property acknowledgement</strong>, I acknowledge that the following remain the intellectual property of <strong>NutriDMS</strong> and <strong>SoftLab Digital</strong> unless otherwise agreed in writing, and that I have no rights to redistribute, resell, or republish raw data:
            <span className="rg-agree-ip-grid">
              <span>Nutrition databases</span>
              <span>Ingredient mappings</span>
              <span>Recipe structures</span>
              <span>Cooking steps</span>
              <span>Recipe videos</span>
              <span>Health-rule systems</span>
              <span>Validation logic</span>
              <span>Loraa.ai outputs</span>
              <span>API documentation</span>
            </span>
          </span>
        </label>
        <label className="rg-agree">
          <input type="checkbox" checked={!!data.agreeData} onChange={(e) => set("agreeData", e.target.checked)} />
          <span className="box"><Icon name="check" size={11} stroke={3.2} /></span>
          <span className="body">
            <strong>Customer data ownership</strong>, Data I upload remains <strong>mine</strong>. I authorise NutriDMS to process it <em>only</em> for:
            <span className="rg-agree-purpose-list">
              <span><Icon name="check-check" size={10} stroke={2.6} /> validation</span>
              <span><Icon name="check-check" size={10} stroke={2.6} /> platform operations</span>
              <span><Icon name="check-check" size={10} stroke={2.6} /> AI improvement</span>
              <span><Icon name="check-check" size={10} stroke={2.6} /> abuse prevention</span>
              <span><Icon name="check-check" size={10} stroke={2.6} /> compliance monitoring</span>
            </span>
          </span>
        </label>
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}><Icon name="arrow-left" size={14} stroke={2.4} /> Back</button>
        <div className="spacer" />
        <button type="submit" className="btn primary" disabled={!valid}>Start 7-day trial <Icon name="arrow-right" size={14} stroke={2.4} /></button>
      </div>
    </form>
  );
}

/* ─── API Step 5, Generate sandbox API key ─── */
function genKey() {
  const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  let k = "";
  for (let i = 0; i < 32; i++) k += chars[Math.floor(Math.random() * chars.length)];
  return `sk_sbx_${k}`;
}

function StepGenerateKey({ data, set, next, back, stepNum, total }) {
  const [phase, setPhase] = useRgState(data.apiKey ? "ready" : "idle"); // idle | generating | ready
  const [revealed, setRevealed] = useRgState(false);
  const [copied, setCopied] = useRgState(false);
  const apiKey = data.apiKey || "";

  const generate = () => {
    setPhase("generating");
    setTimeout(() => {
      const k = genKey();
      set("apiKey", k);
      setPhase("ready");
      setRevealed(true);
    }, 1100);
  };

  const copy = () => {
    if (!apiKey) return;
    navigator.clipboard?.writeText(apiKey);
    setCopied(true);
    setTimeout(() => setCopied(false), 1600);
  };

  const masked = apiKey ? `${apiKey.slice(0, 12)}${"•".repeat(16)}${apiKey.slice(-4)}` : "";

  // §18 Supported endpoints + locked add-on endpoints (§23, §29), full list
  const ALL_ENDPOINTS = [
    { id: "ingredients-lookup", path: "/v1/ingredients/lookup", t: "Ingredient lookup", g: "core", method: "POST" },
    { id: "recipes-analyze", path: "/v1/recipes/analyze", t: "Recipe analyze", g: "core", method: "POST" },
    { id: "beverages-analyze", path: "/v1/beverages/analyze", t: "Beverage analyze", g: "core", method: "POST" },
    { id: "allergens-detect", path: "/v1/allergens/detect", t: "Allergen detection", g: "core", method: "POST" },
    { id: "labels-generate", path: "/v1/labels/generate", t: "Nutrition labels", g: "core", method: "POST" },
    { id: "laura-meal", path: "/v1/laura/analyze-meal", t: "Loraa · analyze meal", g: "laura", method: "POST", lock: "Loraa.ai add-on" },
    { id: "laura-insights", path: "/v1/laura/ingredient-insights", t: "Loraa · ingredient insights", g: "laura", method: "POST", lock: "Loraa.ai add-on" },
    { id: "laura-health", path: "/v1/laura/health-score", t: "Loraa · health score", g: "laura", method: "POST", lock: "Loraa.ai add-on" },
    { id: "laura-subs", path: "/v1/laura/substitution-engine", t: "Loraa · substitution engine", g: "laura", method: "POST", lock: "Loraa.ai add-on" },
    { id: "rules-main", path: "/v1/compliance/health-rules", t: "Health rules check", g: "rules", method: "POST", lock: "Health Rules add-on" },
    { id: "rules-diet", path: "/v1/compliance/dietary-validation", t: "Dietary validation", g: "rules", method: "POST", lock: "Health Rules add-on" },
    { id: "rules-chronic", path: "/v1/compliance/chronic-condition-check", t: "Chronic-condition check", g: "rules", method: "POST", lock: "Health Rules add-on" },
    { id: "rules-allergen", path: "/v1/compliance/allergen-risk", t: "Allergen risk", g: "rules", method: "POST", lock: "Health Rules add-on" },
  ];

  const [selEndpoint, setSel] = useRgState("ingredients-lookup");
  const [lang, setLang] = useRgState("curl");
  const ep = ALL_ENDPOINTS.find(e => e.id === selEndpoint) || ALL_ENDPOINTS[0];
  const k = apiKey || "sk_sbx_••••";

  // Sample payloads per endpoint
  const PAYLOADS = {
    "ingredients-lookup": { query: "grilled chicken breast", per_100g: true },
    "recipes-analyze": { title: "Quinoa Power Bowl", ingredients: ["1 cup cooked quinoa", "150g grilled chicken", "1/2 avocado", "1 tbsp olive oil"] },
    "beverages-analyze": { name: "Iced oat latte", volume_ml: 350, ingredients: ["espresso 60ml", "oat milk 250ml", "ice"] },
    "allergens-detect": { ingredients: ["wheat flour", "milk", "cashews", "eggs"] },
    "labels-generate": { recipe_id: "rcp_3F2x9Q", format: "us_fda_2020" },
    "laura-meal": { meal: { items: ["1 cup oatmeal", "1 banana", "1 tbsp peanut butter"] } },
    "laura-insights": { ingredient: "tempeh" },
    "laura-health": { recipe_id: "rcp_3F2x9Q", conditions: ["diabetes_t2"] },
    "laura-subs": { ingredient: "all-purpose flour", target: "gluten_free" },
    "rules-main": { recipe_id: "rcp_3F2x9Q", rules: ["low_sodium", "heart_health"] },
    "rules-diet": { recipe_id: "rcp_3F2x9Q", diets: ["vegetarian", "gluten_free"] },
    "rules-chronic": { recipe_id: "rcp_3F2x9Q", condition: "ckd_stage_3" },
    "rules-allergen": { recipe_id: "rcp_3F2x9Q", profile: ["dairy", "tree_nuts"] },
  };
  const payload = PAYLOADS[selEndpoint] || {};
  const payloadJson = JSON.stringify(payload, null, 2);

  const SDK = {
    curl: `curl https://api.nutridms.com${ep.path} \\
  -H "Authorization: Bearer ${k}" \\
  -H "Content-Type: application/json" \\
  -d '${JSON.stringify(payload)}'`,
    node: `import { NutriDMS } from "@nutridms/node";
const client = new NutriDMS("${k}");

const result = await client.${ep.id.replace(/-/g, "_")}(${JSON.stringify(payload, null, 2)});
console.log(result);`,
    python: `from nutridms import NutriDMS
client = NutriDMS(api_key="${k}")

result = client.${ep.id.replace(/-/g, "_")}(**${payloadJson.replace(/"([^"]+)":/g, '$1=').replace(/\n/g, "\n  ")})
print(result)`,
    swift: `import NutriDMS
let client = NutriDMS(apiKey: "${k}")

let result = try await client.call(
    endpoint: "${ep.path}",
    body: ${payloadJson}
)`,
    kotlin: `val client = NutriDMS(apiKey = "${k}")

val result = client.post(
    path = "${ep.path}",
    body = mapOf(
${Object.entries(payload).map(([k2, v]) => `        "${k2}" to ${typeof v === "string" ? `"${v}"` : Array.isArray(v) ? `listOf(${v.map(x => typeof x === "string" ? `"${x}"` : x).join(", ")})` : v}`).join(",\n")}
    )
)`,
  };

  // §19 Standard response structure, tailored per endpoint
  const RESPONSES = {
    "ingredients-lookup": {
      ingredient_id: "ing_8H21k", name: "Chicken breast, grilled",
      nutrition_per_100g: { calories: 165, protein_g: 31, carbs_g: 0, fat_g: 3.6, sodium_mg: 74 },
      allergens: [], health_tags: ["high_protein", "low_carb", "lean"], usda_id: "171477", confidence: 0.98,
    },
    "recipes-analyze": {
      recipe_id: "rcp_3F2x9Q", servings: 2,
      ingredients: [{ name: "quinoa, cooked", qty_g: 185 }, { name: "chicken breast", qty_g: 150 }, { name: "avocado", qty_g: 100 }],
      nutrition_summary: { calories: 612, protein_g: 38.4, carbs_g: 41, fat_g: 28, sodium_mg: 96 },
      allergens: [], health_tags: ["high_protein", "heart_healthy", "gluten_free"], confidence: 0.94,
    },
    "allergens-detect": {
      recipe_id: "rcp_3F2x9Q", detected: ["gluten", "milk", "tree_nuts", "eggs"], risk: "high", cross_contam_risk: ["soy"], confidence: 0.91,
    },
  };
  const respJson = JSON.stringify(RESPONSES[selEndpoint] || {
    recipe_id: "rcp_3F2x9Q", ingredients: [], nutrition_summary: {}, allergens: [], health_tags: [], confidence: 0.9,
  }, null, 2);

  const SDK_TABS = [
    { id: "curl", t: "cURL" },
    { id: "node", t: "Node.js" },
    { id: "python", t: "Python" },
    { id: "swift", t: "Swift" },
    { id: "kotlin", t: "Kotlin" },
  ];

  return (
    <div>
      <span className="rg-form-eyebrow"><Icon name="key-round" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Generate your sandbox key</h1>
      <p className="rg-form-sub">This is a <strong>test key</strong>, safe to use against sandbox endpoints with mock data. You can rotate, scope, or revoke it anytime from your API Console.</p>

      <div className={`rg-keybox ${phase}`}>
        {phase === "idle" && (
          <div className="rg-keybox-empty">
            <div className="rg-keybox-icon"><Icon name="key-round" size={22} stroke={2} /></div>
            <strong>No keys yet</strong>
            <p>Generate a sandbox key to start calling endpoints from your nutrition mobile app.</p>
            <button type="button" className="btn primary" onClick={generate}>
              <Icon name="zap" size={14} stroke={2.4} /> Generate sandbox key
            </button>
          </div>
        )}
        {phase === "generating" && (
          <div className="rg-keybox-busy">
            <div className="rg-keybox-spin" />
            <strong>Generating key…</strong>
            <p>Setting up your practice workspace · applying permissions · attaching to {data.workspaceName || "your workspace"}.</p>
          </div>
        )}
        {phase === "ready" && (
          <div className="rg-keybox-ready">
            <div className="rg-keybox-head">
              <span className="rg-keybox-status"><span className="dot" /> Sandbox · Active</span>
              <span className="rg-keybox-name">{(data.workspaceName || "workspace") + " · default-key"}</span>
            </div>
            <div className="rg-keybox-key">
              <code>{revealed ? apiKey : masked}</code>
              <div className="rg-keybox-actions">
                <button type="button" onClick={() => setRevealed(r => !r)} title={revealed ? "Hide" : "Reveal"}>
                  <Icon name={revealed ? "eye-off" : "eye"} size={13} stroke={2.4} />
                </button>
                <button type="button" onClick={copy} title="Copy">
                  <Icon name={copied ? "check" : "copy"} size={13} stroke={2.4} />
                  <span>{copied ? "Copied" : "Copy"}</span>
                </button>
              </div>
            </div>
            <div className="rg-keybox-warn">
              <Icon name="shield-alert" size={12} stroke={2.4} />
              <span>Store this key in your mobile app's secure backend, never bundle it in the client. Need a public key? <a href="#">Read the docs</a>.</span>
            </div>
            <div className="rg-keybox-scope">
              <span className="lbl">Scopes</span>
              <span className="rg-keybox-scope-chip on">ingredients.lookup</span>
              <span className="rg-keybox-scope-chip on">recipes.analyze</span>
              <span className="rg-keybox-scope-chip on">beverages.analyze</span>
              <span className="rg-keybox-scope-chip on">allergens.detect</span>
              <span className="rg-keybox-scope-chip on">labels.generate</span>
              <span className="rg-keybox-scope-chip">laura.ai · add-on</span>
              <span className="rg-keybox-scope-chip">health.rules · add-on</span>
              <span className="rg-keybox-scope-chip">recipe.media · add-on</span>
            </div>
          </div>
        )}
      </div>

      <h3 className="rg-section-h">Developer sandbox<span className="rg-section-h-meta">interactive playground · live request testing · code snippets · SDK examples</span></h3>

      {/* §18 Endpoint picker, all 13 endpoints, with locked indicators for add-ons */}
      <div className="rg-endpoints">
        <div className="rg-endpoint-group">
          <span className="rg-endpoint-group-h">Core endpoints<span>included in your plan</span></span>
          <div className="rg-endpoint-list">
            {ALL_ENDPOINTS.filter(e => e.g === "core").map(e => (
              <button key={e.id} type="button" className={`rg-endpoint ${selEndpoint === e.id ? "on" : ""}`} onClick={() => setSel(e.id)}>
                <span className="m">{e.method}</span>
                <span className="p">{e.path}</span>
                <span className="t">{e.t}</span>
              </button>
            ))}
          </div>
        </div>
        <div className="rg-endpoint-group">
          <span className="rg-endpoint-group-h">Loraa.ai endpoints<span>requires Loraa.ai add-on</span></span>
          <div className="rg-endpoint-list">
            {ALL_ENDPOINTS.filter(e => e.g === "laura").map(e => (
              <button key={e.id} type="button" className={`rg-endpoint locked ${selEndpoint === e.id ? "on" : ""}`} onClick={() => setSel(e.id)}>
                <span className="m">{e.method}</span>
                <span className="p">{e.path}</span>
                <span className="t">{e.t}</span>
                <Icon name="lock" size={11} stroke={2.4} className="lk" />
              </button>
            ))}
          </div>
        </div>
        <div className="rg-endpoint-group">
          <span className="rg-endpoint-group-h">Health Rules endpoints<span>requires Health Rules add-on</span></span>
          <div className="rg-endpoint-list">
            {ALL_ENDPOINTS.filter(e => e.g === "rules").map(e => (
              <button key={e.id} type="button" className={`rg-endpoint locked ${selEndpoint === e.id ? "on" : ""}`} onClick={() => setSel(e.id)}>
                <span className="m">{e.method}</span>
                <span className="p">{e.path}</span>
                <span className="t">{e.t}</span>
                <Icon name="lock" size={11} stroke={2.4} className="lk" />
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Request / Response split, §19 standard response structure */}
      <div className="rg-sandbox">
        <div className="rg-sandbox-col">
          <div className="rg-sandbox-h">
            <span className="rg-sandbox-h-l">Request</span>
            <div className="rg-snippet-tabs">
              {SDK_TABS.map(s => (
                <span key={s.id} className={lang === s.id ? "on" : ""} onClick={() => setLang(s.id)}>{s.t}</span>
              ))}
            </div>
          </div>
          <pre className="rg-snippet-code"><code>{SDK[lang]}</code></pre>
          <div className="rg-snippet-foot">
            <Icon name="terminal-square" size={12} stroke={2.4} />
            {ep.lock
              ? <span><Icon name="lock" size={11} stroke={2.4} /> Endpoint requires the <strong>{ep.lock}</strong>. Sandbox calls return mock data; production calls return <code>subscription_required</code>.</span>
              : <span>Run from your nutrition app's backend or try in the <a href="../api-sandbox.html">interactive sandbox</a>.</span>}
          </div>
        </div>
        <div className="rg-sandbox-col">
          <div className="rg-sandbox-h">
            <span className="rg-sandbox-h-l">Response</span>
            <span className="rg-sandbox-h-r">
              <span className="rg-sandbox-status">200 OK</span>
              <span className="rg-sandbox-latency">142ms</span>
              <button type="button" className="rg-sandbox-copy" onClick={() => navigator.clipboard?.writeText(respJson)}>
                <Icon name="copy" size={11} stroke={2.4} /> Copy JSON
              </button>
            </span>
          </div>
          <pre className="rg-snippet-code response"><code>{respJson}</code></pre>
          <div className="rg-snippet-foot">
            <Icon name="check-circle" size={12} stroke={2.4} />
            Standard response: <code>recipe_id</code>, <code>ingredients</code>, <code>nutrition_summary</code>, <code>allergens</code>, <code>health_tags</code>, <code>confidence</code>.
          </div>
        </div>
      </div>

      {/* SDK matrix */}
      <div className="rg-sdks">
        <span className="rg-sdks-h">Official SDKs</span>
        {[
          { id: "node", t: "Node.js", pkg: "@nutridms/node" },
          { id: "python", t: "Python", pkg: "nutridms" },
          { id: "swift", t: "Swift", pkg: "NutriDMS-iOS" },
          { id: "kotlin", t: "Kotlin", pkg: "io.nutridms:android" },
          { id: "go", t: "Go", pkg: "github.com/nutridms/go" },
          { id: "ruby", t: "Ruby", pkg: "nutridms-rb" },
        ].map(s => (
          <span key={s.id} className="rg-sdk-chip"><strong>{s.t}</strong><code>{s.pkg}</code></span>
        ))}
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}><Icon name="arrow-left" size={14} stroke={2.4} /> Back</button>
        <div className="spacer" />
        <button type="button" className="btn primary" onClick={next} disabled={phase !== "ready"}>
          Open API Console <Icon name="arrow-right" size={14} stroke={2.4} />
        </button>
      </div>
    </div>
  );
}

/* ─── Step 4, Plan ─── */
const TRIAL_PLANS = [
{ id: "starter", name: "Starter", price: "$99", per: "/mo after trial", for: "Small food businesses and early teams.", features: ["Master Ingredient Library", "Recipes and subrecipes", "FDA and CFIA labels", "Basic costing", "5 users", "500 Loraa AI credits/month"] },
{ id: "growth", name: "Growth", price: "$130", per: "/mo after trial", for: "Scaling brands needing audit-grade compliance.", features: ["Everything in Starter", "Supplement Facts", "Loraa QA", "Approval workflows", "12 users", "2,500 Loraa AI credits/month"] },
{ id: "professional", name: "Professional", price: "$299", per: "/mo after trial", for: "Operational food teams managing production.", features: ["Everything in Growth", "Advanced costing", "Inventory and lot tracing", "Production and recalls", "25 users", "5,000 Loraa AI credits/month"], recommended: true },
{ id: "enterprise", name: "Enterprise", price: "$699", per: "/mo after trial", for: "Centralized governance for up to three locations.", features: ["Everything in Professional", "Up to 3 locations", "Advanced RBAC and SSO", "Enterprise API and integrations", "100 users", "Custom Loraa AI credits"] }];


function StepPlan({ data, set, next, back, stepNum = 4, total = 6 }) {
  const valid = data.plan;
  return (
    <div>
      <span className="rg-form-eyebrow"><Icon name="package-2" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Choose your trial plan</h1>
      <p className="rg-form-sub">All trials are free for 7 days. You won't be charged until trial ends and you can downgrade or cancel anytime.</p>

      <div className="rg-plans">
        {TRIAL_PLANS.map((p) =>
          <button key={p.id} type="button" className={`rg-plan ${data.plan === p.id ? "on" : ""}`} onClick={() => set("plan", p.id)}>
            {p.recommended && <div className="ribbon">Recommended</div>}
            <div className="select-mark"><Icon name="check" size={12} stroke={3} /></div>
            <div className="tier-name">{p.name}</div>
            <div className="price">{p.price}<span className="per">{p.per}</span></div>
            <div className="for">{p.for}</div>
            <ul>
              {p.features.map((f, i) =>
                <li key={i}><Icon name="check" size={12} stroke={2.6} /> {f}</li>
              )}
            </ul>
          </button>
        )}
      </div>

      <div className="rg-laura-opt">
        <div className="ic"><Icon name="lightbulb" size={18} stroke={2.2} /></div>
        <div className="body">
          <div className="t">Loraa.ai is included with every trial.</div>
          <div className="d">Try AI-assisted validation, compliance scoring, and ingredient QA. You'll get trial tokens to test it; upgrade or top up later from Settings → AI usage.</div>
          <span className="tokens"><Icon name="zap" size={11} stroke={2.6} /> {data.plan === "enterprise" ? "Custom enterprise allocation" : data.plan === "professional" ? "5,000 Loraa AI credits/month" : data.plan === "growth" ? "2,500 Loraa AI credits/month" : "500 Loraa AI credits/month"}</span>
        </div>
      </div>

      <div className={`rg-wl-opt ${data.plan === "enterprise" ? "on" : ""}`}>
        <div className="rg-wl-opt-main">
          <div className="ic"><Icon name="globe" size={18} stroke={2.2} /></div>
          <div className="body">
            <div className="t">White-label options {data.plan === "enterprise" ? <span className="rg-wl-opt-tag">Included</span> : <span className="rg-wl-opt-tag">Enterprise</span>}</div>
            <div className="d">{data.plan === "enterprise" ? "Enterprise includes white-label options, custom permissions, advanced SSO and dedicated onboarding." : "White-label options are available when the organization upgrades to Enterprise."}</div>
          </div>
        </div>
        <div className="rg-wl-opt-aside">
          <div className="rg-wl-opt-meta">{data.plan === "enterprise" ? "$0 included" : "Not available on this tier"}</div>
        </div>
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}>
          <Icon name="arrow-left" size={14} stroke={2.4} /> Back
        </button>
        <div className="spacer" />
        <button type="button" className="btn primary" onClick={next} disabled={!valid}>
          Start free trial <Icon name="arrow-right" size={14} stroke={2.4} />
        </button>
      </div>
    </div>);

}

/* ─── Step 5, Invite ─── */
const INVITE_ROLES = [
  "Admin",
  "Manager",
  "Compliance",
  "QA Reviewer",
  "Dietitian",
  "Contributor",
  "Media Contributor"];


function StepInvite({ data, set, next, back, skip, stepNum = 5, total = 6, isLast = false }) {
  const invites = data.invites || [{ email: "", role: "Contributor" }];
  const update = (i, k, v) => {
    const next = [...invites];
    next[i] = { ...next[i], [k]: v };
    set("invites", next);
  };
  const add = () => set("invites", [...invites, { email: "", role: "Contributor" }]);
  const remove = (i) => set("invites", invites.filter((_, j) => j !== i));

  return (
    <div>
      <span className="rg-form-eyebrow"><Icon name="users" size={12} stroke={2.6} /> Step {stepNum} of {total}</span>
      <h1 className="rg-form-h1">Invite your team</h1>
      <p className="rg-form-sub">Send invites now or skip and add teammates later. Roles control what each member can see and do, all enforced at the API layer.</p>

      <div className="rg-invite-list">
        {invites.map((inv, i) =>
          <div key={i} className="rg-invite-row">
            <input
              type="email"
              value={inv.email}
              onChange={(e) => update(i, "email", e.target.value)}
              placeholder="teammate@yourcompany.com" />

            <select value={inv.role} onChange={(e) => update(i, "role", e.target.value)}>
              {INVITE_ROLES.map((r) => <option key={r}>{r}</option>)}
            </select>
            <button type="button" className="x" onClick={() => remove(i)} aria-label="Remove" disabled={invites.length <= 1}>
              <Icon name="x" size={16} stroke={2.4} />
            </button>
          </div>
        )}
        <button type="button" className="rg-add-row" onClick={add}>
          <Icon name="plus" size={14} stroke={2.4} /> Add another teammate
        </button>
      </div>

      <div style={{ marginTop: 18, padding: "14px 16px", background: "var(--gray-50)", border: "1px solid var(--gray-200)", borderRadius: 10, fontSize: 12.5, color: "var(--gray-600)", lineHeight: 1.55, display: "flex", gap: 10 }}>
        <Icon name="info" size={14} stroke={2.4} style={{ marginTop: 2, color: "var(--brand-700)", flexShrink: 0 }} />
        <span>
          <strong style={{ color: "var(--text-primary)" }}>Permissions are inherited.</strong> See <a href="../documentation.html#roles" style={{ color: "var(--brand-700)", fontWeight: 700 }}>Roles &amp; permissions</a> for the full matrix. You can change roles or remove members from Workspace → Members.
        </span>
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}>
          <Icon name="arrow-left" size={14} stroke={2.4} /> Back
        </button>
        <div className="spacer" />
        <button type="button" className="skip" onClick={skip}>Skip for now</button>
        <button type="button" className="btn primary" onClick={next}>
          {isLast ? <>Open my workspace <Icon name="arrow-right" size={14} stroke={2.4} /></> : <>Send invites <Icon name="arrow-right" size={14} stroke={2.4} /></>}
        </button>
      </div>
    </div>);

}

/* ─── Step 6, Goals ─── */
const SETUP_GOALS = [
  { id: "ingredients", t: "Import ingredients", s: "Upload your ingredient catalog.", ic: "leaf", action: "upload", actionLabel: "Upload CSV" },
  { id: "recipes", t: "Import recipes", s: "Bulk-upload recipes via CSV.", ic: "chef-hat", action: "upload", actionLabel: "Upload CSV" },
  { id: "allergens", t: "Configure allergens", s: "Set up your allergen matrix.", ic: "shield-alert", action: "later", actionLabel: "Complete in workspace" },
  { id: "rules", t: "Validation rules", s: "Health & compliance rules.", ic: "shield-check", action: "later", actionLabel: "Complete in workspace" },
  { id: "sandbox", t: "Open API sandbox", s: "Try endpoints with sample data.", ic: "code-2", action: "later", actionLabel: "Open from workspace" },
  { id: "labels", t: "Generate labels", s: "Create your first FDA panel.", ic: "file-text", action: "later", actionLabel: "Generate in workspace" }];


/* Drawer shown on the right when an upload-action goal is open */
function UploadDrawer({ goal, data, set, onClose }) {
  if (!goal) return null;
  const uploadedKey = `uploaded_${goal.id}`;
  const sampleRows = goal.id === "ingredients"
    ? [
      ["name", "category", "unit", "supplier", "allergens"],
      ["Chicken Breast", "Protein", "g", "Tyson", ""],
      ["Whole Wheat Flour", "Grain", "g", "Bob's Red Mill", "Wheat,Gluten"],
      ["Greek Yogurt", "Dairy", "g", "Chobani", "Milk"]]

    : [
      ["recipe_name", "servings", "ingredients", "instructions", "health_tags"],
      ["Roasted Salmon Bowl", "4", "Salmon|Rice|Broccoli", "Bake 18 min…", "Low Sodium,High Protein"],
      ["Quinoa Power Bowl", "2", "Quinoa|Chickpea|Spinach", "Toss with…", "Diabetic Safe,Heart Friendly"]];

  const uploaded = data[uploadedKey];

  return (
    <>
      <div className="rg-drawer-scrim" onClick={onClose} />
      <aside className="rg-drawer">
        <div className="rg-drawer-head">
          <div className="rg-drawer-head-meta">
            <div className="ic"><Icon name={goal.ic} size={18} stroke={2.2} /></div>
            <div>
              <h3>{goal.t}</h3>
              <p>{goal.s}</p>
            </div>
          </div>
          <button className="rg-drawer-x" onClick={onClose} aria-label="Close">
            <Icon name="x" size={16} stroke={2.4} />
          </button>
        </div>

        <div className="rg-drawer-body">
          {!uploaded ? (
            <>
              <div className="rg-drop">
                <Icon name="upload-cloud" size={28} stroke={1.8} />
                <strong>Drop your CSV here</strong>
                <p>or click to browse. Max 50 MB · UTF-8 encoded.</p>
                <button
                  type="button"
                  className="btn primary sm"
                  onClick={() => set(uploadedKey, { name: `${goal.id}.csv`, rows: 412, mapped: 408, errors: 4 })}>
                  <Icon name="file-up" size={13} stroke={2.4} /> Choose file
                </button>
              </div>

              <div className="rg-drawer-section">
                <div className="rg-drawer-section-h">
                  <Icon name="file-text" size={13} stroke={2.4} />
                  <strong>Required columns</strong>
                </div>
                <div className="rg-table-preview">
                  {sampleRows.map((row, i) => (
                    <div key={i} className={`row ${i === 0 ? "head" : ""}`}>
                      {row.map((c, j) => <span key={j}>{c}</span>)}
                    </div>
                  ))}
                </div>
                <a href="#" className="rg-drawer-link">
                  <Icon name="download" size={12} stroke={2.4} /> Download {goal.id} CSV template
                </a>
              </div>

              <div className="rg-drawer-section">
                <div className="rg-drawer-section-h">
                  <Icon name="lightbulb" size={13} stroke={2.4} />
                  <strong>What happens next</strong>
                </div>
                <ul className="rg-drawer-list">
                  <li><Icon name="check" size={12} stroke={2.6} /> Loraa.ai maps each row to USDA / FDA references.</li>
                  <li><Icon name="check" size={12} stroke={2.6} /> Any unmapped items show up in workspace QA for review.</li>
                  <li><Icon name="check" size={12} stroke={2.6} /> No data is published until you approve.</li>
                </ul>
              </div>
            </>
          ) : (
            <div className="rg-uploaded">
              <div className="rg-uploaded-head">
                <div className="ic ok"><Icon name="check-check" size={16} stroke={2.6} /></div>
                <div>
                  <strong>{uploaded.name}</strong>
                  <p>{uploaded.rows.toLocaleString()} rows received. Loraa will map them in the background.</p>
                </div>
              </div>
              <div className="rg-uploaded-stats">
                <div><strong>{uploaded.rows}</strong><span>total rows</span></div>
                <div><strong className="ok">{uploaded.mapped}</strong><span>auto-mapped</span></div>
                <div><strong className="warn">{uploaded.errors}</strong><span>need review</span></div>
              </div>
              <button type="button" className="btn ghost sm" onClick={() => set(uploadedKey, null)}>
                <Icon name="rotate-ccw" size={12} stroke={2.4} /> Upload a different file
              </button>
            </div>
          )}
        </div>

        <div className="rg-drawer-foot">
          <button type="button" className="btn ghost sm" onClick={onClose}>Skip, I'll do this later</button>
          <button type="button" className="btn primary" onClick={onClose}>
            <Icon name="check" size={13} stroke={2.4} /> Done
          </button>
        </div>
      </aside>
    </>);

}

function StepGoals({ data, set, next, back, stepNum = 6, total = 6 }) {
  const goals = data.goals || [];
  const [openGoal, setOpenGoal] = useRgState(null);
  const toggle = (g) => {
    const next = goals.includes(g.id) ? goals.filter((x) => x !== g.id) : [...goals, g.id];
    set("goals", next);
    // Auto-open the upload drawer if a CSV-action goal was just turned on
    if (g.action === "upload" && !goals.includes(g.id)) setOpenGoal(g);
  };
  const openDrawer = (g, e) => {
    e.stopPropagation();
    if (!goals.includes(g.id)) {
      set("goals", [...goals, g.id]);
    }
    setOpenGoal(g);
  };

  return (
    <div>
      <span className="rg-form-eyebrow"><Icon name="target" size={12} stroke={2.6} /> Step {stepNum} of {total} · Optional</span>
      <h1 className="rg-form-h1">What do you want to do first?</h1>
      <p className="rg-form-sub">Pick what you want to set up now. <strong style={{ color: "var(--text-primary)" }}>Ingredients</strong> and <strong style={{ color: "var(--text-primary)" }}>recipes</strong> can be uploaded here; everything else becomes a guided task on your dashboard.</p>

      <div className="rg-goals">
        {SETUP_GOALS.map((g) => {
          const selected = goals.includes(g.id);
          const isUpload = g.action === "upload";
          const uploaded = data[`uploaded_${g.id}`];
          return (
            <button
              key={g.id}
              type="button"
              className={`rg-goal ${selected ? "on" : ""} ${isUpload ? "upload-goal" : ""}`}
              onClick={() => toggle(g)}>

              <div className="check"><Icon name="check" size={11} stroke={3} /></div>
              <div className="ic"><Icon name={g.ic} size={16} stroke={2.2} /></div>
              <div className="nm">{g.t}</div>
              <div className="sm">{g.s}</div>

              {isUpload && (
                <div className="rg-goal-action">
                  {uploaded ? (
                    <span className="rg-goal-pill ok">
                      <Icon name="check-circle-2" size={11} stroke={2.6} />
                      {uploaded.rows} rows uploaded
                    </span>
                  ) : selected ? (
                    <span
                      className="rg-goal-pill link"
                      onClick={(e) => openDrawer(g, e)}
                      role="button">
                      <Icon name="upload" size={11} stroke={2.6} />
                      {g.actionLabel}
                    </span>
                  ) : (
                    <span className="rg-goal-pill">
                      <Icon name="upload" size={11} stroke={2.6} />
                      CSV upload
                    </span>
                  )}
                </div>
              )}
              {!isUpload && (
                <div className="rg-goal-action">
                  <span className="rg-goal-pill">
                    <Icon name="clock" size={11} stroke={2.6} />
                    {g.actionLabel}
                  </span>
                </div>
              )}
            </button>);

        })}
      </div>

      <div className="rg-cta-row">
        <button type="button" className="back-btn" onClick={back}>
          <Icon name="arrow-left" size={14} stroke={2.4} /> Back
        </button>
        <div className="spacer" />
        <button type="button" className="btn primary" onClick={next}>
          Open my workspace <Icon name="arrow-right" size={14} stroke={2.4} />
        </button>
      </div>

      <UploadDrawer goal={openGoal} data={data} set={set} onClose={() => setOpenGoal(null)} />
    </div>);

}

/* ─── Final done ─── */
function RgDone({ data }) {
  if (data.isApi) {
    const k = data.apiKey || "";
    const masked = k ? `${k.slice(0, 12)}${"\u2022".repeat(12)}${k.slice(-4)}` : "";
    return (
      <div className="rg-done api">
        <div className="pop"><Icon name="check" size={36} stroke={3} /></div>
        <h1>You're on the API, {data.firstName || "developer"}.</h1>
        <p>Workspace <strong style={{ color: "var(--text-primary)" }}>{data.workspaceName || "your workspace"}</strong> is live in sandbox mode for {data.appName || "your app"}. Production access unlocks after we verify your business email.</p>
        <div className="rg-done-key">
          <span className="l"><Icon name="key-round" size={12} stroke={2.4} /> Sandbox key</span>
          <code>{masked || "sk_sbx_\u2022\u2022\u2022\u2022"}</code>
        </div>
        <div className="cta-row">
          <a href="../api-dashboard.html" className="btn primary lg">Open API Console <Icon name="arrow-right" size={14} stroke={2.4} /></a>
          <a href="../api-sandbox.html" className="btn secondary lg">Try sandbox first</a>
        </div>
        <div className="rg-done-hints">
          <span><Icon name="book-open" size={12} stroke={2.4} /> <a href="../documentation.html">Read the docs</a></span>
          <span><Icon name="lightbulb" size={12} stroke={2.4} /> <a href="#">Add Loraa.ai</a></span>
          <span><Icon name="shield-check" size={12} stroke={2.4} /> <a href="#">Add Health Rules</a></span>
        </div>
      </div>
    );
  }
  return (
    <div className="rg-done">
      <div className="pop"><Icon name="check" size={36} stroke={3} /></div>
      <h1>Welcome to NutriDMS, {data.firstName || "there"}.</h1>
      <p>Your workspace <strong style={{ color: "var(--text-primary)" }}>{data.workspaceName || "your workspace"}</strong> is being set up. We'll redirect you in a few seconds, or open it now.</p>
      <div className="cta-row">
        <a href={data.isApi ? "../api-dashboard.html" : "../index.html"} className="btn primary lg">Open dashboard <Icon name="arrow-right" size={14} stroke={2.4} /></a>
        <a href="../api-sandbox.html" className="btn secondary lg">Try the API sandbox</a>
      </div>
    </div>);

}

/* ─── Tweaks ─── */
function RegisterTweaks({ pattern, setPattern }) {
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Onboarding layout" />
      <TweakRadio
        label="Step pattern"
        value={pattern}
        options={[
          { value: "side", label: "Side" },
          { value: "top", label: "Top" },
          { value: "oqs", label: "1/screen" }]
        }
        onChange={setPattern} />

      <div style={{ fontSize: 11, color: "rgba(41,38,27,.45)", marginTop: 4, lineHeight: 1.5 }}>
        <strong>Side</strong>, Stripe/Linear progress rail (default).<br />
        <strong>Top</strong>, slim dot stepper.<br />
        <strong>1/screen</strong>, Typeform-style focus.
      </div>
    </TweaksPanel>);

}

/* ─── Shell ─── */
function RegisterShell() {
  const TWEAK_DEFAULTS = window.RG_TWEAKS || { pattern: "side" };
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // Pick up ?plan= and ?tier= from the landing CTAs so we can pre-fill the
  // trial-plan step and brand the side rail with the right context.
  const params = useRgMemo(() => new URLSearchParams(window.location.search), []);
  const planKind = params.get("plan") || "platform"; // platform | api | laura
  const tierParam = params.get("tier");

  const PLAN_MAP = {
    "platform/starter": { plan: "starter", kind: "Platform · Starter", title: "Starter trial", sub: "1 workspace · 3 users · 100K Loraa tokens" },
    "platform/professional": { plan: "professional", kind: "Platform · Professional", title: "Professional trial", sub: "10 users · compliance suite · 500K Loraa tokens" },
    "platform/enterprise": { plan: "enterprise", kind: "Platform · Enterprise", title: "Enterprise trial", sub: "Unlimited users · SSO · white-label eligible" },
    "api/starter": {
      plan: "starter", kind: "API · Starter", title: "Starter API trial", sub: "For MVPs, pilots, small apps",
      price: "$99", calls: "25,000", rate: "10 req/sec", overage: "$0.006/call", sla: "Community support",
      intendedFor: ["MVPs", "Small apps", "Student projects", "Pilots"],
      includes: ["Ingredient lookup", "Basic recipe analysis", "Basic allergen detection", "Sandbox access"],
      businessType: "nutrition-app"
    },
    "api/growth": {
      plan: "professional", kind: "API · Growth", title: "Growth API trial", sub: "For growing nutrition apps & clinics",
      price: "$399", calls: "150,000", rate: "50 req/sec", overage: "$0.004/call", sla: "Priority · 24h response",
      intendedFor: ["Growing nutrition apps", "Clinics", "Meal-planning platforms"],
      includes: ["Everything in Starter", "Recipe analyze", "Beverage analyze", "Nutrition labels", "Webhooks"],
      businessType: "nutrition-app"
    },
    "api/business": {
      plan: "enterprise", kind: "API · Business", title: "Business API trial", sub: "For restaurants, POS partners, multi-location brands",
      price: "$1,499", calls: "750,000", rate: "150 req/sec", overage: "$0.0025/call", sla: "SLA support",
      intendedFor: ["Restaurant groups", "Multi-location brands", "POS partners"],
      includes: ["Everything in Growth", "Audit retention", "Team & roles", "Data verification", "Priority routing"],
      businessType: "restaurant-pos"
    },
    "laura/starter-ai": { plan: "starter", kind: "Loraa.ai · Starter", title: "Starter AI trial", sub: "500K tokens · 3 team members" },
    "laura/pro-ai": { plan: "professional", kind: "Loraa.ai · Professional", title: "Professional AI trial", sub: "5M tokens · 10 team members · prompt logs" },
  };
  const planContext = PLAN_MAP[`${planKind}/${tierParam}`]
    || (planKind === "api" ? { plan: "professional", kind: "API", title: "API trial", sub: "Try the NutriDMS API in a sandbox workspace.", businessType: "api" }
      : planKind === "laura" ? { plan: "professional", kind: "Loraa.ai", title: "Loraa.ai trial", sub: "Standalone AI access, 5M trial tokens." }
        : { plan: "professional", kind: "Platform", title: "Professional trial", sub: "Compliance teams, growing operations." });

  const [stepIdx, setStepIdx] = useRgState(0);
  const [data, setData] = useRgState({
    plan: planContext.plan,
    businessType: planContext.businessType || undefined,
    isApi: planKind === "api",
    invites: [{ email: "", role: "Contributor" }],
    goals: []
  });

  const [done, setDone] = useRgState(false);

  useRgEffect(() => {
    document.documentElement.setAttribute("data-rg-pattern", t.pattern);
  }, [t.pattern]);

  const set = (k, v) => setData((d) => ({ ...d, [k]: v }));
  const steps = useRgMemo(() => getStepsForPlan(planKind), [planKind]);
  const next = () => {
    if (stepIdx === steps.length - 1) { setDone(true); return; }
    setStepIdx(stepIdx + 1);
  };
  const back = () => setStepIdx(Math.max(0, stepIdx - 1));
  const skip = () => next();
  const jump = (i) => setStepIdx(i);

  const current = steps[stepIdx];
  const renderStep = () => {
    if (done) return <RgDone data={data} />;
    const stepNum = current.num;
    const total = steps.length;
    switch (current.id) {
      case "account": return <StepAccount data={data} set={set} next={next} stepNum={stepNum} total={total} />;
      case "verify": return <StepVerify data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} />;
      case "workspace": return <StepWorkspace data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} />;
      case "api-workspace": return <StepApiWorkspace data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} />;
      case "billing": return <StepBilling data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} planContext={planContext} />;
      case "key": return <StepGenerateKey data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} />;
      case "plan": return <StepPlan data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} />;
      case "invite": return <StepInvite data={data} set={set} next={next} back={back} skip={skip} stepNum={stepNum} total={total} isLast={stepIdx === total - 1} />;
      case "goals": return <StepGoals data={data} set={set} next={next} back={back} stepNum={stepNum} total={total} />;
      default: return null;
    }
  };

  return (
    <AppCtx.Provider value={_RgCtx}>
      <div className="rg-wrap">
        <RgSidePanel stepIdx={stepIdx} jump={jump} planContext={planContext} steps={steps} />
        <div>
          <RgTopbar stepIdx={stepIdx} steps={steps} />
          <div className="rg-form-wrap">
            <div className="rg-form-top">
              <span style={{ fontSize: 12, color: "var(--gray-500)", fontWeight: 600 }}>
                <LangSwitch />
              </span>
              <span className="help">
                Need help? <a href="../documentation.html">Contact support</a>
              </span>
            </div>
            <div className="rg-card">{renderStep()}</div>
          </div>
        </div>
        <RegisterTweaks pattern={t.pattern} setPattern={(v) => setTweak("pattern", v)} />
      </div>
    </AppCtx.Provider>);

}

function RegisterApp() { return <I18nProvider><RegisterShell /></I18nProvider>; }
ReactDOM.createRoot(document.getElementById("root")).render(<RegisterApp />);
