// VELOUR marketing site — hero: wordmark entrance, live insight ledger, tilting dashboard preview.
const { Button, Card, ProgressBar, Badge } = window.VelourDesignSystem_380ed4;

// Offset-aware current date (matches the app's VELOUR_DAY_OFFSET) so the preview
// always reads as "today," e.g. "Friday, June 26".
function heroDateLabel() {
  const d = new Date();
  const off = Number(window.VELOUR_DAY_OFFSET) || 0;
  if (off) d.setDate(d.getDate() + off);
  return d.toLocaleDateString(undefined, { weekday: "long", month: "long", day: "numeric" });
}

const vlrReduced = () => window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;

// The insight ledger — the product's voice, one observation at a time. Each line
// re-tints the page accent (--vlr-accent) to its pillar's color.
const HERO_INSIGHTS = [
  { t: "14 days. That's a ritual forming.", p: "Rituals", c: "var(--sage)" },
  { t: "Your beige coat hasn't been worn in 94 days.", p: "Wardrobe", c: "var(--amber)" },
  { t: "Home coffee saved $35 this week.", p: "Efficiency", c: "var(--terracotta)" },
  { t: "Six nights over seven hours. Your best week since March.", p: "Wellness", c: "var(--teal)" },
  { t: "Your navy knit costs $2.59 a wear. It earned its place.", p: "Wardrobe", c: "var(--amber)" },
  { t: "Morning pages, 11 days running. Quietly compounding.", p: "Rituals", c: "var(--sage)" },
];

function InsightLedger() {
  const [i, setI] = React.useState(0);
  const [out, setOut] = React.useState(false);
  React.useEffect(() => {
    if (vlrReduced()) return;
    const iv = setInterval(() => {
      setOut(true);
      setTimeout(() => { setI((x) => (x + 1) % HERO_INSIGHTS.length); setOut(false); }, 480);
    }, 4600);
    return () => clearInterval(iv);
  }, []);
  const n = HERO_INSIGHTS[i];
  React.useEffect(() => { document.documentElement.style.setProperty("--vlr-accent", n.c); }, [i]);
  return (
    <div aria-live="polite" className="vlr-hero-ledger" style={{ marginTop: 40, borderTop: "var(--border-width) solid var(--border)", paddingTop: 22, display: "grid", gridTemplateColumns: "auto 1fr", gap: 24, maxWidth: 560 }}>
      <window.Eyebrow style={{ paddingTop: 7, whiteSpace: "nowrap" }}>This week, VELOUR noticed</window.Eyebrow>
      <div>
        <div style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontSize: 23, lineHeight: 1.35, minHeight: "2.75em", color: "var(--vlr-accent, var(--sage))", opacity: out ? 0 : 1, transform: out ? "translateY(8px)" : "none", transition: "opacity .45s cubic-bezier(.16,1,.3,1), transform .45s cubic-bezier(.16,1,.3,1), color .6s cubic-bezier(.16,1,.3,1)" }}>{n.t}</div>
        <div style={{ fontSize: 11.5, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--text-tertiary)", marginTop: 6, opacity: out ? 0 : 1, transition: "opacity .45s" }}>{n.p}</div>
      </div>
    </div>
  );
}

// The thread — signature element. One line moving through all four pillars:
// it draws itself, the pillar nodes bloom in sequence, and a small ink bead
// travels the day. Nodes are live: hover re-tints the page accent, click
// glides to that pillar's demo.
const THREAD_PATH = "M0,70 C95,70 110,38 190,38 C270,38 285,92 380,92 C475,92 490,38 570,38 C650,38 665,70 760,70";
const THREAD_NODES = [
  { name: "Rituals", color: "var(--sage)", cx: 190, cy: 38, tx: 190, ty: 12, target: "demo-rituals" },
  { name: "Wellness", color: "var(--teal)", cx: 380, cy: 92, tx: 380, ty: 124, target: "demo-wellness" },
  { name: "Wardrobe", color: "var(--amber)", cx: 570, cy: 38, tx: 570, ty: 12, target: "demo-wardrobe" },
  { name: "Efficiency", color: "var(--terracotta)", cx: 760, cy: 70, tx: 742, ty: 100, target: "demo-efficiency" },
];

function PillarThread() {
  const ref = React.useRef(null);
  const [inView, setInView] = React.useState(false);
  const reduced = vlrReduced();
  React.useEffect(() => {
    if (!("IntersectionObserver" in window) || reduced) { setInView(true); return; }
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => { if (e.isIntersecting) { setInView(true); io.disconnect(); } });
    }, { threshold: 0.3 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  const goTo = (target) => {
    const t = document.getElementById(target);
    if (t) t.scrollIntoView({ behavior: reduced ? "auto" : "smooth" });
  };
  const tint = (color) => document.documentElement.style.setProperty("--vlr-accent", color);
  return (
    <div ref={ref} style={{ width: "min(760px, 88vw)", margin: "64px auto 0", textAlign: "center" }}>
      <style>{`
        .vlt-path { fill: none; stroke: var(--border); stroke-width: 1.6; stroke-dasharray: 1200; stroke-dashoffset: 1200; }
        .vlt-in .vlt-path { animation: vltDraw 2.6s cubic-bezier(.16,1,.3,1) .2s forwards; }
        @keyframes vltDraw { to { stroke-dashoffset: 0; } }
        .vlt-node { opacity: 0; cursor: pointer; transform-box: fill-box; transform-origin: center; }
        .vlt-in .vlt-node { animation: vltBloom .9s cubic-bezier(.16,1,.3,1) forwards; }
        .vlt-in .vlt-node:nth-of-type(1) { animation-delay: .7s; } .vlt-in .vlt-node:nth-of-type(2) { animation-delay: 1.15s; }
        .vlt-in .vlt-node:nth-of-type(3) { animation-delay: 1.6s; } .vlt-in .vlt-node:nth-of-type(4) { animation-delay: 2.05s; }
        @keyframes vltBloom { 0% { opacity: 0; transform: scale(.3); } 60% { transform: scale(1.18); } 100% { opacity: 1; transform: scale(1); } }
        .vlt-halo { fill: none; stroke-width: 1; opacity: .35; transform-box: fill-box; transform-origin: center; transition: transform .4s cubic-bezier(.16,1,.3,1), opacity .4s; }
        .vlt-node:focus-visible .vlt-halo { transform: scale(1.4); opacity: .7; }
        @media (hover: hover) and (pointer: fine) {
          .vlt-node:hover .vlt-halo { transform: scale(1.4); opacity: .7; }
        }
        .vlt-node text { font-family: var(--font-sans); font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; fill: var(--text-tertiary); transition: fill .3s; }
        @media (hover: hover) and (pointer: fine) { .vlt-node:hover text { fill: var(--text-primary); } }
        .vlt-bead { opacity: 0; }
        .vlt-in .vlt-bead { animation: vltBeadIn 1s ease 3s forwards; }
        @keyframes vltBeadIn { to { opacity: .8; } }
        .vlt-caption { font-size: 12.5px; letter-spacing: .22em; text-transform: uppercase; color: var(--text-tertiary); margin: 24px 0 0; opacity: 0; }
        .vlt-in .vlt-caption { animation: vltRise 1s cubic-bezier(.16,1,.3,1) 2.6s forwards; }
        @keyframes vltRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
        .vlt-drip { display: block; width: 1px; height: 40px; margin: 14px auto 0; background: linear-gradient(var(--border), transparent); }
        @media (prefers-reduced-motion: reduce) {
          .vlt-path { stroke-dashoffset: 0 !important; animation: none !important; }
          .vlt-node, .vlt-caption { opacity: 1 !important; animation: none !important; }
          .vlt-bead { display: none; }
        }
      `}</style>
      <div className={inView ? "vlt-in" : ""}>
        <svg viewBox="0 0 760 130" role="img" aria-label="One thread connecting Rituals, Wellness, Wardrobe, and Efficiency" style={{ width: "100%", height: "auto", display: "block", overflow: "visible" }}>
          <path className="vlt-path" d={THREAD_PATH} />
          {!reduced && (
            <circle className="vlt-bead" r="3" fill="var(--ink)">
              <animateMotion dur="11s" repeatCount="indefinite" begin="3s" path={THREAD_PATH} />
            </circle>
          )}
          {THREAD_NODES.map((n) => (
            <g key={n.name} className="vlt-node" onClick={() => goTo(n.target)} onMouseEnter={() => tint(n.color)} tabIndex={0} role="link" aria-label={`${n.name} — see it working`}
              onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); goTo(n.target); } }}>
              <circle className="vlt-halo" cx={n.cx} cy={n.cy} r="14" stroke={n.color} />
              <circle cx={n.cx} cy={n.cy} r="7" fill={n.color} />
              <text x={n.tx} y={n.ty} textAnchor="middle">{n.name}</text>
            </g>
          ))}
        </svg>
        <p className="vlt-caption">One thread through the whole day</p>
        <span className="vlt-drip" aria-hidden="true"></span>
      </div>
    </div>
  );
}

// Small animated wordmark — letters rise in one by one on load.
function HeroMark() {
  return (
    <div className="vlr-heromark" aria-label="VELOUR" style={{ fontFamily: "var(--font-serif)", fontWeight: 500, fontSize: 13, letterSpacing: "var(--wordmark-ls)", color: "var(--text-primary)", marginBottom: 26 }}>
      {"VELOUR".split("").map((ch, i) => (
        <span key={i} style={{ display: "inline-block", animationDelay: `${0.15 + i * 0.09}s` }}>{ch}</span>
      ))}
    </div>
  );
}

// The preview's four pillars — each carries its tile figures and the one observation
// VELOUR would surface for it. The floating pair always sits two apart in this order,
// so sage and teal (the deutan floor pair) never appear together.
const PREVIEW_PILLARS = [
  { key: "rituals", label: "Rituals", icon: "sun", color: "var(--sage)", fill: "var(--sage-fill)", onFill: "var(--sage-text)",
    metric: "4 / 6", sub: "held today", target: "demo-rituals",
    insight: "Fourteen days of morning pages. That's a ritual forming." },
  { key: "wellness", label: "Wellness", icon: "heart", color: "var(--teal)", fill: "var(--teal-fill)", onFill: "var(--teal-text)",
    metric: "In rhythm", sub: "7h 20m sleep", target: "demo-wellness",
    insight: "You slept 40 minutes longer on the nights you walked." },
  { key: "wardrobe", label: "Wardrobe", icon: "coat-hanger", color: "var(--amber)", fill: "var(--amber-fill)", onFill: "var(--amber-text)",
    metric: "$1.40", sub: "avg cost / wear", target: "demo-wardrobe",
    insight: "Your beige coat hasn't been worn in 94 days." },
  { key: "efficiency", label: "Efficiency", icon: "coins", color: "var(--terracotta)", fill: "var(--terracotta-fill)", onFill: "var(--terracotta-text)",
    metric: "$470", sub: "kept this month", target: "demo-efficiency",
    insight: "Coffee at home kept $35 this week." },
];

// A single pillar stat tile inside the dashboard preview. Lit on hover or focus:
// it lifts, takes its pillar's border, and summons that pillar's observation above.
function HeroStatTile({ p, lit, dim, onHold, onRelease, onOpen }) {
  return (
    <div
      role="link" tabIndex={0}
      aria-label={`${p.label}: ${p.metric}, ${p.sub} — see it working`}
      onMouseEnter={onHold} onFocus={onHold} onBlur={onRelease}
      onClick={onOpen}
      onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onOpen(); } }}
      style={{
        background: "var(--surface-card)",
        border: `var(--border-width) solid ${lit ? p.color : "var(--border)"}`,
        borderRadius: 14, padding: "13px 14px", cursor: "pointer", outline: "none",
        transform: lit ? "translateY(-3px)" : "none",
        boxShadow: lit ? "var(--shadow-lg)" : "none",
        opacity: dim ? 0.7 : 1,
        transition: "transform .45s cubic-bezier(.16,1,.3,1), border-color .45s, box-shadow .45s, opacity .45s",
      }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 9 }}>
        <span style={{ width: 24, height: 24, borderRadius: 7, background: p.fill, display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
          <i className={`ph ph-${p.icon}`} style={{ fontSize: 13, color: p.color }}></i>
        </span>
        <span style={{ fontSize: 11, color: lit ? "var(--text-secondary)" : "var(--text-tertiary)", letterSpacing: "0.02em", transition: "color .45s" }}>{p.label}</span>
      </div>
      <div style={{ fontFamily: "var(--font-serif)", fontSize: 19, color: "var(--text-primary)", letterSpacing: "-0.01em", lineHeight: 1.1, whiteSpace: "nowrap" }}>{p.metric}</div>
      <div style={{ fontSize: 10.5, color: "var(--text-tertiary)", marginTop: 3, whiteSpace: "nowrap" }}>{p.sub}</div>
    </div>
  );
}

// A floating observation. Serif italic is the reflective register, so the insight
// itself is set in it — the one thing on the card that is VELOUR speaking.
function HeroInsightCard({ p, out, delay }) {
  const fade = {
    opacity: out ? 0 : 1,
    transform: out ? "translateY(6px)" : "none",
    transition: `opacity .42s cubic-bezier(.16,1,.3,1) ${delay}, transform .42s cubic-bezier(.16,1,.3,1) ${delay}`,
  };
  return (
    <Card variant="featured" pillar={p.key} padding={14}
      style={{ boxShadow: "var(--shadow-lg)", transition: "border-color .6s cubic-bezier(.16,1,.3,1), background .6s cubic-bezier(.16,1,.3,1)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 6, ...fade }}>
        <i className={`ph ph-${p.icon}`} style={{ fontSize: 14, color: p.color }}></i>
        <span style={{ fontSize: 9.5, letterSpacing: "0.14em", textTransform: "uppercase", color: p.onFill, fontWeight: 500 }}>Velour insight</span>
      </div>
      <div style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontSize: 14, lineHeight: 1.36, color: "var(--text-primary)", minHeight: "2.72em", ...fade }}>{p.insight}</div>
    </Card>
  );
}

// Layered dashboard sneak-peek that answers the cursor: the whole stack tilts in
// perspective, the floating observations drift at their own depths, and the four
// tiles are live — hover one and it summons that pillar's insight, click it and the
// page glides to that pillar working for real. Left alone, the pair cycles by itself,
// so the composition is already moving when someone first lands.
function HeroAppPreview() {
  const ref = React.useRef(null);
  const swap = React.useRef(null);
  const reduced = vlrReduced();
  const [i, setI] = React.useState(0);
  const [out, setOut] = React.useState(false);
  const [lit, setLit] = React.useState(null);

  React.useEffect(() => () => { if (swap.current) clearTimeout(swap.current); }, []);

  // At rest the pair advances on its own; a held tile pins it until release.
  React.useEffect(() => {
    if (reduced || lit !== null) return;
    const iv = setInterval(() => {
      setOut(true);
      swap.current = setTimeout(() => { setI((x) => (x + 1) % PREVIEW_PILLARS.length); setOut(false); }, 420);
    }, 5200);
    return () => clearInterval(iv);
  }, [reduced, lit]);

  const swapTo = (next) => {
    if (swap.current) clearTimeout(swap.current);
    if (reduced) { setI(next); setOut(false); return; }
    setOut(true);
    swap.current = setTimeout(() => { setI(next); setOut(false); }, 300);
  };

  const hold = (idx) => {
    setLit(idx);
    document.documentElement.style.setProperty("--vlr-accent", PREVIEW_PILLARS[idx].color);
    if (idx !== i) swapTo(idx);
  };
  const release = () => setLit(null);
  const open = (target) => {
    const t = document.getElementById(target);
    if (t) t.scrollIntoView({ behavior: reduced ? "auto" : "smooth" });
  };

  const onMove = (e) => {
    const el = ref.current;
    if (!el || reduced) return;
    const r = el.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width - 0.5;
    const y = (e.clientY - r.top) / r.height - 0.5;
    el.style.transform = `perspective(1100px) rotateX(${(-y * 6.5).toFixed(2)}deg) rotateY(${(x * 8.5).toFixed(2)}deg)`;
    el.querySelectorAll("[data-depth]").forEach((f) => {
      const d = +f.dataset.depth;
      f.style.transform = `translate3d(${(x * d).toFixed(1)}px, ${(y * d).toFixed(1)}px, 0)`;
    });
  };
  const onLeave = () => {
    const el = ref.current;
    if (!el) return;
    el.style.transform = "perspective(1100px)";
    el.querySelectorAll("[data-depth]").forEach((f) => { f.style.transform = "none"; });
    release();
  };

  const focus = PREVIEW_PILLARS[i];
  const second = PREVIEW_PILLARS[(i + 2) % PREVIEW_PILLARS.length];

  return (
    <div ref={ref} onMouseMove={onMove} onMouseLeave={onLeave} className="vhp-stack" style={{ position: "relative", margin: "0 auto", transition: "transform .4s cubic-bezier(.16,1,.3,1)", willChange: "transform" }}>
      <style>{`
        .vhp-stack { width: min(404px, 100%); }
        /* The wash sits wider than the panel on purpose. Once the stack is the full
           width of a phone there is nothing either side to sit in, so it pulls in. */
        .vhp-glow { top: -26px; left: -22px; right: -34px; bottom: -34px; }
        @media (max-width: 640px) { .vhp-glow { left: -10px; right: -10px; } }
        .vhp-rise { opacity: 0; transform: translateY(24px); animation: vhpRise .9s cubic-bezier(.16,1,.3,1) forwards; }
        .vhp-panel { animation-delay: .2s; }
        /* Positions live here rather than inline so the small-screen rules below can
           actually win — an inline style beats a media query every time. */
        .vhp-one { position: absolute; z-index: 2; top: -58px; right: -26px; width: 200px; animation-delay: .62s; }
        .vhp-two { position: absolute; z-index: 2; bottom: -78px; left: -64px; width: 214px; animation-delay: .8s; }
        @keyframes vhpRise { to { opacity: 1; transform: none; } }
        .vhp-drift-a { animation: vhpDriftA 7.5s ease-in-out infinite; }
        .vhp-drift-b { animation: vhpDriftB 9.5s ease-in-out infinite; }
        @keyframes vhpDriftA { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
        @keyframes vhpDriftB { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
        /* Under ~640px there is no gutter left for the cards to hang into, so floating
           them stops meaning depth and starts meaning collision — they land on the
           panel's own headline and tiles. Below the break they simply stack: one
           observation above the day, one below, both full width and readable. */
        @media (max-width: 640px) {
          .vhp-stack { display: flex; flex-direction: column; gap: 14px; }
          .vhp-one, .vhp-two { position: static; width: 100%; }
          .vhp-one { order: 1; }
          .vhp-panel { order: 2; }
          .vhp-two { order: 3; }
          .vhp-drift-a, .vhp-drift-b { animation: none; }
        }
        @media (prefers-reduced-motion: reduce) {
          .vhp-rise { opacity: 1 !important; transform: none !important; animation: none !important; }
          .vhp-drift-a, .vhp-drift-b { animation: none !important; }
        }
      `}</style>

      {/* soft pillar-tinted backdrop anchoring the stack */}
      <div aria-hidden="true" className="vhp-glow" style={{ position: "absolute", borderRadius: 40, background: "linear-gradient(135deg, var(--sage-fill) 0%, var(--amber-fill) 55%, var(--teal-fill) 100%)", opacity: 0.55, zIndex: 0 }} />

      {/* primary dashboard panel */}
      <div className="vhp-rise vhp-panel" style={{ position: "relative", zIndex: 1 }}>
        <div style={{ background: "var(--surface-card)", border: "var(--border-width) solid var(--border)", borderRadius: 26, padding: 24, boxShadow: "var(--shadow-xl)" }}>
          <window.Eyebrow color="var(--sage)" style={{ fontSize: 10.5 }}>{heroDateLabel()}</window.Eyebrow>
          <div style={{ fontFamily: "var(--font-serif)", fontWeight: 500, fontSize: 25, letterSpacing: "-0.01em", color: "var(--text-primary)", margin: "8px 0 4px", lineHeight: 1.12, textWrap: "balance" }}>Room for what feels like you.</div>
          <div style={{ display: "flex", alignItems: "flex-start", gap: 7, marginBottom: 18 }}>
            <i className="ph ph-sparkle" style={{ fontSize: 13, color: "var(--sage)", marginTop: 2, flexShrink: 0 }}></i>
            <span style={{ fontSize: 12.5, lineHeight: 1.4, color: "var(--text-secondary)" }}>Day 128 with VELOUR — quietly building.</span>
          </div>
          <div onMouseLeave={release} style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 11 }}>
            {PREVIEW_PILLARS.map((p, idx) => (
              <HeroStatTile key={p.key} p={p} lit={lit === idx} dim={lit !== null && lit !== idx}
                onHold={() => hold(idx)} onRelease={release} onOpen={() => open(p.target)} />
            ))}
          </div>
        </div>
      </div>

      {/* floating observation — top-right, deepest layer */}
      <div className="vhp-rise vhp-one">
        <div data-depth="26" style={{ transition: "transform .3s cubic-bezier(.16,1,.3,1)" }}>
          <div className="vhp-drift-a"><HeroInsightCard p={focus} out={out} delay="0s" /></div>
        </div>
      </div>

      {/* Floating observation — bottom-left, nearer layer, half a beat behind. It clears
          the tile row deliberately: the tiles are hoverable now, so a card resting over
          one would eat the interaction it is meant to advertise. */}
      <div className="vhp-rise vhp-two">
        <div data-depth="14" style={{ transition: "transform .3s cubic-bezier(.16,1,.3,1)" }}>
          <div className="vhp-drift-b"><HeroInsightCard p={second} out={out} delay=".12s" /></div>
        </div>
      </div>
    </div>
  );
}

function Hero() {
  const scrollToPillars = () => {
    const t = document.getElementById("pillars");
    if (t) t.scrollIntoView({ behavior: vlrReduced() ? "auto" : "smooth" });
  };
  return (
    <window.Section pad={84} style={{ paddingTop: 64 }}>
      <style>{`
        :root { --vlr-accent: var(--sage); }
        .vlr-heromark span { opacity: 0; transform: translateY(10px); animation: vlrLetter .7s cubic-bezier(.16,1,.3,1) forwards; }
        @keyframes vlrLetter { to { opacity: 1; transform: none; } }
        .vlr-hero-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 64px; align-items: center; }
        .vlr-hero-h1 { font-size: 64px; }
        .vlr-hero-visual { padding: 36px 0 44px; }
        /* The preview is a fixed 404px stack with cards hanging off both sides, so it
           cannot share a row with the copy once the column would be narrower than the
           card itself. Below the break the two stack and the preview centres. */
        @media (max-width: 900px) {
          .vlr-hero-grid { grid-template-columns: 1fr; gap: 44px; }
          .vlr-hero-h1 { font-size: 52px; }
          .vlr-hero-visual { padding: 8px 0 44px; }
        }
        @media (max-width: 540px) {
          .vlr-hero-h1 { font-size: 40px; }
          .vlr-hero-ledger { grid-template-columns: 1fr !important; gap: 10px !important; }
          .vlr-hero-proof { flex-wrap: wrap; gap: 10px !important; }
          .vlr-hero-proof span[aria-hidden="true"] { display: none; }
        }
        @media (prefers-reduced-motion: reduce) { .vlr-heromark span { opacity: 1; transform: none; animation: none; } }
      `}</style>
      <div className="vlr-hero-grid">
        <div>
          <HeroMark />
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 20 }}>
            <span aria-hidden="true" style={{ display: "flex", gap: 6 }}>
              {["var(--sage)", "var(--teal)", "var(--amber)", "var(--terracotta)"].map((c) => (
                <i key={c} style={{ width: 7, height: 7, borderRadius: "50%", background: c }}></i>
              ))}
            </span>
            <window.Eyebrow color="var(--text-tertiary)">Rituals · Wellness · Wardrobe · Efficiency</window.Eyebrow>
          </div>
          <h1 className="vlr-hero-h1" style={{ fontFamily: "var(--font-serif)", fontWeight: 500, lineHeight: 1.04, letterSpacing: "-0.025em", color: "var(--text-primary)", margin: 0, textWrap: "balance" }}>Soft systems.<br /><span style={{ fontStyle: "italic", fontWeight: 400, color: "var(--text-tertiary)" }}>Sharp life.</span></h1>
          <InsightLedger />
          <div style={{ display: "flex", gap: 14, marginTop: 36, alignItems: "center", flexWrap: "wrap" }}>
            <Button size="lg" iconRight="arrow-right" onClick={() => window.velourOpenSignup && window.velourOpenSignup()}>Begin your first ritual</Button>
            <Button size="lg" variant="ghost" onClick={scrollToPillars}>See the four pillars</Button>
          </div>
          <div className="vlr-hero-proof" style={{ display: "flex", alignItems: "center", gap: 18, marginTop: 30, color: "var(--text-tertiary)", fontSize: 13.5 }}>
            {/* Was "4.9 on the App Store". VELOUR has never shipped to the App Store,
                and there is no rating to average. Anything standing here has to be a
                claim about the product itself, not about an audience it does not have. */}
            <span style={{ display: "flex", alignItems: "center", gap: 7 }}><i className="ph ph-check" style={{ color: "var(--amber)" }}></i> Nothing to keep up with</span>
            <span style={{ width: 4, height: 4, borderRadius: "50%", background: "var(--border-strong)" }}></span>
            <span>Free to start, and free to stay.</span>
          </div>
        </div>
        <div className="vlr-hero-visual"><HeroAppPreview /></div>
      </div>
      <PillarThread />
    </window.Section>
  );
}

window.Hero = Hero;
