// CALCULATOR, the crown jewel
// Tabs: Producer Fee / Publishing / Master Royalty
// Live animation, side-by-side "what producers usually get" vs "what you should get"

const TIERS = [
  { id: "indie", label: "Independent", listeners: "0–100K monthly listeners", share: "~99%", shareOf: "Spotify artists", shareSource: "Dynamoi · Chartmetric", desc: "Bedroom artists, local acts, early-stage indies. Rates are low but credits compound." },
  { id: "rising", label: "Rising", listeners: "100K–500K monthly listeners", share: "~0.3%", shareOf: "Spotify artists", shareSource: "Dynamoi · MBW", desc: "Building a fanbase. Real placements, real budgets, but still negotiable." },
  { id: "established", label: "Established", listeners: "500K–5M monthly listeners", share: "~0.15%", shareOf: "Spotify artists", shareSource: "Spotify Loud & Clear", desc: "Career artist. Working with managers and labels. Standardized rates start applying." },
  { id: "major", label: "Major", listeners: "5M–50M monthly listeners", share: "~0.04%", shareOf: "Spotify artists", shareSource: "Spotify Loud & Clear", desc: "Major-label priority act. Real budgets, real teams, real leverage on both sides." },
  { id: "superstar", label: "Superstar", listeners: "50M+ monthly listeners", share: "<0.01%", shareOf: "Spotify artists", shareSource: "Spotify · Billboard", desc: "Global arena act. Stadium tours, brand deals. The room works around their schedule." },
];

const CREDITS = [
  { id: "building", label: "Building", stat: "0–5 real placements", share: "~85%", shareOf: "producers", shareSource: "Muso.AI · industry est.", who: "Early career. Still building a placement history.", desc: "No major label placements yet. You are establishing your sound and working your way into industry circles. Rates are lower but credits are the currency." },
  { id: "emerging", label: "Emerging", stat: "5–25 placements · a couple plaques", share: "~10%", shareOf: "producers", shareSource: "Muso.AI · RIAA est.", who: "A growing catalog. Managers and A&Rs are starting to know your name.", desc: "A few real placements. You can quote a real fee with a straight face. Reputation is building inside the industry, even if the public doesn't know your name yet." },
  { id: "established", label: "Established", stat: "25–50 placements · Plaques · Billboard", share: "~4%", shareOf: "producers", shareSource: "Billboard · Muso.AI", who: "Repeat placements. Credits that open doors in the room.", desc: "Plaques on the wall. Credits people recognize. Now the rate is the conversation, not the credit." },
  { id: "hitmaker", label: "Hitmaker", stat: "1B+ stream singles · Top #10 records · Executive producer", share: "~2%", shareOf: "producers", shareSource: "Billboard · Grammy · Muso.AI", who: "Executive producer. Top-tier track record. Your name sets the floor for the conversation.", desc: "Chart-defining records at the highest level. You run the session, not just the beat. The rate isn't a question, your name is the floor for the room." },
];

// Producer fee matrix [credit][artistTierIdx] -> [low, high] in USD
// BASE rates = non-exclusive beat lease equivalent. Hand-tuned ladder; all values end on clean increments.
const FEE_MATRIX = {
  building:    [[50, 150],    [150, 400],    [350, 1000],   [600, 2000],   [1000, 3500]],
  emerging:    [[150, 400],   [400, 1200],   [1200, 3500],  [2000, 5500],  [3500, 8500]],
  established: [[300, 800],   [800, 2000],   [2000, 5500],  [4000, 10000], [7000, 14000]],
  hitmaker:    [[400, 1000],  [1000, 3000],  [3000, 6500],  [6000, 15000], [15625, 31250]],
};
const USUAL_RATIO = 0.45; // what producers typically settle for, as a fraction of midpoint

// Snap displayed fees to readable increments after deal-type math
function roundDisplayFee(n) {
  if (n < 200) return Math.round(n / 25) * 25;
  if (n < 1000) return Math.round(n / 50) * 50;
  if (n < 5000) return Math.round(n / 100) * 100;
  if (n < 20000) return Math.round(n / 250) * 250;
  return Math.round(n / 500) * 500;
}

// Publishing splits, "usual" vs "you"
const PUB_MATRIX = {
  building:    { usualLow: 25, usualHigh: 50, youLow: 50, youHigh: 50 },
  emerging:    { usualLow: 30, usualHigh: 50, youLow: 50, youHigh: 50 },
  established: { usualLow: 35, usualHigh: 50, youLow: 50, youHigh: 50 },
  hitmaker:    { usualLow: 38, usualHigh: 50, youLow: 50, youHigh: 50 },
};

const DEAL_TYPES = [
  { id: "lease-ne",  label: "Beat Lease (Non-exclusive)", desc: "Non-exclusive. Artist can use the beat; you keep rights to sell it again. Always cap commercial copies and streaming numbers in the contract." },
  { id: "lease-ex",  label: "Beat Lease (Exclusive)",     desc: "One artist gets exclusive use. You give up the right to resell. Price reflects scarcity." },
  { id: "buyout",    label: "Buyout / Work-for-Hire",     desc: "You hand over everything for a flat fee. No backend. Higher number up front, and that's all." },
  { id: "standard",  label: "Standard Producer Deal",     desc: "Producer fee + 3-5 points + 50% publishing. The industry default for major placements." },
];

// Multipliers per deal type on the fee range
const DEAL_MULT = { "lease-ne": 1, "lease-ex": 2.0, "buyout": 3.2, "standard": 1.6 };

// Beat leases don't apply at career-artist scale — session deals only
const NO_LEASE_TIERS = new Set(["established", "major", "superstar"]);

function dealOptionsForTier(tierId) {
  if (NO_LEASE_TIERS.has(tierId)) {
    return DEAL_TYPES.filter((d) => d.id !== "lease-ne" && d.id !== "lease-ex");
  }
  return DEAL_TYPES;
}

function dealGroupsForTier(tierId) {
  const session = DEAL_TYPES.filter((d) => d.id === "standard" || d.id === "buyout");
  if (NO_LEASE_TIERS.has(tierId)) {
    return [{ label: "Session", options: session }];
  }
  return [
    { label: "Beat market", options: DEAL_TYPES.filter((d) => d.id === "lease-ne" || d.id === "lease-ex") },
    { label: "Session", options: session },
  ];
}

function Calculator({ embedded }) {
  const [tab, setTab] = React.useState("fee"); // fee | publishing | master
  const [tier, setTier] = React.useState("indie");
  const [credit, setCredit] = React.useState("building");
  const [deal, setDeal] = React.useState("lease-ne");
  const [streams, setStreams] = React.useState(1_000_000);

  React.useEffect(() => {
    if (NO_LEASE_TIERS.has(tier) && (deal === "lease-ne" || deal === "lease-ex")) {
      setDeal("standard");
    }
  }, [tier, deal]);

  const tierIdx = TIERS.findIndex((t) => t.id === tier);
  const tierObj = TIERS[tierIdx];
  const creditObj = CREDITS.find((c) => c.id === credit);
  const dealOptions = dealOptionsForTier(tier);
  const dealGroups = dealGroupsForTier(tier);
  const dealObj = dealOptions.find((d) => d.id === deal) || dealOptions[0];
  const dealMult = DEAL_MULT[deal];

  // Producer fee: base range × deal multiplier → round for display
  const range = FEE_MATRIX[credit][tierIdx];
  const youLow = roundDisplayFee(range[0] * dealMult);
  const youHigh = roundDisplayFee(range[1] * dealMult);
  const youMid = (youLow + youHigh) / 2;
  const usual = roundDisplayFee(youMid * USUAL_RATIO);

  // Smoothed values
  const aYouLow = useSmooth(youLow);
  const aYouHigh = useSmooth(youHigh);
  const aUsual = useSmooth(usual);

  // Publishing
  const pub = PUB_MATRIX[credit];
  const aPubUsualLow = useSmooth(pub.usualLow);
  const aPubUsualHigh = useSmooth(pub.usualHigh);
  const aPubYouLow = useSmooth(pub.youLow);

  return (
    <section className={`section rule-top${embedded ? " chapter-embedded" : ""}`} id="calculator">
      <div className="page">
        <div style={{ marginBottom: 32 }}>
          <span className="eyebrow">Free Tool · The Standard</span>
          <h2 className="h-section" style={{ marginTop: 16 }}>
            Know what you're <em>worth</em>
          </h2>
        </div>

        {/* Tab strip — Liquid Glass segmented control */}
        <div style={{ marginBottom: 28 }}>
          <GlassSegmented
            items={[
              { id: "fee", num: "01", label: "Producer Fee", sub: "Upfront check" },
              { id: "publishing", num: "02", label: "Publishing Split", sub: "Songwriter split" },
              { id: "master", num: "03", label: "Master Royalty", sub: "Backend points" },
            ]}
            active={tab}
            onChange={setTab}
            ariaLabel="Calculator mode"
          />
        </div>

        {/* Body, shared context + balanced 50/50 panels */}
        <div className="calc-shell" style={{ marginTop: 0 }}>
          {tab === "fee" && (
          <div className="calc-context">
            <div className="calc-context-note">
              <p className="calc-context-note-main">
                ★ Share % = estimated slice of Spotify artists (artist) or producers (producer).
              </p>
              <p className="calc-context-note-sources">
                Sources: Spotify Loud &amp; Clear, Chartmetric, Dynamoi, Muso.AI, Billboard, RIAA. Rounded.
              </p>
            </div>
            <div className="calc-context-grid calc-context-grid-pair">
              <Field label="Artist size" options={TIERS} value={tier} onChange={setTier}
                     tooltip={tierObj.desc}
                     share={`${tierObj.share} of ${tierObj.shareOf}`}
                     hint={tierObj.listeners} />
              <Field label="Producer size" options={CREDITS} value={credit} onChange={setCredit}
                     tooltip={creditObj.desc}
                     share={`${creditObj.share} of ${creditObj.shareOf}`}
                     hint={creditObj.stat} />
            </div>
            <div className="calc-context-deal">
              <Field label="Deal type" groups={dealGroups} options={dealOptions} value={deal} onChange={setDeal} tooltip={dealObj.desc} hint={dealObj.desc} />
            </div>
          </div>
          )}

          {tab === "fee" && (
          <div className="calc-benchmark-row">
            <span className="caption">Benchmark · usual vs. standard</span>
            <BenchmarkPanel
              tab={tab}
              layout="horizontal"
              usual={aUsual} youLow={aYouLow} youHigh={aYouHigh}
              usualRaw={usual} youLowRaw={youLow} youHighRaw={youHigh}
              pub={{ uLow: aPubUsualLow, uHigh: aPubUsualHigh, yLow: aPubYouLow }}
            />
          </div>
          )}

          <div className="calc-panel calc-panel-workspace">
            {tab === "fee" && (
              <FeeResults usual={aUsual} youLow={aYouLow} youHigh={aYouHigh} usualRaw={usual} youLowRaw={youLow} youHighRaw={youHigh} deal={deal} compact />
            )}
            {tab === "publishing" && (
              <PubSplitEditor streams={streams} setStreams={setStreams} />
            )}
            {tab === "master" && (
              <MasterCalc streams={streams} setStreams={setStreams} />
            )}
          </div>

          {tab === "publishing" && (
            <CollapsibleAppendix title="Regional publishing breakdown" sub="Performance vs. mechanical by territory">
              <RegionalPublishingBreakdown embedded streams={streams} setStreams={setStreams} />
            </CollapsibleAppendix>
          )}
          {tab === "master" && (
            <CollapsibleAppendix title="Platform master rates" sub="Per-stream by DSP and region">
              <PlatformMasterBreakdown embedded streams={streams} setStreams={setStreams} />
            </CollapsibleAppendix>
          )}
        </div>

        {/* CTA rail */}
        <div className="grid-12" style={{ marginTop: 32, alignItems: "center" }}>
          <div style={{ gridColumn: "span 8" }}>
            <span className="caption">★ Estimates based on 400+ negotiated deals. Actual numbers vary. The point is the gap, and you knowing it walks in with you.</span>
          </div>
          <div style={{ gridColumn: "span 4", display: "flex", justifyContent: "flex-end", gap: 12 }}>
            <JoinCta href={PU_LINKS.free} variant="ghost">Join free on Skool</JoinCta>
            <JoinCta href={PU_LINKS.plus}>Start the Roadmap</JoinCta>
          </div>
        </div>
      </div>
    </section>
  );
}

function CollapsibleAppendix({ title, sub, children }) {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="calc-appendix">
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        style={{
          width: "100%",
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          gap: 16,
          padding: "18px 0",
          background: "transparent",
          border: "none",
          cursor: "pointer",
          textAlign: "left",
          color: "var(--ink)",
        }}
      >
        <div>
          <span className="eyebrow no-mark" style={{ color: "var(--gold)" }}>{title}</span>
          {sub && <p className="caption" style={{ marginTop: 6 }}>{sub}</p>}
        </div>
        <span style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.14em", color: "var(--gold)" }}>
          {open ? "HIDE ↑" : "EXPAND ↓"}
        </span>
      </button>
      {open && <div style={{ paddingBottom: 8 }}>{children}</div>}
    </div>
  );
}

function BenchmarkPanel({ tab, layout = "vertical", usual, youLow, youHigh, usualRaw, youLowRaw, youHighRaw, pub, master }) {
  const barsClass = layout === "horizontal" ? "calc-benchmark-bars" : "";
  const barsStyle = layout === "horizontal"
    ? undefined
    : { marginTop: 20, display: "flex", flexDirection: "column", gap: 20 };

  if (tab === "fee") {
    const max = Math.max(youHighRaw, usualRaw) * 1.1 || 1;
    return (
      <div className={barsClass} style={barsStyle}>
        <BarBlock tone="dim" label="What producers usually settle for" rangeLabel="Mid-range" value={`$${formatNum(usual)}`} tag="USUAL" pct={(usualRaw / max) * 100} />
        <BarBlock tone="gold" label="What you should quote" rangeLabel="Floor → ceiling" value={`$${formatNum(youLow)} – $${formatNum(youHigh)}`} tag="STANDARD" pct={(youHighRaw / max) * 100} secondaryPct={(youLowRaw / max) * 100} />
      </div>
    );
  }
  if (tab === "publishing") {
    const max = 50;
    return (
      <div className={barsClass} style={barsStyle}>
        <BarBlock tone="dim" label="What producers usually get" rangeLabel="Writer share" value={`${Math.round(pub.uLow)}–${Math.round(pub.uHigh)}%`} tag="USUAL" pct={(pub.uHigh / max) * 100} />
        <BarBlock tone="gold" label="What you should get" rangeLabel="If you wrote it" value={`${Math.round(pub.yLow)}%`} tag="STANDARD" pct={(pub.yLow / max) * 100} />
        {layout !== "horizontal" && (
          <p className="body-text" style={{ fontSize: 13, lineHeight: 1.5, margin: 0, color: "var(--ink-3)" }}>
            Use the workspace → to model splits with co-producers and the artist.
          </p>
        )}
      </div>
    );
  }
  const max = Math.max(master.yHigh, master.uHigh, 1) || 6;
  return (
    <div style={layout === "horizontal" ? { marginTop: 16 } : undefined}>
      <div className={barsClass} style={barsStyle}>
        <BarBlock tone="dim" label="What producers usually get" rangeLabel="Master points" value={`${Math.round(master.uLow)}–${Math.round(master.uHigh)} pts`} tag="USUAL" pct={(master.uHigh / max) * 100} />
        <BarBlock tone="gold" label="What you should target" rangeLabel="Points on master" value={`${Math.round(master.yLow)}–${Math.round(master.yHigh)} pts`} tag="STANDARD" pct={(master.yHigh / max) * 100} secondaryPct={(master.yLow / max) * 100} />
      </div>
      <p className="body-text" style={{ fontSize: 13, lineHeight: 1.5, margin: layout === "horizontal" ? "14px 0 0" : 0, color: "var(--ink-3)" }}>
        Indie = ownership % via distro. Signed = points + recoup. Workspace ↓ for the math.
      </p>
    </div>
  );
}


function FieldTooltip({ text }) {
  const [open, setOpen] = React.useState(false);
  if (!text) return null;
  return (
    <span className="field-tooltip-wrap">
      <button
        type="button"
        className="field-tooltip-trigger"
        aria-label="More info"
        aria-expanded={open}
        onMouseEnter={() => setOpen(true)}
        onMouseLeave={() => setOpen(false)}
        onFocus={() => setOpen(true)}
        onBlur={() => setOpen(false)}
      >
        ⓘ
      </button>
      {open && (
        <span className="field-tooltip-popover" role="tooltip">
          {text}
        </span>
      )}
    </span>
  );
}

function Field({ label, options, groups, value, onChange, desc, tooltip, share, hint }) {
  const selected = options.find((o) => o.id === value);
  const tipText = tooltip ?? selected?.desc ?? desc;
  return (
    <div className="field-block">
      <div className="field-label-row">
        <span className="field-label">
          {label}
          <FieldTooltip text={tipText} />
        </span>
      </div>
      {share && (
        <p className="field-share-subline">
          <span className="field-label-share-key">Share:</span> {share}
        </p>
      )}
      <div className="field-select-wrap">
        <select className="field" value={value} onChange={(e) => onChange(e.target.value)}>
          {groups
            ? groups.map((g) => (
                <optgroup key={g.label} label={g.label}>
                  {g.options.map((o) => (
                    <option key={o.id} value={o.id} style={{ background: "var(--bg)", color: "var(--ink)" }}>
                      {o.label}
                    </option>
                  ))}
                </optgroup>
              ))
            : options.map((o) => (
                <option key={o.id} value={o.id} style={{ background: "var(--bg)", color: "var(--ink)" }}>
                  {o.label}
                </option>
              ))}
        </select>
        <span className="field-select-chevron">▼</span>
      </div>
      {hint && <p className="field-hint">{hint}</p>}
    </div>
  );
}

function FeeResults({ usual, youLow, youHigh, usualRaw, youLowRaw, youHighRaw, deal, compact }) {
  const delta = youHighRaw - usualRaw;
  const unit = deal === "lease-ne" || deal === "lease-ex" ? "beat" : "placement";
  const unitPlural = deal === "lease-ne" || deal === "lease-ex" ? "beats" : "placements";

  return (
    <div className="fee-results">
      <div className="fee-results-gap">
        <div className="fee-results-gap-main">
          <span className="caption" style={{ color: "var(--gold)" }}>Extra per {unit}, if you quote your ceiling</span>
          <div className="fee-results-gap-row">
            <span className="fee-results-gap-number">+${formatNum(delta)}</span>
            <span className="fee-results-gap-note">
              Same {unit}. Same artist. You just asked for the top of your range instead of the usual.
            </span>
          </div>
        </div>
        <div className="fee-results-gap-stack">
          <span className="caption">Stack 10 {unitPlural} at this level</span>
          <div className="fee-results-gap-stack-value">${formatNum(delta * 10)}</div>
        </div>
      </div>
    </div>
  );
}

function BarBlock({ tone, label, rangeLabel, value, tag, pct, secondaryPct, compact }) {
  return (
    <div>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: compact ? 8 : 10 }}>
        <div>
          <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.16em", color: tone === "gold" ? "var(--gold)" : "var(--ink-3)" }}>
            {tag}
          </span>
          <div style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: compact ? 14 : 16, color: tone === "gold" ? "var(--ink)" : "var(--ink-2)", marginTop: 2, letterSpacing: "-0.01em" }}>
            {label}
          </div>
        </div>
        <div style={{ textAlign: "right" }}>
          <div className="caption" style={{ fontSize: compact ? 9 : undefined }}>{rangeLabel}</div>
          <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: compact ? "clamp(22px, 2.4vw, 32px)" : "clamp(28px, 3.6vw, 48px)", letterSpacing: "-0.03em", color: tone === "gold" ? "var(--gold)" : "var(--ink-2)", lineHeight: 1, fontVariantNumeric: "tabular-nums" }}>
            {value}
          </div>
        </div>
      </div>
      <div style={{ position: "relative", height: compact ? 14 : 18, background: "rgba(255,255,255,0.04)", overflow: "hidden" }}>
        {secondaryPct !== undefined && (
          <div style={{
            position: "absolute", inset: 0,
            width: `${secondaryPct}%`,
            background: tone === "gold" ? "rgba(212,166,74,0.35)" : "var(--ink-4)",
            transition: "width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1)",
          }}></div>
        )}
        <div style={{
          position: "absolute", inset: 0,
          width: `${pct}%`,
          background: tone === "gold"
            ? "linear-gradient(90deg, var(--gold-dim), var(--gold))"
            : "linear-gradient(90deg, #2a2620, #4a4234)",
          transition: "width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1)",
        }}></div>
        {secondaryPct !== undefined && (
          <>
            <div style={{ position: "absolute", left: `${secondaryPct}%`, top: -3, bottom: -3, width: 1, background: "var(--ink-2)" }}></div>
            <div style={{ position: "absolute", left: `${pct}%`, top: -3, bottom: -3, width: 1, background: "var(--gold)" }}></div>
          </>
        )}
      </div>
    </div>
  );
}

// Regional royalty data, comprehensive breakdown
// US all-in publishing (performance + mechanical) ≈ $600–800 per million streams.
const US_PUB_PER_1K = 0.70;

const REGIONAL_PUBLISHING = {
  us: { label: "United States", perf: 0.35, mech: 0.35, total: US_PUB_PER_1K, confidence: "defensible", source: "MLC/ASCAP/BMI collateral + distributor data" },
  eu: { label: "Europe (high-ARPU)", perf: 0.43, mech: 0.47, total: 0.90, confidence: "defensible", source: "SoundExchange EU + MCPS/PRS data" },
  mexico: { label: "Mexico", perf: 0.20, mech: 0.25, total: 0.45, confidence: "consensus", source: "Distributor reports + SACM" },
  asia: { label: "Asia ex-Japan", perf: 0.10, mech: 0.10, total: 0.20, confidence: "extrapolated", source: "Low ARPU regions; sparse data" },
  japan: { label: "Japan", perf: 0.48, mech: 0.52, total: 1.00, confidence: "consensus", source: "High-ARPU market + local societies" },
};

const PLATFORM_MASTER_RATES = {
  spotify: { us: 0.004, eu: 0.005, mx: 0.0015, asia: 0.0008, confidence: "defensible" },
  apple: { us: 0.0087, eu: 0.0095, mx: 0.004, asia: 0.002, confidence: "defensible" },
  tidal: { us: 0.013, eu: 0.013, mx: 0.006, asia: 0.003, confidence: "industry-consensus" },
  amazon: { us: 0.0072, eu: 0.0075, mx: 0.003, asia: 0.0015, confidence: "consensus" },
  youtube: { us: 0.002, eu: 0.0025, mx: 0.001, asia: 0.0005, confidence: "extrapolated" },
};

// Confidence badge colors
const CONFIDENCE_COLORS = {
  defensible: { bg: "rgba(106,184,232,0.12)", border: "#6ab8e8", text: "#7bc4f0", label: "Defensible" },
  consensus: { bg: "rgba(122,207,153,0.12)", border: "#7acf99", text: "#8acaa0", label: "Industry consensus" },
  "industry-consensus": { bg: "rgba(122,207,153,0.12)", border: "#7acf99", text: "#8acaa0", label: "Industry consensus" },
  extrapolated: { bg: "rgba(184,137,255,0.12)", border: "#b889ff", text: "#c5a3ff", label: "Extrapolated" },
};

const ROLE_COLORS = {
  Producer: { fg: "#d4a64a", bg: "rgba(212,166,74,0.18)", border: "var(--gold)" },
  "Co-producer": { fg: "#e8c878", bg: "rgba(232,200,120,0.14)", border: "#e8c878" },
  Songwriter: { fg: "#b889ff", bg: "rgba(184,137,255,0.14)", border: "#b889ff" },
  Artist: { fg: "#6ab8e8", bg: "rgba(106,184,232,0.14)", border: "#6ab8e8" },
};

const PUB_PERF_COLOR = "var(--gold)";
const PUB_MECH_COLOR = "#7acf99";

const PUB_SIDE_CAP = 50;
const PUB_STREAM_STOPS = [10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000];

function pubStreamStopIndex(value) {
  let best = 0;
  let bestDiff = Infinity;
  PUB_STREAM_STOPS.forEach((v, i) => {
    const diff = Math.abs(v - value);
    if (diff < bestDiff) {
      bestDiff = diff;
      best = i;
    }
  });
  return best;
}

function pubStreamChipLabel(n) {
  if (n >= 1_000_000_000) return `${n / 1_000_000_000}B`;
  if (n >= 1_000_000) return `${n / 1_000_000}M`;
  return `${n / 1_000}K`;
}

function pubRoyaltyBreakdown(streams, writerSharePct = 100) {
  const { perf, mech } = REGIONAL_PUBLISHING.us;
  const perfPool = (streams / 1000) * perf;
  const mechPool = (streams / 1000) * mech;
  const mult = writerSharePct / 100;
  return {
    perfPool,
    mechPool,
    yourPerf: perfPool * mult,
    yourMech: mechPool * mult,
  };
}
const isProducerSide = (role) => role === "Producer" || role === "Co-producer";
const isArtistSide = (role) => role === "Artist" || role === "Songwriter";

function splitSideEvenly(count, sideCap = PUB_SIDE_CAP) {
  if (!count) return [];
  const base = Math.floor((sideCap / count) * 10) / 10;
  const shares = Array.from({ length: count }, () => base);
  shares[0] = +(shares[0] + (sideCap - shares.reduce((a, s) => a + s, 0))).toFixed(1);
  return shares;
}

function rebalanceSide(list, sideFilter) {
  const sideMembers = list.filter((c) => sideFilter(c));
  const shares = splitSideEvenly(sideMembers.length);
  let i = 0;
  return list.map((c) => {
    if (!sideFilter(c)) return c;
    return { ...c, share: shares[i++] };
  });
}

function rebalanceBothSides(list) {
  return rebalanceSide(rebalanceSide(list, (c) => isProducerSide(c.role)), (c) => isArtistSide(c.role));
}

function clampSideShare(value, sideCap = PUB_SIDE_CAP) {
  return Math.max(0, Math.min(sideCap, Number(value) || 0));
}

function PubSplitEditor({ streams, setStreams }) {
  const [contributors, setContributors] = React.useState([
    { id: 1, role: "Producer", name: "You", share: 50 },
    { id: 2, role: "Artist", name: "The Artist", share: 50 },
  ]);

  const producerSide = contributors.filter((c) => isProducerSide(c.role));
  const artistSide = contributors.filter((c) => isArtistSide(c.role));
  const producerTotal = producerSide.reduce((a, c) => a + Number(c.share || 0), 0);
  const artistTotal = artistSide.reduce((a, c) => a + Number(c.share || 0), 0);
  const pubPool = (streams / 1000) * US_PUB_PER_1K;
  const yourRow = contributors[0];
  const yourShare = Number(yourRow?.share || 0);
  const yourEarned = pubPool * (yourShare / 100);

  const update = (id, patch) => {
    setContributors((cs) => {
      const prev = cs.find((c) => c.id === id);
      let next = cs.map((c) => (c.id === id ? { ...c, ...patch } : c));
      if (patch.role && prev && ((isProducerSide(prev.role) && isArtistSide(patch.role)) || (isArtistSide(prev.role) && isProducerSide(patch.role)))) {
        next = rebalanceBothSides(next);
      } else if (patch.share !== undefined) {
        next = next.map((c) => (c.id === id ? { ...c, share: clampSideShare(patch.share) } : c));
      }
      return next;
    });
  };

  const add = (role) => {
    const newId = Math.max(...contributors.map((c) => c.id), 0) + 1;
    const defaultName = role === "Co-producer" ? "Co-producer" : role === "Songwriter" ? "Songwriter" : role;
    setContributors((cs) => {
      const next = [...cs, { id: newId, role, name: defaultName, share: 0 }];
      if (isProducerSide(role)) return rebalanceSide(next, (c) => isProducerSide(c.role));
      if (isArtistSide(role)) return rebalanceSide(next, (c) => isArtistSide(c.role));
      return next;
    });
  };

  const remove = (id) => {
    setContributors((cs) => {
      if (cs[0].id === id) return cs;
      const removed = cs.find((c) => c.id === id);
      const next = cs.filter((c) => c.id !== id);
      if (!next.some((c) => isProducerSide(c.role)) || !next.some((c) => isArtistSide(c.role))) return cs;
      if (removed && isProducerSide(removed.role)) return rebalanceSide(next, (c) => isProducerSide(c.role));
      return rebalanceSide(next, (c) => isArtistSide(c.role));
    });
  };

  const rebalanceProducerSide = () => setContributors((cs) => rebalanceSide(cs, (c) => isProducerSide(c.role)));
  const rebalanceArtistSide = () => setContributors((cs) => rebalanceSide(cs, (c) => isArtistSide(c.role)));

  return (
    <div className="tool-split" style={{ gap: 0, border: "1px solid var(--rule-strong)", marginTop: 4 }}>
      <div style={{ display: "flex", flexDirection: "column", gap: 16, borderRight: "1px solid var(--rule-strong)", padding: "clamp(22px, 3vw, 32px)", minWidth: 0 }}>
        <PubBlock label="Streams">
          <StreamScrubber streams={streams} setStreams={setStreams} />
        </PubBlock>

        <PubBlock label="Writer split">
          <SideSplitBar producerSide={producerSide} artistSide={artistSide} />

          <PubSideGroup
            label="Producer side"
            color="var(--gold)"
            total={producerTotal}
            sideCap={PUB_SIDE_CAP}
            actions={(
              <>
                <AddBtn label="+ Co-producer" onClick={() => add("Co-producer")} />
                <AddBtn label="↺ Even" onClick={rebalanceProducerSide} />
              </>
            )}
          >
            {producerSide.map((c) => (
              <PubContributorRow
                key={c.id}
                c={c}
                isYou={c.id === 1}
                sideCap={PUB_SIDE_CAP}
                onChange={(patch) => update(c.id, patch)}
                onRemove={() => remove(c.id)}
              />
            ))}
          </PubSideGroup>

          <PubSideGroup
            label="Artist side"
            color="#6ab8e8"
            total={artistTotal}
            sideCap={PUB_SIDE_CAP}
            actions={(
              <>
                <AddBtn label="+ Songwriter" onClick={() => add("Songwriter")} />
                <AddBtn label="+ Artist" onClick={() => add("Artist")} />
                <AddBtn label="↺ Even" onClick={rebalanceArtistSide} />
              </>
            )}
          >
            {artistSide.map((c) => (
              <PubContributorRow
                key={c.id}
                c={c}
                isYou={false}
                sideCap={PUB_SIDE_CAP}
                onChange={(patch) => update(c.id, patch)}
                onRemove={() => remove(c.id)}
              />
            ))}
          </PubSideGroup>
        </PubBlock>
      </div>

      <div style={{ position: "sticky", top: 24, padding: "clamp(22px, 3vw, 32px)", alignSelf: "start", minWidth: 0 }}>
        <div style={{ padding: "28px 28px 32px", background: "rgba(212,166,74,0.06)", border: "1px solid var(--rule-gold)" }}>
          <span className="caption" style={{ color: "var(--gold)" }}>You keep</span>
          <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: "clamp(36px, 4.5vw, 56px)", letterSpacing: "-0.035em", color: "var(--gold)", lineHeight: 1, fontVariantNumeric: "tabular-nums", marginTop: 8 }}>
            ${formatNum(yourEarned)}
          </div>
          <p className="caption" style={{ marginTop: 10, color: "var(--ink-3)" }}>
            {yourShare.toFixed(yourShare % 1 ? 1 : 0)}% · {formatNum(streams)} streams · ~${US_PUB_PER_1K.toFixed(2)}/1K US
          </p>

          <PubWaterfall
            pubPool={pubPool}
            streams={streams}
            producerSide={producerSide}
            artistSide={artistSide}
          />
        </div>
      </div>
    </div>
  );
}

function PubBlock({ label, children }) {
  return (
    <div style={{ padding: "18px 20px", background: "rgba(255,255,255,0.02)", border: "1px solid var(--rule-strong)" }}>
      <span style={{ display: "block", fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.16em", color: "var(--gold)", textTransform: "uppercase", marginBottom: 12 }}>{label}</span>
      {children}
    </div>
  );
}

function PubSideGroup({ label, color, total, sideCap = PUB_SIDE_CAP, actions, children }) {
  const balanced = Math.abs(total - sideCap) < 0.05;
  return (
    <div style={{ marginTop: 14, padding: "12px 12px 10px", border: `1px solid ${color === "var(--gold)" ? "rgba(212,166,74,0.25)" : "rgba(106,184,232,0.25)"}`, background: "rgba(0,0,0,0.15)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 8, marginBottom: 8 }}>
        <span className="caption" style={{ color: balanced ? color : "#e88a7d" }}>
          {label} · {total.toFixed(total % 1 ? 1 : 0)}%{balanced ? "" : ` · must equal ${sideCap}%`}
        </span>
        <div style={{ display: "flex", gap: 6, flexWrap: "wrap", justifyContent: "flex-end" }}>{actions}</div>
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>{children}</div>
    </div>
  );
}

function SideSplitBar({ producerSide, artistSide }) {
  const prodTotal = Math.max(1, producerSide.reduce((a, c) => a + Number(c.share || 0), 0));
  const artTotal = Math.max(1, artistSide.reduce((a, c) => a + Number(c.share || 0), 0));
  return (
    <div style={{ display: "flex", height: 28, overflow: "hidden", border: "1px solid var(--rule-strong)" }}>
      <div style={{ width: "50%", display: "flex", borderRight: "1px solid var(--rule-strong)" }}>
        {producerSide.map((c, i) => {
          const col = ROLE_COLORS[c.role] || ROLE_COLORS.Producer;
          const pct = (Number(c.share) / prodTotal) * 100;
          return (
            <div key={c.id} title={`${c.name} · ${c.share}%`}
              style={{ width: `${pct}%`, background: col.bg, borderRight: i < producerSide.length - 1 ? "1px solid var(--rule-strong)" : "none", transition: "width 0.35s ease", minWidth: 0 }}
            />
          );
        })}
      </div>
      <div style={{ width: "50%", display: "flex" }}>
        {artistSide.map((c, i) => {
          const col = ROLE_COLORS[c.role] || ROLE_COLORS.Artist;
          const pct = (Number(c.share) / artTotal) * 100;
          return (
            <div key={c.id} title={`${c.name} · ${c.share}%`}
              style={{ width: `${pct}%`, background: col.bg, borderRight: i < artistSide.length - 1 ? "1px solid var(--rule-strong)" : "none", transition: "width 0.35s ease", minWidth: 0 }}
            />
          );
        })}
      </div>
    </div>
  );
}

function PubStreamsInput({ streams, setStreams }) {
  const maxIdx = PUB_STREAM_STOPS.length - 1;
  const stopIndex = pubStreamStopIndex(streams);
  const pct = maxIdx > 0 ? (stopIndex / maxIdx) * 100 : 0;
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft] = React.useState("");

  const beginEdit = () => {
    setDraft(formatNum(streams));
    setEditing(true);
  };

  const applyDraft = () => {
    const parsed = Math.max(0, Math.round(Number(String(draft).replace(/,/g, "")) || 0));
    setStreams(parsed || PUB_STREAM_STOPS[0]);
    setEditing(false);
  };

  return (
    <div style={{ minWidth: 0 }}>
      <div style={{ display: "flex", alignItems: "baseline", justifyContent: "flex-end", marginBottom: 12 }}>
        {editing ? (
          <input
            autoFocus
            type="text"
            inputMode="numeric"
            value={draft}
            onChange={(e) => setDraft(e.target.value)}
            onBlur={applyDraft}
            onKeyDown={(e) => {
              if (e.key === "Enter") applyDraft();
              if (e.key === "Escape") setEditing(false);
            }}
            style={{
              background: "transparent",
              border: "none",
              borderBottom: "1px solid rgba(212,166,74,0.4)",
              color: "var(--gold)",
              fontFamily: "var(--sans)",
              fontWeight: 800,
              fontSize: "clamp(28px, 3.4vw, 44px)",
              letterSpacing: "-0.025em",
              fontVariantNumeric: "tabular-nums",
              textAlign: "right",
              width: "min(100%, 240px)",
              outline: "none",
              padding: "2px 4px",
            }}
          />
        ) : (
          <button
            type="button"
            onClick={beginEdit}
            title="Click to type a custom stream count"
            style={{
              background: "transparent",
              border: "none",
              borderBottom: "1px solid rgba(212,166,74,0.4)",
              color: "var(--gold)",
              fontFamily: "var(--sans)",
              fontWeight: 800,
              fontSize: "clamp(28px, 3.4vw, 44px)",
              letterSpacing: "-0.025em",
              fontVariantNumeric: "tabular-nums",
              textAlign: "right",
              cursor: "text",
              outline: "none",
              padding: "2px 4px",
              lineHeight: 1.1,
            }}
          >
            {formatNum(streams)}
          </button>
        )}
      </div>

      <input
        type="range"
        min={0}
        max={maxIdx}
        step={1}
        value={stopIndex}
        onChange={(e) => setStreams(PUB_STREAM_STOPS[Number(e.target.value)])}
        className="pu-slider"
        style={{ width: "100%", display: "block", "--pu-pct": `${pct}%` }}
      />

      <div style={{ position: "relative", height: 22, marginTop: 10 }}>
        {PUB_STREAM_STOPS.map((s, i) => {
          const left = maxIdx > 0 ? (i / maxIdx) * 100 : 0;
          return (
            <span
              key={s}
              className="caption"
              style={{
                position: "absolute",
                left: `${left}%`,
                transform: i === 0 ? "none" : i === maxIdx ? "translateX(-100%)" : "translateX(-50%)",
                whiteSpace: "nowrap",
              }}
            >
              {pubStreamChipLabel(s)}
            </span>
          );
        })}
      </div>
    </div>
  );
}

function PubContributorRow({ c, isYou, sideCap, onChange, onRemove }) {
  const col = ROLE_COLORS[c.role] || ROLE_COLORS.Producer;
  const roleOptions = isProducerSide(c.role)
    ? ["Producer", "Co-producer"]
    : ["Artist", "Songwriter"];
  return (
    <div style={{
      display: "grid",
      gridTemplateColumns: "auto 1fr auto auto",
      gap: 10,
      alignItems: "center",
      padding: "8px 10px",
      border: "1px solid var(--rule-strong)",
      background: "rgba(255,255,255,0.02)",
    }}>
      <select
        value={c.role}
        disabled={isYou}
        onChange={(e) => onChange({ role: e.target.value })}
        style={{
          background: col.bg,
          color: col.fg,
          border: `1px solid ${col.border}`,
          fontFamily: "var(--mono)",
          fontSize: 10,
          letterSpacing: "0.14em",
          padding: "6px 10px",
          appearance: "none",
          cursor: isYou ? "default" : "pointer",
          fontWeight: 600,
          opacity: isYou ? 0.85 : 1,
        }}
      >
        {roleOptions.map((r) => (
          <option key={r} value={r} style={{ background: "var(--bg)", color: "var(--ink)" }}>{r.toUpperCase()}</option>
        ))}
      </select>
      <input
        value={c.name}
        disabled={isYou}
        onChange={(e) => onChange({ name: e.target.value })}
        style={{
          background: "transparent",
          border: "none",
          color: "var(--ink)",
          fontFamily: "var(--sans)",
          fontWeight: 600,
          fontSize: 14,
          padding: "4px 0",
          outline: "none",
          width: "100%",
          letterSpacing: "-0.01em",
        }}
      />
      <div style={{ display: "flex", alignItems: "baseline", gap: 2 }}>
        <input
          type="number"
          value={c.share}
          min="0"
          max={sideCap}
          step="0.5"
          onChange={(e) => onChange({ share: Math.max(0, Math.min(sideCap, Number(e.target.value) || 0)) })}
          style={{
            background: "transparent",
            border: "none",
            borderBottom: `1px solid ${col.fg}`,
            color: col.fg,
            fontFamily: "var(--sans)",
            fontWeight: 700,
            fontSize: 14,
            width: 40,
            textAlign: "right",
            padding: "2px 2px",
            outline: "none",
            fontVariantNumeric: "tabular-nums",
          }}
        />
        <span style={{ color: col.fg, fontFamily: "var(--sans)", fontWeight: 700, fontSize: 14 }}>%</span>
      </div>
      {isYou ? <span style={{ width: 24 }}></span> : (
        <button type="button" onClick={onRemove} style={{ background: "transparent", border: "1px solid var(--rule)", color: "var(--ink-3)", fontFamily: "var(--mono)", fontSize: 12, width: 24, height: 24, cursor: "pointer" }}>×</button>
      )}
    </div>
  );
}

function PubRoyaltySubRows({ streams, writerSharePct }) {
  const { yourPerf, yourMech } = pubRoyaltyBreakdown(streams, writerSharePct);
  return (
    <div style={{ paddingLeft: 10, marginTop: 6, display: "flex", flexDirection: "column", gap: 4 }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 12, alignItems: "baseline" }}>
        <span className="caption" style={{ color: "var(--ink-3)" }}>Performance · PRO</span>
        <span style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 12, color: PUB_PERF_COLOR, fontVariantNumeric: "tabular-nums" }}>${formatNum(yourPerf)}</span>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 12, alignItems: "baseline" }}>
        <span className="caption" style={{ color: "var(--ink-3)" }}>Mechanical · MLC</span>
        <span style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 12, color: PUB_MECH_COLOR, fontVariantNumeric: "tabular-nums" }}>${formatNum(yourMech)}</span>
      </div>
    </div>
  );
}

function PubWaterfall({ pubPool, streams, producerSide, artistSide }) {
  const renderProducerRow = (c) => {
    const earned = pubPool * (Number(c.share) / 100);
    const col = ROLE_COLORS[c.role] || ROLE_COLORS.Producer;
    const shareLabel = Number(c.share).toFixed(c.share % 1 ? 1 : 0);
    return (
      <div key={c.id} style={{ padding: "8px 0", borderBottom: "1px dashed var(--rule)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 16, alignItems: "baseline" }}>
          <div style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 14, color: "var(--ink-2)" }}>
            {c.name} · <span style={{ color: col.fg }}>{shareLabel}%</span>
          </div>
          <div style={{ fontFamily: "var(--sans)", fontWeight: 700, fontSize: 16, color: col.fg, fontVariantNumeric: "tabular-nums" }}>${formatNum(earned)}</div>
        </div>
        <PubRoyaltySubRows streams={streams} writerSharePct={Number(c.share)} />
      </div>
    );
  };

  const renderArtistRow = (c) => {
    const earned = pubPool * (Number(c.share) / 100);
    const col = ROLE_COLORS[c.role] || ROLE_COLORS.Artist;
    const shareLabel = Number(c.share).toFixed(c.share % 1 ? 1 : 0);
    return (
      <div key={c.id} style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 16, alignItems: "baseline", padding: "8px 0", borderBottom: "1px dashed var(--rule)" }}>
        <div style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 14, color: "var(--ink-2)" }}>
          {c.name} · <span style={{ color: col.fg }}>{shareLabel}%</span>
        </div>
        <div style={{ fontFamily: "var(--sans)", fontWeight: 700, fontSize: 16, color: col.fg, fontVariantNumeric: "tabular-nums" }}>${formatNum(earned)}</div>
      </div>
    );
  };

  const renderSide = (label, color, members, renderRow) => (
    <div style={{ marginTop: 16 }}>
      <span className="caption" style={{ color, display: "block", marginBottom: 4 }}>{label}</span>
      {label === "Producer side" && (
        <p className="caption" style={{ margin: "0 0 8px", color: "var(--ink-3)", lineHeight: 1.4 }}>
          Register PRO + MLC to collect · until then it sits at the societies
        </p>
      )}
      {members.map(renderRow)}
    </div>
  );

  return (
    <div style={{ marginTop: 24, paddingTop: 24, borderTop: "1px solid var(--rule-gold)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 16, alignItems: "baseline", padding: "10px 0", borderBottom: "1px dashed var(--rule)" }}>
        <div style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 14, color: "var(--ink)" }}>Pool</div>
        <div style={{ fontFamily: "var(--sans)", fontWeight: 700, fontSize: 22, color: "var(--gold)", fontVariantNumeric: "tabular-nums" }}>${formatNum(pubPool)}</div>
      </div>
      {renderSide("Producer side", "var(--gold)", producerSide, renderProducerRow)}
      {renderSide("Artist side", "#6ab8e8", artistSide, renderArtistRow)}
    </div>
  );
}

function AddBtn({ label, onClick }) {
  return (
    <button onClick={onClick} style={{
      background: "transparent",
      border: "1px dashed var(--rule-strong)",
      color: "var(--ink-2)",
      fontFamily: "var(--mono)",
      fontSize: 11,
      letterSpacing: "0.14em",
      padding: "8px 12px",
      cursor: "pointer",
      textTransform: "uppercase",
      transition: "all 0.18s ease",
    }}
    onMouseEnter={(e) => { e.currentTarget.style.borderColor = "var(--gold)"; e.currentTarget.style.color = "var(--gold)"; }}
    onMouseLeave={(e) => { e.currentTarget.style.borderColor = "var(--rule-strong)"; e.currentTarget.style.color = "var(--ink-2)"; }}
    >
      {label}
    </button>
  );
}

const MASTER_VALUE = "clamp(22px, 2.4vw, 32px)";
const MASTER_HERO = "clamp(32px, 3.6vw, 44px)";
const MASTER_ROW_PAD = "14px 20px";
const MASTER_PANEL_PAD = "18px 20px";
const MASTER_GOLD = "#d4a64a";

const MASTER_TONES = {
  benchmark: { color: "#9a9283", bg: "rgba(0,0,0,0.14)", border: "rgba(255,255,255,0.08)" },
  streams: { color: "#6ab8e8", bg: "rgba(106,184,232,0.07)", border: "rgba(106,184,232,0.2)" },
  advance: { color: "#b889ff", bg: "rgba(184,137,255,0.07)", border: "rgba(184,137,255,0.2)" },
  deal: { color: "#d4a64a", bg: "rgba(212,166,74,0.06)", border: "rgba(212,166,74,0.22)" },
  distro: { color: "#7acf99", bg: "rgba(122,207,153,0.06)", border: "rgba(122,207,153,0.2)" },
  result: { color: "#d4a64a", bg: "rgba(212,166,74,0.08)", border: "rgba(212,166,74,0.32)" },
};

function masterTone(tone) {
  return MASTER_TONES[tone] || MASTER_TONES.deal;
}

function MasterLayoutToggle({ layout, setLayout }) {
  return (
    <div className="master-layout-toggle">
      <span className="caption">Preview</span>
      <GlassSegmented
        items={[
          { id: "a", num: "A", label: "Two columns" },
          { id: "b", num: "B", label: "Step strips" },
        ]}
        active={layout}
        onChange={setLayout}
        ariaLabel="Master preview layout"
      />
    </div>
  );
}

function MasterFieldA({ label, children, last, deal }) {
  return (
    <div className={`master-field-a${last ? " last" : ""}${deal ? " is-deal" : ""}`}>
      <span className="master-field-label">{label}</span>
      {children}
    </div>
  );
}

function MasterFieldB({ label, children, last }) {
  return (
    <div className={`master-field-b${last ? " last" : ""}`}>
      <span className="master-field-label" style={{ color: "var(--gold)" }}>{label}</span>
      {children}
    </div>
  );
}

function MasterStripB({ tone, label, labelExtra, children }) {
  const t = masterTone(tone);
  return (
    <div className="master-strip-b" style={{ "--strip-color": t.color }}>
      <span className="master-field-label" style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>{label}{labelExtra}</span>
      {children}
    </div>
  );
}

function InfoTip({ text }) {
  const [show, setShow] = React.useState(false);
  return (
    <span style={{ position: "relative", display: "inline-block" }}>
      <span
        onMouseEnter={() => setShow(true)}
        onMouseLeave={() => setShow(false)}
        style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.1em", color: "var(--ink-4)", cursor: "help", border: "1px solid var(--ink-4)", padding: "1px 5px", lineHeight: 1.2 }}
      >?</span>
      {show && (
        <div style={{
          position: "absolute",
          left: "calc(100% + 8px)",
          top: "50%",
          transform: "translateY(-50%)",
          zIndex: 200,
          background: "#181410",
          border: "1px solid var(--rule-strong)",
          padding: "10px 14px",
          width: 240,
          fontSize: 13,
          color: "var(--ink-2)",
          fontFamily: "var(--sans)",
          lineHeight: 1.5,
          pointerEvents: "none",
          boxShadow: "0 4px 24px rgba(0,0,0,0.6)",
        }}>
          {text}
        </div>
      )}
    </span>
  );
}

function MasterDistroPicker({ distro, setDistro, distroObj, selectedColor }) {
  const sel = selectedColor || MASTER_GOLD;
  return (
    <>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
        {DISTRIBUTORS.map((d) => (
          <button key={d.id} type="button" onClick={() => setDistro(d.id)} style={{
            background: distro === d.id ? sel : "transparent",
            color: distro === d.id ? "#16110a" : "var(--ink-2)",
            border: `1px solid ${distro === d.id ? sel : "var(--rule-strong)"}`,
            fontFamily: "var(--sans)",
            fontWeight: distro === d.id ? 700 : 500,
            fontSize: 12,
            padding: "6px 10px",
            cursor: "pointer",
          }}>
            {d.label}
          </button>
        ))}
      </div>
      <p className="field-help" style={{ marginTop: 10, marginBottom: 0, fontSize: 12 }}>{distroObj.note}</p>
    </>
  );
}

function MasterSection({ tone, label, hint, children }) {
  const t = masterTone(tone);
  return (
    <div style={{ padding: MASTER_ROW_PAD, borderBottom: `1px solid ${t.border}`, background: t.bg, borderLeft: `3px solid ${t.color}` }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: children ? 8 : 0, gap: 8, flexWrap: "wrap" }}>
        <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.16em", color: t.color, textTransform: "uppercase" }}>{label}</span>
        {hint && <span className="caption" style={{ fontSize: 9, color: "var(--ink-3)", lineHeight: 1.4 }}>{hint}</span>}
      </div>
      {children}
    </div>
  );
}

function MasterInputBlock({ tone, label, children }) {
  const t = masterTone(tone);
  return (
    <div style={{ padding: "14px 16px", background: t.bg, border: `1px solid ${t.border}`, borderLeft: `3px solid ${t.color}` }}>
      <span style={{ display: "block", fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.16em", color: t.color, textTransform: "uppercase", marginBottom: 10 }}>{label}</span>
      {children}
    </div>
  );
}

function MasterSliderControl({ tone, hint, valueDisplay, unit, min, max, step, value, onChange, pct, sliderClass, ticks, tickLabels, layout = "b" }) {
  const t = masterTone(tone);
  const accent = layout === "a" ? MASTER_GOLD : t.color;
  const sliderToneClass = layout === "a"
    ? "tone-custom"
    : sliderClass || (tone === "streams" ? "role-artist" : tone === "advance" ? "role-songwriter" : "tone-custom");
  const valueClass = layout === "a" ? "master-value-a" : "";
  const valueStyle = layout === "a" ? undefined : { fontFamily: "var(--sans)", fontWeight: 800, fontSize: MASTER_VALUE, color: accent, fontVariantNumeric: "tabular-nums", letterSpacing: "-0.025em", lineHeight: 1 };

  return (
    <>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 8, flexWrap: "wrap", gap: 6 }}>
        {hint && <span className="caption" style={{ color: "var(--ink-2)", fontSize: 10 }}>{hint}</span>}
        <div style={{ display: "flex", alignItems: "baseline", gap: 4, marginLeft: hint ? "auto" : 0, width: hint ? undefined : "100%", justifyContent: hint ? undefined : "flex-end" }}>
          {layout === "a" ? (
            <span className={valueClass}>{valueDisplay}{unit ? ` ${unit}` : ""}</span>
          ) : (
            <>
              <span style={valueStyle}>{valueDisplay}</span>
              {unit && <span style={{ fontFamily: "var(--sans)", fontWeight: 600, fontSize: 14, color: "var(--ink-2)" }}>{unit}</span>}
            </>
          )}
        </div>
      </div>
      <input
        type="range"
        min={min}
        max={max}
        step={step}
        value={value}
        onChange={onChange}
        className={`pu-slider ${sliderToneClass}`}
        style={{ width: "100%", "--pu-pct": `${pct}%`, "--slider-color": accent }}
      />
      {tickLabels ? (
        <div style={{ position: "relative", height: 14, marginTop: 4 }}>
          {tickLabels.map(({ left, label, active }) => (
            <span key={label} className="caption" style={{
              position: "absolute",
              left: `${left}%`,
              transform: left === 0 ? "none" : left === 100 ? "translateX(-100%)" : "translateX(-50%)",
              whiteSpace: "nowrap",
              fontSize: 9,
              color: active ? accent : "var(--ink-3)",
              fontWeight: active ? 600 : 400,
            }}>{label}</span>
          ))}
        </div>
      ) : ticks ? (
        <div style={{ display: "flex", justifyContent: "space-between", marginTop: 6, fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.12em", color: "var(--ink-3)" }}>
          {ticks.map((tick) => <span key={tick}>{tick}</span>)}
        </div>
      ) : null}
    </>
  );
}

function MasterYouKeepPanel({ headline, subline, rows, footnote, layout = "b", flat }) {
  const t = masterTone("result");
  return (
    <div style={{ position: flat ? "static" : "sticky", top: flat ? undefined : 24, padding: flat ? MASTER_PANEL_PAD : layout === "a" ? "16px 20px" : MASTER_PANEL_PAD, alignSelf: "start", minWidth: 0, background: flat ? t.bg : undefined }}>
      <div style={{ padding: flat ? 0 : layout === "a" ? "20px" : "18px 20px", background: flat ? "transparent" : t.bg, border: flat ? "none" : `1px solid ${t.border}`, borderTop: flat ? "none" : `2px solid ${t.color}` }}>
        <span className="caption" style={{ color: t.color }}>You keep</span>
        {layout === "a" ? (
          <div className="master-hero-a" style={{ color: t.color, marginTop: 6 }}>{headline}</div>
        ) : (
          <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: MASTER_HERO, letterSpacing: "-0.035em", color: t.color, lineHeight: 1, fontVariantNumeric: "tabular-nums", marginTop: 6 }}>
            {headline}
          </div>
        )}
        {subline && <p className="caption" style={{ marginTop: 8, color: "var(--ink-3)", fontSize: 10, lineHeight: 1.45 }}>{subline}</p>}
        {rows?.length > 0 && (
          <div style={{ marginTop: 16, paddingTop: 14, borderTop: `1px solid ${t.border}` }}>
            {rows.map((row, i) => (
              <div key={i} style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 10, padding: "7px 0", borderBottom: i < rows.length - 1 ? "1px dashed var(--rule)" : "none" }}>
                <span style={{ fontFamily: "var(--sans)", fontWeight: row.emphasis ? 600 : 500, fontSize: 13, color: row.emphasis ? "var(--ink-2)" : "var(--ink-3)" }}>{row.label}</span>
                <span style={{ fontFamily: "var(--sans)", fontWeight: row.emphasis ? 700 : 600, fontSize: row.emphasis ? 15 : 14, color: row.color || t.color, fontVariantNumeric: "tabular-nums" }}>{row.value}</span>
              </div>
            ))}
          </div>
        )}
        {footnote && <p className="caption" style={{ marginTop: 12, color: "var(--ink-3)", lineHeight: 1.45, fontSize: 10 }}>{footnote}</p>}
      </div>
    </div>
  );
}

const TERRITORY_CERTS = {
  us: {
    label: "US", flag: "🇺🇸", body: "RIAA", type: "Single",
    tiers: [
      { name: "Gold",     color: "#d4a64a", units: 500_000,    streams: 75_000_000   },
      { name: "Platinum", color: "#c0c8d8", units: 1_000_000,  streams: 150_000_000  },
      { name: "Diamond",  color: "#a8d4e8", units: 10_000_000, streams: 1_500_000_000 },
    ],
  },
  uk: {
    label: "UK", flag: "🇬🇧", body: "BPI", type: "Single",
    tiers: [
      { name: "Silver",      color: "#b0b8c8", units: 200_000,   streams: 20_000_000  },
      { name: "Gold",        color: "#d4a64a", units: 400_000,   streams: 40_000_000  },
      { name: "Platinum",    color: "#c0c8d8", units: 600_000,   streams: 60_000_000  },
      { name: "3× Platinum", color: "#e8c878", units: 1_800_000, streams: 180_000_000 },
    ],
  },
  global: {
    label: "Global", flag: "🌍", body: "IFPI", type: "Single",
    tiers: [
      { name: "Platinum",       color: "#c0c8d8", units: 1_000_000,  streams: 150_000_000  },
      { name: "Multi-Platinum", color: "#e8c878", units: 3_000_000,  streams: 450_000_000  },
      { name: "Diamond",        color: "#a8d4e8", units: 10_000_000, streams: 1_500_000_000 },
    ],
  },
};

const BASE_STREAM_STOPS = [10_000, 100_000, 1_000_000, 10_000_000];

function StreamScrubber({ streams, setStreams }) {
  const [territory, setTerritory] = React.useState("us");
  const tdata = TERRITORY_CERTS[territory];

  const plaqueStreams = new Set(tdata.tiers.map((t) => t.streams));
  const allStops = [...BASE_STREAM_STOPS, ...tdata.tiers.map((t) => t.streams)].sort((a, b) => a - b);

  const currentPlaque = tdata.tiers.find((t) => t.streams === streams);

  const streamLabel = streams >= 1_000_000_000
    ? `${(streams / 1_000_000_000).toFixed(1).replace(/\.0$/, "")}B streams`
    : streams >= 1_000_000
    ? `${Math.round(streams / 1_000_000)}M streams`
    : `${Math.round(streams / 1_000)}K streams`;

  function stopLabel(s) {
    const p = tdata.tiers.find((t) => t.streams === s);
    if (p) return p.name;
    if (s >= 1_000_000_000) return `${s / 1_000_000_000}B`;
    if (s >= 1_000_000) return `${s / 1_000_000}M`;
    return `${s / 1_000}K`;
  }

  function stopColor(s) {
    const p = tdata.tiers.find((t) => t.streams === s);
    return p ? p.color : null;
  }

  const unitsLabel = (n) => {
    if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(0)}M`;
    if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K`;
    return n;
  };

  return (
    <div style={{ marginBottom: 20, padding: "16px 20px", border: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.02)" }}>
      {/* Territory selector */}
      <div style={{ display: "flex", gap: 6, marginBottom: 14 }}>
        {Object.entries(TERRITORY_CERTS).map(([key, td]) => (
          <button key={key} type="button" onClick={() => setTerritory(key)} style={{
            background: territory === key ? "rgba(255,255,255,0.07)" : "transparent",
            border: `1px solid ${territory === key ? "var(--rule-strong)" : "var(--rule)"}`,
            color: territory === key ? "var(--ink)" : "var(--ink-3)",
            fontFamily: "var(--mono)",
            fontSize: 10,
            letterSpacing: "0.12em",
            padding: "4px 10px",
            cursor: "pointer",
            transition: "all 0.15s ease",
          }}>
            {td.flag} {td.label}
          </button>
        ))}
        <span className="caption" style={{ alignSelf: "center", marginLeft: 4 }}>{tdata.body} · {tdata.type}</span>
      </div>

      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 12 }}>
        <div>
          <div className="caption">Projection — if this song does</div>
          <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: "clamp(22px, 2.6vw, 34px)", color: currentPlaque ? currentPlaque.color : "var(--gold)", letterSpacing: "-0.025em", lineHeight: 1, marginTop: 4, fontVariantNumeric: "tabular-nums", transition: "color 0.2s ease" }}>
            {streamLabel}
          </div>
          {currentPlaque ? (
            <div style={{ marginTop: 6, fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.14em", color: currentPlaque.color, opacity: 0.85 }}>
              {tdata.body} {currentPlaque.name.toUpperCase()} · {tdata.flag} {tdata.label} · {unitsLabel(currentPlaque.units)} CERTIFIED UNITS
            </div>
          ) : (
            <div style={{ marginTop: 6, height: 14 }} />
          )}
        </div>
        <div style={{ display: "flex", border: "1px solid var(--rule-strong)", overflow: "hidden", flexWrap: "wrap" }}>
          {allStops.map((s) => {
            const pc = stopColor(s);
            const isActive = streams === s;
            return (
              <button key={s} type="button" onClick={() => setStreams(s)} style={{
                background: isActive ? (pc || "var(--gold)") : "transparent",
                color: isActive ? "#16110a" : pc ? pc : "var(--ink-2)",
                border: "none",
                borderRight: "1px solid var(--rule-strong)",
                fontFamily: "var(--mono)",
                fontSize: 10,
                letterSpacing: "0.08em",
                padding: "10px 12px",
                cursor: "pointer",
                fontWeight: isActive ? 700 : pc ? 500 : 400,
                transition: "all 0.15s ease",
                opacity: pc && !isActive ? 0.85 : 1,
              }}>
                {stopLabel(s)}
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function MasterStreamsSlider({ streams, setStreams, layout = "b" }) {
  const maxIdx = PUB_STREAM_STOPS.length - 1;
  const stopIndex = pubStreamStopIndex(streams);
  const pct = maxIdx > 0 ? (stopIndex / maxIdx) * 100 : 0;
  const tickLabels = PUB_STREAM_STOPS.map((s, i) => ({
    left: maxIdx > 0 ? (i / maxIdx) * 100 : 0,
    label: pubStreamChipLabel(s),
    active: stopIndex === i,
  }));

  return (
    <MasterSliderControl
      layout={layout}
      tone="streams"
      hint={layout === "b" ? "If this song does" : undefined}
      valueDisplay={formatNum(streams)}
      min={0}
      max={maxIdx}
      step={1}
      value={stopIndex}
      onChange={(e) => setStreams(PUB_STREAM_STOPS[Number(e.target.value)])}
      pct={pct}
      tickLabels={tickLabels}
    />
  );
}

function MasterStreamsRow({ streams, setStreams, layout = "b" }) {
  if (layout === "a") return null;
  return (
    <MasterStripB tone="streams" label="Streams">
      <MasterStreamsSlider streams={streams} setStreams={setStreams} layout="b" />
    </MasterStripB>
  );
}

const DISTRIBUTORS = [
  { id: "distrokid",      label: "DistroKid",       splits: true,   note: "Splits feature is built-in. Free. You get added as an automatic split recipient." },
  { id: "tunecore",       label: "TuneCore",        splits: true,   note: "Auto-Split is a paid add-on. Pays direct to your account each cycle." },
  { id: "unitedmasters",  label: "UnitedMasters",   splits: true,   note: "Built-in splits. Pays out the same day the artist gets paid." },
  { id: "stem",           label: "Stem",            splits: true,   note: "Splits are the entire product. Best-in-class transparency." },
  { id: "symphonic",      label: "Symphonic",       splits: true,   note: "Built-in. Common for working catalogs at the mid-tier." },
  { id: "2lost",          label: "Toolost",         splits: true,   note: "Newer distro. Built-in splits, supports collabs natively." },
  { id: "vydia",          label: "Vydia",           splits: true,   note: "Splits + analytics. Often used by managers." },
  { id: "onerpm",         label: "ONErpm",          splits: true,   note: "Built-in splits. Common for global indie acts." },
  { id: "cdbaby",         label: "CD Baby",         splits: false,  note: "No native splits. You'll need a separate split agreement, or insist the artist switches." },
  { id: "other",          label: "Other / unsure",  splits: false,  note: "Ask the artist which distributor they use, then check their splits support before agreeing to a master share." },
];

const MASTER_BENCH = {
  independent: { usualLo: 0, usualHi: 10, targetLo: 25, targetHi: 50, usualRange: "Ownership %", targetRange: "Distro split", max: 50 },
  signed: { usualLo: 0, usualHi: 2, targetLo: 3, targetHi: 5, usualRange: "Master points", targetRange: "Points on master", max: 6 },
};

function MasterUsualBar({ structure }) {
  const b = MASTER_BENCH[structure];
  return (
    <BarBlock
      compact
      tone="dim"
      label="What producers usually settle for"
      rangeLabel={b.usualRange}
      value={`${b.usualLo}–${b.usualHi}${structure === "independent" ? "%" : " pts"}`}
      tag="USUAL"
      pct={(b.usualHi / b.max) * 100}
    />
  );
}

function MasterTargetBar({ structure }) {
  const b = MASTER_BENCH[structure];
  return (
    <BarBlock
      compact
      tone="gold"
      label="What you should target"
      rangeLabel={b.targetRange}
      value={`${b.targetLo}–${b.targetHi}${structure === "independent" ? "%" : " pts"}`}
      tag="STANDARD"
      pct={(b.targetHi / b.max) * 100}
      secondaryPct={(b.targetLo / b.max) * 100}
    />
  );
}

function MasterBenchmarkPanel({ structure }) {
  return (
    <div className="calc-benchmark-bars master-benchmark-bars">
      <MasterUsualBar structure={structure} />
      <MasterTargetBar structure={structure} />
    </div>
  );
}

function MasterCalc({ streams, setStreams }) {
  const [structure, setStructure] = React.useState("independent");

  return (
    <div>
      <div style={{ display: "flex", flexDirection: "column", border: "1px solid var(--rule-strong)" }}>
        <StepStrip
          step="01"
          active={structure === "independent"}
          onClick={() => setStructure("independent")}
          label="Independent artist"
          sub="Distro splits · ownership %"
          tag="OWNERSHIP %"
          accent="#d4a64a"
        />
        <StepStrip
          step="02"
          active={structure === "signed"}
          onClick={() => setStructure("signed")}
          label="Signed artist"
          sub="Label deal · points + recoup"
          tag="POINTS"
          accent="#b889ff"
        />
      </div>

      {structure === "independent"
        ? <IndependentMaster layout="b" streams={streams} setStreams={setStreams} />
        : <SignedMaster layout="b" streams={streams} setStreams={setStreams} />
      }
    </div>
  );
}

function StructBtn({ active, onClick, label, sub, right, last, accent = "#d4a64a", activeBg = "rgba(212,166,74,0.10)" }) {
  return (
    <button onClick={onClick} style={{
      flex: 1,
      background: active ? activeBg : "transparent",
      border: "none",
      borderRight: last ? "none" : "1px solid var(--rule-strong)",
      cursor: "pointer",
      padding: "16px 20px",
      textAlign: "left",
      color: active ? "var(--ink)" : "var(--ink-3)",
      position: "relative",
      transition: "all 0.18s ease",
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
        <span style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.14em", color: active ? accent : "var(--ink-3)" }}>{active ? "ACTIVE" : "SETUP"}</span>
        <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.14em", color: active ? accent : "var(--ink-3)" }}>{right}</span>
      </div>
      <div style={{ fontFamily: "var(--sans)", fontWeight: active ? 800 : 600, fontSize: 17, letterSpacing: "-0.015em" }}>{label}</div>
      <div className="caption" style={{ marginTop: 4 }}>{sub}</div>
      {active && <span style={{ position: "absolute", left: 0, right: 0, bottom: 0, height: 2, background: accent }}></span>}
    </button>
  );
}

function StepStrip({ step, active, onClick, label, sub, tag, accent = "#d4a64a" }) {
  return (
    <button type="button" onClick={onClick} style={{
      display: "flex",
      alignItems: "center",
      gap: 20,
      width: "100%",
      background: active ? `rgba(${accent === "#b889ff" ? "184,137,255" : "212,166,74"},0.06)` : "transparent",
      border: "none",
      borderBottom: "1px solid var(--rule-strong)",
      borderLeft: `3px solid ${active ? accent : "transparent"}`,
      cursor: "pointer",
      padding: "16px 22px",
      textAlign: "left",
      color: active ? "var(--ink)" : "var(--ink-3)",
      transition: "all 0.18s ease",
    }}>
      <span style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.18em", color: active ? accent : "var(--ink-4)", minWidth: 24, fontWeight: 600 }}>
        {step}
      </span>
      <div style={{ flex: 1 }}>
        <div style={{ fontFamily: "var(--sans)", fontWeight: active ? 800 : 600, fontSize: 16, letterSpacing: "-0.015em" }}>{label}</div>
        <div className="caption" style={{ marginTop: 2 }}>{sub}</div>
      </div>
      <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.14em", color: active ? accent : "var(--ink-4)", textAlign: "right" }}>{tag}</span>
    </button>
  );
}

// =========== INDEPENDENT ARTIST FLOW ===========

function IndependentMaster({ layout = "a", streams, setStreams }) {
  const [ownership, setOwnership] = React.useState(25);
  const [distro, setDistro] = React.useState("distrokid");

  const distroObj = DISTRIBUTORS.find((d) => d.id === distro);
  const MASTER_PER_1K = 3.3;
  const masterPool = (streams / 1000) * MASTER_PER_1K;
  const yourCut = masterPool * (ownership / 100);
  const artistCut = masterPool - yourCut;

  const youKeep = {
    headline: `$${formatNum(yourCut)}`,
    subline: `${ownership}% ownership · ${formatNum(streams)} streams · ~$${MASTER_PER_1K.toFixed(2)}/1K`,
    rows: [
      { label: "Master pool", value: `$${formatNum(masterPool)}`, emphasis: true },
      { label: `Artist · ${100 - ownership}%`, value: `$${formatNum(artistCut)}`, color: "var(--ink-2)" },
      { label: `You · ${ownership}%`, value: `$${formatNum(yourCut)}` },
    ],
    footnote: "No recoupment on indie splits. Paid direct each cycle if you're on their distro.",
  };

  if (layout === "a") {
    return (
      <div style={{ marginTop: 16 }}>
        <div className="master-card master-layout-a">
          <div className="tool-split" style={{ gap: 0 }}>
            <div className="master-layout-a-inputs">
              <MasterFieldA label="Benchmark">
                <MasterBenchmarkPanel structure="independent" />
                <p className="master-bench-note">Indie artists pay via their distributor. Get on splits before release.</p>
              </MasterFieldA>
              <MasterFieldA label="Streams">
                <MasterStreamsSlider streams={streams} setStreams={setStreams} layout="a" />
              </MasterFieldA>
              <MasterFieldA label="Your ownership" deal>
                <MasterSliderControl
                  layout="a"
                  tone="deal"
                  hint="Target · 25–50%"
                  valueDisplay={ownership}
                  unit="%"
                  min={0}
                  max={50}
                  step={1}
                  value={ownership}
                  onChange={(e) => setOwnership(Number(e.target.value))}
                  pct={(ownership / 50) * 100}
                  ticks={["0%", "25%", "50%"]}
                />
              </MasterFieldA>
              <MasterFieldA label="Their distributor" last>
                <MasterDistroPicker distro={distro} setDistro={setDistro} distroObj={distroObj} />
              </MasterFieldA>
            </div>
            <MasterYouKeepPanel layout="a" {...youKeep} />
          </div>
        </div>
        <DistroDiagram distro={distroObj} ownership={ownership} artistShare={100 - ownership} />
        <SplitsHowTo distro={distroObj} />
      </div>
    );
  }

  return (
    <div style={{ marginTop: 16 }}>
      <div className="master-card master-layout-b">
        <MasterStripB tone="benchmark" label="Benchmark · usual vs. standard">
          <MasterBenchmarkPanel structure="independent" />
        </MasterStripB>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", borderBottom: "1px solid var(--rule-strong)" }}>
          <div style={{ padding: "14px 20px", borderRight: "1px solid var(--rule-strong)" }}>
            <span className="master-field-label">Your ownership</span>
            <MasterSliderControl
              layout="b"
              tone="deal"
              hint="Target · 25–50%"
              valueDisplay={ownership}
              unit="%"
              min={0}
              max={50}
              step={1}
              value={ownership}
              onChange={(e) => setOwnership(Number(e.target.value))}
              pct={(ownership / 50) * 100}
              ticks={["0%", "25%", "50%"]}
            />
          </div>
          <div style={{ padding: "14px 20px" }}>
            <span className="master-field-label">Their distributor</span>
            <MasterDistroPicker distro={distro} setDistro={setDistro} distroObj={distroObj} selectedColor={MASTER_TONES.distro.color} />
          </div>
        </div>
        <MasterStripB tone="streams" label="Streams">
          <StreamScrubber streams={streams} setStreams={setStreams} />
        </MasterStripB>
        {/* Diagram left · You keep right */}
        <div style={{ display: "grid", gridTemplateColumns: "3fr 2fr", borderTop: "1px solid var(--rule-strong)" }}>
          <div style={{ borderRight: "1px solid var(--rule-strong)" }}>
            <DistroDiagram distro={distroObj} ownership={ownership} artistShare={100 - ownership} embedded />
          </div>
          <MasterYouKeepPanel layout="b" flat {...youKeep} />
        </div>
      </div>
      <SplitsHowTo distro={distroObj} />
    </div>
  );
}

function DistroDiagram({ distro, ownership, artistShare, embedded }) {
  return (
    <div style={embedded ? { padding: "16px 20px" } : { marginTop: 16, padding: "24px 26px", border: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.015)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16, flexWrap: "wrap", gap: 8 }}>
        <span className="caption">How money reaches you (independent setup)</span>
        <span className="caption">Fig. 03 · The distro chain</span>
      </div>

      <svg viewBox="0 0 800 280" style={{ width: "100%", height: "auto", display: "block" }}>
        <defs>
          <radialGradient id="distroDot">
            <stop offset="0%" stopColor="#fff3cf" />
            <stop offset="40%" stopColor="#d4a64a" />
            <stop offset="100%" stopColor="rgba(212,166,74,0)" />
          </radialGradient>
        </defs>

        {/* DSPs (top) */}
        <DistroNode x={400} y={20} w={300} h={50} label="Streaming Platforms" sub="Spotify · Apple · YouTube · Tidal" />

        {/* Distributor (mid) */}
        <DistroNode x={400} y={110} w={260} h={56} label={distro.label} sub={distro.splits ? "Splits configured → paid direct" : "No native splits → manual payout"} accent />

        {/* Lines */}
        <path d="M 400 70 L 400 110" stroke="#d4a64a" strokeWidth="1.5" strokeDasharray="3 3" opacity="0.5" />

        {/* Split, artist vs you */}
        <path d={`M ${400} ${166} L ${400} ${200} L ${220} ${200} L ${220} ${220}`} stroke="#cfc7b8" strokeWidth="1.5" strokeDasharray="3 3" opacity="0.45" />
        <path d={`M ${400} ${166} L ${400} ${200} L ${580} ${200} L ${580} ${220}`} stroke="#d4a64a" strokeWidth="1.5" strokeDasharray="3 3" opacity={0.7} />

        {/* Particles */}
        <circle r="3.5" fill="url(#distroDot)">
          <animateMotion dur="3s" repeatCount="indefinite" path={`M 400 70 L 400 200 L 220 200 L 220 220`} />
        </circle>
        <circle r="3.5" fill="url(#distroDot)">
          <animateMotion dur="3s" repeatCount="indefinite" begin="1.2s" path={`M 400 70 L 400 200 L 580 200 L 580 220`} />
        </circle>

        {/* Artist node */}
        <DistroNode x={220} y={220} w={220} h={50} label="The Artist" sub={`${artistShare}% of master`} muted />

        {/* You node */}
        <DistroNode x={580} y={220} w={220} h={50} label="You (Producer)" sub={`${ownership}% · paid each cycle`} accent />
      </svg>

      <p className="body-text" style={{ fontSize: 13, lineHeight: 1.55, marginTop: 14, color: "var(--ink-2)" }}>
        The artist's distributor account is what pays out streaming revenue. <span className="gold">You only collect master royalties if you're configured as a split recipient inside that account.</span> Otherwise the full pool lands in the artist's bank, and you're chasing it.
      </p>
    </div>
  );
}

function DistroNode({ x, y, w, h, label, sub, accent, muted }) {
  const fill = accent ? "rgba(212,166,74,0.10)" : muted ? "rgba(255,255,255,0.025)" : "#181613";
  const border = accent ? "#d4a64a" : muted ? "rgba(255,255,255,0.15)" : "rgba(255,255,255,0.18)";
  const labelColor = accent ? "#d4a64a" : "#f5f1e8";
  return (
    <g>
      <rect x={x - w/2} y={y} width={w} height={h} fill={fill} stroke={border} strokeWidth="1" />
      <text x={x} y={y + 22} textAnchor="middle" fontFamily="var(--sans)" fontWeight="700" fontSize="14" letterSpacing="-0.01em" fill={labelColor}>{label}</text>
      <text x={x} y={y + 40} textAnchor="middle" fontFamily="var(--mono)" fontSize="9" letterSpacing="1.3" fill="#8c8576">{sub.toUpperCase()}</text>
    </g>
  );
}

function SplitsHowTo({ distro }) {
  const steps = distro.splits ? [
    `The artist opens their ${distro.label} dashboard and finds the song.`,
    "Adds you as a split recipient, your email, your ownership %.",
    "You accept the split request in your inbox / create a free account.",
    "From this release forward, your share is paid direct to you each cycle. No invoicing, no chasing.",
  ] : [
    "Splits aren't supported natively here, you have two options.",
    "Option A: insist the artist switch to a distro with splits before release (Stem, DistroKid, UnitedMasters).",
    "Option B: get a signed master share / co-ownership agreement and invoice them quarterly based on their statements.",
    "Option A is better in almost every case. Manual payouts are where producers go unpaid.",
  ];
  return (
    <div style={{ marginTop: 22, padding: "24px 26px", border: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.015)" }}>
      <span className="caption">Getting on the splits</span>
      <div className="pull-serif" style={{ fontSize: 19, lineHeight: 1.3, marginTop: 4, color: "var(--ink)" }}>
        Master ownership without distro splits = <span className="gold">unpaid royalties.</span> Fix the chain before the song goes up.
      </div>
      <ol style={{ listStyle: "none", padding: 0, margin: "18px 0 0", display: "flex", flexDirection: "column", gap: 10 }}>
        {steps.map((s, i) => (
          <li key={i} style={{ display: "flex", gap: 14, fontSize: 15, lineHeight: 1.45, color: "var(--ink-2)" }}>
            <span style={{ fontFamily: "var(--mono)", color: "var(--gold)", minWidth: 24, fontWeight: 600 }}>{String(i + 1).padStart(2, "0")}</span>
            <span>{s}</span>
          </li>
        ))}
      </ol>
    </div>
  );
}

// =========== SIGNED ARTIST FLOW (existing points logic) ===========

const RECOUP_LINE_ITEMS = [
  { id: "recording",   label: "Recording costs (studio, mix, master)", amount: 30_000, note: "100% recoupable — the baseline in every deal" },
  { id: "artist_adv",  label: "Artist advance (their signing bonus)",   amount: 50_000, note: "100% recoupable — charged to artist's royalty account" },
  { id: "video",       label: "Music video (50% recoupable)",           amount: 12_500, note: "Label standard: only 50% of video budget charged back" },
  { id: "tour",        label: "Tour support",                           amount: 10_000, note: "100% recoupable — label advance to cover touring losses" },
  { id: "indie_promo", label: "Independent radio promotion",            amount: 10_000, note: "100% recoupable — can run $50K–$150K per single" },
  { id: "net_profit",  label: "Marketing / advertising (360 deal only)",amount: 50_000, note: "Only recoupable in net-profit/360 deals — NOT standard" },
];

function SignedMaster({ layout = "a", streams, setStreams }) {
  const [points, setPoints] = React.useState(4);
  const [advance, setAdvance] = React.useState(10_000);
  const [recoupToggles, setRecoupToggles] = React.useState({});
  const [showRecoupWall, setShowRecoupWall] = React.useState(false);

  const MASTER_PER_1K = 3.3;
  const grossMasterPool = (streams / 1000) * MASTER_PER_1K;
  const yourGross = grossMasterPool * (points / 100);
  const labelCut = grossMasterPool - yourGross;
  const artistRoyaltyFromLabel = labelCut * 0.15;

  const extraRecoup = RECOUP_LINE_ITEMS
    .filter((i) => recoupToggles[i.id])
    .reduce((sum, i) => sum + i.amount, 0);
  const totalDebt = advance + extraRecoup;
  const totalRemainingDebt = Math.max(0, totalDebt - yourGross);
  const totalRecoupedPct = totalDebt > 0 ? Math.min(100, (yourGross / totalDebt) * 100) : 100;
  const totalFree = totalDebt === 0 || totalRecoupedPct >= 100;
  const ratePerStream = streams > 0 ? yourGross / streams : 0;
  const streamsToBreakEven = ratePerStream > 0 ? Math.ceil(totalDebt / ratePerStream) : 0;

  const remainingDebt = Math.max(0, advance - yourGross);
  const yourNet = Math.max(0, yourGross - advance);
  const recoupedPct = advance > 0 ? Math.min(100, (yourGross / advance) * 100) : 100;

  const youKeep = {
    headline: `$${formatNum(advance > 0 ? yourNet : yourGross)}`,
    subline: `${points} pts · ${formatNum(streams)} streams · ~$${MASTER_PER_1K.toFixed(2)}/1K`,
    rows: [
      { label: "Master pool", value: `$${formatNum(grossMasterPool)}`, emphasis: true },
      { label: `Your ${points} pts (gross)`, value: `$${formatNum(yourGross)}` },
      {
        label: advance > 0 ? (remainingDebt > 0 ? "After recoup" : "Fully recouped") : "Take-home",
        value: `$${formatNum(advance > 0 ? yourNet : yourGross)}`,
        color: remainingDebt > 0 ? "var(--ink-2)" : "#8acaa0",
      },
    ],
    footnote: advance > 0 && remainingDebt > 0 ? `Still ${formatMoney(remainingDebt)} to recoup from your master share.` : undefined,
  };

  const pointsBlock = (
    <>
      <MasterSliderControl
        layout={layout}
        tone="deal"
        hint="Target · 3–5 pts"
        valueDisplay={points}
        unit="pts"
        min={0}
        max={10}
        step={0.5}
        value={points}
        onChange={(e) => setPoints(Number(e.target.value))}
        pct={(points / 10) * 100}
        ticks={["0", "5", "10 pts"]}
      />
    </>
  );

  if (layout === "a") {
    return (
      <div style={{ marginTop: 16 }}>
        <div className="master-card master-layout-a">
          <div className="tool-split" style={{ gap: 0 }}>
            <div className="master-layout-a-inputs">
              <MasterFieldA label="Benchmark">
                <MasterBenchmarkPanel structure="signed" />
                <p className="master-bench-note">Signed deals pay points from the label's master pool. Fee is separate.</p>
              </MasterFieldA>
              <MasterFieldA label="Streams">
                <MasterStreamsSlider streams={streams} setStreams={setStreams} layout="a" />
              </MasterFieldA>
              <MasterFieldA label="Advance / recoup">
                <RecoupmentBlock
                  advance={advance}
                  setAdvance={setAdvance}
                  yourGross={yourGross}
                  remainingDebt={remainingDebt}
                  recoupedPct={recoupedPct}
                  slim
                  layout="a"
                />
              </MasterFieldA>
              <MasterFieldA label="Your points" deal last>
                {pointsBlock}
              </MasterFieldA>
            </div>
            <MasterYouKeepPanel layout="a" {...youKeep} />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div style={{ marginTop: 16 }}>
      <div className="master-card master-layout-b">
        <MasterStripB tone="benchmark" label="Benchmark · usual vs. standard">
          <MasterBenchmarkPanel structure="signed" />
        </MasterStripB>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", borderBottom: "1px solid var(--rule-strong)" }}>
          <div style={{ padding: "14px 20px", borderRight: "1px solid var(--rule-strong)" }}>
            <span className="master-field-label" style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
              Your points
              <InfoTip text="1 point = 1% of the master royalty. 4 points on a 10M-stream record = 4% of every dollar that master earns — forever, on every play of that recording." />
            </span>
            {pointsBlock}
          </div>
          <div style={{ padding: "14px 20px" }}>
            <span className="master-field-label">Advance / recoup</span>
            <RecoupmentBlock
              advance={advance}
              setAdvance={setAdvance}
              yourGross={yourGross}
              remainingDebt={remainingDebt}
              recoupedPct={recoupedPct}
              compact
              layout="b"
            />
          </div>
        </div>
        {/* Deal receipt */}
        <div style={{ borderBottom: "1px solid var(--rule-strong)", padding: "18px 20px" }}>
          {/* Always-visible: master split */}
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 12 }}>
            <span className="caption">Deal receipt — who takes what</span>
            <span className="caption" style={{ color: "var(--ink-4)" }}>Example only — every deal is different</span>
          </div>

          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8, marginBottom: 14 }}>
            <div style={{ padding: "10px 12px", border: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.02)" }}>
              <div className="caption" style={{ color: "var(--ink-3)" }}>Label keeps</div>
              <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: 18, color: "var(--ink-2)", marginTop: 4, fontVariantNumeric: "tabular-nums" }}>
                ${formatNum(labelCut)}
              </div>
              <div className="caption" style={{ marginTop: 3 }}>{(100 - points).toFixed(0)}% of pool</div>
            </div>
            <div style={{ padding: "10px 12px", border: "1px solid rgba(200,180,160,0.3)", background: "rgba(200,180,160,0.04)" }}>
              <div className="caption" style={{ color: "#c8b4a0" }}>Artist royalty</div>
              <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: 18, color: "#c8b4a0", marginTop: 4, fontVariantNumeric: "tabular-nums" }}>
                ~${formatNum(artistRoyaltyFromLabel)}
              </div>
              <div className="caption" style={{ marginTop: 3 }}>~15% from label</div>
            </div>
            <div style={{ padding: "10px 12px", border: "1px solid var(--rule-gold)", background: "rgba(212,166,74,0.06)" }}>
              <div className="caption" style={{ color: "var(--gold)" }}>Your {points} pts</div>
              <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: 18, color: "var(--gold)", marginTop: 4, fontVariantNumeric: "tabular-nums" }}>
                ${formatNum(yourGross)}
              </div>
              <div className="caption" style={{ marginTop: 3 }}>{points}% of pool</div>
            </div>
          </div>

          {/* Recoup wall toggle */}
          <button
            type="button"
            onClick={() => setShowRecoupWall((v) => !v)}
            style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%", background: showRecoupWall ? "rgba(224,80,64,0.05)" : "rgba(255,255,255,0.02)", border: "1px solid var(--rule-strong)", padding: "9px 14px", cursor: "pointer", transition: "background 0.15s" }}
          >
            <span style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.12em", color: showRecoupWall ? "#e05040" : "var(--ink-3)" }}>
              RECOUP WALL — {showRecoupWall ? "hide example" : "see what hides your money"}
            </span>
            <span style={{ fontFamily: "var(--mono)", fontSize: 10, color: showRecoupWall ? "#e05040" : "var(--ink-4)" }}>
              {showRecoupWall ? "▲" : "▼"}
            </span>
          </button>

          {showRecoupWall && (
            <div style={{ border: "1px solid var(--rule-strong)", borderTop: "none", background: "rgba(255,255,255,0.01)" }}>
              {/* Disclaimer */}
              <div style={{ padding: "10px 14px", borderBottom: "1px solid var(--rule-strong)", background: "rgba(184,137,255,0.06)" }}>
                <p style={{ margin: 0, fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.08em", color: "#c5a3ff", lineHeight: 1.55 }}>
                  ★ This is an illustrative example — not your deal. Every contract is negotiated differently. A good entertainment lawyer can isolate you to recording recoupment only, cap album costs, and in some cases negotiate a <strong>half-recoupable advance</strong> (only 50% charged back). Without one, labels use their boilerplate — and their boilerplate is not written for you.
                </p>
              </div>
              {/* Advance row */}
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 14px", borderBottom: "1px solid var(--rule)" }}>
                <span style={{ fontFamily: "var(--mono)", fontSize: 11, color: "var(--ink-2)" }}>Your advance</span>
                <span style={{ fontFamily: "var(--mono)", fontSize: 11, color: "var(--ink)", fontVariantNumeric: "tabular-nums" }}>${formatNum(advance)}</span>
              </div>
              {/* Toggleable items */}
              {RECOUP_LINE_ITEMS.map((item) => {
                const active = !!recoupToggles[item.id];
                const isWarning = item.id === "net_profit";
                const accentColor = isWarning ? "#b889ff" : "#e05040";
                return (
                  <div key={item.id} style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", padding: "7px 14px", borderBottom: "1px solid var(--rule)", background: active ? `rgba(${isWarning ? "184,137,255" : "224,80,64"},0.04)` : "transparent", transition: "background 0.15s" }}>
                    <div style={{ display: "flex", flexDirection: "column", gap: 2, flex: 1, minWidth: 0 }}>
                      <button
                        type="button"
                        onClick={() => setRecoupToggles((t) => ({ ...t, [item.id]: !t[item.id] }))}
                        style={{ display: "flex", alignItems: "center", gap: 8, background: "none", border: "none", cursor: "pointer", padding: 0 }}
                      >
                        <span style={{ width: 14, height: 14, border: `1px solid ${active ? accentColor : "var(--rule-strong)"}`, background: active ? `rgba(${isWarning ? "184,137,255" : "224,80,64"},0.18)` : "transparent", display: "inline-flex", alignItems: "center", justifyContent: "center", fontSize: 10, color: active ? accentColor : "var(--ink-4)", transition: "all 0.15s", flexShrink: 0 }}>
                          {active ? "×" : "+"}
                        </span>
                        <span style={{ fontFamily: "var(--mono)", fontSize: 11, color: active ? "var(--ink-2)" : "var(--ink-4)" }}>{item.label}</span>
                      </button>
                      {active && item.note && (
                        <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.08em", color: "var(--ink-4)", paddingLeft: 22 }}>{item.note}</span>
                      )}
                    </div>
                    <span style={{ fontFamily: "var(--mono)", fontSize: 11, color: active ? accentColor : "var(--ink-4)", fontVariantNumeric: "tabular-nums", transition: "color 0.15s", flexShrink: 0, marginLeft: 8 }}>
                      {active ? `$${formatNum(item.amount)}` : "—"}
                    </span>
                  </div>
                );
              })}
              {/* Total + bar */}
              <div style={{ padding: "10px 14px", borderTop: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.02)" }}>
                <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8, fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.1em" }}>
                  <span style={{ color: "var(--ink-3)" }}>TOTAL TO RECOUP</span>
                  <span style={{ color: totalFree && totalDebt > 0 ? "#8acaa0" : totalDebt > yourGross ? "#e05040" : "var(--ink)", transition: "color 0.3s", fontVariantNumeric: "tabular-nums" }}>
                    ${formatNum(totalDebt)}
                    {totalDebt > 0 && !totalFree && ` · ${formatNum(streamsToBreakEven)} streams to clear`}
                  </span>
                </div>
                <div style={{ position: "relative", height: 16, background: "rgba(255,255,255,0.04)", overflow: "hidden", border: "1px solid var(--rule-strong)" }}>
                  <div style={{
                    position: "absolute", inset: 0,
                    width: `${Math.min(100, totalRecoupedPct)}%`,
                    background: totalFree && totalDebt > 0
                      ? "linear-gradient(90deg, #2a5a3a, #7acf99)"
                      : "linear-gradient(90deg, #6a1a10, #c0392b)",
                    transition: "width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.4s ease",
                  }} />
                  <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.12em", color: totalRecoupedPct >= 50 ? "#16110a" : "var(--ink-2)", fontWeight: 600 }}>
                    {totalFree && totalDebt > 0 ? "CLEARED" : `${formatMoney(totalRemainingDebt)} LEFT`}
                  </div>
                </div>
              </div>
              {/* Recoupment trigger note */}
              <div style={{ padding: "8px 14px", borderTop: "1px solid var(--rule)", background: "rgba(255,255,255,0.01)" }}>
                <p style={{ margin: 0, fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.08em", color: "var(--ink-4)", lineHeight: 1.5 }}>
                  ★ <strong style={{ color: "var(--ink-3)" }}>Release recoupment</strong> (standard): royalties frozen until the entire album recoups all recording costs — then your advance clears as a second hurdle. Once both clear, royalties pay out retroactively to stream 1. <strong style={{ color: "var(--ink-3)" }}>Recording recoupment</strong> (negotiate for this): only your track's costs need to clear. The difference is years of unpaid royalties — or never seeing a check at all.
                </p>
              </div>
            </div>
          )}
        </div>

        <MasterStripB tone="streams" label="Streams">
          <StreamScrubber streams={streams} setStreams={setStreams} />
        </MasterStripB>
        {/* You keep — full width at bottom */}
        <div style={{ borderTop: "1px solid var(--rule-strong)" }}>
          <MasterYouKeepPanel layout="b" flat {...youKeep} />
        </div>
      </div>
    </div>
  );
}

// ---- POINTS DIAGRAM, 100 squares ----
function PointsDiagram({ points, compact }) {
  const total = 100;
  const yourSquares = Math.min(total, Math.round(points));
  const cells = Array.from({ length: total });

  return (
    <div style={{ marginTop: compact ? 10 : 24, padding: compact ? "12px 0 0" : "22px 24px", border: compact ? "none" : "1px solid var(--rule-strong)", background: compact ? "transparent" : "rgba(255,255,255,0.015)" }}>
      {!compact && (
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16, flexWrap: "wrap", gap: 12 }}>
          <div>
            <span className="caption">What are points, exactly?</span>
            <div className="pull-serif" style={{ fontSize: 18, lineHeight: 1.3, marginTop: 4, color: "var(--ink-2)" }}>
              One point = one percent of the master. <span className="gold">100 squares, 100 points, 100% of the master royalty.</span>
            </div>
          </div>
          <div style={{ display: "flex", gap: 14, fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.14em" }}>
            <span style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <span style={{ width: 10, height: 10, background: "var(--gold)", display: "inline-block" }}></span>
              <span style={{ color: "var(--gold)" }}>YOU · {points}%</span>
            </span>
            <span style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <span style={{ width: 10, height: 10, background: "var(--ink-4)", display: "inline-block" }}></span>
              <span style={{ color: "var(--ink-3)" }}>REST · LABEL + ARTIST</span>
            </span>
          </div>
        </div>
      )}
      <div style={{ display: "grid", gridTemplateColumns: compact ? "repeat(10, 1fr)" : "repeat(20, 1fr)", gap: 3 }}>
        {cells.map((_, i) => {
          const isYou = i < yourSquares;
          return (
            <div key={i} style={{
              aspectRatio: "1",
              background: isYou ? "var(--gold)" : "rgba(255,255,255,0.045)",
              border: isYou ? "1px solid var(--gold-2)" : "1px solid rgba(255,255,255,0.04)",
              transition: "background 0.3s ease, border-color 0.3s ease",
            }}></div>
          );
        })}
      </div>
      <p className="caption" style={{ marginTop: compact ? 8 : 14 }}>
        {compact
          ? `${points} pts = ${points}% of every master dollar, forever.`
          : "★ Each square is 1% (\"1 point\") of the master royalty. \"5 points\" means you collect 5 of these squares' worth of every dollar the master earns, forever, on every play of that recording."}
      </p>
    </div>
  );
}

function RecoupmentBlock({ advance, setAdvance, yourGross, remainingDebt, recoupedPct, compact, slim, layout = "b" }) {
  const isCompact = compact || slim;
  const free = advance === 0 || recoupedPct >= 100;
  const inDebt = !free && advance > 0;

  // Debt-state color shift: red when in debt, green when free, neutral when advance = 0
  const stateColor = free && advance > 0 ? "#8acaa0" : inDebt ? "#e05040" : masterTone("advance").color;
  const stateBorder = free && advance > 0 ? "rgba(74,138,90,0.45)" : inDebt ? "rgba(192,57,43,0.4)" : masterTone("advance").border;
  const stateBg = free && advance > 0 ? "rgba(74,138,90,0.06)" : inDebt ? "rgba(192,57,43,0.06)" : masterTone("advance").bg;

  return (
    <div style={{
      marginTop: slim ? 0 : compact ? 0 : 24,
      padding: slim ? 0 : compact ? 0 : "24px 26px",
      border: isCompact ? "none" : `1px solid ${stateBorder}`,
      background: isCompact ? "transparent" : stateBg,
      transition: "border-color 0.4s ease, background 0.4s ease",
    }}>
      {!isCompact && (
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 18 }}>
          <span className="caption" style={{ color: stateColor, transition: "color 0.4s ease" }}>The advance trap</span>
          <span className="caption">Drag the advance amount →</span>
        </div>
      )}

      {slim ? (
        <MasterSliderControl
          layout={layout}
          tone={layout === "a" ? "deal" : "advance"}
          hint={layout === "b" ? "Advance amount" : undefined}
          valueDisplay={`$${formatNum(advance)}`}
          min={0}
          max={50000}
          step={500}
          value={advance}
          onChange={(e) => setAdvance(Number(e.target.value))}
          pct={(advance / 50000) * 100}
          ticks={["$0", "$25K", "$50K"]}
        />
      ) : (
        <div style={{ display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 16, alignItems: "center" }}>
          <span className="caption" style={{ minWidth: 0 }}>$0</span>
          <input
            type="range"
            min="0"
            max="50000"
            step="500"
            value={advance}
            onChange={(e) => setAdvance(Number(e.target.value))}
            className={`pu-slider${inDebt ? " debt-track" : free && advance > 0 ? " green-track" : " role-songwriter"}`}
            style={{ width: "100%", "--pu-pct": `${(advance / 50000) * 100}%` }}
          />
          <div style={{ display: "flex", alignItems: "baseline", gap: 4, minWidth: 100, justifyContent: "flex-end" }}>
            <span style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: 24, color: stateColor, letterSpacing: "-0.02em", fontVariantNumeric: "tabular-nums", transition: "color 0.4s ease" }}>${formatNum(advance)}</span>
            <span className="caption">advance</span>
          </div>
        </div>
      )}

      <div style={{ marginTop: slim ? 8 : 20 }}>
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: slim ? 4 : 6, fontFamily: "var(--mono)", fontSize: slim ? 9 : 10, letterSpacing: "0.14em" }}>
          <span style={{ color: "var(--ink-3)" }}>RECOUPMENT</span>
          <span style={{ color: free && advance > 0 ? "#8acaa0" : stateColor, transition: "color 0.4s ease" }}>
            {free && advance > 0 ? "100% RECOUPED ✓" : `${Math.round(recoupedPct)}% PAID BACK`}
          </span>
        </div>
        <div style={{ position: "relative", height: slim ? 14 : 22, background: "rgba(255,255,255,0.05)", overflow: "hidden", border: `1px solid ${stateBorder}` }}>
          <div style={{
            position: "absolute", inset: 0,
            width: `${Math.min(100, recoupedPct)}%`,
            background: free && advance > 0
              ? "linear-gradient(90deg, #2a5a3a, #7acf99)"
              : inDebt
              ? "linear-gradient(90deg, #6a1a10, #c0392b)"
              : `linear-gradient(90deg, rgba(184,137,255,0.45), ${masterTone("advance").color})`,
            transition: "width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.4s ease",
          }}></div>
          <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "var(--mono)", fontSize: slim ? 9 : 11, letterSpacing: "0.12em", color: recoupedPct >= 50 ? "#16110a" : "var(--ink-2)", fontWeight: 600 }}>
            {free && advance > 0 ? "RECOUPED — ROYALTIES NOW FLOWING" : `${formatMoney(remainingDebt)} LEFT`}
          </div>
        </div>
      </div>
    </div>
  );
}

function MasterAdvanceRow({ advance, setAdvance, yourGross, remainingDebt, recoupedPct, layout = "b" }) {
  if (layout === "a") return null;
  return (
    <MasterStripB tone="advance" label="Advance / recoup">
      <RecoupmentBlock
        advance={advance}
        setAdvance={setAdvance}
        yourGross={yourGross}
        remainingDebt={remainingDebt}
        recoupedPct={recoupedPct}
        slim
        layout="b"
      />
    </MasterStripB>
  );
}

function Tile({ label, value, sub, gold, flag }) {
  return (
    <div style={{ padding: "14px 16px", border: "1px solid var(--rule)", background: "rgba(255,255,255,0.02)" }}>
      <div className="caption">{label}</div>
      <div style={{
        fontFamily: "var(--sans)",
        fontWeight: 800,
        fontSize: "clamp(20px, 2.4vw, 28px)",
        letterSpacing: "-0.02em",
        color: flag ? "#8acaa0" : gold ? "var(--gold)" : "var(--ink)",
        marginTop: 4,
        fontVariantNumeric: "tabular-nums",
      }}>
        {value}
      </div>
      {sub && <div className="caption" style={{ marginTop: 6 }}>{sub}</div>}
    </div>
  );
}

// Regional publishing breakdown, shows perf vs mech by region
function RegionalPublishingBreakdown({ embedded, streams, setStreams }) {
  const [selectedRegion, setSelectedRegion] = React.useState("us");

  const region = REGIONAL_PUBLISHING[selectedRegion];
  const confs = {
    us: { label: "Baseline US rates", bg: "rgba(212,166,74,0.12)", border: "var(--gold)", text: "#d4a64a" },
    eu: { label: "EU premium (higher ARPU)", bg: "rgba(76,196,208,0.12)", border: "#4cc4d0", text: "#4cc4d0" },
    mexico: { label: "Emerging market (lower rates)", bg: "rgba(184,137,255,0.12)", border: "#b889ff", text: "#c5a3ff" },
    asia: { label: "Asia-Pacific variance", bg: "rgba(200,180,160,0.12)", border: "#c8b4a0", text: "#d9cac2" },
    japan: { label: "Japan premium (high ARPU)", bg: "rgba(76,196,208,0.12)", border: "#4cc4d0", text: "#4cc4d0" }
  };
  const conf = confs[selectedRegion];

  const totalEarned = streams * region.total / 1000;
  const perfEarned = streams * region.perf / 1000;
  const mechEarned = streams * region.mech / 1000;

  return (
    <div style={embedded ? { marginTop: 8 } : { marginTop: 48, paddingTop: 40, borderTop: "1px solid var(--rule)" }}>
      {!embedded && (
        <div style={{ marginBottom: 28 }}>
          <span className="caption">Deep dive: regional publishing breakdown</span>
          <h3 className="pull-serif" style={{ fontSize: 24, lineHeight: 1.3, margin: "10px 0 0", color: "var(--ink)" }}>
            Performance royalties (radio, streaming) + mechanical royalties (reproductions) vary dramatically by region.
          </h3>
        </div>
      )}

      {/* Education panel */}
      <div style={{ padding: "20px 22px", background: "rgba(212,166,74,0.03)", border: "1px solid var(--rule-gold)", marginBottom: 24 }}>
        <span className="caption" style={{ color: "var(--gold)" }}>Why the difference?</span>
        <ul className="body-text" style={{ marginTop: 8, paddingLeft: 20, fontSize: 14, lineHeight: 1.5, color: "var(--ink-2)" }}>
          <li><strong>Performance royalties</strong> come from collecting societies (ASCAP, BMI, PRS, etc.) and reflect per-stream rates from platforms.</li>
          <li><strong>Mechanical royalties</strong> are paid for reproduction rights, controlled by different societies per region. US rate is statutory (~$0.091/reproduction), but varies globally.</li>
          <li><strong>Regional variation</strong> reflects ARPU (average revenue per user), local licensing structures, and collecting society rates.</li>
        </ul>
      </div>

      {/* Region selector */}
      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 24 }}>
        {Object.entries(REGIONAL_PUBLISHING).map(([key, data]) => (
          <button
            key={key}
            onClick={() => setSelectedRegion(key)}
            style={{
              padding: "10px 14px",
              background: selectedRegion === key ? "var(--gold)" : "transparent",
              color: selectedRegion === key ? "#16110a" : "var(--ink-2)",
              border: `1px solid ${selectedRegion === key ? "var(--gold)" : "var(--rule-strong)"}`,
              fontFamily: "var(--sans)",
              fontWeight: selectedRegion === key ? 700 : 500,
              fontSize: 13,
              letterSpacing: "-0.01em",
              cursor: "pointer",
              transition: "all 0.15s ease",
            }}
          >
            {data.label}
          </button>
        ))}
      </div>

      {/* Regional breakdown */}
      <div style={{ padding: "24px 28px", border: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.015)", marginBottom: 24 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 20, flexWrap: "wrap", gap: 12 }}>
          <div>
            <span className="caption">Per 1,000 streams in {region.label}</span>
            <div className="pull-serif" style={{ fontSize: 20, lineHeight: 1.3, margin: "8px 0 0", color: "var(--ink)" }}>
              ${region.total.toFixed(2)} total publishing pool
            </div>
          </div>
          <div style={{ ...(conf && conf.bg ? { background: conf.bg, border: `1px solid ${conf.border}`, borderRadius: "4px", padding: "6px 10px" } : {}), fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.12em", color: conf?.text }}>
            ★ {conf?.label}
          </div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
          <div style={{ padding: "14px 16px", border: "1px solid rgba(212,166,74,0.3)", background: "rgba(212,166,74,0.06)" }}>
            <div className="caption" style={{ color: "var(--gold)" }}>Performance royalties</div>
            <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: 24, color: "var(--gold)", marginTop: 6, letterSpacing: "-0.02em" }}>
              ${region.perf.toFixed(2)}
            </div>
            <div className="caption" style={{ marginTop: 4, color: "var(--ink-3)" }}>Streaming, radio, performance</div>
          </div>
          <div style={{ padding: "14px 16px", border: "1px solid rgba(122,207,153,0.3)", background: "rgba(122,207,153,0.06)" }}>
            <div className="caption" style={{ color: PUB_MECH_COLOR }}>Mechanical royalties</div>
            <div style={{ fontFamily: "var(--sans)", fontWeight: 800, fontSize: 24, color: PUB_MECH_COLOR, marginTop: 6, letterSpacing: "-0.02em" }}>
              ${region.mech.toFixed(2)}
            </div>
            <div className="caption" style={{ marginTop: 4, color: "var(--ink-3)" }}>Reproductions & distributions</div>
          </div>
        </div>

        <div className="caption" style={{ marginTop: 12, color: "var(--ink-3)" }}>
          Source: {region.source}
        </div>
      </div>

      {/* Earnings projection */}
      <div style={{ padding: "24px 28px", border: "1px solid var(--rule-gold)", background: "rgba(212,166,74,0.04)" }}>
        <span className="caption" style={{ color: "var(--gold)" }}>Estimated earnings · {region.label}</span>
        <StreamScrubber streams={streams} setStreams={setStreams} />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }}>
          <Tile label="Publishing pool" value={`$${formatNum(totalEarned)}`} sub={`${formatNum(streams)} streams × $${region.total.toFixed(2)}/1K`} gold />
          <Tile label="Performance split" value={`$${formatNum(perfEarned)}`} sub={`${(region.perf / region.total * 100).toFixed(0)}% of pool`} />
          <Tile label="Mechanical split" value={`$${formatNum(mechEarned)}`} sub={`${(region.mech / region.total * 100).toFixed(0)}% of pool`} />
        </div>
      </div>
    </div>
  );
}

// Platform master rates by region
function PlatformMasterBreakdown({ embedded, streams, setStreams }) {
  const [selectedPlatform, setSelectedPlatform] = React.useState("spotify");
  const [selectedRegion, setSelectedRegion] = React.useState("us");

  const platformRates = PLATFORM_MASTER_RATES[selectedPlatform];
  const regionKey = selectedRegion === "eu" ? "eu" : selectedRegion === "mx" ? "mx" : selectedRegion === "asia" ? "asia" : "us";
  const ratePerStream = platformRates[regionKey];
  const totalEarned = (streams * ratePerStream);

  return (
    <div style={embedded ? { marginTop: 8 } : { marginTop: 48, paddingTop: 40, borderTop: "1px solid var(--rule)" }}>
      {!embedded && (
        <div style={{ marginBottom: 28 }}>
          <span className="caption">Deep dive: master royalties by platform & region</span>
          <h3 className="pull-serif" style={{ fontSize: 24, lineHeight: 1.3, margin: "10px 0 0", color: "var(--ink)" }}>
            Per-stream rates to the master (sound recording) rights holder vary wildly by platform and listener location.
          </h3>
        </div>
      )}

      {/* Education panel */}
      <div style={{ padding: "20px 22px", background: "rgba(212,166,74,0.03)", border: "1px solid var(--rule-gold)", marginBottom: 24 }}>
        <span className="caption" style={{ color: "var(--gold)" }}>Master royalties explained</span>
        <ul className="body-text" style={{ marginTop: 8, paddingLeft: 20, fontSize: 14, lineHeight: 1.5, color: "var(--ink-2)" }}>
          <li><strong>Master = sound recording rights.</strong> Not the song itself, the actual recorded performance. Producer master shares or independent master ownership are paid here.</li>
          <li><strong>Platform variation:</strong> Tidal (~$0.013/stream) pays 3–4x what Spotify (~$0.004/stream) does. YouTube is lowest (~$0.002).</li>
          <li><strong>Regional variation:</strong> A stream from Norway pays ~10x more than a stream from India (different subscription tiers, ARPU, licensing deals).</li>
          <li><strong>Not fixed.</strong> "Per stream" is a simplification. Platforms pool money and split by market share; these are averages extracted from distributor disclosures.</li>
        </ul>
      </div>

      {/* Selectors */}
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20, marginBottom: 24 }}>
        <div>
          <span className="caption">Platform</span>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 10 }}>
            {Object.keys(PLATFORM_MASTER_RATES).map((platform) => (
              <button
                key={platform}
                onClick={() => setSelectedPlatform(platform)}
                style={{
                  padding: "8px 12px",
                  background: selectedPlatform === platform ? "var(--gold)" : "transparent",
                  color: selectedPlatform === platform ? "#16110a" : "var(--ink-2)",
                  border: `1px solid ${selectedPlatform === platform ? "var(--gold)" : "var(--rule-strong)"}`,
                  fontFamily: "var(--sans)",
                  fontWeight: selectedPlatform === platform ? 700 : 500,
                  fontSize: 12,
                  letterSpacing: "-0.005em",
                  cursor: "pointer",
                  transition: "all 0.15s ease",
                  textTransform: "capitalize",
                }}
              >
                {platform === "youtube" ? "YouTube" : platform.charAt(0).toUpperCase() + platform.slice(1)}
              </button>
            ))}
          </div>
        </div>

        <div>
          <span className="caption">Region</span>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 10 }}>
            {["us", "eu", "mx", "asia"].map((r) => {
              const labels = { us: "United States", eu: "Europe", mx: "Mexico", asia: "Asia" };
              return (
                <button
                  key={r}
                  onClick={() => setSelectedRegion(r)}
                  style={{
                    padding: "8px 12px",
                    background: selectedRegion === r ? "var(--gold)" : "transparent",
                    color: selectedRegion === r ? "#16110a" : "var(--ink-2)",
                    border: `1px solid ${selectedRegion === r ? "var(--gold)" : "var(--rule-strong)"}`,
                    fontFamily: "var(--sans)",
                    fontWeight: selectedRegion === r ? 700 : 500,
                    fontSize: 12,
                    letterSpacing: "-0.005em",
                    cursor: "pointer",
                    transition: "all 0.15s ease",
                  }}
                >
                  {labels[r]}
                </button>
              );
            })}
          </div>
        </div>
      </div>

      {/* Rate card */}
      <div style={{ padding: "24px 28px", border: "1px solid var(--rule-strong)", background: "rgba(255,255,255,0.015)", marginBottom: 24 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 20, flexWrap: "wrap", gap: 12 }}>
          <div>
            <span className="caption">{selectedPlatform.toUpperCase()} · {selectedRegion === "eu" ? "Europe" : selectedRegion === "mx" ? "Mexico" : selectedRegion === "asia" ? "Asia" : "United States"}</span>
            <div className="pull-serif" style={{ fontSize: 20, lineHeight: 1.3, margin: "8px 0 0", color: "var(--ink)" }}>
              ${(ratePerStream * 1000).toFixed(2)} per 1,000 streams
            </div>
          </div>
          <div style={{ background: "rgba(184,137,255,0.12)", border: "1px solid #b889ff", borderRadius: "4px", padding: "6px 10px", fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.12em", color: "#c5a3ff" }}>
            ★ Extrapolated
          </div>
        </div>
      </div>

      {/* Earnings */}
      <div style={{ padding: "24px 28px", border: "1px solid var(--rule-gold)", background: "rgba(212,166,74,0.04)" }}>
        <span className="caption" style={{ color: "var(--gold)" }}>Estimated earnings · {selectedPlatform}</span>
        <StreamScrubber streams={streams} setStreams={setStreams} />
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 16 }}>
          <Tile label="Total streams" value={formatNum(streams)} sub={`on ${selectedPlatform}`} />
          <Tile label={`Rate per stream`} value={`$${(ratePerStream * 1000).toFixed(2)}`} sub={`${selectedRegion === "eu" ? "EU" : selectedRegion === "mx" ? "MX" : selectedRegion === "asia" ? "Asia" : "US"}`} />
          <Tile label="Master earnings (gross)" value={`$${formatNum(totalEarned)}`} sub="Before label/distro splits" gold />
        </div>

        <p className="body-text" style={{ fontSize: 13, lineHeight: 1.55, marginTop: 16, color: "var(--ink-2)" }}>
          This is the <span className="gold">gross master pool</span> before it's split between the label (if signed), distributor fees, and producer master share. If you own 5% of the master, you get 5% of this amount. If you're independent, you get your full ownership percentage minus distributor fees (~10%).
        </p>
      </div>

      {/* Platform comparison */}
      <PlatformComparison selectedRegion={selectedRegion} streams={streams} />
    </div>
  );
}

// Platform comparison matrix
function PlatformComparison({ selectedRegion, streams }) {
  const platforms = Object.keys(PLATFORM_MASTER_RATES);
  const regionKey = selectedRegion === "eu" ? "eu" : selectedRegion === "mx" ? "mx" : selectedRegion === "asia" ? "asia" : "us";

  return (
    <div style={{ marginTop: 28 }}>
      <span className="caption">How platforms compare (same region, same stream count)</span>
      <div style={{ marginTop: 16, display: "flex", flexDirection: "column", gap: 12 }}>
        {platforms.map((platform) => {
          const rate = PLATFORM_MASTER_RATES[platform][regionKey];
          const earned = streams * rate;
          const maxEarned = streams * 0.013; // Tidal max
          const pct = (earned / maxEarned) * 100;

          return (
            <div key={platform} style={{ display: "flex", gap: 12, alignItems: "center" }}>
              <div style={{ minWidth: 80, fontFamily: "var(--sans)", fontWeight: 600, fontSize: 13, textTransform: "capitalize" }}>
                {platform === "youtube" ? "YouTube" : platform}
              </div>
              <div style={{ flex: 1, position: "relative", height: 24, background: "rgba(255,255,255,0.04)" }}>
                <div style={{
                  position: "absolute",
                  inset: 0,
                  width: `${pct}%`,
                  background: "linear-gradient(90deg, #4a3818, var(--gold))",
                  transition: "width 0.3s ease",
                }}></div>
                <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", paddingLeft: 8, fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.12em", color: pct > 50 ? "#16110a" : "var(--ink-2)" }}>
                  {(rate * 1000).toFixed(2)}/1K
                </div>
              </div>
              <div style={{ minWidth: 100, textAlign: "right", fontFamily: "var(--sans)", fontWeight: 700, fontSize: 14, color: "var(--gold)" }}>
                ${formatNum(earned)}
              </div>
            </div>
          );
        })}
      </div>
      <p className="caption" style={{ marginTop: 12, color: "var(--ink-3)" }}>
        ★ Tidal pays ~3–4x what Spotify does per stream. If a release gets the same number of plays across platforms, Tidal earnings dwarf Spotify's. This is why indie artists often say "direct to Tidal" first.
      </p>
    </div>
  );
}

window.Calculator = Calculator;
window.StreamScrubber = StreamScrubber;
window.TERRITORY_CERTS = TERRITORY_CERTS;
