/* Redacted Archives — main app */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#e63329",
  "grain": 0.06,
  "redactStyle": "black",
  "showAgeGate": true,
  "marqueeSpeed": 38,
  "cursorMode": "redact"
}/*EDITMODE-END*/;

/* ---------- tiny helpers ---------- */
const Logo = ({ size = 22, color = "#e63329" }) => (
  <svg viewBox="0 0 100 100" aria-hidden="true">
    <text x="50" y="42" textAnchor="middle" fontFamily="Archivo Black, sans-serif"
          fontSize="17" fill={color} letterSpacing="0.5">REDACTED</text>
    <line x1="10" y1="42" x2="90" y2="38" stroke={color} strokeWidth="2.4" />
    <text x="50" y="60" textAnchor="middle" fontFamily="Archivo Black, sans-serif"
          fontSize="17" fill="#f6f3ec" letterSpacing="0.5">ARCHIVES</text>
    <text x="50" y="76" textAnchor="middle" fontFamily="Space Mono, monospace"
          fontSize="5" fill={color} letterSpacing="1.6">· EST 2025 ·</text>
  </svg>
);

const Rd = ({ children, variant }) => (
  <span className={"rd " + (variant === "red" ? "red" : "")}>{children}</span>
);

/* ---------- announcement marquee ---------- */
const Announcement = ({ speed }) => {
  const items = [
    "DROP 003 // CLASSIFIED OBJECTS",
    "FREE SHIPPING OVER $80",
    "REDACTED BY POPULAR DEMAND",
    "NEW: ASK ME ABOUT MY ████ TEE",
    "EVIDENCE LOCKER NOW OPEN",
    "MEMBERS ONLY — SIGN THE NDA",
    "DROP 003 // CLASSIFIED OBJECTS",
    "FREE SHIPPING OVER $80",
    "REDACTED BY POPULAR DEMAND",
    "NEW: ASK ME ABOUT MY ████ TEE",
    "EVIDENCE LOCKER NOW OPEN",
    "MEMBERS ONLY — SIGN THE NDA",
  ];
  return (
    <div className="ann">
      <div className="ann-track" style={{ animationDuration: speed + "s" }}>
        <span>{items.map((t, i) => <React.Fragment key={i}>{t}<i>◆</i></React.Fragment>)}</span>
        <span>{items.map((t, i) => <React.Fragment key={"b"+i}>{t}<i>◆</i></React.Fragment>)}</span>
      </div>
    </div>
  );
};

/* ---------- drop 003 code modal ---------- */
const DropCodeModal = ({ open, onClose }) => {
  const [code, setCode] = React.useState("");
  const [busted, setBusted] = React.useState(false);
  const [verifying, setVerifying] = React.useState(false);
  const inputRef = React.useRef(null);

  React.useEffect(() => {
    if (open) {
      setCode(""); setBusted(false); setVerifying(false);
      setTimeout(() => inputRef.current && inputRef.current.focus(), 100);
    }
  }, [open]);

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    if (open) window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  const submit = (e) => {
    e.preventDefault();
    if (!code.trim()) return;
    setVerifying(true);
    setTimeout(() => { setVerifying(false); setBusted(true); }, 900);
  };

  if (!open) return null;

  return (
    <div className="code-modal" onClick={onClose}>
      <div className={"code-box " + (busted ? "busted" : "")} onClick={(e) => e.stopPropagation()}>
        <button className="code-x" onClick={onClose} aria-label="Close">✕</button>

        {!busted ? (
          <>
            <div className="code-tag">· CLASSIFIED · ACCESS REQUIRED ·</div>
            <h3 className="code-h">Drop 003<br/>is sealed.</h3>
            <p className="code-p">
              This file is members-only until <b style={{ color:"var(--red)" }}>06.21.26</b>.
              Enter your access code to declassify early.
            </p>
            <form onSubmit={submit} className="code-form">
              <label className="code-lbl">ACCESS CODE</label>
              <input ref={inputRef} type="text" value={code}
                onChange={(e) => setCode(e.target.value.toUpperCase())}
                placeholder="RA-████-████" maxLength={20} disabled={verifying} />
              <button type="submit" disabled={verifying || !code.trim()}>
                {verifying ? "VERIFYING…" : "DECLASSIFY →"}
              </button>
            </form>
            <div className="code-hint">Don't have a code? <a href="#news" onClick={onClose}>Sign the NDA</a> to get one.</div>
          </>
        ) : (
          <>
            <div className="code-tag red">· ACCESS GRANTED · LEAKED FILE ·</div>
            <div className="code-img">
              <img src="assets/gotcha.jpeg" alt="You think you are that smart" />
              <div className="code-stamp">EXHIBIT A<br/><small>FILE ███.███</small></div>
            </div>
            <h3 className="code-h sm">Nice try.</h3>
            <p className="code-p">
              We don't actually have codes. Drop 003 unlocks for everyone <b>06.21.26 @ 6pm ET</b>.
              <Rd>You played yourself.</Rd>
            </p>
            <div className="code-row">
              <button className="ibtn" onClick={() => setBusted(false)}>TRY ANOTHER CODE</button>
              <button className="ibtn red" onClick={onClose}>RESPECT, CLOSE</button>
            </div>
          </>
        )}
      </div>
    </div>
  );
};

/* ---------- nav ---------- */
const Nav = ({ onDropClick }) => {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.style.overflow = open ? "hidden" : "";
  }, [open]);
  const close = () => setOpen(false);
  const dropClick = (e) => { e.preventDefault(); close(); onDropClick(); };
  return (
    <>
      <nav className="nav">
        <div className="nav-row">
          <div className="nav-logo">
            <div className="lo"><Logo /></div>
            <div className="mono" style={{ letterSpacing: ".22em" }}>REDACTED//ARCHIVES</div>
          </div>
          <div className="nav-links">
            <a href="#shop">Shop</a>
            <a href="#drop" onClick={dropClick} className="drop-link">Drop 003 <span className="lock">🔒</span></a>
            <a href="#lookbook">Lookbook</a>
            <a href="#manifesto">Manifesto</a>
            <a href="#schedule">Drops</a>
          </div>
          <div className="nav-actions">
            <button className="ibtn search">Search</button>
            <button className="ibtn red">Cart · 0</button>
            <button className={"burger " + (open ? "open" : "")} onClick={() => setOpen(o => !o)} aria-label="Menu">
              <span /><span /><span />
            </button>
          </div>
        </div>
      </nav>
      <div className={"mobile-menu " + (open ? "open" : "")}>
        <a href="#shop" onClick={close}>Shop <small>01</small></a>
        <a href="#drop" onClick={dropClick}>Drop 003 🔒 <small>02</small></a>
        <a href="#lookbook" onClick={close}>Lookbook <small>03</small></a>
        <a href="#manifesto" onClick={close}>Manifesto <small>04</small></a>
        <a href="#schedule" onClick={close}>Drop Schedule <small>05</small></a>
        <a href="#news" onClick={close}>Sign the NDA <small>06</small></a>
        <div className="m-foot">
          <div className="mono" style={{ color:"rgba(246,243,236,.5)" }}>FILE #003 · Q2 2026</div>
          <button className="ibtn red" onClick={close}>Cart · 0</button>
        </div>
      </div>
    </>
  );
};

/* ---------- hero ---------- */
const Hero = () => (
  <section className="hero">
    <div className="hero-stripe top">
      <div className="hero-top" style={{ display:"grid", gridTemplateColumns:"1fr auto 1fr", width:"100%", color:"rgba(246,243,236,.5)", fontFamily:"'Space Mono',monospace", fontSize:10, letterSpacing:".2em", textTransform:"uppercase" }}>
        <div>File #003 // Quarter II / 2026</div>
        <div className="c" style={{ textAlign:"center", color:"#e63329" }}>● CLASSIFIED // NOT FOR PUBLIC RECORD ●</div>
        <div className="r" style={{ textAlign:"right" }}>NY · LA · LIS · MNL</div>
      </div>
    </div>

    <div className="hero-mid">
      <h1 className="display">
        <span className="row">EVIDENCE</span>
        <span className="row" style={{ display:"flex", alignItems:"center", gap:"0.04em" }}>
          <span>OF&nbsp;A</span>
          <span style={{ flex:1, height:"10px", background:"#e63329", margin:"0 0.12em 0.1em" }} />
        </span>
        <span className="row strike-red">MISSPENT</span>
        <span className="row">YOUTH<span style={{ color:"#e63329" }}>.</span></span>
      </h1>

      <div className="sticker" style={{ right: "6%", top: "18%" }}>
        <div>
          <span className="age">18+</span>
          NDA<br/>REQUIRED
        </div>
      </div>
    </div>

    <div className="hero-cap">
      <div className="tag">
        Cut-and-sew tees, hoodies and accessories for the chronically online.
        Each drop is a folder of evidence we forgot to shred.
        <Rd>Don't tell mom.</Rd>
      </div>
      <div className="meta">
        Drop 003 ↘<br/>
        Opens 06.21.26 · 6pm ET<br/>
        <span style={{ color:"#e63329" }}>—— scroll to declassify ——</span>
      </div>
    </div>
  </section>
);

/* ---------- tee mockup ---------- */
const Tee = ({ color = "dark", children, textColor = "#fff", small }) => (
  <div className={"tee " + color}>
    <svg viewBox="0 0 200 240" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="shade" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor="rgba(255,255,255,.08)" />
          <stop offset="1" stopColor="rgba(0,0,0,.25)" />
        </linearGradient>
      </defs>
      <path className="body" d="M40 30 L70 18 Q 100 38 130 18 L160 30 L185 60 L165 80 L155 70 L155 220 L45 220 L45 70 L35 80 L15 60 Z" />
      <path d="M40 30 L70 18 Q 100 38 130 18 L160 30 L185 60 L165 80 L155 70 L155 220 L45 220 L45 70 L35 80 L15 60 Z" fill="url(#shade)" />
      <path d="M70 18 Q100 50 130 18" fill="none" stroke="rgba(0,0,0,.18)" strokeWidth="1" />
    </svg>
    <div className="tee-text" style={{ color: textColor, fontSize: small ? 13 : 18 }}>
      {children}
    </div>
  </div>
);

/* ---------- drop grid ---------- */
const Drop = () => {
  const cards = [
    {
      size: "feat", code: "RA-003-01", tag: "NEW", stock: "IN STOCK", stockClr: "",
      title: "Ask me about my ████", price: "$58", color: "dark",
      teeText: <>ASK ME ABOUT<br/>MY <span style={{ background:"#000", color:"transparent", padding:"0 .15em" }}>████</span></>,
      teeColor: "dark", teeTextColor: "#f2ebd9",
      stamp: "ITEM 001 / 06 · COTTON 240GSM"
    },
    {
      size: "skin", code: "RA-003-02", tag: "DROP 003", stock: "LOW STOCK", stockClr: "a",
      title: "Big If True", price: "$54", color: "cream",
      teeText: <>BIG<br/>IF<br/>TRUE</>,
      teeColor: "cream", teeTextColor: "#e63329",
      stamp: "ITEM 002 / 06 · HEAVYWEIGHT"
    },
    {
      size: "skin", code: "RA-003-03", tag: "PREORDER", stock: "PREORDER", stockClr: "r",
      title: "Emotionally Unavailable™", price: "$62", color: "red",
      teeText: <>EMOTIONALLY<br/>UNAVAILABLE™</>,
      teeColor: "red", teeTextColor: "#0a0a0a",
      stamp: "ITEM 003 / 06 · BOXY FIT"
    },
    {
      size: "skin", code: "RA-003-04", tag: "RESTOCK", stock: "IN STOCK", stockClr: "",
      title: "Touch Grass / or Don't", price: "$48", color: "dark",
      teeText: <>TOUCH GRASS<br/><span style={{ color:"#e63329" }}>OR DON'T</span></>,
      teeColor: "dark", teeTextColor: "#f2ebd9",
      stamp: "ITEM 004 / 06 · OVERSIZED"
    },
    {
      size: "feat", code: "RA-003-05", tag: "LIMITED 200", stock: "LIVE FRI", stockClr: "a",
      title: "Probably Oversharing Hoodie", price: "$110", color: "cream",
      teeText: <>PROBABLY<br/>OVERSHARING</>,
      teeColor: "cream", teeTextColor: "#0a0a0a",
      stamp: "ITEM 005 / 06 · HEAVY FLEECE"
    },
    {
      size: "skin", code: "RA-003-06", tag: "RUNS SMALL", stock: "IN STOCK", stockClr: "",
      title: "Not For Your FYP", price: "$52", color: "dark",
      teeText: <>NOT FOR<br/>YOUR FYP</>,
      teeColor: "dark", teeTextColor: "#f2ebd9",
      stamp: "ITEM 006 / 06 · BOXY"
    },
  ];
  return (
    <section className="sec" id="shop">
      <div className="sec-hd">
        <div>
          <div className="num" style={{ marginBottom:14 }}>§ 01 / DROP 003 ——— CLASSIFIED OBJECTS</div>
          <h2>The current<br/>evidence locker.</h2>
        </div>
        <div className="right">
          06 files / 240gsm cotton / printed in a basement somewhere in Brooklyn / receipts available on request.
        </div>
      </div>

      <div className="grid">
        {cards.map((c, i) => (
          <article key={i} className={"card " + c.size}>
            <div className="img">
              <div className="ph" />
              <Tee color={c.teeColor} textColor={c.teeTextColor} small={c.size === "skin"}>
                {c.teeText}
              </Tee>
              <div className="corner">{c.code}</div>
              <div className="corner r">{c.stamp.split("·")[1]}</div>
              <span className={"pill " + (c.tag === "RESTOCK" || c.tag === "RUNS SMALL" ? "gray" : "")}>{c.tag}</span>
            </div>
            <div className="info">
              <div>
                <div style={{ color:"#fff", letterSpacing:".18em", marginBottom:4, fontFamily:"'Archivo Black',sans-serif", fontSize:14, textTransform:"uppercase" }}>{c.title}</div>
                <div>{c.stamp}</div>
              </div>
              <div style={{ textAlign:"right" }}>
                <div style={{ color:"#fff", fontFamily:"'Space Mono',monospace", fontSize:14 }}>{c.price}</div>
                <div><span className={"dot " + c.stockClr}></span>{c.stock}</div>
              </div>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
};

/* ---------- lookbook ---------- */
const Lookbook = () => {
  const slots = [
    { cls: "lb big", num: "PHOTO 01 / RA-003", stamp: "EXHIBIT A", name: "Subject 01 — Brooklyn rooftop", mt: "Wearing 'Ask me about my ████'", reveal: "Subject was seen leaving the scene." },
    { cls: "lb tall", num: "PHOTO 02 / RA-003", stamp: "EXHIBIT B", name: "Subject 02 — Bedroom mirror", mt: "Wearing 'Emotionally Unavailable™'", reveal: "Refused to answer further questions." },
    { cls: "lb med2", num: "PHOTO 03 / RA-003", stamp: "EXHIBIT C", name: "Subject 03 — Bodega exterior, 2:14am", mt: "Wearing 'Touch grass / or don't'", reveal: "Last seen buying a four loko." },
    { cls: "lb med", num: "PHOTO 04 / RA-003", stamp: "EXHIBIT D", name: "Subject 04 — Backseat of an Uber", mt: "Wearing 'Big if true' tee", reveal: "Conversation was lightly unhinged." },
  ];
  return (
    <section className="sec" id="lookbook">
      <div className="sec-hd">
        <div>
          <div className="num" style={{ marginBottom:14 }}>§ 02 / LOOKBOOK ——— SURVEILLANCE FOOTAGE</div>
          <h2>People we<br/>can't name.</h2>
        </div>
        <div className="right">
          Hover any frame to declassify. All subjects consented. Mostly.
        </div>
      </div>

      <div className="look">
        {slots.map((s, i) => (
          <figure key={i} className={s.cls}>
            <div className="ph" />
            <div className="num">{s.num}</div>
            <div className="stamp-stk">{s.stamp}</div>
            <div className="bars"><span /><span /><span /></div>
            <div className="reveal">{s.reveal}</div>
            <figcaption className="cap">
              <div className="nm">{s.name}</div>
              <div className="mt">{s.mt}</div>
            </figcaption>
          </figure>
        ))}
      </div>
    </section>
  );
};

/* ---------- manifesto ---------- */
const Manifesto = () => (
  <section className="mani" id="manifesto">
    <div className="num mono" style={{ color:"rgba(10,10,10,.55)", marginBottom:18 }}>§ 03 / MANIFESTO ——— WHY THIS EXISTS</div>
    <h2>
      Clothes for<br/>
      <Rd>thoughts</Rd> you<br/>
      shouldn't<br/>
      have <span style={{ color:"#e63329" }}>posted.</span>
    </h2>
    <div className="mani-row">
      <div className="lead">
        Redacted Archives is a<br/>
        New York streetwear<br/>
        label. We make tees,<br/>
        hoodies and small<br/>
        objects for the chronically<br/>
        online generation —<br/>
        printed in small batches,<br/>
        sold once, never restocked.
      </div>
      <div className="body">
        <p>
          We're collecting evidence. Bad text messages, group chat receipts,
          notes app confessions, screenshots you should've deleted. We turn
          them into clothes.
        </p>
        <p>
          Every drop is a folder. Six files, usually under two hundred units.
          When the folder is gone, it's gone — sealed, classified, and
          archived. That's the point.
        </p>
        <p>
          We are not a vibe. We are not a brand voice. We are a <Rd>kink</Rd> for
          things you can't say at thanksgiving.
        </p>
      </div>
    </div>
    <div className="mani-stamp">
      <div className="seal">
        AUTHORIZED<br/>
        BY THE<br/>
        DEPT. OF<br/>
        OVERSHARING
      </div>
      <div>
        Signed,<br/>
        ████ ███████ — founder<br/>
        ████ ████ — creative director
      </div>
    </div>
  </section>
);

/* ---------- drop schedule ---------- */
const Schedule = () => {
  const rows = [
    { dt:"06.21", yr:"2026 · FRI", nm:"DROP 003 — Classified Objects", sub:"6 files. 240gsm cotton. NY studio.", st:"OPENS 6PM ET", pc:"06 PIECES", live:true, gone:false, action:"NOTIFY ME →" },
    { dt:"05.10", yr:"2026 · SAT", nm:"DROP 002 — Group Chat Receipts", sub:"4 files. Hoodie + tee co-drop.", st:"SOLD OUT", pc:"04 PIECES", live:false, gone:true, action:"WAITLIST" },
    { dt:"03.30", yr:"2026 · SUN", nm:"DROP 001 — Notes App Confessions", sub:"3 files. Founder edition.", st:"SOLD OUT", pc:"03 PIECES", live:false, gone:true, action:"ARCHIVE" },
    { dt:"08.??", yr:"2026 · ???", nm:"DROP 004 — █████████████████", sub:"Classified. Members get the file first.", st:"REDACTED", pc:"?? PIECES", live:false, gone:false, action:"SIGN THE NDA" },
  ];
  return (
    <section className="sec" id="schedule">
      <div className="sec-hd">
        <div>
          <div className="num" style={{ marginBottom:14 }}>§ 04 / DROP SCHEDULE ——— DOCKET</div>
          <h2>What's<br/>declassified next.</h2>
        </div>
        <div className="right">
          Drops happen once a month-ish. Folders open at 6pm Eastern. Once they're gone, they're gone.
        </div>
      </div>
      <div className="sched">
        <div className="sched-row sched-head" style={{ color:"rgba(246,243,236,.5)", fontFamily:"'Space Mono',monospace", fontSize:10, letterSpacing:".22em", textTransform:"uppercase", paddingTop:0, paddingBottom:14, borderTop:"none" }}>
          <div>DATE</div><div>FILE</div><div>STATUS</div><div>UNITS</div><div style={{ textAlign:"right" }}>ACTION</div>
        </div>
        {rows.map((r, i) => (
          <div key={i} className={"sched-row " + (r.live ? "live " : "") + (r.gone ? "gone " : "")}>
            <div className="dt">{r.dt}<small>{r.yr}</small></div>
            <div className="nm">{r.nm}<small>{r.sub}</small></div>
            <div className="st">{r.st}</div>
            <div className="pc">{r.pc}</div>
            <div className="ac"><button className="ibtn" style={{ padding:"9px 12px" }}>{r.action}</button></div>
          </div>
        ))}
      </div>
    </section>
  );
};

/* ---------- newsletter / NDA ---------- */
const Newsletter = () => (
  <section className="news" id="news">
    <div className="news-wrap">
      <div className="num mono" style={{ marginBottom:24 }}>§ 05 / MEMBERS ONLY ——— SIGN THE NDA</div>
      <h2>
        sign the <span className="strike-red">NDA</span>.<br/>
        get the file<br/>
        before the world.
      </h2>
      <p>
        Members get drops 24 hours early, leaked sketches from upcoming
        folders, and the occasional shipping freebie. We email maybe twice
        a month. No spam — we have nothing to gain from annoying you.
      </p>
      <form className="news-form" onSubmit={(e) => { e.preventDefault(); alert("Welcome to the archive. We've got receipts on you now."); }}>
        <input type="email" required placeholder="your.alias@gmail.com" />
        <button type="submit">Sign</button>
      </form>
      <div className="news-tags">
        <span>NO SPAM</span>
        <span>UNSUBSCRIBE ANYTIME</span>
        <span>WE DON'T SELL YOUR DATA</span>
        <span>WE DO KEEP RECEIPTS</span>
      </div>
    </div>
  </section>
);

/* ---------- footer ---------- */
const Footer = () => (
  <footer>
    <div className="ft-grid">
      <div className="ft-brand">
        <div className="lo"><Logo size={42} /></div>
        <div>
          <h4 style={{ marginBottom:8 }}>REDACTED ARCHIVES</h4>
          <p>
            A New York streetwear label collecting evidence of a misspent youth.
            Tees, hoodies, and small classified objects, printed in small batches.
          </p>
        </div>
      </div>
      <div>
        <h4>SHOP</h4>
        <ul>
          <li>All Files</li>
          <li>Tees</li>
          <li>Hoodies</li>
          <li>Accessories</li>
          <li>Archive (Sold Out)</li>
        </ul>
      </div>
      <div>
        <h4>INFO</h4>
        <ul>
          <li>Sizing</li>
          <li>Shipping</li>
          <li>Returns</li>
          <li>Care Instructions</li>
          <li>Contact</li>
        </ul>
      </div>
      <div>
        <h4>CLASSIFIED</h4>
        <ul>
          <li>Manifesto</li>
          <li>Drop Schedule</li>
          <li>Newsletter</li>
          <li>Instagram ↗</li>
          <li>TikTok ↗</li>
        </ul>
      </div>
    </div>
    <div className="ft-mass">REDACTED ARCHIVES</div>
    <div className="ft-bot">
      <div>© 2026 REDACTED ARCHIVES LLC · BROOKLYN, NY</div>
      <div>// THIS PAGE WAS NOT REDACTED · YOU JUST CAN'T HANDLE IT //</div>
      <div>v.003.01</div>
    </div>
  </footer>
);

/* ---------- age gate ---------- */
const AgeGate = ({ onPass }) => (
  <div className="gate">
    <div className="gate-box">
      <h3>This file is classified.</h3>
      <p>
        Some of our designs contain double meanings, mild profanity, and
        general overshare. Confirm you're 18 or older to enter the archive.
      </p>
      <div className="gate-row">
        <button className="no" onClick={() => window.location.href = "https://www.google.com"}>No, I am a child</button>
        <button className="go" onClick={onPass}>Yes, declassify</button>
      </div>
    </div>
  </div>
);

/* ---------- redacting cursor ---------- */
const RedactCursor = ({ enabled }) => {
  const ref = React.useRef(null);
  const isTouch = typeof window !== "undefined" && window.matchMedia("(hover: none)").matches;
  React.useEffect(() => {
    if (!enabled || isTouch) return;
    const el = ref.current;
    const move = (e) => {
      el.style.transform = `translate(${e.clientX - 24}px, ${e.clientY - 8}px)`;
    };
    window.addEventListener("mousemove", move);
    return () => window.removeEventListener("mousemove", move);
  }, [enabled, isTouch]);
  if (!enabled || isTouch) return null;
  return (
    <div ref={ref} style={{
      position:"fixed", top:0, left:0, width:48, height:16, background:"#e63329",
      pointerEvents:"none", zIndex:9100, mixBlendMode:"difference",
      boxShadow:"0 0 0 1px rgba(255,255,255,.2)"
    }} />
  );
};

/* ---------- root ---------- */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [gate, setGate] = React.useState(t.showAgeGate);
  const [codeOpen, setCodeOpen] = React.useState(false);

  React.useEffect(() => {
    document.documentElement.style.setProperty("--red", t.accent);
    document.documentElement.style.setProperty("--grain-op", String(t.grain));
  }, [t.accent, t.grain]);

  React.useEffect(() => {
    if (t.redactStyle === "red") {
      document.querySelectorAll(".rd").forEach(el => el.classList.add("red"));
    } else {
      document.querySelectorAll(".rd").forEach(el => el.classList.remove("red"));
    }
  }, [t.redactStyle]);

  return (
    <>
      {gate && <AgeGate onPass={() => setGate(false)} />}
      <RedactCursor enabled={t.cursorMode === "redact"} />

      <Announcement speed={t.marqueeSpeed} />
      <Nav onDropClick={() => setCodeOpen(true)} />
      <DropCodeModal open={codeOpen} onClose={() => setCodeOpen(false)} />
      <Hero />
      <Drop />
      <Lookbook />
      <Manifesto />
      <Schedule />
      <Newsletter />
      <Footer />

      <TweaksPanel>
        <TweakSection label="Brand" />
        <TweakColor label="Accent" value={t.accent}
          options={["#e63329", "#ff2b6b", "#ff5b1e", "#ffc233", "#3ddc84"]}
          onChange={(v) => setTweak("accent", v)} />
        <TweakRadio label="Redact style" value={t.redactStyle}
          options={["black", "red"]} onChange={(v) => setTweak("redactStyle", v)} />
        <TweakSection label="Feel" />
        <TweakSlider label="Grain" value={t.grain} min={0} max={0.2} step={0.01}
          onChange={(v) => setTweak("grain", v)} />
        <TweakSlider label="Marquee speed" value={t.marqueeSpeed} min={8} max={80} step={2} unit="s"
          onChange={(v) => setTweak("marqueeSpeed", v)} />
        <TweakRadio label="Cursor" value={t.cursorMode}
          options={["redact", "default"]} onChange={(v) => setTweak("cursorMode", v)} />
        <TweakSection label="Entry" />
        <TweakToggle label="Age gate on load" value={t.showAgeGate}
          onChange={(v) => { setTweak("showAgeGate", v); setGate(v); }} />
        <TweakButton label="Reopen age gate" onClick={() => setGate(true)} />
      </TweaksPanel>
    </>
  );
}

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