// os-section.jsx — BuildQ Project OS accordion centerpiece.
// Loads 2nd. Exports: window.OSSection

const OS_LAYERS = [
{
  n: "01",
  name: "Large Language Models",
  hint: "Model-agnostic foundation",
  desc: "BuildQ is model-agnostic, selecting the best model for each task. The better the models get, the more ambitious the work we can take on.",
  caps: [
  "Frontier model routing per task",
  "Specialized models for code, math, vision",
  "Continuous model evaluation",
  "Provider redundancy and failover",
  "Inference cost optimization"]

},
{
  n: "02",
  name: "Agentic Harness",
  hint: "Turns general LLMs into infra agents",
  desc: "The orchestration engine that gives BuildQ agents the context, tools, and memory to work like infrastructure specialists.\n\n",
  caps: [
  "Infrastructure-specific reasoning",
  "Multi-step task planning",
  "Tool use and verification loops",
  "Domain-aware prompting",
  "Workflow orchestration"]

},
{
  n: "03",
  name: "Data & Integrations",
  hint: "Lives inside the project, not alongside it",
  desc: "Native integrations with data rooms, DMS, project schedules, utility correspondence, interconnection portals, leases, and financial models. BuildQ lives inside the project, not alongside it.",
  caps: [
  "Data rooms and DMS",
  "Project schedules and milestones",
  "Utility correspondence and portals",
  "Lease and title systems",
  "Financial models and reporting tools"]

},
{
  n: "04",
  name: "Context & Knowledge",
  hint: "600+ projects, 20+ GW of precedent",
  desc: "Project playbooks, transaction precedents, regulatory frameworks, and matter history across every asset class \u2014 CRE, data centers, and energy \u2014 layered into every agent action. Teams inherit the collective experience of 600+ projects and 20+ GW.",
  caps: [
  "Project playbooks across asset classes",
  "Transaction and matter precedents",
  "Regulatory and permitting frameworks",
  "CRE, data center, and energy expertise",
  "Continuously updated knowledge base"]

},
{
  n: "05",
  name: "Expert Network",
  hint: "AI leverage. Human judgment.",
  desc: "In-house validators with deep domain experience and a curated network of specialist partners \u2014 attorneys, EPCs, permitting, interconnection, tax credits, real estate counsel, MEP engineers \u2014 activated when projects hit blockers. AI does the leverage. Humans do the judgment.",
  caps: [
  "In-house validators",
  "Energy and real estate attorneys",
  "EPCs and MEP engineers",
  "Permitting and interconnection specialists",
  "Tax credit and incentive advisors"]

},
{
  n: "06",
  name: "Products & Interfaces",
  hint: "Built from the ground up, for infrastructure",
  desc: "Purpose-built surfaces for every project workflow: diligence, execution, mobilization, and delivery. Built from the ground up, for infrastructure.",
  caps: [
  "Diligence and risk surfaces",
  "Execution control towers",
  "Mobilization and partner workflows",
  "Delivery and reporting views",
  "Custom views per project type"]

},
{
  n: "07",
  name: "Security & Governance",
  hint: "Built in, not bolted on",
  desc: "The foundation that makes Project OS enterprise-ready. Cross-project isolation, audit trails on every AI inference, role-based access, no training on customer data. Built into every layer, not bolted on.",
  caps: [
  "Cross-project isolation",
  "Audit trails on every AI inference",
  "Role-based access controls",
  "No training on customer data",
  "SOC 2 (in progress) \u00b7 GDPR"]

}];


/* Layer thumbnails — small abstract diagrams in monochrome + accent.
   Each is 280x180, designed to feel like a quiet, technical illustration. */
function LayerThumbnail({ n }) {
  const stroke = "var(--fg-2)";
  const dim = "var(--fg-3)";
  const accent = "var(--accent)";
  const common = { width: "100%", viewBox: "0 0 280 180", style: { display: "block" } };

  if (n === "01") {
    // Documents flowing into a node
    return (
      <svg {...common}>
        <g fill="none" stroke={dim} strokeWidth="1">
          {[0, 1, 2, 3, 4].map((i) =>
          <g key={i} transform={`translate(${20 + i * 6}, ${40 + i * 6})`}>
              <rect x="0" y="0" width="70" height="92" rx="2" fill="var(--surface-2)" />
              <line x1="10" y1="18" x2="50" y2="18" />
              <line x1="10" y1="28" x2="60" y2="28" />
              <line x1="10" y1="38" x2="44" y2="38" />
              <line x1="10" y1="52" x2="56" y2="52" />
              <line x1="10" y1="62" x2="38" y2="62" />
            </g>
          )}
        </g>
        <g fill="none" stroke={stroke} strokeWidth="1">
          <path d="M 130 90 Q 170 90 200 90" strokeDasharray="2 3" />
          <path d="M 132 78 Q 168 78 200 90" strokeDasharray="2 3" opacity="0.5" />
          <path d="M 132 102 Q 168 102 200 90" strokeDasharray="2 3" opacity="0.5" />
        </g>
        <circle cx="218" cy="90" r="22" fill="var(--surface-2)" stroke={accent} />
        <circle cx="218" cy="90" r="4" fill={accent} />
        <text x="218" y="138" textAnchor="middle" fill={dim} fontSize="9" fontFamily="var(--font-mono)" letterSpacing="1">
          INGEST
        </text>
      </svg>);

  }
  if (n === "02") {
    // Graph nodes — extracted entities
    return (
      <svg {...common}>
        <g fill="none" stroke={dim} strokeWidth="1">
          <line x1="60" y1="50" x2="140" y2="90" />
          <line x1="60" y1="50" x2="140" y2="40" />
          <line x1="60" y1="130" x2="140" y2="90" />
          <line x1="60" y1="130" x2="140" y2="140" />
          <line x1="140" y1="40" x2="220" y2="55" />
          <line x1="140" y1="90" x2="220" y2="55" />
          <line x1="140" y1="90" x2="220" y2="125" />
          <line x1="140" y1="140" x2="220" y2="125" />
        </g>
        {[
        [60, 50], [60, 130], [140, 40], [140, 140]].
        map(([x, y], i) =>
        <circle key={i} cx={x} cy={y} r="6" fill="var(--surface-2)" stroke={stroke} />
        )}
        <circle cx="140" cy="90" r="8" fill={accent} />
        <circle cx="220" cy="55" r="6" fill="var(--surface-2)" stroke={accent} />
        <circle cx="220" cy="125" r="6" fill="var(--surface-2)" stroke={accent} />
        <text x="140" y="170" textAnchor="middle" fill={dim} fontSize="9" fontFamily="var(--font-mono)" letterSpacing="1">
          ENTITIES · RISKS · LINKS
        </text>
      </svg>);

  }
  if (n === "03") {
    // AI output + human review
    return (
      <svg {...common}>
        <g>
          <rect x="20" y="40" width="100" height="100" rx="2" fill="var(--surface-2)" stroke={dim} />
          <text x="30" y="58" fill={dim} fontSize="8" fontFamily="var(--font-mono)" letterSpacing="0.5">AI · DRAFT</text>
          {[70, 82, 94, 106, 118].map((y, i) =>
          <line key={i} x1="30" y1={y} x2={i % 2 === 0 ? 105 : 90} y2={y} stroke={dim} strokeWidth="1" />
          )}
        </g>
        <path d="M 130 90 L 158 90" stroke={stroke} strokeWidth="1" strokeDasharray="2 3" />
        <g>
          <rect x="160" y="40" width="100" height="100" rx="2" fill="var(--surface-2)" stroke={accent} />
          <text x="170" y="58" fill={accent} fontSize="8" fontFamily="var(--font-mono)" letterSpacing="0.5">EXPERT · ✓</text>
          {[70, 82, 94, 106, 118].map((y, i) =>
          <g key={i}>
              <line x1="170" y1={y} x2={i % 2 === 0 ? 245 : 230} y2={y} stroke={stroke} strokeWidth="1" />
              {i === 1 && <circle cx="252" cy={y} r="2" fill={accent} />}
              {i === 3 && <circle cx="237" cy={y} r="2" fill={accent} />}
            </g>
          )}
        </g>
      </svg>);

  }
  if (n === "04") {
    // Radar / spider chart
    const cx = 140,cy = 90;
    const dims = ["Power", "Permits", "Equip.", "Capital", "Exec.", "COD"];
    const angles = dims.map((_, i) => -Math.PI / 2 + i * 2 * Math.PI / dims.length);
    const ring = (r) => angles.map((a) => [cx + Math.cos(a) * r, cy + Math.sin(a) * r]);
    const poly = (vals) => vals.map((v, i) => {
      const [x, y] = [cx + Math.cos(angles[i]) * v, cy + Math.sin(angles[i]) * v];
      return `${x},${y}`;
    }).join(" ");
    return (
      <svg {...common}>
        {[20, 35, 50, 65].map((r) =>
        <polygon key={r} points={ring(r).map((p) => p.join(",")).join(" ")} fill="none" stroke={dim} strokeWidth="0.5" />
        )}
        {angles.map((a, i) =>
        <line key={i} x1={cx} y1={cy} x2={cx + Math.cos(a) * 65} y2={cy + Math.sin(a) * 65} stroke={dim} strokeWidth="0.5" />
        )}
        <polygon
          points={poly([55, 42, 48, 30, 50, 58])}
          fill="var(--accent-soft)"
          stroke={accent}
          strokeWidth="1.25" />
        
        {ring(65).map(([x, y], i) =>
        <text key={i} x={x} y={y + (y < cy ? -4 : 10)} textAnchor="middle" fill={dim} fontSize="8" fontFamily="var(--font-mono)" letterSpacing="0.5">{dims[i]}</text>
        )}
      </svg>);

  }
  if (n === "05") {
    // Network with one node activating
    return (
      <svg {...common}>
        <g fill="none" stroke={dim} strokeWidth="1">
          <line x1="140" y1="90" x2="60" y2="50" />
          <line x1="140" y1="90" x2="60" y2="130" />
          <line x1="140" y1="90" x2="220" y2="50" />
          <line x1="140" y1="90" x2="220" y2="130" />
          <line x1="140" y1="90" x2="140" y2="30" />
          <line x1="140" y1="90" x2="140" y2="150" />
        </g>
        <line x1="140" y1="90" x2="220" y2="50" stroke={accent} strokeWidth="1.5" />
        {[
        [60, 50], [60, 130], [220, 130], [140, 30], [140, 150]].
        map(([x, y], i) =>
        <g key={i}>
            <circle cx={x} cy={y} r="6" fill="var(--surface-2)" stroke={stroke} />
          </g>
        )}
        <circle cx="220" cy="50" r="8" fill={accent} />
        <circle cx="220" cy="50" r="14" fill="none" stroke={accent} strokeWidth="0.5" opacity="0.6" />
        <circle cx="140" cy="90" r="9" fill="var(--surface-2)" stroke={stroke} strokeWidth="1.5" />
        <text x="218" y="32" textAnchor="middle" fill={accent} fontSize="9" fontFamily="var(--font-mono)" letterSpacing="0.8">PERMIT · ATTY</text>
      </svg>);

  }
  if (n === "06") {
    // Bar / chart dashboard
    return (
      <svg {...common}>
        <rect x="20" y="30" width="240" height="120" rx="2" fill="var(--surface-2)" stroke={dim} />
        <text x="32" y="48" fill={dim} fontSize="8" fontFamily="var(--font-mono)" letterSpacing="0.5">BOARD MEMO · WK 18</text>
        {[
        [40, 80, 30], [70, 80, 50], [100, 80, 38], [130, 80, 62], [160, 80, 44], [190, 80, 70], [220, 80, 56]].
        map(([x, baseY, h], i) =>
        <rect key={i} x={x} y={baseY + (60 - h)} width="14" height={h} fill={i === 5 ? accent : dim} opacity={i === 5 ? 1 : 0.6} />
        )}
        <line x1="32" y1="140" x2="248" y2="140" stroke={dim} strokeWidth="0.5" />
      </svg>);

  }
  if (n === "07") {
    // Audit trail / shield
    return (
      <svg {...common}>
        <g>
          <path d="M 100 35 L 140 28 L 180 35 L 180 100 Q 180 130 140 145 Q 100 130 100 100 Z"
          fill="var(--surface-2)" stroke={accent} strokeWidth="1.25" />
          <text x="140" y="88" textAnchor="middle" fill={accent} fontSize="11" fontFamily="var(--font-mono)" letterSpacing="1.5">SOC 2</text>
          <text x="140" y="104" textAnchor="middle" fill={dim} fontSize="7" fontFamily="var(--font-mono)" letterSpacing="0.5">IN PROGRESS</text>
        </g>
        <g stroke={dim} strokeWidth="0.5">
          {[50, 60, 70, 80, 90, 100, 110, 120].map((y, i) =>
          <line key={i} x1="20" y1={y} x2={i % 2 === 0 ? 80 : 70} y2={y} />
          )}
          {[50, 60, 70, 80, 90, 100, 110, 120].map((y, i) =>
          <line key={i + "r"} x1="200" y1={y} x2={i % 2 === 0 ? 260 : 250} y2={y} />
          )}
        </g>
      </svg>);

  }
  return null;
}

/* Tiny inline icons (60x28) — quick visual marker per layer. */
function LayerIcon({ n, active }) {
  const c = active ? "var(--accent)" : "var(--fg-3)";
  const dim = "var(--border-strong)";
  const common = { width: 60, height: 28, viewBox: "0 0 60 28", style: { display: "block" } };
  if (n === "01") {
    // Stacked model variants
    return (
      <svg {...common}>
        {[6, 12, 18, 24].map((y, i) =>
        <line key={i} x1="8" y1={y} x2={20 + i * 8} y2={y} stroke={i === 1 ? c : dim} strokeWidth="1.25" />
        )}
        <circle cx="52" cy="14" r="3" fill={c} />
      </svg>);

  }
  if (n === "02") {
    // Branching nodes
    return (
      <svg {...common}>
        <line x1="8" y1="14" x2="22" y2="14" stroke={dim} strokeWidth="1" />
        <line x1="22" y1="14" x2="36" y2="6" stroke={dim} strokeWidth="1" />
        <line x1="22" y1="14" x2="36" y2="22" stroke={c} strokeWidth="1.25" />
        <line x1="36" y1="6" x2="50" y2="6" stroke={dim} strokeWidth="1" />
        <line x1="36" y1="22" x2="50" y2="22" stroke={c} strokeWidth="1.25" />
        <circle cx="8" cy="14" r="2" fill={dim} />
        <circle cx="22" cy="14" r="2" fill={c} />
        <circle cx="50" cy="22" r="2.5" fill={c} />
        <circle cx="50" cy="6" r="2" fill={dim} />
      </svg>);

  }
  if (n === "03") {
    // Data flow pipes
    return (
      <svg {...common}>
        {[8, 14, 20].map((y, i) =>
        <line key={i} x1="6" y1={y} x2="38" y2={y} stroke={i === 1 ? c : dim} strokeWidth="1" strokeDasharray="2 2" />
        )}
        <rect x="40" y="6" width="16" height="16" fill="none" stroke={c} strokeWidth="1" />
        <circle cx="48" cy="14" r="1.5" fill={c} />
      </svg>);

  }
  if (n === "04") {
    // Concentric rings
    return (
      <svg {...common}>
        {[10, 7, 4].map((r, i) =>
        <circle key={i} cx="30" cy="14" r={r} fill="none" stroke={i === 0 ? dim : i === 1 ? dim : c} strokeWidth="1" />
        )}
        <circle cx="30" cy="14" r="1.5" fill={c} />
      </svg>);

  }
  if (n === "05") {
    // Network of nodes
    return (
      <svg {...common}>
        <line x1="10" y1="8" x2="30" y2="20" stroke={dim} strokeWidth="0.75" />
        <line x1="30" y1="20" x2="50" y2="8" stroke={c} strokeWidth="1" />
        <line x1="10" y1="20" x2="30" y2="8" stroke={dim} strokeWidth="0.75" />
        <line x1="30" y1="8" x2="50" y2="20" stroke={dim} strokeWidth="0.75" />
        <circle cx="10" cy="8" r="2" fill={dim} />
        <circle cx="10" cy="20" r="2" fill={dim} />
        <circle cx="30" cy="8" r="2" fill={dim} />
        <circle cx="30" cy="20" r="2.5" fill={c} />
        <circle cx="50" cy="8" r="2.5" fill={c} />
        <circle cx="50" cy="20" r="2" fill={dim} />
      </svg>);

  }
  if (n === "06") {
    // Window frames
    return (
      <svg {...common}>
        <rect x="6" y="4" width="22" height="20" fill="none" stroke={dim} strokeWidth="1" />
        <line x1="6" y1="9" x2="28" y2="9" stroke={dim} strokeWidth="0.75" />
        <rect x="32" y="4" width="22" height="20" fill="none" stroke={c} strokeWidth="1.25" />
        <line x1="32" y1="9" x2="54" y2="9" stroke={c} strokeWidth="0.75" />
        <circle cx="36" cy="6.5" r="0.75" fill={c} />
        <circle cx="38.5" cy="6.5" r="0.75" fill={c} />
      </svg>);

  }
  if (n === "07") {
    // Shield with key
    return (
      <svg {...common}>
        <path d="M 22 4 L 30 2 L 38 4 L 38 16 Q 38 22 30 25 Q 22 22 22 16 Z"
        fill="none" stroke={c} strokeWidth="1.25" />
        <line x1="6" y1="14" x2="20" y2="14" stroke={dim} strokeWidth="0.75" strokeDasharray="2 2" />
        <line x1="40" y1="14" x2="54" y2="14" stroke={dim} strokeWidth="0.75" strokeDasharray="2 2" />
      </svg>);

  }
  return null;
}

/* ───────── Architecture stack ─────────
   Replaces the old 3D plates: a single full-width stack of horizontal
   bands, each labeled with its layer number, name, hint, and glyph.
   Active band expands inline with description + capability list. */
function ArchitectureStack({ layers, active, setActive, revealed }) {
  const activeIdx = layers.findIndex((l) => l.n === active);
  return (
    <div
      style={{
        border: "1px solid var(--border-2)",
        borderRadius: 8,
        overflow: "hidden",
        background: "linear-gradient(180deg, var(--bg-2) 0%, var(--surface) 100%)",
        boxShadow: "0 1px 0 rgba(255,255,255,0.04) inset, 0 24px 60px rgba(0,0,0,0.35)"
      }}>
      
      {layers.map((layer, i) => {
        const isActive = i === activeIdx;
        const delay = i * 70;
        return (
          <div
            key={layer.n}
            style={{
              borderTop: i > 0 ? "1px solid var(--border)" : "none",
              background: isActive ?
              "linear-gradient(90deg, rgba(229,162,105,0.08) 0%, rgba(229,162,105,0.00) 70%)" :
              "transparent",
              transition: "background .3s ease"
            }}>
            
            <button
              type="button"
              onClick={() => setActive(layer.n)}
              data-comment-anchor={`os-layer-${layer.n}`}
              style={{
                width: "100%",
                textAlign: "left",
                padding: "22px 28px",
                background: "transparent",
                border: "none",
                borderLeft: `3px solid ${isActive ? "var(--accent)" : "transparent"}`,
                cursor: "pointer",
                display: "grid",
                gridTemplateColumns: "64px 1fr 100px 32px",
                alignItems: "center",
                gap: 24,
                color: "var(--fg)",
                fontFamily: "inherit",
                opacity: revealed ? 1 : 0,
                transform: revealed ? "translateY(0)" : "translateY(8px)",
                transition: `opacity 600ms cubic-bezier(0.22,1,0.36,1) ${delay}ms, transform 600ms cubic-bezier(0.22,1,0.36,1) ${delay}ms, border-color .25s ease`,
                outline: "none"
              }}>
              
              <span
                className="num-serif"
                style={{
                  fontSize: 28,
                  color: isActive ? "var(--accent)" : "var(--fg-3)",
                  transition: "color .25s ease",
                  lineHeight: 1
                }}>
                
                {layer.n}
              </span>
              <div style={{ display: "flex", flexDirection: "column", gap: 4, minWidth: 0 }}>
                <span
                  style={{
                    fontSize: 18,
                    fontWeight: 500,
                    letterSpacing: "-0.01em",
                    color: isActive ? "var(--fg)" : "var(--fg-2)",
                    transition: "color .25s ease"
                  }}>
                  
                  {layer.name}
                </span>
                <span className="muted" style={{ fontSize: 12.5, color: "var(--fg-3)" }}>
                  {layer.hint}
                </span>
              </div>
              <div style={{ display: "flex", justifyContent: "flex-end", opacity: 0.9 }}>
                <LayerIcon n={layer.n} active={isActive} />
              </div>
              <span
                aria-hidden
                style={{
                  width: 24,
                  height: 24,
                  display: "inline-flex",
                  alignItems: "center",
                  justifyContent: "center",
                  color: isActive ? "var(--accent)" : "var(--fg-3)",
                  border: `1px solid ${isActive ? "var(--accent)" : "var(--border-2)"}`,
                  borderRadius: 999,
                  transition: "color .25s ease, border-color .25s ease, transform .3s ease",
                  transform: isActive ? "rotate(45deg)" : "rotate(0deg)"
                }}>
                
                <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
                  <path d="M5 2 V8 M2 5 H8" stroke="currentColor" strokeWidth="1.25" strokeLinecap="round" />
                </svg>
              </span>
            </button>

            {isActive &&
            <div
              style={{
                padding: "0 28px 30px 95px",
                borderLeft: "3px solid var(--accent)",
                animation: "fadeIn .35s ease"
              }}>
              
                <p
                style={{
                  margin: "0 0 22px",
                  fontSize: 15,
                  lineHeight: 1.55,
                  color: "var(--fg-2)",
                  maxWidth: 760
                }}>
                
                  {layer.desc}
                </p>
                <div style={{ display: "none" }}>
                  {layer.caps.map((cap) =>
                <div
                  key={cap}
                  style={{
                    fontSize: 13,
                    color: "var(--fg-2)"
                  }}>
                      {cap}
                    </div>
                )}
                </div>
              </div>
            }
          </div>);

      })}
    </div>);

}


/* ───────── 3D stack reveal + side list ─────────
   Stack animates in on scroll (staggered).
   Hovering a row in the side list highlights its plate.
   The stack itself is decorative — all interaction happens in the list,
   so hover targets are flat and reliable. */

function OSSection({ defaultLayer = "01" }) {
  const [active, setActive] = React.useState(defaultLayer);
  const [revealed, setRevealed] = React.useState(false);
  const sectionRef = React.useRef(null);
  const outerRef = React.useRef(null);

  React.useEffect(() => setActive(defaultLayer), [defaultLayer]);

  React.useEffect(() => {
    if (!sectionRef.current || revealed) return;
    const io = new IntersectionObserver(
      ([entry]) => {if (entry.isIntersecting) setRevealed(true);},
      { threshold: 0.2, rootMargin: "0px 0px -80px 0px" }
    );
    io.observe(sectionRef.current);
    return () => io.disconnect();
  }, [revealed]);

  // Scroll-driven layer progression: as the user scrolls through this
  // section, advance the active layer 01 → 07 based on scroll progress.
  // The outer container is tall; the inner section is sticky-pinned.
  React.useEffect(() => {
    let ticking = false;
    const onScroll = () => {
      if (ticking) return;
      ticking = true;
      requestAnimationFrame(() => {
        ticking = false;
        const outer = outerRef.current;
        if (!outer) return;
        const rect = outer.getBoundingClientRect();
        const viewportH = window.innerHeight;
        const total = rect.height - viewportH;
        if (total <= 0) return;
        const scrolled = Math.max(0, Math.min(total, -rect.top));
        const progress = scrolled / total; // 0 → 1
        const n = OS_LAYERS.length;
        let idx = Math.floor(progress * n);
        if (idx >= n) idx = n - 1;
        if (idx < 0) idx = 0;
        setActive(OS_LAYERS[idx].n);
      });
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, []);

  const activeIdx = Math.max(0, OS_LAYERS.findIndex((l) => l.n === active));
  const progressPct = ((activeIdx + 1) / OS_LAYERS.length) * 100;

  return (
    <div
      ref={outerRef}
      style={{
        position: "relative",
        // Tall enough to give each layer ~35vh of scroll while the inner
        // section is pinned. 7 layers × 35vh + 50vh buffer ≈ 295vh.
        height: `${OS_LAYERS.length * 35 + 50}vh`
      }}>
      <section
        ref={sectionRef}
        data-screen-label="04 Project OS"
        style={{
          position: "sticky",
          top: 0,
          minHeight: "100vh",
          display: "flex",
          flexDirection: "column",
          justifyContent: "center",
          paddingTop: "10vh",
          paddingBottom: "10vh",
          boxSizing: "border-box"
        }}>
        <div className="wrap">
          {/* Header */}
          <div style={{ marginBottom: 48, maxWidth: 760, display: "flex", alignItems: "flex-end", justifyContent: "space-between", flexWrap: "wrap", gap: 24 }}>
            <div>
              <div className="eyebrow" style={{ marginBottom: 18 }}>INTRODUCING</div>
              <h2 className="display display-2" style={{ marginBottom: 22 }}>
                BuildQ Project OS™
              </h2>
              <p className="lede" style={{ maxWidth: 560 }}>The operating engine behind every project.</p>
            </div>
            {/* Scroll progress indicator */}
            <div style={{
              display: "flex", flexDirection: "column", gap: 10, alignItems: "flex-end",
              fontFamily: "var(--font-mono)", color: "var(--fg-3)",
              fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase"
            }}>
              <span>
                Layer <span style={{ color: "var(--accent)" }}>{String(activeIdx + 1).padStart(2, "0")}</span>
                <span style={{ opacity: 0.5 }}> / {String(OS_LAYERS.length).padStart(2, "0")}</span>
              </span>
              <div style={{
                width: 180, height: 2, background: "var(--border)",
                position: "relative", overflow: "hidden", borderRadius: 1,
              }}>
                <div style={{
                  position: "absolute", left: 0, top: 0, bottom: 0,
                  width: `${progressPct}%`,
                  background: "var(--accent)",
                  transition: "width .4s cubic-bezier(0.22,1,0.36,1)",
                }} />
              </div>
            </div>
          </div>

          <ArchitectureStack
            layers={OS_LAYERS}
            active={active}
            setActive={setActive}
            revealed={revealed} />
        </div>
      </section>
    </div>);

}

window.OSSection = OSSection;