const { useState, useEffect, useRef, useMemo } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "acid",
  "intensity": "loud",
  "glitch": true,
  "showCursor": true
} /*EDITMODE-END*/;

const ACCENT_MAP = {
  acid: { hex: "#c8ff2e", name: "ACID GREEN" },
  magenta: { hex: "#ff2bd6", name: "HOT MAGENTA" },
  blood: { hex: "#ff3b1f", name: "BLOOD ORANGE" },
  cyan: { hex: "#2bf3ff", name: "CRT CYAN" }
};

// ---------- shared bits ----------
function Marquee({ children, speed = 40, reverse = false, accent }) {
  const items = Array(8).fill(0);
  return (
    <div style={{
      overflow: "hidden",
      borderTop: "1px solid " + accent,
      borderBottom: "1px solid " + accent,
      background: "var(--ink)",
      position: "relative"
    }}>
      <div style={{
        display: "flex",
        whiteSpace: "nowrap",
        animation: `marquee-${reverse ? 'r' : 'l'} ${speed}s linear infinite`,
        willChange: "transform"
      }}>
        {items.map((_, i) =>
        <span key={i} className="display" style={{
          fontSize: 48, lineHeight: 1, padding: "14px 0",
          color: i % 2 ? accent : "var(--paper)",
          display: "inline-flex", alignItems: "center", gap: 24, paddingRight: 48
        }}>
            {children}
            <span style={{ width: 14, height: 14, background: i % 2 ? "var(--paper)" : accent, borderRadius: 999 }} />
          </span>
        )}
      </div>
      <style>{`
        @keyframes marquee-l { from{transform:translateX(0)} to{transform:translateX(-50%)} }
        @keyframes marquee-r { from{transform:translateX(-50%)} to{transform:translateX(0)} }
      `}</style>
    </div>);

}

function Tombstone({ name, born, died, epitaph, cause, accent }) {
  return (
    <div style={{
      position: "relative",
      background: "var(--paper)",
      color: "var(--ink)",
      padding: "36px 28px 32px",
      borderRadius: "140px 140px 8px 8px",
      boxShadow: "inset 0 -6px 0 rgba(0,0,0,.15), 0 30px 0 -20px rgba(0,0,0,.4)",
      textAlign: "center",
      fontFamily: '"Newsreader",serif',
      minHeight: 380,
      display: "flex", flexDirection: "column", justifyContent: "space-between"
    }}>
      <div>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", opacity: .55 }}>† R.I.P †</div>
        <div className="display" style={{ fontSize: 34, lineHeight: 0.95, marginTop: 10, letterSpacing: "-0.03em" }}>
          {name}
        </div>
        <div className="mono" style={{ fontSize: 11, marginTop: 10, opacity: .7 }}>
          {born} — {died}
        </div>
        <div style={{
          margin: "18px auto", height: 1, width: 60, background: "var(--ink)", opacity: .3
        }} />
        <div style={{ fontStyle: "italic", fontSize: 15, lineHeight: 1.35, opacity: .8 }}>
          “{epitaph}”
        </div>
      </div>
      <div className="mono" style={{
        marginTop: 18, fontSize: 10, letterSpacing: "0.15em",
        padding: "6px 8px", border: "1px solid rgba(0,0,0,.4)",
        display: "inline-block", alignSelf: "center"
      }}>
        CAUSE OF DEATH — {cause}
      </div>
      <div aria-hidden style={{
        position: "absolute", top: 18, left: "50%", transform: "translateX(-50%)",
        width: 32, height: 32, color: accent, fontSize: 24, lineHeight: 1
      }}>✟</div>
    </div>);

}

function TerminalCard({ title, lines, accent }) {
  return (
    <div style={{
      background: "#0e0d0a",
      border: "1px solid #1f1d18",
      borderRadius: 6,
      fontFamily: '"JetBrains Mono",monospace',
      overflow: "hidden",
      boxShadow: "0 0 0 1px rgba(255,255,255,.03), 0 30px 80px -40px " + accent + "55"
    }}>
      <div style={{
        display: "flex", alignItems: "center", gap: 8,
        padding: "10px 14px", borderBottom: "1px solid #1f1d18",
        background: "#0a0907"
      }}>
        <span style={{ width: 10, height: 10, borderRadius: 99, background: "#ff5f56" }} />
        <span style={{ width: 10, height: 10, borderRadius: 99, background: "#ffbd2e" }} />
        <span style={{ width: 10, height: 10, borderRadius: 99, background: "#27c93f" }} />
        <span style={{ flex: 1, textAlign: "center", fontSize: 11, color: "#7d7567", letterSpacing: "0.1em" }}>{title}</span>
      </div>
      <div style={{ padding: "18px 18px 22px", fontSize: 13, lineHeight: 1.6 }}>
        {lines.map((l, i) =>
        <div key={i} style={{ color: l.c || "var(--paper-dim)" }}>
            {l.p && <span style={{ color: accent }}>{l.p} </span>}
            {l.t}
          </div>
        )}
      </div>
    </div>);

}

// ---------- sections ----------
function TopBar({ accent }) {
  return (
    <div style={{
      display: "flex", alignItems: "center", justifyContent: "space-between",
      padding: "18px 28px", borderBottom: "1px solid #1a1815",
      position: "sticky", top: 0, zIndex: 50,
      background: "rgba(10,9,7,0.85)", backdropFilter: "blur(8px)"
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
        <div className="display" style={{ fontSize: 22, letterSpacing: "-0.03em" }}>
          let<span style={{ color: accent }}>.rip</span>
        </div>
        <div className="mono" style={{ fontSize: 10, opacity: .5, padding: "4px 8px", border: "1px solid #2a2722" }}>
          PRE-LAUNCH · BUILD 0.0.1
        </div>
      </div>
      <div className="mono" style={{ display: "flex", gap: 24, fontSize: 11, letterSpacing: "0.12em" }}>
        <a href="#manifesto" style={{ textDecoration: "none", opacity: .7 }}>MANIFESTO</a>
        <a href="#system" style={{ textDecoration: "none", opacity: .7 }}>SYSTEM</a>
        <a href="#waitlist" style={{ textDecoration: "none", color: accent }}>JOIN WAITLIST →</a>
      </div>
    </div>);

}

function Hero({ accent, glitch }) {
  const [count, setCount] = useState(2847);
  useEffect(() => {
    const t = setInterval(() => setCount((c) => c + (Math.random() < 0.3 ? 1 : 0)), 1800);
    return () => clearInterval(t);
  }, []);
  return (
    <section style={{
      position: "relative",
      padding: "36px 28px 32px",
      borderBottom: "1px solid #1a1815",
      overflow: "hidden",
      minHeight: "calc(100svh - 57px)",
      display: "flex",
      flexDirection: "column"
    }}>
      {/* grid bg */}
      <div aria-hidden style={{
        position: "absolute", inset: 0,
        backgroundImage: "linear-gradient(rgba(236,229,212,0.04) 1px,transparent 1px), linear-gradient(90deg, rgba(236,229,212,0.04) 1px,transparent 1px)",
        backgroundSize: "40px 40px",
        maskImage: "radial-gradient(ellipse at center, black 20%, transparent 75%)",
        pointerEvents: "none"
      }} />
      <div style={{ maxWidth: 1280, margin: "0 auto", position: "relative", width: "100%", flex: 1, display: "flex", flexDirection: "column", justifyContent: "space-between", gap: "min(48px, 4vh)" }}>
        <div>
        <div className="mono" style={{
            display: "inline-flex", alignItems: "center", gap: 10,
            fontSize: 11, letterSpacing: "0.2em",
            padding: "6px 10px", border: "1px solid " + accent, color: accent
          }}>
          <span style={{ width: 8, height: 8, background: accent, borderRadius: 99, boxShadow: "0 0 12px " + accent }} />
          OBITUARY EDITION · MMXXVI
        </div>

        <h1 className="display" style={{
            fontSize: "min(4.2vw, 9vh)",
            lineHeight: 0.95,
            margin: "min(20px, 2vh) 0 0",
            letterSpacing: "-0.045em",
            textWrap: "balance"
          }}>
          <span style={{ color: accent }}>THE IDE IS DEAD.</span><br />
          <span style={{
              color: "#ffffff", fontFamily: "\"Archivo Black\""
            }}>CURSOR WAS LIFE SUPPORT<br /><span style={{ color: "#ffffff" }}>- A FOSSIL WITH A CHAT PANEL .</span>

            </span><br />
          <span style={{ color: accent }}>LET RIP.</span><br />
          <span style={{ color: "#ffffff" }}></span>
        </h1>
        </div>

        <div style={{
          display: "grid", gridTemplateColumns: "1.2fr 1fr", gap: 48,
          alignItems: "end"
        }}>
          <div>
            <p className="mono" style={{ fontSize: 12, marginTop: "min(22px, 2vh)", opacity: .55, maxWidth: 540, lineHeight: 1.6 }}>
               <span style={{ color: accent }}></span>
            </p>
            <div style={{ display: "flex", gap: 12, marginTop: "min(28px, 2.4vh)", flexWrap: "wrap", alignItems: "center" }}>
              <a href="#waitlist" style={{
                textDecoration: "none",
                background: accent, color: "var(--ink)",
                padding: "16px 26px",
                fontFamily: '"Archivo Black",sans-serif',
                fontSize: 15, letterSpacing: "0.05em",
                display: "inline-flex", alignItems: "center", gap: 10
              }}>CLAIM YOUR RIDE →

              </a>
              <a href="#manifesto" style={{
                textDecoration: "none",
                border: "1px solid var(--paper)", color: "var(--paper)",
                padding: "16px 26px",
                fontFamily: '"JetBrains Mono",monospace',
                fontSize: 12, letterSpacing: "0.12em"
              }}>
                READ THE MANIFESTO
              </a>
            </div>
            <div className="mono" style={{ marginTop: "min(20px, 1.8vh)", fontSize: 11, opacity: .55 }}>
              <span style={{ color: accent }}>●</span> {count.toLocaleString()} engineers have buried their IDE
            </div>
          </div>

          {/* tombstone visual */}
          <div style={{ position: "relative", height: "min(480px, 56vh)", minHeight: 240 }}>
            <div style={{
              position: "absolute", inset: 0,
              display: "flex", justifyContent: "center", alignItems: "flex-end"
            }}>
              <img
                src="assets/surfboard-tombstone.png"
                alt="Surfboard tombstone: IDE died of nostalgia"
                style={{
                  width: "100%",
                  maxWidth: 560,
                  height: "100%",
                  objectFit: "contain",
                  objectPosition: "bottom",
                  filter: "drop-shadow(0 40px 30px rgba(0,0,0,0.5))"
                }} />
              
            </div>
          </div>
        </div>
      </div>
      {glitch &&
      <style>{`
          @keyframes glitch-x { 0%,90%,100%{transform:translate(0,0)} 92%{transform:translate(-2px,0)} 94%{transform:translate(2px,-1px)} 96%{transform:translate(-1px,1px)} }
          h1.display { animation: glitch-x 5s infinite }
        `}</style>
      }
    </section>);

}

function Graveyard({ accent }) {
  const stones = [
  { name: "VS CODE", born: "2015", died: "2026", epitaph: "A fine place to read code. Not a place to ship it.", cause: "EXTENSION FATIGUE" },
  { name: "CURSOR", born: "2023", died: "2026", epitaph: "Believed agent-mode would save it. It tried.", cause: "STUCK BETWEEN ERAS" },
  { name: "JETBRAINS", born: "2000", died: "2026", epitaph: "Indexed itself to death.", cause: "COULDN\u2019T LET GO" },
  { name: "VIM", born: "1991", died: "\u221e", epitaph: "Survived out of spite. Still in the terminal. We respect that.", cause: "NATURAL CAUSES" },
  { name: "WINDSURF", born: "2024", died: "2026", epitaph: "Got picked up. Got put down.", cause: "ACQUIRED & FORGOTTEN" },
  { name: "COPILOT", born: "2021", died: "2026", epitaph: "Autocompleted itself into obsolescence.", cause: "MISTOOK SUGGESTION FOR DIRECTION" },
  { name: "LOVABLE", born: "2023", died: "2026", epitaph: "Lovely little landing pages. No way to ship a real product.", cause: "TOY CEILING" },
  { name: "v0 / BOLT / REPLIT", born: "2023", died: "2026", epitaph: "Demoware. Couldn\u2019t survive a real codebase.", cause: "DEMO COLLAPSE" }];

  return (
    <section id="graveyard" style={{
      borderBottom: "1px solid #1a1815",
      background: "#070604",
      padding: "100px 28px 120px",
      position: "relative",
      overflow: "hidden"
    }}>
      <div aria-hidden style={{
        position: "absolute", inset: "auto 0 0 0", height: 120,
        background: "linear-gradient(to top, #1a1815, transparent)"
      }} />
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", marginBottom: 48, gap: 24, flexWrap: "wrap" }}>
          <div>
            <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", color: accent, marginBottom: 10 }}>
              § 01 — THE GRAVEYARD
            </div>
            <h2 className="display" style={{ fontSize: "clamp(48px,7vw,96px)", margin: 0, lineHeight: 0.9, letterSpacing: "-0.04em", maxWidth: 1100 }}>
              EVERY TOOL YOU<br />OUTGREW DESERVES A FUNERAL.
            </h2>
          </div>
          <p style={{ maxWidth: 380, opacity: .7, fontSize: 16, lineHeight: 1.5, margin: 0 }}>
            We held the wake so you don&apos;t have to. Pay your respects. Then go and build the future.
          </p>
        </div>

        <div style={{
          display: "grid",
          gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))",
          gap: 28
        }}>
          {stones.map((s) => <Tombstone key={s.name} {...s} accent={accent} />)}
        </div>
      </div>
    </section>);

}

function Manifesto({ accent }) {
  return (
    <section id="manifesto" style={{
      background: "var(--paper)", color: "var(--ink)",
      padding: "120px 28px"
    }}>
      <div style={{ maxWidth: 1180, margin: "0 auto" }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.25em", opacity: .55 }}>
          THE IDE.RIP DAILY — VOL. I, NO. 1 — A WAKE
        </div>
        <div style={{ borderTop: "4px double var(--ink)", borderBottom: "1px solid var(--ink)", margin: "10px 0", padding: "4px 0" }}>
          <div style={{ display: "flex", justifyContent: "space-between", fontFamily: '"JetBrains Mono",monospace', fontSize: 11 }}>
            <span>EST. 2026</span>
            <span>OBITUARY EDITION</span>
            <span>PRICE: FREE</span>
          </div>
        </div>

        <h2 className="display" style={{
          fontSize: "clamp(48px,7.5vw,112px)",
          margin: "24px 0 8px",
          lineHeight: 0.9,
          letterSpacing: "-0.045em",
          textAlign: "center"
        }}>
          A MANIFESTO<br />FOR THE POST-EDITOR ERA.
        </h2>
        <div style={{ textAlign: "center", fontStyle: "italic", fontSize: 16, opacity: .7, marginBottom: 64 }}>
          Read aloud. Slowly. Then close your IDE.
        </div>

        <div style={{
          maxWidth: 720, margin: "0 auto",
          fontFamily: '"Newsreader",Georgia,serif',
          fontSize: 18, lineHeight: 1.55
        }}>
          <h3 className="display" style={{
            fontSize: "clamp(28px,3.4vw,40px)", lineHeight: 1.05,
            letterSpacing: "-0.025em", margin: "0 0 18px"
          }}>
            Syntax was never the genius.
          </h3>
          <p style={{ margin: "0 0 18px" }}>
            <span className="display" style={{ fontSize: 64, float: "left", lineHeight: 0.82, paddingRight: 10, paddingTop: 4 }}>L</span>
            earning syntax, like learning a language, means you can communicate. You can speak. Nothing more.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            Every good developer, CTO, seasoned product manager knows that great software is in planning, database design, software architecture and user experience.{" "}
            <code style={{
              fontFamily: '"JetBrains Mono",monospace', fontSize: 15,
              background: "rgba(10,9,7,0.08)", padding: "2px 6px"
            }}>if(you can only write the code) {"{"} you were crap anyway {"}"}</code>.
            The genius was elsewhere.
          </p>
          <p style={{ margin: "0 0 24px" }}>
            If AI is exceptional at speaking syntax — in a post-AI world, IDEs are dead. The genius you can bring is product direction.
          </p>
          <p className="display" style={{
            fontSize: "clamp(28px,3.6vw,44px)", letterSpacing: "-0.02em",
            margin: "0 0 8px"
          }}>
            <span style={{ background: accent, padding: "0 10px" }}>LET RIP.</span>
          </p>

          <hr style={{ border: "none", borderTop: "1px solid rgba(10,9,7,0.25)", margin: "48px 0" }} />

          <h3 className="display" style={{
            fontSize: "clamp(28px,3.4vw,40px)", lineHeight: 1.05,
            letterSpacing: "-0.025em", margin: "0 0 18px"
          }}>
            AI is not new.
          </h3>
          <p style={{ margin: "0 0 18px", fontStyle: "italic", fontSize: 21, lineHeight: 1.4 }}>
            “I've been using AI for 20 years. It just used to cost £180k a year and need a 1:1 every fortnight.”
          </p>
          <p style={{ margin: "0 0 18px" }}>
            Chief product officers have been using “AI” for years. It just used to be a team of engineers and designers that needed prompting.
          </p>
          <p style={{ margin: "0 0 24px" }}>
            The new team is Claude, Codex, et al. Faster. Still screws up. Still needs management. But when you LET RIP, a production-ready product can now be achieved in days.
          </p>
          <p className="display" style={{
            fontSize: "clamp(28px,3.6vw,44px)", letterSpacing: "-0.02em",
            margin: "0 0 8px"
          }}>
            <span style={{ background: accent, padding: "0 10px" }}>LET RIP.</span>
          </p>

          <hr style={{ border: "none", borderTop: "1px solid rgba(10,9,7,0.25)", margin: "48px 0" }} />

          <h3 className="display" style={{
            fontSize: "clamp(28px,3.4vw,40px)", lineHeight: 1.05,
            letterSpacing: "-0.025em", margin: "0 0 18px"
          }}>
            The cockpit was the problem.
          </h3>
          <p style={{ margin: "0 0 18px" }}>
            Cursor. Copilot. Windsurf. Brave attempts. They put an AI co-pilot next to the human pilot and called the cockpit modern.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            But the cockpit was the problem. The plane didn&apos;t need two pilots. It needed a flight plan and a destination.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            Lovable and its cousins went the other way. They removed the cockpit and handed you a paper aeroplane. Beautiful for a demo. Useless for a business.
          </p>
          <p style={{ margin: 0 }}>
            Neither side admitted the obvious:{" "}
            <strong>the editor itself was the bottleneck.</strong>
          </p>
        </div>

        <blockquote style={{
          margin: "64px auto", maxWidth: 820, textAlign: "center",
          fontFamily: '"Newsreader",serif', fontStyle: "italic",
          fontSize: "clamp(24px,3vw,36px)", lineHeight: 1.25,
          borderTop: "1px solid rgba(10,9,7,0.3)", borderBottom: "1px solid rgba(10,9,7,0.3)",
          padding: "32px 20px"
        }}>
          “Cursor kept the IDE on life support and called it the future.”<br />
          <span style={{ background: accent, padding: "0 8px" }}>It was a fossil with a chat panel.</span>
        </blockquote>

        <div style={{
          maxWidth: 720, margin: "0 auto",
          fontFamily: '"Newsreader",Georgia,serif',
          fontSize: 18, lineHeight: 1.55
        }}>
          <h3 className="display" style={{
            fontSize: "clamp(28px,3.4vw,40px)", lineHeight: 1.05,
            letterSpacing: "-0.025em", margin: "0 0 18px"
          }}>
            The unit of work has changed.
          </h3>
          <p style={{ margin: "0 0 18px" }}>
            It used to be the keystroke. Then the line. Then the file.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            Now it&apos;s the <strong>phase</strong>. Discovery. Schema. Spec. Ship.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            You don&apos;t write code. You carefully direct it. You don&apos;t open files. You open plans. You don&apos;t debug for an hour. You reject a PR in ten seconds.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            The AI writes. You curate. You own the vision, what&apos;s kept and what&apos;s killed.
          </p>
          <p style={{ margin: 0 }}>
            That&apos;s not vibe coding. <em>That&apos;s the new job.</em>
          </p>

          <hr style={{ border: "none", borderTop: "1px solid rgba(10,9,7,0.25)", margin: "48px 0" }} />

          <h3 className="display" style={{
            fontSize: "clamp(28px,3.4vw,40px)", lineHeight: 1.05,
            letterSpacing: "-0.025em", margin: "0 0 18px"
          }}>
            This is not for everyone. It&apos;s for the survivors.
          </h3>
          <p style={{ margin: "0 0 18px" }}>
            It&apos;s 2028. There are two types of survivor:
          </p>
          <p style={{ margin: "0 0 18px" }}>
            <strong>The engineer who skilled up in product.</strong> They&apos;ve upskilled in delivery end-to-end. They prevent tech debt before it lands. They push back on every poor technical decision the AI tries to make.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            <strong>The product person who skilled up in tech.</strong> They&apos;ve upskilled in the stack. They apply their creative and delivery instincts to end-to-end shipping. They guard quality the way they used to guard the roadmap.
          </p>
          <p style={{ margin: "0 0 18px" }}>
            LET RIP is for the ones who can give clinical, specific, opinionated direction, and want a system that turns it into a product that doesn&apos;t fall over on day one.
          </p>
          <p style={{ margin: 0 }}>
            It&apos;s 2028. Everyone who didn&apos;t Let Rip is catching up, or left behind.
          </p>
        </div>

        <blockquote style={{
          margin: "64px auto", maxWidth: 820, textAlign: "center",
          fontFamily: '"Newsreader",serif', fontStyle: "italic",
          fontSize: "clamp(24px,3vw,36px)", lineHeight: 1.25,
          borderTop: "1px solid rgba(10,9,7,0.3)", borderBottom: "1px solid rgba(10,9,7,0.3)",
          padding: "32px 20px"
        }}>
          “Vibe coding got you a prototype.”<br />
          <span style={{ background: accent, padding: "0 8px" }}>Let rip and you get a product.</span>
        </blockquote>

        <div style={{
          maxWidth: 720, margin: "0 auto", textAlign: "center"
        }}>
          <p className="display" style={{
            fontSize: "clamp(36px,5.5vw,72px)", lineHeight: 1, letterSpacing: "-0.03em",
            margin: "0 0 6px"
          }}>
            The text editor is dead.
          </p>
          <p className="display" style={{
            fontSize: "clamp(36px,5.5vw,72px)", lineHeight: 1, letterSpacing: "-0.03em",
            margin: "0 0 14px"
          }}>
            You are the curator.
          </p>
          <p className="display" style={{
            fontSize: "clamp(56px,9vw,128px)", lineHeight: 0.95, letterSpacing: "-0.04em",
            margin: 0
          }}>
            <span style={{ background: accent, padding: "0 14px" }}>LET RIP.</span>
          </p>
        </div>

        <div style={{
          display: "flex", justifyContent: "space-between", alignItems: "center",
          marginTop: 64, paddingTop: 24, borderTop: "4px double var(--ink)"
        }}>
          <div className="mono" style={{ fontSize: 11, opacity: .6 }}>SIGNED — THE ide.rip CONSPIRACY</div>
          <div className="display" style={{ fontSize: 24, letterSpacing: "-0.03em" }}>
            ide<span style={{ color: "oklch(0.65 0.2 130)" }}>.rip</span>
          </div>
        </div>
      </div>
    </section>);

}

function System({ accent }) {
  const phases = [
  { n: "01", k: "IMAGINE", t: "You imagine and describe the product.", d: "Let.Rip creates a roadmap with releases, epics, dev phases, acceptance criteria, test plans, risk flags. You're ready to ride." },
  { n: "02", k: "CURATE", t: "Direct every phase. Curate production.", d: "Every phase is planned, you curate options on product direction, technology decisions, UX flows, UI. You're in control. Let.Rip pedals." },
  { n: "03", k: "CODE", t: "Using your Claude/Codex subscription.", d: "No more expensive API calls and Cursor subscriptions. Let.Rip uses the CLI tools compliantly. Let.Rip fast, hard and cost efficiently." },
  { n: "04", k: "DOCUMENT", t: "Perfect docs you'll never read, but need.", d: "Every phase has a spec. Decisions are logged. Implementation is documented. Let.Rip keeps everything current. You may never read the docs, BUT, context for AI is now perfect." },
  { n: "05", k: "TEST", t: "Full testing suite, plus manual tests.", d: "TDD is back. Full testing suite. Browser tests automated by the AI, and manual tests documented and tracked against every phase." },
  { n: "06", k: "SHIP, LEARN, IMPROVE", t: "Let.Rip learns, fixes & suggests.", d: "Let.Rip fixes bugs automatically, analyses feedback and requests and makes roadmap suggestions.\n\n\n\u2026 coding is dead." }];

  return (
    <section id="system" style={{
      padding: "120px 28px",
      borderBottom: "1px solid #1a1815",
      position: "relative",
      overflow: "hidden"
    }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", color: accent, marginBottom: 10 }}>
          § 04 — THE SYSTEM
        </div>
        <h2 className="display" style={{ margin: "0 0 16px", letterSpacing: "-0.04em", maxWidth: 1100 }}>
          <span style={{
            display: "block",
            fontSize: "clamp(56px,8.5vw,128px)",
            lineHeight: 0.88,
            color: "var(--paper)",
            marginBottom: "0.35em"
          }}>
            A BRAIN FOR THE WHOLE BUILD.
          </span>
          <span style={{
            display: "block",
            fontSize: "clamp(24px,3vw,40px)",
            lineHeight: 1.1,
            letterSpacing: "-0.02em",
            color: accent,
            marginBottom: "0.4em"
          }}>
            Vision. Roadmap. Specs. Stack. Code. Tests. Docs — one living model. Always coherent. Always current.
          </span>
          <span style={{
            display: "block",
            fontSize: "clamp(24px,3vw,40px)",
            lineHeight: 1.1,
            letterSpacing: "-0.02em",
            color: "#ffffff"
          }}>
            YOU READ THE WAVES AND CURATE THE RIDE.
          </span>
        </h2>
        <p style={{ maxWidth: 680, fontSize: 16, lineHeight: 1.5, opacity: .8, margin: "0 0 48px" }}>

        </p>

        <div style={{
          display: "grid",
          gridTemplateColumns: "repeat(auto-fit, minmax(360px, 1fr))",
          columnGap: 48,
          rowGap: 0,
          alignItems: "start"
        }}>
          {phases.map((p, i) =>
          <div key={p.n} style={{
            display: "grid", gridTemplateColumns: "80px 1fr",
            gap: 24,
            padding: "32px 0",
            borderTop: "1px solid #2a2722",
            borderBottom: i === phases.length - 1 || i === phases.length - 2 ? "1px solid #2a2722" : "none"
          }}>
              <div className="mono" style={{ fontSize: 13, color: accent, paddingTop: 6 }}>{p.n}</div>
              <div>
                <div className="bebas" style={{ fontSize: 14, letterSpacing: "0.25em", opacity: .6, marginBottom: 6 }}>{p.k}</div>
                <div className="display" style={{ fontSize: 28, letterSpacing: "-0.02em", lineHeight: 1.05, marginBottom: 10 }}>{p.t}</div>
                <div style={{ fontSize: 16, lineHeight: 1.55, opacity: .75, whiteSpace: "pre-line" }}>{p.d}</div>
              </div>
            </div>
          )}
        </div>
      </div>
    </section>);

}

function ForWho({ accent }) {
  const cards = [
  { tag: "FOR THE LEAD ENGINEER", line: "You stopped writing code last quarter. You just hadn&apos;t admitted it to your team. ide.rip is where you admit it \u2014 and start out-shipping the rest of engineering.", icon: "⌘" },
  { tag: "FOR THE PRODUCT MANAGER", line: "You can finally ship the thing in your head without booking three engineers&apos; calendars. Acceptance criteria become acceptance tests. The Jira ticket <em>is</em> the merge.", icon: "◇" },
  { tag: "FOR THE FOUNDER", line: "Your AI subscription is already paid for. This is what lets it actually finish something. Demo to revenue without hiring two engineers to clean up after the agent.", icon: "⚠" },
  { tag: "FOR THE BUSINESS ARCHITECT", line: "Oi hi there unsung hero \ud83d\udc4b.<br/><br/>You who knows how to take needs and pain and turn them into requirements. This is your time. Take the spotlight. We have everything else covered. Let.Rip.", icon: "△" }];

  return (
    <section style={{
      padding: "100px 28px",
      borderBottom: "1px solid #1a1815",
      background: "#0c0a07"
    }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", color: accent, marginBottom: 10 }}>
          § 05 — THE NEXT GENERATION
        </div>
        <h2 className="display" style={{ fontSize: "clamp(40px,6vw,84px)", margin: "0 0 16px", lineHeight: 0.92, letterSpacing: "-0.04em", maxWidth: 1100 }}>
          BUILT FOR PEOPLE WHO REFUSE<br />TO OPEN ANOTHER <span style={{ textDecoration: "line-through", opacity: .55 }}>.tsx</span> FILE.
        </h2>
        <p style={{ maxWidth: 680, fontSize: 16, lineHeight: 1.5, opacity: .75, margin: "0 0 48px" }}>
          If you can give a sharp instruction, you can ship a real product. If you can&apos;t, no editor in the world will save you.
        </p>
        <div style={{
          display: "grid",
          gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))",
          gap: 1, background: "#2a2722", border: "1px solid #2a2722"
        }}>
          {cards.map((c) =>
          <div key={c.tag} style={{
            background: "#0c0a07", padding: "36px 28px", minHeight: 240,
            display: "flex", flexDirection: "column", justifyContent: "space-between"
          }}>
              <div style={{ fontSize: 48, color: accent, lineHeight: 1 }}>{c.icon}</div>
              <div>
                <div className="mono" style={{ fontSize: 11, letterSpacing: "0.18em", color: accent, marginBottom: 10 }}>{c.tag}</div>
                <div className="display" style={{ fontSize: 22, letterSpacing: "-0.01em", lineHeight: 1.15 }} dangerouslySetInnerHTML={{ __html: c.line }} />
              </div>
            </div>)}
        </div>
      </div>
    </section>);
}

function Comparison({ accent }) {
  const rows = [
  ["The unit of work", "A line of code", "A phase"],
  ["What you open", "A file", "A roadmap and worklog"],
  ["When the AI loses the plot", "It invents another one", "Let.Rip forces focus."],
  ["Delivery", "Vibes-as-a-service", "Planned. Executed. Tested."],
  ["QA", "Manual, eventually", "Documented. Automated. Tracked."],
  ["Source of truth", "Git history", "Roadmap, decisions, documentation, always up to date."],
  ["What you get", "A repo you inherited", "50x productivity. Less stress. More shipped. Better docs."],
  ["When you ship", "When it compiles", "Constantly."]];

  return (
    <section style={{
      padding: "100px 28px", borderBottom: "1px solid #1a1815"
    }}>
      <div style={{ maxWidth: 1180, margin: "0 auto" }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", color: accent, marginBottom: 10 }}>
          § 06 — CODE BY VIBE
        </div>
        <h2 className="display" style={{ fontSize: "clamp(40px,6vw,80px)", margin: "0 0 16px", lineHeight: 0.9, letterSpacing: "-0.04em" }}>
          THE TOY WAY vs. <span style={{ color: accent }}>ide.rip</span>
        </h2>
        <p style={{ maxWidth: 680, fontSize: 16, lineHeight: 1.5, opacity: .75, margin: "0 0 48px" }}>
          Lovable, Bolt and the rest got you to a screenshot. We get you to a system of record.
        </p>
        <div style={{
          display: "grid", gridTemplateColumns: "1fr 1fr 1fr",
          border: "1px solid #2a2722"
        }}>
          <div className="mono" style={{ padding: "16px 20px", fontSize: 11, letterSpacing: "0.2em", opacity: .55, borderBottom: "1px solid #2a2722" }}>METRIC</div>
          <div className="mono" style={{ padding: "16px 20px", fontSize: 11, letterSpacing: "0.2em", opacity: .55, borderBottom: "1px solid #2a2722", borderLeft: "1px solid #2a2722", textDecoration: "line-through" }}>THE TOY WAY</div>
          <div className="mono" style={{ padding: "16px 20px", fontSize: 11, letterSpacing: "0.2em", color: accent, borderBottom: "1px solid #2a2722", borderLeft: "1px solid #2a2722" }}>ide.rip</div>
          {rows.map((r, i) =>
          <React.Fragment key={i}>
              <div style={{ padding: "22px 20px", borderBottom: i === rows.length - 1 ? "none" : "1px solid #2a2722", fontSize: 16, opacity: .85 }}>{r[0]}</div>
              <div style={{ padding: "22px 20px", borderBottom: i === rows.length - 1 ? "none" : "1px solid #2a2722", borderLeft: "1px solid #2a2722", fontSize: 16, opacity: .55, textDecoration: "line-through" }}>{r[1]}</div>
              <div style={{ padding: "22px 20px", borderBottom: i === rows.length - 1 ? "none" : "1px solid #2a2722", borderLeft: "1px solid #2a2722", fontSize: 16, fontWeight: 600 }}>{r[2]}</div>
            </React.Fragment>
          )}
        </div>
      </div>
    </section>);

}

function Waitlist({ accent }) {
  const [email, setEmail] = useState("");
  const [role, setRole] = useState("LEAD ENGINEER");
  const [submitted, setSubmitted] = useState(false);
  const [position, setPosition] = useState(0);
  const [duplicate, setDuplicate] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");
  const [website, setWebsite] = useState(""); // honeypot

  const onSubmit = async (e) => {
    e.preventDefault();
    if (!email.includes("@")) return;
    if (submitting) return;
    setSubmitting(true);
    setError("");
    try {
      const res = await fetch("/api/waitlist", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ email, role, website })
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok || !data.ok) {
        setError(
          data.error === "invalid_email" ? "That email doesn't look right." :
          "Couldn't reach the registrar. Try again in a moment."
        );
        setSubmitting(false);
        return;
      }
      setPosition(data.position || 0);
      setDuplicate(!!data.duplicate);
      setSubmitted(true);
    } catch {
      setError("Network down. The IDE refuses to die quietly. Try again.");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <section id="waitlist" style={{
      padding: "120px 28px",
      background: "var(--ink)",
      borderBottom: "1px solid #1a1815",
      position: "relative", overflow: "hidden"
    }}>
      {/* spotlight */}
      <div aria-hidden style={{
        position: "absolute", inset: 0,
        background: `radial-gradient(ellipse 600px 400px at 50% 30%, ${accent}22, transparent 70%)`,
        pointerEvents: "none"
      }} />
      <div style={{ maxWidth: 920, margin: "0 auto", position: "relative", textAlign: "center" }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.25em", color: accent, marginBottom: 14 }}>CLAIM YOUR BOARD

        </div>
        <h2 className="display" style={{ fontSize: "clamp(56px,9vw,124px)", margin: "0 0 24px", lineHeight: 0.88, letterSpacing: "-0.045em" }}>
          BE FIRST TO<br /><span style={{ color: accent }}>LET.RIP</span>
        </h2>
        <p style={{ fontSize: 16, opacity: .8, maxWidth: 640, margin: "0 auto 48px", lineHeight: 1.5 }}>Private beta opens Q3 2026. The first 1,000 operators get lifetime founding access and pricing, a real headstone in the digital cemetery for their old tools, and free listings in the Let.Rip product directory.

        </p>

        {!submitted ?
        <form onSubmit={onSubmit} style={{ maxWidth: 680, margin: "0 auto" }}>
            <div style={{
            display: "grid", gridTemplateColumns: "1fr auto",
            border: "1px solid " + accent,
            background: "#0e0d0a"
          }}>
              <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              required
              placeholder="email@you-built-something-real.com"
              className="mono"
              style={{
                background: "transparent", border: "none", outline: "none",
                padding: "22px 20px", color: "var(--paper)", fontSize: 15,
                letterSpacing: "0.02em"
              }} />
            
              <button type="submit" disabled={submitting} className="display" style={{
              border: "none", background: accent, color: "var(--ink)",
              padding: "0 32px", fontSize: 14, letterSpacing: "0.08em",
              cursor: submitting ? "wait" : "pointer",
              opacity: submitting ? 0.6 : 1
            }}>
                {submitting ? "BURYING…" : "BURY THE IDE →"}
              </button>
            </div>
            <div style={{ display: "flex", gap: 10, justifyContent: "center", flexWrap: "wrap", marginTop: 20 }}>
              {["LEAD ENGINEER", "PRODUCT MANAGER", "FOUNDER", "BUSINESS ARCHITECT", "LAST CARTOGRAPHER"].map((r) =>
            <button type="button" key={r} onClick={() => setRole(r)} className="mono" style={{
              background: role === r ? accent : "transparent",
              color: role === r ? "var(--ink)" : "var(--paper)",
              border: "1px solid " + (role === r ? accent : "#2a2722"),
              padding: "8px 14px", fontSize: 10, letterSpacing: "0.15em", cursor: "pointer"
            }}>{r}</button>
            )}
            </div>
            <div className="mono" style={{ fontSize: 11, opacity: .5, marginTop: 24 }}>
              no spam. one email per phase ship. unsubscribe = your IDE comes back.
            </div>
            {error && <div className="mono" style={{ fontSize: 12, color: "#ff6b5e", marginTop: 14 }}>{error}</div>}
            {/* honeypot — hidden from humans, bots fill it and get silently dropped */}
            <input
              type="text"
              tabIndex={-1}
              autoComplete="off"
              value={website}
              onChange={(e) => setWebsite(e.target.value)}
              name="website"
              style={{ position: "absolute", left: "-9999px", width: 1, height: 1, opacity: 0 }}
              aria-hidden="true" />
          </form> :

        <div style={{
          border: "1px solid " + accent,
          background: "#0e0d0a",
          padding: "44px 32px",
          maxWidth: 560, margin: "0 auto",
          textAlign: "left"
        }}>
            <div className="mono" style={{ fontSize: 11, color: accent, letterSpacing: "0.2em", marginBottom: 14 }}>
              {duplicate ? "✓ ALREADY ON THE LIST" : "✓ INTERRED — CERTIFICATE OF DEATH ISSUED"}
            </div>
            <div className="display" style={{ fontSize: 36, lineHeight: 1, marginBottom: 16, letterSpacing: "-0.03em" }}>
              YOU'RE #{position} IN THE PROCESSION.
            </div>
            <div style={{ fontSize: 15, opacity: .8, lineHeight: 1.5, marginBottom: 20 }}>
              We've added <span className="mono" style={{ color: accent }}>{email}</span> to the {role.toLowerCase()} cohort. Watch your inbox — first 1,000 plots get founding access when private beta opens.
            </div>
            <div className="mono" style={{ fontSize: 11, opacity: .55, paddingTop: 16, borderTop: "1px solid #2a2722" }}>
              tweet @ide_rip with #IDEisDead to skip {Math.floor(position / 3)} places.
            </div>
          </div>
        }
      </div>
    </section>);

}

function FAQ({ accent }) {
  const [open, setOpen] = useState(0);
  const faq = [
  { q: "Wait — is this actually replacing my IDE?", a: "Yes - and your project management system, and JIRA, and your testing platform, and your Notion documentation ... and probably more. You can always open it if you're feeling nostalgic." },
  { q: "What if I want to look at the code?", a: "You always can. ide.rip is not a black box. Every phase produces a reviewable diff, a self-written PR description, and a passing test suite. The difference is you’re reviewing outcomes, not authoring inputs. Your IDE becomes what cat and less became when IDEs arrived: a viewing tool, not a working tool. It doesn’t die. It gets demoted." },
  { q: "How is this different from Cursor / Copilot / agent mode?", a: "Cursor and friends are editors with an agent in the sidebar. The human is still expected to live in the file. ide.rip is an agent with a foreman on top. The human lives in the plan. The file is an artifact, not a workspace. The other difference: scope. Cursor helps you write a function. ide.rip ships a product — roadmap, schema, auth, billing, QA, release notes, roadmap update, all phases of one running job." },
  { q: "How is this different from Lovable / Bolt / v0?", a: "If you're qualified to use Let.Rip and you've used these tools, you know the frustrations.\n\n\nThey're landing-page generators with a database bolted on. They are wonderful for a weekend. They collapse the first time you need a migration, a real auth model, a third-party integration, or someone to call when production breaks at 2 AM.\n\n\nLet.Rip is for professionals." },
  { q: "Will this work for my real, complicated, legacy codebase?", a: "Yes — that’s the whole point.\n\n\nLet.Rip plans against the codebase you have, or starts from scratch.\n\n\nLet.Rip reads the repo, builds a model of what’s there. We build the roadmap on top." },
  { q: "What does it cost?", a: "Pricing announced during Private Beta (Q3 2026). Huge discount for first 1,000 users." },
  { q: "Are you serious about the tombstones?", a: "Deadly." }];

  return (
    <section style={{ padding: "100px 28px", borderBottom: "1px solid #1a1815" }}>
      <div style={{ maxWidth: 980, margin: "0 auto" }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", color: accent, marginBottom: 10 }}>
          § 08 — LAST WORDS
        </div>
        <h2 className="display" style={{ fontSize: "clamp(40px,6vw,80px)", margin: "0 0 40px", lineHeight: 0.9, letterSpacing: "-0.04em" }}>
          QUESTIONS FROM THE MOURNERS.
        </h2>
        <div>
          {faq.map((f, i) =>
          <div key={i} style={{ borderTop: "1px solid #2a2722" }}>
              <button onClick={() => setOpen(open === i ? -1 : i)} style={{
              width: "100%", textAlign: "left", background: "transparent",
              border: "none", color: "var(--paper)", padding: "22px 0",
              display: "flex", justifyContent: "space-between", alignItems: "center",
              cursor: "pointer", fontFamily: "inherit"
            }}>
                <span className="display" style={{ fontSize: 22, letterSpacing: "-0.01em" }}>{f.q}</span>
                <span className="mono" style={{ color: accent, fontSize: 20 }}>{open === i ? "−" : "+"}</span>
              </button>
              {open === i &&
            <div style={{ padding: "0 0 28px", fontSize: 16, lineHeight: 1.55, opacity: .78, maxWidth: 760 }}>{f.a}</div>
            }
            </div>
          )}
          <div style={{ borderTop: "1px solid #2a2722" }} />
        </div>
      </div>
    </section>);

}

function Footer({ accent }) {
  return (
    <footer style={{ padding: "60px 28px 40px", color: "var(--paper)" }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div className="display" style={{
          fontSize: "clamp(80px,18vw,260px)", lineHeight: 0.82, letterSpacing: "-0.05em",
          textAlign: "center", margin: "20px 0"
        }}>
          Let<span style={{ color: accent }}>.Rip</span>
        </div>
        <div style={{ textAlign: "center", fontStyle: "italic", fontSize: 16, opacity: .6, marginBottom: 36 }}>LFG

        </div>
        <div style={{
          display: "flex", justifyContent: "space-between",
          paddingTop: 24, borderTop: "1px solid #2a2722",
          fontFamily: '"JetBrains Mono",monospace', fontSize: 11, letterSpacing: "0.15em",
          opacity: .6, flexWrap: "wrap", gap: 16
        }}>
          <span>© MMXXVI — ide.rip</span>
          <span>BUILT WITHOUT AN IDE</span>
          <span>hello@ide.rip · @ide_rip</span>
        </div>
      </div>
    </footer>);

}

// ---------- glitch cursor ----------
function GhostCursor({ accent, on }) {
  const [pos, setPos] = useState({ x: -100, y: -100 });
  useEffect(() => {
    if (!on) return;
    const h = (e) => setPos({ x: e.clientX, y: e.clientY });
    window.addEventListener("mousemove", h);
    return () => window.removeEventListener("mousemove", h);
  }, [on]);
  if (!on) return null;
  return (
    <div aria-hidden style={{
      position: "fixed", left: pos.x, top: pos.y, zIndex: 999,
      pointerEvents: "none", transform: "translate(-50%,-50%)",
      mixBlendMode: "difference"
    }}>
      <div className="mono" style={{
        color: accent, fontSize: 10, letterSpacing: "0.15em",
        whiteSpace: "nowrap", transform: "translate(14px, -14px)"
      }}>
        █ NO IDE FOUND
      </div>
    </div>);

}

// ---------- in-page tweaks toggle ----------
function TweaksLauncher({ accent }) {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onMsg = (e) => {
      const t = e?.data?.type;
      if (t === '__activate_edit_mode') setOpen(true);else
      if (t === '__deactivate_edit_mode') setOpen(false);
    };
    window.addEventListener('message', onMsg);
    return () => window.removeEventListener('message', onMsg);
  }, []);
  const toggle = () => {
    window.postMessage({ type: open ? '__deactivate_edit_mode' : '__activate_edit_mode' }, '*');
  };
  return (
    <button
      onClick={toggle}
      className="mono"
      style={{
        position: 'fixed', right: 16, bottom: 16, zIndex: 100,
        background: open ? accent : 'var(--ink)',
        color: open ? 'var(--ink)' : accent,
        border: '1px solid ' + accent,
        padding: '12px 16px',
        fontSize: 11, letterSpacing: '0.18em',
        cursor: 'pointer',
        boxShadow: '0 10px 30px -10px ' + accent + '88'
      }}>
      {open ? '× CLOSE TWEAKS' : '⚙ TWEAKS'}
    </button>);
}

// ---------- app ----------
function App() {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  const accent = ACCENT_MAP[t.accent]?.hex || ACCENT_MAP.acid.hex;
  const TP = window.TweaksPanel;
  const TS = window.TweakSection;
  const TR = window.TweakRadio;
  const TToggle = window.TweakToggle;

  // marquee text varies on intensity
  const marqueeTxt = t.intensity === "loud" ?
  "✟ THE EDITOR IS DEAD ✟ LONG LIVE THE FOREMAN ✟ DO NOT OPEN FILES ✟ DIRECT THE WORK ✟ SHIP THE ROADMAP ✟" :
  "the editor is dead · long live the foreman · do not open files · direct the work · ship the roadmap";

  return (
    <div>
      <GhostCursor accent={accent} on={t.showCursor} />
      <TweaksLauncher accent={accent} />
      <TopBar accent={accent} />
      <Hero accent={accent} glitch={t.glitch} />
      <Marquee accent={accent} speed={t.intensity === "loud" ? 34 : 60}>{marqueeTxt}</Marquee>
      <Manifesto accent={accent} />
      <Marquee accent={accent} reverse speed={t.intensity === "loud" ? 38 : 64}>
        WAITING LIST OPEN · WAITING LIST OPEN · PRE-LAUNCH · PRE-LAUNCH ·
      </Marquee>
      <System accent={accent} />
      <ForWho accent={accent} />
      <Comparison accent={accent} />
      <Waitlist accent={accent} />
      <FAQ accent={accent} />
      <Footer accent={accent} />

      <TP title="Tweaks">
        <TS label="Accent color">
          <div style={{ display: "flex", gap: 8 }}>
            {Object.entries(ACCENT_MAP).map(([k, v]) =>
            <button key={k} onClick={() => setTweak("accent", k)} title={v.name} style={{
              width: 36, height: 36, borderRadius: 99,
              background: v.hex, cursor: "pointer",
              border: t.accent === k ? "2px solid var(--paper)" : "2px solid transparent",
              outline: "1px solid #2a2722"
            }} />
            )}
          </div>
        </TS>
        <TR
          label="Intensity"
          options={[{ value: "loud", label: "Loud" }, { value: "quiet", label: "Quiet" }]}
          value={t.intensity}
          onChange={(v) => setTweak("intensity", v)} />
        
        <TToggle label="Glitch animation" value={t.glitch} onChange={(v) => setTweak("glitch", v)} />
        <TToggle label="Ghost cursor" value={t.showCursor} onChange={(v) => setTweak("showCursor", v)} />
      </TP>
    </div>);

}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);