// rules.jsx — Marketplace Rules: 3-audience policy reference
//
// Content distilled from internal specs:
//   - skill-marketplace-rules-v0.1.md (R1-R8 high-level decisions)
//   - skill-marketplace-template-vscode-baseline.md (R1-R15 detailed policy)
//
// Three audience tabs:
//   • Users  — what you're agreeing to when you install a skill
//   • Creators — how to publish, get paid, what changes when
//   • Governance — how IrisGo reviews, enforces, and stays accountable
//
// This page is intentionally a single source of policy truth — not
// marketing copy. Things that are still open we mark as TBD; we don't
// promise what we haven't decided.

const { useState: useStateR } = React;

const RULES_VERSION = "v0.1 · Draft";
const RULES_UPDATED = "May 2026";

// ─────────────────────────────────────────────────────────── Tabs
function RulesTabs({ value, options, onChange }) {
  return (
    <div className="row" style={{
      borderBottom: "1px solid var(--line)",
      gap: 4, marginTop: 16, marginBottom: 32,
    }}>
      {options.map(o => (
        <button key={o.id} className="unstyled" onClick={() => onChange(o.id)}
          style={{
            padding: "12px 16px",
            font: "500 14px/1 var(--font-sans)",
            color: value === o.id ? "var(--ink)" : "var(--ink-3)",
            borderBottom: value === o.id ? "2px solid var(--accent)" : "2px solid transparent",
            marginBottom: -1, cursor: "pointer", background: "transparent",
          }}>
          <div>{o.label}</div>
          <div style={{ font: "400 11px/1.4 var(--font-sans)", color: "var(--ink-4)", marginTop: 4 }}>
            {o.subtitle}
          </div>
        </button>
      ))}
    </div>
  );
}

// ─────────────────────────────────────────────────────────── Section primitives
function Section({ id, title, kicker, children }) {
  return (
    <section id={id} style={{ marginBottom: 40, scrollMarginTop: 80 }}>
      {kicker && (
        <div style={{
          font: "500 11px/1 var(--font-mono)", color: "var(--ink-3)",
          textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8,
        }}>{kicker}</div>
      )}
      <h2 style={{
        font: "600 22px/1.3 var(--font-display)", color: "var(--ink)",
        margin: "0 0 16px 0",
      }}>{title}</h2>
      <div style={{ font: "400 15px/1.6 var(--font-sans)", color: "var(--ink-1)" }}>
        {children}
      </div>
    </section>
  );
}

function Note({ tone = "info", children }) {
  const tones = {
    info:    { bg: "var(--bg-muted)", border: "var(--line)", ink: "var(--ink-2)" },
    warn:    { bg: "var(--amber-50)", border: "var(--amber-100)", ink: "var(--amber-700)" },
    success: { bg: "var(--green-50)", border: "var(--green-100)", ink: "var(--green-700)" },
    open:    { bg: "var(--bg-sunken)", border: "var(--line-strong)", ink: "var(--ink-3)" },
  };
  const t = tones[tone] || tones.info;
  return (
    <div style={{
      background: t.bg, border: `1px solid ${t.border}`, color: t.ink,
      padding: "12px 14px", borderRadius: "var(--r-3)", margin: "12px 0",
      font: "400 14px/1.55 var(--font-sans)",
    }}>{children}</div>
  );
}

function Table({ headers, rows }) {
  return (
    <div style={{ overflowX: "auto", margin: "12px 0" }}>
      <table style={{
        width: "100%", borderCollapse: "collapse",
        font: "400 14px/1.5 var(--font-sans)",
      }}>
        <thead>
          <tr>
            {headers.map((h, i) => (
              <th key={i} style={{
                textAlign: "left", padding: "10px 12px",
                borderBottom: "1px solid var(--line-strong)",
                font: "600 12px/1.4 var(--font-sans)",
                color: "var(--ink-3)", textTransform: "uppercase",
                letterSpacing: "0.04em",
              }}>{h}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, ri) => (
            <tr key={ri}>
              {row.map((cell, ci) => (
                <td key={ci} style={{
                  padding: "10px 12px", verticalAlign: "top",
                  borderBottom: "1px solid var(--line-soft)",
                  color: "var(--ink-1)",
                }}>{cell}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function CodeBlock({ children }) {
  return (
    <pre style={{
      background: "var(--ink)", color: "var(--lime-light)",
      padding: "14px 16px", borderRadius: "var(--r-3)", overflowX: "auto",
      font: "400 13px/1.55 var(--font-mono)", margin: "12px 0",
    }}>{children}</pre>
  );
}

// ─────────────────────────────────────────────────────────── Audience: Users
function UserContent() {
  return (
    <div>
      <Section kicker="What you're agreeing to" title="When you install a skill">
        <p>Every IrisGo Skill is a sandboxed program that asks for specific access to your context — your email, calendar, documents, etc. You see exactly what it wants before you say yes.</p>
        <Note tone="success">
          <b>Privacy floor:</b> raw event content (the body of an email, the contents of a document) never leaves your device unless a skill explicitly asks and you explicitly grant.
        </Note>
      </Section>

      <Section kicker="Risk tiers" title="How safe is this skill?">
        <p>Every skill carries a risk tier, computed from what it asks for — not self-declared by the creator.</p>
        <Table
          headers={["Tier", "What it can do", "How it gets to you"]}
          rows={[
            ["🟢 Low", "Reads from local files only. No network access.", "Auto-scan, available immediately. We sample-audit after publish."],
            ["🟡 Medium", "Network calls or access to medium-sensitivity topics.", "Auto-scan + occasional manual sampling. Available immediately."],
            ["🔴 High", "Runs shell commands or modifies system settings.", "Manual review required before publication."],
            ["🚨 Restricted", "Reads raw context events or touches payment APIs.", "Manual review + IrisGo team co-signature + creator KYC."],
          ]} />
      </Section>

      <Section kicker="Permissions" title="What you grant — and how to take it back">
        <p>At install, you see a topic-level grant request, e.g., <code style={{ font: "500 13px/1 var(--font-mono)" }}>work.email.*</code>. Required permissions are needed to run the skill at all; optional ones are for nice-to-have features.</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>You can deny optional permissions at install — toggles are not dark-patterned.</li>
          <li>If a skill later wants more access than it declared, you get a just-in-time prompt. You can say no, and the skill must degrade gracefully.</li>
          <li>Per-topic revoke: <em>Settings → Skills → [skill] → granted topics</em>. Takes effect immediately.</li>
          <li>One skill's grant doesn't extend to another skill. Period.</li>
        </ul>
        <Note>
          <b>Privacy nutrition labels:</b> before installing, you see the topic list, sensitivity level, network access, and any third parties involved (for partner skills).
        </Note>
      </Section>

      <Section kicker="Telemetry" title="What we collect — and what we don't">
        <Table
          headers={["Signal", "Default", "Visibility"]}
          rows={[
            ["Skill install count (global aggregate)", "On", "Public"],
            ["Per-skill execution count", "On (you can disable)", "Aggregated to creator"],
            ["Outcome — success / fail / abandoned only", "On", "Aggregated to creator"],
            ["Creator-defined detailed events", "Off — opt-in only", "Aggregated to creator"],
            ["Raw event content", "Never collected", "—"],
            ["Individual user behavior", "Never shared", "—"],
          ]} />
        <p>Aggregates are only released above a k-anonymity threshold (≥100 unique users) with a minimum 24-hour aggregation window. You can disable telemetry globally in <em>Settings → Privacy</em>.</p>
      </Section>

      <Section kicker="Discovery" title="Why you see what you see">
        <p>We have two ranking surfaces, with different jobs:</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li><b>For You</b> — personalized to what your IrisGo agent is actually doing. Driven by context match, retention rate, uninstall penalty, and a publisher-diversity cap (no single publisher gets more than 20% of your For You).</li>
          <li><b>Trending</b> — global 7-day install velocity, weighted by retention. With anti-farming guards.</li>
        </ul>
        <Note>
          <b>What we won't do:</b> no Editor's Pick on the homepage. No alphabetical browse as the primary entry. No paid placement until usage volume justifies it. The published list of ranking inputs is on the Governance tab.
        </Note>
      </Section>

      <Section kicker="Refunds" title="If you change your mind">
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li><b>Free skills:</b> no refund (you didn't pay).</li>
          <li><b>One-time purchase / first subscription charge:</b> 7-day refund window.</li>
          <li><b>Subscription, mid-cycle:</b> if a creator unpublishes or we force-remove a skill, the unused portion is pro-rated back.</li>
          <li><b>Metered usage:</b> unused balance returns to your GoT wallet.</li>
        </ul>
      </Section>

      <Section kicker="Removal" title="Uninstalling">
        <p>When you uninstall:</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>The skill's permissions are revoked immediately.</li>
          <li>Its data is moved to an archived area for 30 days — restorable in one click.</li>
          <li>After 30 days, hard delete (right to be forgotten).</li>
          <li>If it was a paid subscription, the subscription cancels automatically.</li>
        </ul>
      </Section>
    </div>
  );
}

// ─────────────────────────────────────────────────────────── Audience: Creators
function CreatorContent() {
  return (
    <div>
      <Section kicker="Three skill types" title="Which kind of creator are you?">
        <p>Skills come in three shapes. Pick the one that matches what you actually have to ship.</p>
        <Table
          headers={["Type", "Who it's for", "Where it runs", "Take rate (steady state)"]}
          rows={[
            ["A — AI App Listing", "Companies with their own product (own backend, own brand) wanting distribution.", "Your infrastructure.", "5%, BD-negotiated"],
            ["B — Standard Skill", "Individuals or small teams. Declarative, manifest-driven (think SKILL.md + scripts).", "IrisGo on-device sandbox.", "Tier 1 schedule (see below)"],
            ["C — Custom Code Skill", "Developers writing TS/JS/Python that needs more programmatic freedom than B allows.", "IrisGo on-device sandbox.", "Tier 1 schedule (see below)"],
          ]} />
        <Note tone="open">
          <b>Today (Stage 1):</b> 1–3 Type A partners co-launching with us, IrisGo-internal Type B/C only. Type B/C public submissions open in Stage 2.
        </Note>
      </Section>

      <Section kicker="Onboarding" title="Becoming a Verified Publisher">
        <p>Five steps. Designed to take a day or two of calendar time, not paperwork weeks.</p>
        <ol style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>Sign up at <code style={{ font: "500 13px/1 var(--font-mono)" }}>creator.irisgo.ai</code> with a working email.</li>
          <li>Verify domain ownership via DNS TXT record (the same flow VS Code Marketplace uses).</li>
          <li>Sign Terms of Service + Creator Agreement.</li>
          <li>Provide identity: individuals — government ID image (we store a hash, not the image); companies — tax ID + W-9 / W-8.</li>
          <li>Wait 24–72 hours for review. You receive a publisher namespace and signing certificate.</li>
        </ol>
        <Note>
          <b>7-day cooldown:</b> new Verified Publishers can't submit their first skill until 7 days after verification — to deter typosquatting and burst spam.
        </Note>
      </Section>

      <Section kicker="Manifest" title="The skill manifest, in one shape">
        <p>JSON, with inline locale dictionaries. We chose JSON to align with VS Code and Anthropic Skills tooling. The minimum viable manifest:</p>
        <CodeBlock>{`{
  "manifest_version": 1,
  "id": "com.kdanmobile.pdf-summarizer",
  "version": "1.2.3",
  "publisher": "kdanmobile",

  "engines": {
    "irisgo": ">=1.0",
    "cae_schema": ">=1.0"
  },

  "name": {
    "en": "PDF Summarizer",
    "zh-TW": "KDAN PDF 摘要"
  },

  "intent": {
    "primary": "summarize.document",
    "description": {
      "en": "Summarize PDF documents into key points"
    }
  },

  "categories": ["productivity", "documents"],

  "permissions": {
    "required": ["cae:read:work.docs.read"],
    "optional": ["cae:read:work.email.compose"]
  },

  "runtime": "process-sandbox",
  "activation_triggers": [
    { "on_topic": "work.docs.*" },
    { "on_intent": "summarize.*pdf" },
    { "on_user_invoke": true }
  ],

  "pricing": { "type": "free" },
  "drm": "none",
  "extensions": {}
}`}</CodeBlock>
        <p><b>Intent</b> is a hybrid: <code style={{ font: "500 13px/1 var(--font-mono)" }}>intent.primary</code> is from a controlled vocabulary (~20 verbs at v1) so the routing model can do exact matching; <code style={{ font: "500 13px/1 var(--font-mono)" }}>intent.description</code> is free text per locale, for users and search. New enum values have a 24-hour SLA.</p>
        <p><b>i18n</b> ships <code style={{ font: "500 13px/1 var(--font-mono)" }}>en</code> + <code style={{ font: "500 13px/1 var(--font-mono)" }}>zh-TW</code> at v1; we're aligning with our OEM target markets and adding more by demand. Missing locale falls back to <code style={{ font: "500 13px/1 var(--font-mono)" }}>en</code>.</p>
      </Section>

      <Section kicker="Pricing" title="Five pricing models, you pick one">
        <Table
          headers={["Model", "How it works"]}
          rows={[
            ["Free", "0 GoT. Attribution required. You must disclose how the skill is funded (ads, data, donation, OSS contribution)."],
            ["One-time purchase", "X GoT, perpetual access."],
            ["Subscription", "Y GoT/month or year (you choose monthly, yearly, or both)."],
            ["Metered (per-use)", "Z GoT per execution. You declare a per-use cap so users aren't surprised."],
            ["Freemium", "Free tier + paid tier in the same skill."],
          ]} />
        <p><b>1 GoT = $0.002 USD</b> base rate. Currency starts as GoT-only — closed loop. Cash payouts open after we hit the volume gate (and we figure out the tax/KYC plumbing).</p>
      </Section>

      <Section kicker="Take rate" title="What IrisGo takes — and the income cliff plan">
        <Table
          headers={["Period", "Rate", "Why"]}
          rows={[
            ["Year 1", "0%", "Cold-start incentive. Build the catalog."],
            ["Year 2", "15%", "Stripe-tier. Paid tier opens; DRM ships."],
            ["Year 3+", "30%", "Apple-tier. Only after $5M+ MRR proof point."],
            ["Tier A — AI App partners", "5% (BD-negotiated)", "You bring your own infra and brand."],
            ["Tier 3 — Sensitive opt-out (medical/financial)", "20%", "Self-hosted; no CAE auto-injection."],
          ]} />
        <Note tone="success">
          <b>Cliff mitigation:</b> the first 100 Verified Creators get a grandfathered 5% rate over Year 2. Take-rate changes get at least 6 months' advance notice (except for emergency compliance). Tier A contracts honor their own pricing terms — no unilateral retroactive changes.
        </Note>
        <Note tone="open">
          <b>Open:</b> exact "first 100" definition (first-come vs revenue threshold) — to be locked before Year 1 ends. Whether a small-developer 15% tier exists past Year 2 — to be decided before Year 2 ends.
        </Note>
      </Section>

      <Section kicker="Review" title="How submissions get reviewed">
        <p>Risk-based hybrid. Most skills go through automated scanning and post-publish observation. Higher-risk skills get pre-publish manual review.</p>
        <Table
          headers={["Tier", "Review mode", "What we check"]}
          rows={[
            ["🟢 Low / 🟡 Medium", "Auto-scan, available immediately. Sampling after publish.", "License, secrets, harmful patterns, manifest validity."],
            ["🔴 High", "Pre-publish manual review.", "Full code review. Permissions justified by behavior."],
            ["🚨 Restricted", "Pre-publish manual + IrisGo co-sign + creator KYC.", "Above + identity verification + payment-API audit."],
          ]} />
        <p><b>If we reject your submission</b> you get: a specific category, the file or permission or clause we cited, and a suggested fix. We don't do black-box rejections.</p>
        <p><b>Resubmission</b> follows the same flow as a first submission. <b>Tier promotion</b> (e.g., adding network access in v1.3) requires the new tier's review process.</p>
      </Section>

      <Section kicker="Ranking" title="How your skill gets ranked">
        <p>Two surfaces with different jobs (For You — personalized; Trending — popularity). The inputs are public; the weights are not (to avoid an SEO arms race).</p>
        <Table
          headers={["Signal", "Direction"]}
          rows={[
            ["Context match (For You only)", "Higher = better"],
            ["Recent install velocity (percentile, not absolute)", "Higher = better"],
            ["7-day post-install retention (CAE interaction-verified)", "Higher = better"],
            ["Uninstall rate", "Negative signal"],
            ["Same-publisher diversity cap", "Capped at 20% of For You slate"],
            ["Verified Publisher tier boost", "Mild only (<5%)"],
          ]} />
        <Note>
          <b>Creator dashboard (Stage 2+)</b> shows you your own skill's ranking signal strengths (e.g., "your retention is below median") — not your competitors' numbers.
        </Note>
      </Section>

      <Section kicker="Reviews & ratings" title="What users say about your skill">
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>5-star + optional text. No multi-axis ratings (kept simple).</li>
          <li><b>Verified install required</b> — every review corresponds to a real CAE interaction. Anonymous review is not allowed; the user_id is linked, even if the displayed handle is anonymous.</li>
          <li><b>7-day cooldown</b> — users can review only after using your skill for 7 days.</li>
          <li><b>Publisher reply</b> — one reply per review, no edit-then-reply chains.</li>
          <li><b>Helpful voting</b> — outlier ratings (extreme score, low helpfulness) don't count toward your average.</li>
        </ul>
      </Section>

      <Section kicker="Versioning" title="How updates work">
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li><b>Semver, mandatory.</b> You manage your version numbers.</li>
          <li><b>Patch (1.2.3 → 1.2.4):</b> auto-approved if no permission change.</li>
          <li><b>Minor (1.2 → 1.3):</b> goes through the same review tier as your first submission.</li>
          <li><b>Major (1.x → 2.0):</b> full review + 90 days of v1/v2 coexistence before sunsetting v1. You write a migration note. Users can pin v1 until sunset.</li>
          <li><b>Adding a permission</b> means users see a grant prompt at update — same as install. No silent grants. They can refuse and stay on v1's permission set.</li>
          <li><b>CAE schema dependency</b> is declared in <code style={{ font: "500 13px/1 var(--font-mono)" }}>engines.cae_schema</code>. Mismatched schema → marketplace won't list, install is blocked, the user sees an update CTA.</li>
        </ul>
      </Section>

      <Section kicker="Verified tiers" title="What the badges mean">
        <Table
          headers={["Tier", "Badge", "Conditions"]}
          rows={[
            ["Unverified", "(none)", "Stage 3 only. No marketplace ranking."],
            ["Verified Publisher", "✓ Blue", "Email + DNS + ToS + ID/Tax. Standard publish."],
            ["Verified Partner", "✓ Gold", "Tier A commercial contract + KYC. Own infra allowed."],
            ["IrisGo Official", "✓ Black", "IrisGo internal. We do not boost ourselves in ranking."],
          ]} />
      </Section>

      <Section kicker="Liability" title="What you're on the hook for">
        <p>You are responsible for what your skill does. IrisGo is the platform — we mediate the relationship, we don't underwrite it.</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>For paid skills, you cover the refund waterfall (7-day window, pro-rated for subscriptions).</li>
          <li>Chargebacks: respond within 48 hours; silence = ruling against you.</li>
          <li>Trademark disputes: 7-day creator response window before takedown.</li>
          <li>Bug bounty (data leak / permission escalation / malicious code): you cover the payout. We coordinate the deprecation and user remediation.</li>
        </ul>
      </Section>
    </div>
  );
}

// ─────────────────────────────────────────────────────────── Audience: Governance
function GovernanceContent() {
  return (
    <div>
      <Section kicker="Stance" title="What kind of marketplace this is">
        <p>IrisGo Skill Marketplace is a routing engine wearing a marketplace's clothing. Distribution is the surface; personalized routing into the right skill at the right moment is the actual product. Every policy here gets evaluated against one question: <em>does this make us more like a directory, or more like a routing engine?</em> We pick the second answer.</p>
        <Note>
          <b>Status:</b> {RULES_VERSION}. These rules are early-stage and will evolve with stakeholder review (CEO / COO / CMO independent reads still pending). We publish them so creators and partners can plan against them, not as a final commitment.
        </Note>
      </Section>

      <Section kicker="What we review" title="The review philosophy">
        <p>We're not Apple-strict, and we're not Microsoft-permissive. We use a risk-based hybrid: low and medium risk get auto-scanned and observed; high and restricted risk get blocked until manually reviewed.</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>Risk tier is computed from declared permissions and the sensitivity level of the topics touched — not creator self-report.</li>
          <li>Rejections cite a specific category, specific evidence, and a suggested fix. No black-box "violates guideline 4.3" rejections.</li>
          <li>Resubmission goes through the same flow as first submission. Promotions across tiers (e.g., adding shell exec) require the new tier's process.</li>
        </ul>
      </Section>

      <Section kicker="What we don't review" title="The intentional gaps">
        <p>For low and medium risk, we accept that some bad skills will land on the marketplace and get pulled after the fact. The trade-off is creator velocity.</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>We do not review for taste or quality. Ranking handles that.</li>
          <li>We do not approve every update. Patch bumps with no permission change are auto-approved.</li>
          <li>We do not adjudicate creator-vs-creator disputes (e.g., similar skill names) beyond the trademark and typosquatting checks.</li>
        </ul>
      </Section>

      <Section kicker="Disputes" title="The liability waterfall">
        <p>When a user reports harm:</p>
        <ol style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>IrisGo triages within 24 hours (acknowledgment, not resolution).</li>
          <li>Creator is responsible for skill behavior. Paid skills: creator covers refund / pro-rata.</li>
          <li>IrisGo's role is to provide the refund mechanism, force takedown when warranted, and coordinate user notification.</li>
          <li>Severe cases (data leak, permission escalation, malicious update) trigger bug-bounty payout — covered by the creator per ToS, not by IrisGo.</li>
        </ol>
      </Section>

      <Section kicker="Removal" title="How a skill leaves the marketplace">
        <Table
          headers={["Scenario", "Process", "User impact"]}
          rows={[
            ["User uninstalls", "Immediate.", "Permissions revoked. Data archived 30 days, then hard-deleted. Subscription auto-cancels."],
            ["Publisher unpublishes", "Goes through deprecation (cannot remove instantly).", "Existing installs keep working with security patches for 6 months. Pro-rated refund for subscribers."],
            ["IrisGo enforced removal", "24-hour notice + dispute window. Hidden from new users immediately.", "Existing installs get 14-day grace, then forced uninstall with data archive."],
            ["CRL push (critical security override)", "Immediate. Bypasses notice.", "Skill execution blocked instantly. User notified with reason. Data archived."],
          ]} />
      </Section>

      <Section kicker="Discovery promises" title="What we won't do on the homepage">
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li><b>No Editor's Pick.</b> Curation lives inside the Starter Pack for first-time users only — not as a homepage promotion mechanism.</li>
          <li><b>No alphabetical browse.</b> Categories exist but are demoted to secondary nav.</li>
          <li><b>No paid placement</b> until usage volume justifies the conversation. Threshold is volume-based, not date-based.</li>
          <li><b>No ranking boost for IrisGo Official skills.</b> The diversity cap (≤20% of For You from one publisher) applies to us too. Long-term trust beats short-term revenue.</li>
        </ul>
      </Section>

      <Section kicker="Transparency" title="What we publish, and what we don't">
        <Table
          headers={["Item", "Public?"]}
          rows={[
            ["Risk tier definitions and what triggers each", "Yes"],
            ["Ranking signal list (the inputs)", "Yes"],
            ["Ranking signal weights", "No — to avoid SEO arms race"],
            ["Take rate timeline + 6-month change notice policy", "Yes — published on creator portal"],
            ["Aggregate skill metrics (install count)", "Yes"],
            ["Per-skill detailed metrics", "Creator only, for their own skills"],
            ["Individual user behavior", "Never published"],
          ]} />
      </Section>

      <Section kicker="Privacy floor" title="The hard rules we won't break">
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li>Topic-level aggregates only — never down to a specific file, app, or content body.</li>
          <li>No raw event content travels to the cloud. CAE event content stays on-device.</li>
          <li>No individual user behavior shared with creators, ever.</li>
          <li>K-anonymity threshold of 100 unique users before any aggregate is surfaced.</li>
          <li>Aggregation window of at least 24 hours, to make real-time tracking infeasible.</li>
        </ul>
      </Section>

      <Section kicker="Open questions" title="What we haven't decided yet">
        <p>We're publishing this in draft because we'd rather show our work than pretend a v0.1 is final. These are the items we know we still owe an answer on:</p>
        <ul style={{ paddingLeft: 20, margin: "8px 0" }}>
          <li><b>GoT supply policy</b> — how we manage token supply and inflation as the four GoT use-cases scale. Roblox Robux is our cautionary tale.</li>
          <li><b>Conflict resolution</b> — when two skills declare the same intent, how routing chooses, and how we present that to the user.</li>
          <li><b>Inter-skill dependency</b> — whether a skill can require another skill, and how that composes inside the sandbox.</li>
          <li><b>"First 100" grandfather mechanics</b> — first-come vs revenue-threshold definition.</li>
          <li><b>Per-region pricing and ToS</b> — GDPR/CCPA/local data law alignment beyond the current U.S./Taiwan baseline.</li>
        </ul>
      </Section>

      <Section kicker="How to push back" title="When you disagree with us">
        <p>This page is the fastest way to find out what the rules are. It is not the fastest way to change them. If you're a creator or partner with a structural concern, raise it through your existing IrisGo contact for now — a dedicated <code style={{ font: "500 13px/1 var(--font-mono)" }}>policy@irisgo.ai</code> intake will open alongside the public launch. Either way, we read what comes in; we don't promise to agree.</p>
      </Section>
    </div>
  );
}

// ─────────────────────────────────────────────────────────── Main screen
function RulesScreen({ onNav }) {
  const [tab, setTab] = useStateR("user");

  const tabs = [
    { id: "user",       label: "Users",       subtitle: "What you're agreeing to" },
    { id: "creator",    label: "Creators",    subtitle: "How to publish & get paid" },
    { id: "governance", label: "Governance",  subtitle: "How we review & enforce" },
  ];

  let body = null;
  if (tab === "user") body = <UserContent />;
  else if (tab === "creator") body = <CreatorContent />;
  else if (tab === "governance") body = <GovernanceContent />;

  return (
    <main style={{ maxWidth: 880, margin: "0 auto", padding: "32px 24px 80px" }}>
      <div style={{ marginBottom: 8 }}>
        <span style={{
          font: "500 11px/1 var(--font-mono)", color: "var(--ink-3)",
          textTransform: "uppercase", letterSpacing: "0.08em",
        }}>Marketplace Rules · {RULES_VERSION} · Updated {RULES_UPDATED}</span>
      </div>
      <h1 style={{
        font: "700 32px/1.2 var(--font-display)", color: "var(--ink)",
        margin: "0 0 12px 0",
      }}>The rules of the IrisGo Skill Marketplace</h1>
      <p style={{ font: "400 16px/1.55 var(--font-sans)", color: "var(--ink-2)", margin: 0 }}>
        Three audiences read these rules differently. Pick the lens that matches what you're trying to do.
        We keep this page in sync with the internal policy spec — what you read here is the operating contract,
        not marketing copy.
      </p>

      <RulesTabs value={tab} options={tabs} onChange={setTab} />
      {body}

      <div style={{
        marginTop: 48, paddingTop: 24, borderTop: "1px solid var(--line)",
        font: "400 13px/1.6 var(--font-sans)", color: "var(--ink-3)",
      }}>
        Source policy: <code style={{ font: "500 12px/1 var(--font-mono)" }}>skill-marketplace-rules-v0.1.md</code> + <code style={{ font: "500 12px/1 var(--font-mono)" }}>skill-marketplace-template-vscode-baseline.md</code>.
        Public reading; not yet binding while we run independent review (CEO / COO / CMO). Substantive changes will be announced with at least 6 months' notice for take-rate items, and immediately for clarifications. — IrisGo
      </div>
    </main>
  );
}

window.RulesScreen = RulesScreen;
