// Lens landing — single Expressive variant. Reuses BDECap visual vocabulary:
// generous whitespace, centered narrow content, Spectral italic accent words,
// thin rules, definition-list rows, navy primary, cream paper background.

const LENS_BRAND = {
  navy: '#1F3A5F',
  purple: '#4F1964',
  accent: '#F9A01B',
  paper: '#FBFAF8',
  ink: '#1A1A2E',
  mute: '#7A7A85',
  rule: 'rgba(26,26,46,0.12)',
  ruleSoft: 'rgba(26,26,46,0.07)',
  cream: '#F1ECE2',
};
const LENS_DEFAULT = LENS_BRAND.navy;

// ---------- Atoms ----------
function LensMark({ color, size = 22 }) {
  const c = color || LENS_DEFAULT;
  return (
    <svg width={size} height={size} viewBox="0 0 64 64" aria-label="Lens">
      <path d="M 8 26 L 8 56 L 38 56" fill="none" stroke={c} strokeWidth="3" strokeLinecap="square" />
      <path d="M 26 8 L 56 8 L 56 38" fill="none" stroke={c} strokeWidth="3" strokeLinecap="square" />
      <circle cx="14" cy="50" r="2.4" fill={c} />
      <circle cx="50" cy="14" r="2.4" fill={c} />
    </svg>
  );
}

function BrandChip({ color }) {
  const c = color || LENS_DEFAULT;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
      <LensMark color={c} size={18} />
      <span style={{ fontFamily: "'Spectral', serif", fontWeight: 500, fontSize: 17, letterSpacing: '-0.02em', color: c }}>Lens</span>
      <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.16em', color: LENS_BRAND.mute, textTransform: 'uppercase' }}>by BDE Capital</span>
    </div>
  );
}

const NAV_HREFS = {
  'How it works': '/how-it-works',
  'Talk to Lens': 'mailto:lens@bdecap.com',
  'In use': '#',
  'Today': '#',
  'For operators': '#',
  'Pricing': '#'
};
function PageNav({ color, links }) {
  const c = color || LENS_DEFAULT;
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '32px 56px', position: 'relative', zIndex: 5 }}>
      <a href="/" style={{ textDecoration: 'none' }}><BrandChip color={c} /></a>
      <div style={{ display: 'flex', alignItems: 'center', gap: 32 }}>
        {(links || ['How it works']).map((l) => (
          <a key={l} href={NAV_HREFS[l] || '#'} style={{ color: LENS_BRAND.ink, textDecoration: 'none', fontSize: 12, fontWeight: 500, letterSpacing: '0.04em', fontFamily: "'DM Sans', sans-serif" }}>{l}</a>
        ))}
        <a href="mailto:lens@bdecap.com" style={{ background: c, color: LENS_BRAND.paper, padding: '10px 16px', fontSize: 11, fontWeight: 500, letterSpacing: '0.06em', textTransform: 'uppercase', textDecoration: 'none', fontFamily: "'DM Sans', sans-serif" }}>Talk to Lens</a>
      </div>
    </div>
  );
}

function PrimaryCTA({ color, label = 'Talk to Lens', size = 'md', href = 'mailto:lens@bdecap.com' }) {
  const c = color || LENS_DEFAULT;
  const pad = size === 'lg' ? '14px 22px' : '11px 18px';
  const fs = size === 'lg' ? 13 : 11;
  return (
    <a href={href} style={{ display: 'inline-flex', alignItems: 'center', gap: 10, padding: pad, background: c, color: LENS_BRAND.paper, fontFamily: "'DM Sans', sans-serif", fontWeight: 500, fontSize: fs, letterSpacing: '0.06em', textTransform: 'uppercase', textDecoration: 'none' }}>
      <span>{label}</span><span style={{ fontSize: 14, lineHeight: 1, marginTop: -2 }}>→</span>
    </a>
  );
}
function SecondaryCTA({ color, label = 'Talk to Lens', size = 'md', href = 'mailto:lens@bdecap.com' }) {
  const c = color || LENS_DEFAULT;
  const pad = size === 'lg' ? '13px 22px' : '10px 18px';
  const fs = size === 'lg' ? 13 : 11;
  return (
    <a href={href} style={{ display: 'inline-flex', alignItems: 'center', gap: 10, padding: pad, background: 'transparent', color: LENS_BRAND.ink, border: `1px solid ${c}`, fontFamily: "'DM Sans', sans-serif", fontWeight: 500, fontSize: fs, letterSpacing: '0.06em', textTransform: 'uppercase', textDecoration: 'none' }}>
      <span>{label}</span><span style={{ fontSize: 14, lineHeight: 1, marginTop: -2, color: c }}>→</span>
    </a>
  );
}

function It({ color, children }) {
  return <em style={{ fontStyle: 'italic', color: color || LENS_DEFAULT, fontWeight: 500 }}>{children}</em>;
}

function FooterStrip() {
  return (
    <div style={{ padding: '32px 56px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderTop: `1px solid ${LENS_BRAND.ruleSoft}`, fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', color: LENS_BRAND.mute, textTransform: 'uppercase' }}>
      <span>lens.bdecap.com</span>
      <span>v0.1 · operator preview · 2026</span>
      <span>lens@bdecap.com</span>
    </div>
  );
}

// ---------- Hero rotating role ----------
// Roles are SHORT abbreviations only so we never bleed onto a new line.
const ROTATING_ROLES = ['CFO', 'COO', 'CMO', 'CRO', 'GC', 'CTO', 'CPO'];
function useRotatingRole(roles, ms = 2200) {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setI((x) => (x + 1) % roles.length), ms);
    return () => clearInterval(t);
  }, [roles.length, ms]);
  return roles[i];
}

// ---------- Interactive Lens Stack ----------
// Library of available lenses + scenarios. User can:
//   • click lenses to add/remove from the active stack (max 3 visible)
//   • pick a scenario (the "problem")
// The Claude-style consult panel updates with role-specific takes.
const LENS_LIBRARY = [
  { id: 'cfo',  role: 'CFO',           name: 'C. Ngozi',  tagline: 'Cash conversion is the leading indicator.' },
  { id: 'ops',  role: 'Head of Ops',   name: 'M. Reyes',  tagline: 'Volume below partner tier is fixed cost without leverage.' },
  { id: 'gc',   role: 'General Counsel', name: 'A. Tanaka', tagline: 'Customer concentration is a covenant problem.' },
  { id: 'cro',  role: 'CRO',           name: 'P. Walsh',  tagline: 'Pipeline coverage lies before churn does.' },
  { id: 'cmo',  role: 'CMO',           name: 'S. Desai',  tagline: 'CAC payback is the only honest growth metric.' },
  { id: 'cpo',  role: 'CPO',           name: 'D. Larsen', tagline: 'Activation, not signups. Always.' },
  { id: 'cto',  role: 'CTO',           name: 'J. Park',   tagline: 'Reliability compounds. Velocity decays.' },
  { id: 'cos',  role: 'Chief of Staff', name: 'R. Khoury', tagline: 'If two leaders disagree, you have one decision to make.' },
];

const SCENARIOS = [
  { id: 'q3',     label: 'Q3-FORECAST.XLSX',          q: 'Look at this Q3 forecast through these lenses. What would they push back on?' },
  { id: 'memo',   label: 'BOARD-MEMO-DRAFT.DOCX',     q: 'Read this board memo. Where does the argument get weak?' },
  { id: 'deal',   label: 'ACQUISITION-LOI.PDF',       q: 'Should we sign the LOI? What are the deal-breaker terms?' },
  { id: 'churn',  label: 'CHURN-COHORT-REPORT.CSV',   q: 'Why are we losing the mid-market segment? What’s the real story?' },
];

// Industries shape how each lens reads a problem. The same CFO sees different
// risks in a SaaS forecast vs a consumer-goods forecast.
const INDUSTRIES = [
  { id: 'saas',     label: 'B2B SaaS' },
  { id: 'consumer', label: 'Consumer / DTC' },
  { id: 'fintech',  label: 'Fintech' },
  { id: 'health',   label: 'Healthcare' },
  { id: 'industrial', label: 'Industrial' },
];

function Mark({ children }) { return <span style={{ background: `${LENS_BRAND.accent}40`, padding: '0 3px' }}>{children}</span>; }

// Industry-aware takes. Keys are `${industry}_${scenario}_${lens}`. We write
// the high-density combos by hand so each industry actually changes the
// content meaningfully. Falls back to a generic-but-still-distinct line if a
// specific combo isn't authored.
const TAKES = {
  // ===== B2B SaaS =====
  saas_q3_cfo:  <>Top-line in row 14 looks fine, but ARR-to-cash assumptions haven’t been touched since FY24. <Mark>If our top three accounts pay annually-in-arrears like Q2, the cash plan is short by ~$420K.</Mark> Re-run with the longer collection cycle before approving the hiring ramp.</>,
  saas_q3_ops:  <>Customer success headcount scales linearly here. That breaks above 400 accounts … the playbook assumes pooled CSMs, not named ones. <Mark>Either commit to pooled, or the fulfillment cost is 30% higher than this row says.</Mark></>,
  saas_q3_gc:   <>Two customers are 41% of forecast ARR. <Mark>That trips the concentration covenant in the venture-debt facility</Mark> if either renewal slips a quarter. Flag to the lender now.</>,
  saas_q3_cro:  <>Pipeline coverage is showing 2.8×. Same number we had in Q2 right before we missed by 18%. <Mark>I want stage-3 coverage, not total.</Mark> Below 1.4× and this forecast is fiction.</>,
  saas_q3_cmo:  <>Paid CAC is up 31% off the top of my head; the blend held only because referrals carried it. <Mark>Don’t plan referrals into the forecast.</Mark></>,
  saas_q3_cpo:  <>Expansion line uses activation rates from the Series-B cohort. New cohort is 14 points lower on first-week activation. <Mark>Expansion will lag by a quarter unless onboarding is in the plan.</Mark></>,
  saas_q3_cto:  <>Infra cost in row 9 grows step-wise at the next AWS region tier. <Mark>Add ~$60K/qtr that’s not in opex.</Mark></>,

  saas_memo_cfo: <>Page 2 leans on a 38% ARR growth claim that uses gross-of-discount. <Mark>Net growth is closer to 22%.</Mark> The board will run the math anyway.</>,
  saas_memo_cro: <>Replace "$48M qualified pipeline" with stage-weighted; <Mark>the qualified number gives the wrong board confidence.</Mark></>,
  saas_memo_gc:  <>"No material litigation" is technically true and operationally misleading … <Mark>disclose the demand letter in a footnote.</Mark></>,

  saas_deal_cfo: <>Working-capital adjustment in 4.3 excludes deferred revenue. <Mark>We’d be funding their cash gap.</Mark> Push to standard GAAP working capital.</>,
  saas_deal_gc:  <>The MAC clause excludes pandemic-class events. <Mark>Add a carve-back</Mark> or this LOI is a free option for them.</>,
  saas_deal_cro: <>Their revenue concentration is worse than the deck shows. Top account is 28% and they’re a churned competitor logo. <Mark>Model losing half that book.</Mark></>,
  saas_deal_ops: <>Integration timeline assumes their CS team stays. <Mark>Two of their three CSMs are vesting through next quarter</Mark> and will leave. Adjust onboarding capacity accordingly.</>,

  saas_churn_cro: <>It’s not churn, it’s sales-fit. <Mark>The IC discounted into accounts that were never going to expand.</Mark> Look at deal-source, not segment.</>,
  saas_churn_cpo: <>Activation for that segment is 30% below enterprise. <Mark>They never got value, so they didn’t renew.</Mark> Fix onboarding before re-investing.</>,
  saas_churn_cmo: <>Mid-market funnel was over-paid in 2024. <Mark>You bought low-quality logos with high CAC;</Mark> churn is the bill coming due.</>,
  saas_churn_cfo: <>Churn is concentrated in deals signed during the discount push. <Mark>The cohort is artificially expensive to retain.</Mark></>,

  // ===== Consumer / DTC =====
  consumer_q3_cfo: <>The forecast assumes Q4 paid-media efficiency holds. <Mark>iOS attribution is still soft;</Mark> last year we missed by 12% on the same assumption. Stress-test at 0.85x.</>,
  consumer_q3_ops: <>Fulfillment line scales linearly. That’s wrong below 18K units/week … <Mark>we hit the 3PL’s minimum tier discount only above that.</Mark> Either commit to the volume or move fulfillment to a step function.</>,
  consumer_q3_cmo: <>Blended ROAS hides the story. <Mark>Meta is at 1.8 and TikTok is at 0.9;</Mark> the blend works because brand search is doing the heavy lifting. Brand search is not a growth lever.</>,
  consumer_q3_gc:  <>Two retail partners are 41% of forecast wholesale revenue. <Mark>The MFN pricing clause with the larger one</Mark> means a discount to either is a discount to both. Re-pace the promo plan.</>,
  consumer_q3_cro: <>DTC return rate assumption is pre-skew. <Mark>The new SKU-mix is 4 points higher returns;</Mark> net revenue is overstated by ~6%.</>,

  consumer_memo_cfo: <>Net revenue claim doesn’t back out the platform-fee bump. <Mark>Real growth is 19%, not 28%.</Mark></>,
  consumer_memo_ops: <>The supply-chain section reads like everything’s on track. It isn’t … <Mark>the new contract manufacturer is two months behind on tooling.</Mark> Lead with the risk.</>,
  consumer_memo_cmo: <>"Brand momentum" without a measurement framework is a feeling. <Mark>Tie it to aided awareness or unaided consideration</Mark> or pull the line.</>,

  consumer_deal_cfo: <>Earnout uses gross revenue. <Mark>Their returns are 22%;</Mark> we’d be paying them for revenue that comes back. Switch to net.</>,
  consumer_deal_ops: <>Integration assumes their warehouse stays put for 18 months. <Mark>Their lease is up in 11.</Mark> Negotiate the lease into the deal or the math doesn’t hold.</>,
  consumer_deal_gc: <>Influencer-contract assignability is unclear in section 7. <Mark>Half their CAC is contracted talent</Mark> who can walk on change-of-control.</>,

  consumer_churn_cmo: <>Mid-market funnel was over-paid into during 2024 promo windows. <Mark>You bought one-time buyers, not subscribers.</Mark></>,
  consumer_churn_ops: <>Repeat rate is fine on hero SKUs and broken on the new line. <Mark>It’s a product-quality issue showing up as churn,</Mark> not a marketing one.</>,
  consumer_churn_cfo: <>Discount-cohort retention is below break-even on second order. <Mark>Stop discounting acquisition</Mark> or accept the unit economics.</>,

  // ===== Fintech =====
  fintech_q3_cfo: <>Net interest margin assumption ignores the rate path the lender is now pricing. <Mark>NIM compresses 40bps if SOFR moves as forecast;</Mark> re-run revenue with both scenarios.</>,
  fintech_q3_gc:  <>Customer concentration plus state-by-state licensure exposure. <Mark>Losing the NY money-transmitter would knock 18% of forecast.</Mark> Confirm renewal status before locking the plan.</>,
  fintech_q3_ops: <>Loss-rate assumption uses 12-month vintage data. <Mark>The newest vintage is 90bps worse on day-30 delinquency.</Mark> Reserve accordingly or the P&L is a fantasy.</>,
  fintech_q3_cro: <>Sales-led acquisition for fintech-treasury accounts assumes a 6-week cycle. Real cycle is 14 weeks with security review. <Mark>Pipeline-to-close is half what this models.</Mark></>,
  fintech_q3_cmo: <>Compliance review is bottlenecking creative. <Mark>You can’t front-load Q3 spend if legal needs 3 weeks per asset.</Mark></>,

  fintech_memo_gc:  <>SAR-volume disclosure is missing from the risk section. <Mark>If the regulator sees the memo before they see the SARs,</Mark> we have a different conversation.</>,
  fintech_memo_cfo: <>Capital-ratio claim uses the prior reporting period. <Mark>This quarter’s ratio is 80bps tighter</Mark> after the loan-loss true-up.</>,

  fintech_deal_gc:  <>Money-transmitter licenses are not freely transferable in 14 of the states they operate in. <Mark>The deal needs a state-by-state consent timeline,</Mark> not a closing date.</>,
  fintech_deal_cfo: <>Their loan book reserves are at peer-low. <Mark>If we mark to our reserve policy, the price is 18% high.</Mark></>,

  fintech_churn_cfo: <>Card-program churn is concentrated in interchange-light cohorts. <Mark>You’re losing the revenue you don’t want anyway;</Mark> don’t over-correct.</>,
  fintech_churn_gc:  <>Onboarding KYC friction is the proximate cause. <Mark>The product team won’t fix it without a regulatory cover memo.</Mark> Write it.</>,
  fintech_churn_cro: <>Churn correlates with deals where treasury didn’t get to the security review. <Mark>It’s a process leak, not a product loss.</Mark></>,

  // ===== Healthcare =====
  health_q3_cfo: <>Forecast assumes reimbursement at the current contracted rate. <Mark>Two payors are mid-renegotiation</Mark> and the historical pattern is a 3-6% haircut. Reserve a band.</>,
  health_q3_ops: <>Staffing model uses last year’s acuity mix. <Mark>Acuity is up 9% YoY;</Mark> nursing hours per patient day are mis-forecast by ~12%. That’s where the OT dollars are coming from.</>,
  health_q3_gc:  <>Stark and AKS exposure on the new referral pathway is real and undisclosed. <Mark>Get a written safe-harbor opinion</Mark> before forecast revenue from it is approved.</>,
  health_q3_cro: <>RCM denial rate is creeping past 8%. <Mark>That’s the leading indicator;</Mark> the cash forecast lags by a quarter. Forecast cash, not booked revenue.</>,
  health_q3_cmo: <>Patient-acquisition spend assumes the referring-physician pipeline. <Mark>Two of the top five referrers retired in Q2.</Mark> The pipeline is a relationship, not a channel.</>,

  health_memo_gc:  <>"No HIPAA incidents" excludes the breach-notification threshold. <Mark>The May incident was 412 records, under threshold but reportable to the OCR.</Mark> Disclose it.</>,
  health_memo_cfo: <>Operating margin uses gross collections. <Mark>Net collections after denials and contractuals is 14 points lower.</Mark></>,
  health_memo_ops: <>Staffing chart shows green. The chart aggregates float pool with FTE. <Mark>Float-pool turnover is 38%;</Mark> the green is masking attrition.</>,

  health_deal_gc:  <>Provider-employment agreements have non-competes that aren’t enforceable in three of their states post-FTC. <Mark>The retention plan is the diligence,</Mark> not the contracts.</>,
  health_deal_cfo: <>Their AR aging shows 28% over 120 days. <Mark>Mark the receivables down 35% before pricing the deal.</Mark></>,
  health_deal_ops: <>EHR migration is the deal. <Mark>Underestimate it and the synergy thesis evaporates.</Mark> Add 6 months and a vendor change-order.</>,

  health_churn_cro: <>Patient leakage to in-network competitors is up because referring physicians changed groups. <Mark>You don’t have a churn problem, you have a referral-relationship problem.</Mark></>,
  health_churn_cfo: <>Self-pay cohort is the ones leaving. <Mark>It’s not a clinical problem,</Mark> it’s a billing-experience problem. RCM team should own this metric.</>,
  health_churn_ops: <>Wait-time data correlates 1:1 with leakage. <Mark>Drop wait below 22 minutes</Mark> and the segment retains.</>,

  // ===== Industrial =====
  industrial_q3_cfo: <>Backlog conversion assumes 90-day shipment lead time. <Mark>Steel is 14 weeks today, not 12.</Mark> Push the revenue out a quarter or pre-order at risk.</>,
  industrial_q3_ops: <>Plant utilization in row 11 assumes the new line is at 80% by week 6. <Mark>Last commissioning took 14 weeks to hit 80%, not 6.</Mark> Either accept the gap or move the launch date.</>,
  industrial_q3_cro: <>Distributor sell-through hides channel inventory. <Mark>They’re carrying 9 weeks of stock;</Mark> sell-in will fall before sell-out does. Forecast on sell-through.</>,
  industrial_q3_gc:  <>Two federal contracts are 38% of forecast. <Mark>One is up for re-compete in November.</Mark> If we lose it, the plan is short 18% in Q4.</>,
  industrial_q3_cmo: <>OEM co-marketing dollars are pencil-booked. <Mark>Two of the four OEM partners are mid-leadership change;</Mark> don’t bank that revenue.</>,

  industrial_memo_ops: <>"On-time delivery 94%" uses the most recent month. <Mark>YTD is 81%.</Mark> Use YTD or pull the line.</>,
  industrial_memo_cfo: <>EBITDA bridge omits the warranty accrual increase. <Mark>The new product line drove a $1.4M reserve add</Mark> that isn’t walked through here.</>,

  industrial_deal_ops: <>Their plant is one earthquake retrofit away from a $4M cap-ex bill. <Mark>The seismic study sat in their data room;</Mark> diligence didn’t walk through it.</>,
  industrial_deal_cfo: <>Working capital is mostly raw-material inventory at last year’s steel prices. <Mark>Mark to current and the deal value drops 9%.</Mark></>,
  industrial_deal_gc:  <>Their environmental disclosures don’t mention the Phase II at the secondary site. <Mark>Pull the Phase II</Mark> before signing.</>,

  industrial_churn_cro: <>Distributor churn correlates with the price-list change last year. <Mark>You raised prices through channel without raising co-op;</Mark> they walked.</>,
  industrial_churn_ops: <>OEM customers leave when warranty claims hit 4%. <Mark>You’re at 3.6% on the new line</Mark> and trending up. Fix the QC station before the OEMs read the same number.</>,
};

// Generic-but-distinct fallback per industry, so the panel never feels stale.
const FALLBACK_BY_INDUSTRY = {
  saas:       (role) => <>For a B2B SaaS read, this is where {role} would dig. Want to attach the cohort or the pipeline export to go deeper?</>,
  consumer:   (role) => <>{role} would want the SKU-level and channel-level cuts before answering this. Attach the marketing-mix or returns data.</>,
  fintech:    (role) => <>{role} would want the regulatory and unit-economic context before signing off. Attach the latest call report or product P&L.</>,
  health:     (role) => <>{role} would want payor-mix, denial codes, and acuity data before answering. Attach the RCM or staffing report.</>,
  industrial: (role) => <>{role} would want the BOM, the backlog, and the channel inventory before answering. Attach the latest S&OP file.</>,
};

function getTake(lensId, scenarioId, industryId) {
  const lens = LENS_LIBRARY.find((l) => l.id === lensId);
  const role = lens?.role || 'this role';
  const key = `${industryId}_${scenarioId}_${lensId}`;
  if (TAKES[key]) return TAKES[key];
  const fb = FALLBACK_BY_INDUSTRY[industryId];
  if (fb) return fb(role);
  return <>{role} would want more context before answering this. Attach the underlying data and we’ll go deeper.</>;
}

function LensChip({ lens, active, onToggle, color }) {
  const c = color || LENS_DEFAULT;
  return (
    <button onClick={() => onToggle(lens.id)} style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      padding: '10px 14px',
      background: active ? c : LENS_BRAND.paper,
      color: active ? LENS_BRAND.paper : LENS_BRAND.ink,
      border: `1px solid ${active ? c : LENS_BRAND.rule}`,
      fontFamily: "'DM Sans', sans-serif", fontSize: 13, fontWeight: 500,
      cursor: 'pointer', transition: 'all 120ms ease',
      letterSpacing: '-0.005em',
    }}>
      <svg width="12" height="12" viewBox="0 0 64 64">
        <path d="M 8 26 L 8 56 L 38 56" fill="none" stroke={active ? LENS_BRAND.paper : c} strokeWidth="5" strokeLinecap="square" />
        <path d="M 26 8 L 56 8 L 56 38" fill="none" stroke={active ? LENS_BRAND.paper : c} strokeWidth="5" strokeLinecap="square" />
      </svg>
      <span>{lens.role}</span>
    </button>
  );
}

function ScenarioPill({ scenario, active, onClick, color }) {
  const c = color || LENS_DEFAULT;
  return (
    <button onClick={() => onClick(scenario.id)} style={{
      padding: '8px 12px',
      background: active ? `${c}10` : 'transparent',
      color: active ? c : LENS_BRAND.mute,
      border: `1px solid ${active ? c : LENS_BRAND.ruleSoft}`,
      fontFamily: "'JetBrains Mono', monospace", fontSize: 10,
      letterSpacing: '0.14em', textTransform: 'uppercase',
      cursor: 'pointer', transition: 'all 120ms ease',
    }}>{scenario.label}</button>
  );
}

function IndustryPill({ industry, active, onClick, color }) {
  const c = color || LENS_DEFAULT;
  return (
    <button onClick={() => onClick(industry.id)} style={{
      padding: '10px 14px',
      background: active ? c : LENS_BRAND.paper,
      color: active ? LENS_BRAND.paper : LENS_BRAND.ink,
      border: `1px solid ${active ? c : LENS_BRAND.rule}`,
      fontFamily: "'DM Sans', sans-serif", fontSize: 13, fontWeight: 500,
      letterSpacing: '-0.005em',
      cursor: 'pointer', transition: 'all 120ms ease',
    }}>{industry.label}</button>
  );
}

function InteractiveStack({ color }) {
  const c = color || LENS_DEFAULT;
  const [active, setActive] = React.useState(['cfo', 'ops', 'gc']);
  const [scenario, setScenario] = React.useState('q3');
  const [industry, setIndustry] = React.useState('saas');
  const sc = SCENARIOS.find((s) => s.id === scenario);
  const ind = INDUSTRIES.find((i) => i.id === industry);
  const toggle = (id) => {
    setActive((cur) => {
      if (cur.includes(id)) return cur.filter((x) => x !== id);
      if (cur.length >= 3) return [...cur.slice(1), id]; // FIFO when at cap
      return [...cur, id];
    });
  };
  const activeLenses = active.map((id) => LENS_LIBRARY.find((l) => l.id === id)).filter(Boolean);

  return (
    <div>
      {/* Available lenses tray */}
      <div style={{ marginBottom: 18 }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', color: LENS_BRAND.mute, marginBottom: 12, textTransform: 'uppercase' }}>
          Pick lenses · stack up to three
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
          {LENS_LIBRARY.map((l) => (
            <LensChip key={l.id} lens={l} active={active.includes(l.id)} onToggle={toggle} color={c} />
          ))}
        </div>
      </div>

      {/* Industry picker */}
      <div style={{ marginBottom: 18 }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', color: LENS_BRAND.mute, marginBottom: 12, textTransform: 'uppercase' }}>
          Pick the industry context
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
          {INDUSTRIES.map((i) => (
            <IndustryPill key={i.id} industry={i} active={industry === i.id} onClick={setIndustry} color={c} />
          ))}
        </div>
      </div>

      {/* Scenario picker */}
      <div style={{ marginBottom: 18 }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', color: LENS_BRAND.mute, marginBottom: 12, textTransform: 'uppercase' }}>
          Pick the problem
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
          {SCENARIOS.map((s) => (
            <ScenarioPill key={s.id} scenario={s} active={scenario === s.id} onClick={setScenario} color={c} />
          ))}
        </div>
      </div>

      {/* Claude-style consult panel */}
      <div style={{ background: LENS_BRAND.paper, border: `1px solid ${LENS_BRAND.rule}` }}>
        <div style={{ padding: '18px 28px', borderBottom: `1px solid ${LENS_BRAND.rule}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, fontFamily: "'JetBrains Mono', monospace", fontSize: 11, letterSpacing: '0.14em', color: LENS_BRAND.mute }}>
            <span style={{ width: 8, height: 8, background: c, display: 'inline-block' }}></span>
            CLAUDE · LENS CONNECTOR
          </div>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.14em', color: LENS_BRAND.mute, display: 'flex', gap: 18 }}>
            <span>INDUSTRY: {ind.label.toUpperCase()}</span>
            <span>ATTACHMENT: {sc.label}</span>
          </div>
        </div>
        <div style={{ padding: '28px 28px 8px' }}>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.16em', color: LENS_BRAND.mute, marginBottom: 10 }}>YOU ASK</div>
          <div style={{ fontFamily: "'Spectral', serif", fontSize: 21, lineHeight: 1.35, color: LENS_BRAND.ink }}>{sc.q}</div>
        </div>
        <div style={{ height: 1, background: LENS_BRAND.rule, margin: '24px 0 0' }}></div>
        {activeLenses.length === 0 ? (
          <div style={{ padding: '40px 28px', textAlign: 'center', color: LENS_BRAND.mute, fontSize: 13.5, fontStyle: 'italic' }}>
            Pick at least one lens above.
          </div>
        ) : activeLenses.map((r, i) => (
          <div key={r.id} style={{ padding: '24px 28px', borderTop: i === 0 ? 'none' : `1px solid ${LENS_BRAND.ruleSoft}` }}>
            <div style={{ display: 'grid', gridTemplateColumns: '200px 1fr', gap: 32, alignItems: 'flex-start' }}>
              <div>
                <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.16em', color: c, marginBottom: 6 }}>{r.role.toUpperCase()} LENS</div>
                <div style={{ fontFamily: "'Spectral', serif", fontStyle: 'italic', fontSize: 14, color: LENS_BRAND.ink, marginBottom: 4, lineHeight: 1.35 }}>“{r.tagline}”</div>
                <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.12em', color: LENS_BRAND.mute }}>… {r.name}</div>
              </div>
              <div style={{ fontSize: 14.5, lineHeight: 1.65, color: LENS_BRAND.ink }}>{getTake(r.id, scenario, industry)}</div>
            </div>
          </div>
        ))}
        <div style={{ padding: '14px 28px', borderTop: `1px solid ${LENS_BRAND.ruleSoft}`, fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.14em', color: LENS_BRAND.mute, display: 'flex', justifyContent: 'space-between' }}>
          <span>{LENS_LIBRARY.length} LENSES · {INDUSTRIES.length} INDUSTRIES · {active.length} STACKED</span>
          <span>YOUR LIBRARY GROWS AS YOU CAPTURE</span>
        </div>
      </div>
      <div style={{ marginTop: 14, fontSize: 11, color: LENS_BRAND.mute, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.08em', textAlign: 'center' }}>
        TRY IT … STACK LENSES, INDUSTRY, OR PROBLEM ABOVE · COMPOSITE · NAMES AND NUMBERS ABSTRACTED
      </div>
    </div>
  );
}

// ============================================================
// MAIN VARIANT — Expressive
// ============================================================
function VariantExpressive({ accent, headline }) {
  const c = accent || LENS_DEFAULT;
  const role = useRotatingRole(ROTATING_ROLES);

  return (
    <div style={{ width: 1440, background: LENS_BRAND.paper, color: LENS_BRAND.ink, fontFamily: "'DM Sans', sans-serif" }}>
      <PageNav color={c} />

      {/* HERO */}
      <div style={{ padding: '120px 56px 100px', textAlign: 'center' }}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 32 }}>
          <LensMark color={c} size={56} />
        </div>
        <div style={{ fontFamily: "'Spectral', serif", fontWeight: 500, fontSize: 248, lineHeight: 0.92, letterSpacing: '-0.04em', color: c, margin: 0 }}>
          Lens.
        </div>

        {/* Headline with fixed-width slot for the rotating role to prevent line bleed */}
        <h1 style={{
          fontFamily: "'Spectral', serif", fontWeight: 500,
          fontSize: 38, lineHeight: 1.22, letterSpacing: '-0.018em',
          color: LENS_BRAND.ink, margin: '60px auto 0', maxWidth: 880,
          textAlign: 'center',
        }}>
          See any business problem through your{' '}
          <span style={{
            display: 'inline-block',
            minWidth: '2.6ch', // CFO/COO/CMO/CRO/GC/CTO/CPO all fit
            textAlign: 'center',
            position: 'relative',
          }}>
            <em key={role} style={{
              fontStyle: 'italic',
              color: LENS_BRAND.accent,
              fontWeight: 500,
              animation: 'lensRoleFade 2.2s ease',
              display: 'inline-block',
            }}>{role}</em>
          </span>
          {"’"}s lens.
        </h1>

        <div style={{ marginTop: 20, fontSize: 16, color: LENS_BRAND.mute, maxWidth: 580, margin: '20px auto 0', lineHeight: 1.6 }}>
          Connect Lens inside Claude. Drop in the spreadsheet, the deal memo, the customer thread … then consult any role on your senior team.
        </div>
        <div style={{ display: 'flex', gap: 12, marginTop: 40, justifyContent: 'center' }}>
          <PrimaryCTA color={c} size="lg" />
        </div>

        <style>{`
          @keyframes lensRoleFade {
            0%   { opacity: 0; transform: translateY(6px); }
            18%  { opacity: 1; transform: translateY(0); }
            82%  { opacity: 1; transform: translateY(0); }
            100% { opacity: 0; transform: translateY(-6px); }
          }
        `}</style>
      </div>

      {/* DEFINITION — simple, eye-catching, five-year-old can read it */}
      <div style={{ padding: '160px 56px', borderTop: `1px solid ${LENS_BRAND.rule}`, borderBottom: `1px solid ${LENS_BRAND.rule}`, marginTop: 40 }}>
        <div style={{ width: 1080, margin: '0 auto', textAlign: 'center' }}>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.2em', color: LENS_BRAND.mute, textTransform: 'uppercase', marginBottom: 36 }}>
            What Lens is
          </div>
          <div style={{ fontFamily: "'Spectral', serif", fontSize: 64, fontWeight: 500, lineHeight: 1.08, letterSpacing: '-0.028em', color: LENS_BRAND.ink }}>
            Your best people, <span style={{ color: c, fontStyle: 'italic' }}>on demand.</span>
          </div>
          <div style={{ marginTop: 36, fontFamily: "'Spectral', serif", fontSize: 24, fontWeight: 400, lineHeight: 1.45, color: LENS_BRAND.ink, maxWidth: 760, margin: '36px auto 0', letterSpacing: '-0.005em' }}>
            We capture how your senior team thinks. Then anyone on your team can ask them a question in Claude … and get an answer in their voice.
          </div>
        </div>
      </div>

      {/* INTERACTIVE STACK */}
      <div style={{ padding: '140px 56px 0' }}>
        <div style={{ width: 1180, margin: '0 auto' }}>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.2em', color: LENS_BRAND.mute, textTransform: 'uppercase', marginBottom: 16, textAlign: 'center' }}>
            How it{"’"}s used
          </div>
          <div style={{ fontFamily: "'Spectral', serif", fontSize: 40, fontWeight: 500, letterSpacing: '-0.02em', lineHeight: 1.18, marginBottom: 16, textAlign: 'center', maxWidth: 880, margin: '0 auto' }}>
            Stack the lenses you need. <It color={c}>Run them on any problem.</It>
          </div>
          <div style={{ fontSize: 15, color: LENS_BRAND.mute, lineHeight: 1.6, textAlign: 'center', maxWidth: 720, margin: '20px auto 56px' }}>
            Lens captures the tribal knowledge of your senior team {"\u2014\u2009"}role by role, voice by voice. Stack any combination. Run them against the spreadsheet, the memo, the LOI. Add new lenses for new roles, new industries, new operators as you grow.
          </div>

          <InteractiveStack color={c} />
        </div>
      </div>

      {/* WHAT YOU'RE ACTUALLY BUYING — spec sheet (Variant A) */}
      <SpecSheet color={c} />

      {/* FAQ removed from here — moved to the very end of the page */}

      {/* FINAL CTA — workshopped headline */}
      <div style={{ padding: '180px 56px 200px', textAlign: 'center', borderTop: `1px solid ${LENS_BRAND.rule}` }}>
        <div style={{ fontFamily: "'Spectral', serif", fontStyle: 'italic', fontWeight: 500, fontSize: 26, letterSpacing: '-0.012em', color: c, marginBottom: 36 }}>
          Tribal knowledge, captured.
        </div>
        <div style={{ fontFamily: "'Spectral', serif", fontSize: 68, fontWeight: 500, lineHeight: 1.05, letterSpacing: '-0.026em', color: LENS_BRAND.ink, maxWidth: 1100, margin: '0 auto' }}>
          Stop losing your senior team{"’"}s judgment to <span style={{ color: c, fontStyle: 'italic' }}>inboxes, calls, and memory.</span>
        </div>
        <div style={{ marginTop: 28, fontSize: 16, color: LENS_BRAND.mute, maxWidth: 620, margin: '28px auto 0', lineHeight: 1.6 }}>
          Lens captures it once, in their voice, and makes it consultable for everyone who needs it next.
        </div>
        <div style={{ display: 'flex', gap: 14, marginTop: 48, justifyContent: 'center' }}>
          <PrimaryCTA color={c} size="lg" />
        </div>
      </div>

      <FooterStrip />

      {/* FAQ hidden 2026-05-01 per Christien — keep component available for future restore */}
    </div>
  );
}

// ---------- FAQ ----------
// Final 12-question set from the 2026-05-01 hand-off package.
const FAQ_ITEMS = [
  {
    q: 'Where does Lens live?',
    a: 'Inside Claude. Lens is a Custom Connector you add once on the team account. After that, every captured operator shows up in the same chat your team already uses. No separate login.',
  },
  {
    q: 'Has anyone used a lens to make a real decision yet?',
    a: 'Yes. Real uses to date include rewriting a board memo in the captured CFO\u2019s voice, redlining an LOI through the captured GC, and structuring a churn diagnosis through the captured Head of Ops.',
  },
  {
    q: 'How does capture work without burning the operator\u2019s time?',
    a: 'About 2 to 3 hours of operator time, spread over two weeks. Most of it is forwarding existing memos and recordings of recurring meetings already on the calendar. A Telegram capture line handles ad-hoc notes between sessions. We don\u2019t run interviews. Most operators stop being asked the same question 6 times a quarter by week two.',
  },
  {
    q: 'What happens to my data, who can read it?',
    a: 'Each client has their own data. Each captured operator is maintained as its own file inside that client\u2019s space. Nothing crosses between clients. Nothing crosses between captured operators.',
  },
  {
    q: 'How is this different from a custom GPT or a Claude project?',
    a: 'A custom GPT or project gives you a system prompt and a few uploaded files. Lens captures judgment over time across memos, calls, and decisions, with inline citations back to source. The operator\u2019s voice is derived from a structured corpus, not a paragraph of instructions. And it compounds: every new memo, redline, or recording refines it.',
  },
  {
    q: 'What happens when the operator leaves?',
    a: 'The lens stays. That is the point. Captured judgment is a company asset, not a personal one. When your retiring CFO walks out the door, her reasoning on the last six quarterly reforecasts is still consultable next Tuesday. The next person in the role inherits a captured predecessor, not a blank seat.',
  },
  {
    q: 'Who can use a lens, and how does access work?',
    a: 'Any seat on your team Claude account that you grant. You can stack lenses (CFO + GC + Head of Ops) in a single chat, attach a document, and consult them together. Access is per-seat and revocable. Soft cap of 3 lenses per query, see failure modes.',
  },
  {
    q: 'What does it cost?',
    a: 'Three components. An install fee (one-time, covers hand-run capture and setup). A monthly retainer (covers up to 10 lenses, freshness tuning, support). A per-lens fee for additional captured operators beyond the 10 in the retainer. Pricing is per-lens, not per-seat. We are calibrating during operator preview, so exact numbers are negotiated as part of the pilot conversation.',
  },
  {
    q: 'Who builds the lens?',
    a: 'The Lens team builds it directly alongside you. We run intake with the source operator (one 60 to 90 minute capture session), review the first batch of structured records with you, and tune voice over the first two weeks. Existing memos, recurring meeting recordings, and a Telegram capture line for off-hours notes are folded in throughout. Self-serve build is not on the 2026 roadmap. The judgment about what to capture and how to tune voice is the work, and that work is human-led today.',
  },
  {
    q: 'What if my industry is unusual?',
    a: 'Lens does not assume a vertical. The captures come from your operator and your documents, so industry context is whatever you bring. Healthcare and B2B services are well-represented in the live tenants. Other verticals are doable but unproven at scale.',
  },
  {
    q: 'What are the failure modes?',
    a: 'Three real ones. First, sparse capture: if the operator has no written memos or recurring meetings, the voice stays generic. Second, voice drift: if the operator\u2019s thinking changes faster than the capture cadence, the lens lags reality. Third, over-stacking: combining 5+ lenses in a single query produces consensus mush. We address these with capture-density checks, freshness decay, and a soft cap of 3 lenses per stack.',
  },
  {
    q: 'When is Lens the wrong answer?',
    a: 'Three cases. First, if your senior operators don\u2019t already write memos or run recurring meetings, there\u2019s nothing to capture. Lens captures what\u2019s already being expressed, it doesn\u2019t manufacture judgment. Second, if your team isn\u2019t on Claude, this isn\u2019t the moment for you. We deliver inside Claude, not as a standalone product. Third, if you need a single answer to a generic question (best-practices, industry norms), a frontier model already does that for free. Lens is for "what would our CFO say about this specifically."',
  },
];

function FAQItem({ item, color }) {
  const c = color || LENS_DEFAULT;
  return (
    <div style={{ borderTop: `1px solid ${LENS_BRAND.rule}`, padding: '28px 0' }}>
      <div style={{ fontFamily: "'Spectral', serif", fontSize: 22, fontWeight: 500, letterSpacing: '-0.012em', color: LENS_BRAND.ink, lineHeight: 1.35, marginBottom: 14 }}>
        {item.q}
      </div>
      <div style={{ paddingRight: 56, fontSize: 15.5, lineHeight: 1.7, color: LENS_BRAND.ink, maxWidth: 760 }}>
        {item.a}
      </div>
    </div>
  );
}

function FAQ({ color }) {
  const c = color || LENS_DEFAULT;
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{ borderTop: `1px solid ${LENS_BRAND.rule}` }}>
      <button
        onClick={() => setOpen(!open)}
        style={{
          display: 'block', width: '100%', padding: '36px 56px', background: 'transparent', border: 'none',
          cursor: 'pointer', textAlign: 'left',
        }}
      >
        <div style={{ width: 1080, margin: '0 auto', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 40 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 24 }}>
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.2em', color: LENS_BRAND.mute, textTransform: 'uppercase' }}>
              Common questions
            </span>
            <span style={{ fontFamily: "'Spectral', serif", fontSize: 22, fontWeight: 500, letterSpacing: '-0.012em', color: LENS_BRAND.ink }}>
              Things <It color={c}>operators</It> ask before they connect.
            </span>
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, color: LENS_BRAND.mute, letterSpacing: '0.14em' }}>
              {FAQ_ITEMS.length} QUESTIONS
            </span>
          </div>
          <span
            aria-hidden="true"
            style={{
              display: 'inline-flex', flexDirection: 'column', justifyContent: 'center', gap: 5,
              width: 28, height: 18,
            }}
          >
            <span style={{
              display: 'block', height: 1.5, background: c,
              transform: open ? 'rotate(45deg) translate(4px, 4px)' : 'none',
              transition: 'transform 200ms ease',
            }}></span>
            <span style={{
              display: 'block', height: 1.5, background: c,
              opacity: open ? 0 : 1,
              transition: 'opacity 200ms ease',
            }}></span>
            <span style={{
              display: 'block', height: 1.5, background: c,
              transform: open ? 'rotate(-45deg) translate(5px, -5px)' : 'none',
              transition: 'transform 200ms ease',
            }}></span>
          </span>
        </div>
      </button>
      {open && (
        <div style={{ padding: '20px 56px 140px', borderTop: `1px solid ${LENS_BRAND.rule}` }}>
          <div style={{ width: 1080, margin: '0 auto' }}>
            <div style={{ display: 'grid', gridTemplateColumns: '320px 1fr', gap: 80, alignItems: 'flex-start', paddingTop: 60 }}>
              <div style={{ position: 'sticky', top: 56 }}>
                <div style={{ fontFamily: "'Spectral', serif", fontSize: 36, fontWeight: 500, lineHeight: 1.12, letterSpacing: '-0.02em', color: LENS_BRAND.ink }}>
                  Things <It color={c}>operators</It> ask before they connect.
                </div>
                <div style={{ marginTop: 20, fontSize: 14, color: LENS_BRAND.mute, lineHeight: 1.6, maxWidth: 280 }}>
                  Don{"’"}t see yours? <a href="mailto:lens@bdecap.com" style={{ color: LENS_BRAND.ink, textDecoration: 'underline', textDecorationColor: c }}>Email Lens</a> directly.
                </div>
              </div>
              <div>
                {FAQ_ITEMS.map((item, i) => (
                  <FAQItem key={i} item={item} color={c} />
                ))}
                <div style={{ borderTop: `1px solid ${LENS_BRAND.rule}` }}></div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ---------- Voices rotation (three side-by-side cards) ----------
const ROTATION_QUOTES = [
  {
    quote: 'I used to draft the same portfolio-review memo every quarter, then verify every number myself before sending. Now I pull the captured CFO’s lens, ask for the draft on a specific portco, and the memo comes back in his cadence with the source already cited. I spot-check three numbers instead of forty.',
    name: 'Janice J.',
    role: 'Partner, private-equity firm',
  },
  {
    quote: 'Half the reason my dispatch desk works is that two guys have been there ten years. If either of them left, we’d be guessing for six months … so we captured how they triage urgency. Now when a new dispatcher hits a call they don’t know how to handle, they ask the lens before they ask me.',
    name: 'Tony R.',
    role: 'Head of Ops, multi-crew field-services co',
  },
  {
    quote: 'Our RCM director knows every payer rep by first name and remembers which denial patterns hit which contracts. She left for two weeks last August and we missed cash we’d have caught. Now her lens gets the questions first … she comes back to fewer fires.',
    name: 'Priya M.',
    role: 'RCM director, 300-bed hospital system',
  },
];

function VoicesRotation({ color }) {
  const c = color || LENS_DEFAULT;
  return (
    <div style={{ padding: '180px 56px', background: LENS_BRAND.cream, marginTop: 140 }}>
      <div style={{ width: 1280, margin: '0 auto' }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.2em', color: LENS_BRAND.mute, textTransform: 'uppercase', marginBottom: 48, textAlign: 'center' }}>
          Voices from the preview
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 24 }}>
          {ROTATION_QUOTES.map((q, i) => (
            <div key={i} style={{ padding: '40px 32px', background: LENS_BRAND.paper, border: `1px solid ${LENS_BRAND.rule}`, display: 'flex', flexDirection: 'column' }}>
              <div style={{ fontFamily: "'Spectral', serif", fontStyle: 'italic', fontSize: 18, fontWeight: 400, lineHeight: 1.55, color: LENS_BRAND.ink, letterSpacing: '-0.005em', flex: 1 }}>
                “{q.quote}”
              </div>
              <div style={{ marginTop: 28, paddingTop: 20, borderTop: `1px solid ${LENS_BRAND.ruleSoft}` }}>
                <div style={{ fontFamily: "'DM Sans', sans-serif", fontSize: 13, fontWeight: 500, color: LENS_BRAND.ink }}>
                  {q.name}
                </div>
                <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.12em', color: c, marginTop: 6, textTransform: 'uppercase' }}>
                  {q.role}
                </div>
              </div>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 28, fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.14em', color: LENS_BRAND.mute, textAlign: 'center' }}>
          COMPOSITE QUOTES · GROUNDED IN REAL OPERATOR PATTERNS · NAMES ABSTRACTED
        </div>
      </div>
    </div>
  );
}

// ---------- Spec sheet ("What you're actually buying") ----------
// Reframed with "your X, not generic" pattern per copy direction.
const SPEC_ITEMS = [
  {
    k: 'YOUR OPERATOR, NOT A TEMPLATE',
    v: <>Each lens is one specific person on <em style={{ fontStyle: 'italic' }}>your</em> team, not a generic CFO persona. Built from their actual memos, decisions, and recurring meetings.</>,
  },
  {
    k: 'YOUR DATA, WITH RECEIPTS',
    v: <>Every answer cites <em style={{ fontStyle: 'italic' }}>your</em> source documents: the memo, the call, the deck. Not generic web data. Click through and read it yourself.</>,
  },
  {
    k: 'COMPOUNDING INSIGHT',
    v: <>Each new memo, redline, or recurring meeting refines the lens. The longer you run it, the more it sounds like the operator and the sharper the judgment gets.</>,
  },
  {
    k: 'CONTEXTUAL MEMORY',
    v: <>Lens remembers the patterns specific to your business: your customers, your covenants, your supply chain. Not industry averages. Yours.</>,
  },
  {
    k: 'INSIDE THE TOOLS YOU ALREADY USE',
    v: <>Lens shows up in Claude as a Custom Connector. No new login, no new place to check. It’s in the chat your team already has open.</>,
  },
];

function SpecSheet({ color }) {
  const c = color || LENS_DEFAULT;
  return (
    <div style={{ padding: '180px 56px 140px' }}>
      <div style={{ width: 1080, margin: '0 auto' }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.2em', color: LENS_BRAND.mute, textTransform: 'uppercase', marginBottom: 28, textAlign: 'center' }}>
          What you’re actually buying
        </div>
        <div style={{ fontFamily: "'Spectral', serif", fontSize: 50, fontWeight: 500, letterSpacing: '-0.024em', lineHeight: 1.08, textAlign: 'center', marginBottom: 80 }}>
          The day you connect <span style={{ color: LENS_BRAND.accent }}>Lens</span> to <span style={{ color: LENS_BRAND.accent }}>Claude</span>,<br/>
          this is in the box.
        </div>
        <div>
          {SPEC_ITEMS.map((it, i) => (
            <div key={it.k} style={{ display: 'grid', gridTemplateColumns: '64px 320px 1fr', gap: 32, alignItems: 'baseline', padding: '36px 0', borderTop: `1px solid ${LENS_BRAND.rule}`, borderBottom: i === SPEC_ITEMS.length - 1 ? `1px solid ${LENS_BRAND.rule}` : 'none' }}>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, color: c, letterSpacing: '0.1em' }}>0{i + 1}</div>
              <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.14em', color: LENS_BRAND.ink }}>{it.k}</div>
              <div style={{ fontFamily: "'Spectral', serif", fontSize: 20, lineHeight: 1.5, color: LENS_BRAND.ink, letterSpacing: '-0.005em' }}>{it.v}</div>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 32, fontSize: 11, color: LENS_BRAND.mute, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.16em', textAlign: 'center', textTransform: 'uppercase' }}>
          Operator preview · invite-only
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  VariantExpressive, LENS_BRAND, LENS_DEFAULT,
  LensMark, BrandChip, PageNav, PrimaryCTA, SecondaryCTA, It, FooterStrip,
  FAQ,
});
