/* global React, ReactDOM, useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakToggle */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- VIEWPORT HOOK ---------- */
function useViewport() {
  const [w, setW] = useState(typeof window !== "undefined" ? window.innerWidth : 1440);
  useEffect(() => {
    const on = () => setW(window.innerWidth);
    window.addEventListener("resize", on);
    return () => window.removeEventListener("resize", on);
  }, []);
  return { w, narrow: w < 1100, tiny: w < 760, mobile: w < 480 };
}

/* ---------- THEMES ---------- */
const THEMES = {
  amber:  { bg: "#000000", fg: "#e8e6e1", dim: "#7a7672", rule: "#1a1a1a", panel: "#0a0a0a", accent: "#ffb300", accentDim: "#664700", danger: "#ff4d2e", ok: "#7cff5c" },
  cyan:   { bg: "#000000", fg: "#e8e6e1", dim: "#7a7672", rule: "#1a1a1a", panel: "#0a0a0a", accent: "#00e5ff", accentDim: "#005966", danger: "#ff4d2e", ok: "#7cff5c" },
  red:    { bg: "#000000", fg: "#e8e6e1", dim: "#7a7672", rule: "#1a1a1a", panel: "#0a0a0a", accent: "#ff3b30", accentDim: "#5a1410", danger: "#ff3b30", ok: "#7cff5c" },
  lime:   { bg: "#000000", fg: "#e8e6e1", dim: "#7a7672", rule: "#1a1a1a", panel: "#0a0a0a", accent: "#b6ff3c", accentDim: "#3a5410", danger: "#ff4d2e", ok: "#b6ff3c" },
  paper:  { bg: "#ece8df", fg: "#0a0a0a", dim: "#6b6660", rule: "#cfc8bb", panel: "#e2ddd1", accent: "#c43c14", accentDim: "#f0c9bc", danger: "#c43c14", ok: "#1f6b1f" },
};

/* ---------- DATA ---------- */
const SERVICES = [
  { id: "IR-01", name: "Incident Response", sla: "1h callback · 24/7", scope: "Pre- and post-breach. Containment, forensics, eradication, recovery. Court-ready chain of custody.", tags: ["DFIR", "Ransomware", "BEC", "APT"] },
  { id: "MD-02", name: "Managed Detection", sla: "Continuous", scope: "Tech-agnostic MDR layered onto your existing SIEM/EDR. We don't sell you tools — we run yours better.", tags: ["SIEM", "EDR", "XDR", "Cloud"] },
  { id: "TH-03", name: "Threat Hunting", sla: "Quarterly + ad-hoc", scope: "Proactive hypothesis-driven hunts against your environment using fresh IOCs from our research desk.", tags: ["MITRE", "TTPs", "OSINT"] },
  { id: "RT-04", name: "Retainer & Tabletop", sla: "On-call", scope: "Pre-negotiated IR retainer with executive tabletop exercises, runbook authoring, and breach-coach coordination.", tags: ["Retainer", "Tabletop", "Counsel"] },
];

const ADVISORIES = [
  { id: "HBA-2026-041", date: "2026-04-28", sev: "CRITICAL", title: "Sustained exploitation of CVE-2026-3199 in Atlassian Confluence Data Center", actor: "UNC-RIPSAW", sectors: ["Legal", "Healthcare", "Finance"], reads: "12.4k" },
  { id: "HBA-2026-040", date: "2026-04-22", sev: "HIGH",     title: "BlackToad ransomware affiliate pivots to MSP supply chain via stolen RMM tokens", actor: "BLACKTOAD",  sectors: ["MSP", "Manufacturing"], reads: "8.1k" },
  { id: "HBA-2026-039", date: "2026-04-15", sev: "HIGH",     title: "Living-off-the-land persistence via Azure Arc onboarding scripts", actor: "STORM-2440", sectors: ["Energy", "Public Sector"], reads: "5.6k" },
  { id: "HBA-2026-038", date: "2026-04-09", sev: "MEDIUM",   title: "OAuth consent phishing campaign targeting M365 global admins in EU law firms", actor: "MIDNIGHT-OWL", sectors: ["Legal"], reads: "4.2k" },
  { id: "HBA-2026-037", date: "2026-04-02", sev: "MEDIUM",   title: "Crypto-drainer-as-a-service infrastructure mapped across 14 Telegram channels", actor: "DRAINPIPE", sectors: ["Web3", "Exchanges"], reads: "9.7k" },
  { id: "HBA-2026-036", date: "2026-03-25", sev: "LOW",      title: "False-positive surge from Defender for Endpoint signature 1.405.221.0 — workaround", actor: "—", sectors: ["All"], reads: "2.1k" },
];

const STATS = [
  { k: "MTTR-median", v: "4.2h", note: "containment, last 90d" },
  { k: "Engagements", v: "318", note: "since 2016" },
  { k: "Researchers", v: "6", note: "full-time, in-house" },
];

/* ---------- PRIMITIVES ---------- */
const Rule = ({ v, style }) => {
  const t = useTheme();
  return <div style={{ background: t.rule, ...(v ? { width: 1, alignSelf: "stretch" } : { height: 1, width: "100%" }), ...style }} />;
};

const ThemeCtx = React.createContext(THEMES.amber);
const useTheme = () => React.useContext(ThemeCtx);

function Caret() {
  const [on, setOn] = useState(true);
  useEffect(() => { const i = setInterval(() => setOn(o => !o), 530); return () => clearInterval(i); }, []);
  const t = useTheme();
  return <span style={{ display: "inline-block", width: "0.55ch", height: "1em", background: on ? t.accent : "transparent", verticalAlign: "-0.12em", marginLeft: "0.15ch" }} />;
}

function Clock() {
  const [now, setNow] = useState(new Date());
  useEffect(() => { const i = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(i); }, []);
  const utc = now.toISOString().replace("T", " ").slice(0, 19) + " UTC";
  return <span>{utc}</span>;
}

function SevDot({ sev }) {
  const t = useTheme();
  const c = sev === "CRITICAL" ? t.danger : sev === "HIGH" ? t.accent : sev === "MEDIUM" ? t.dim : t.ok;
  return <span style={{ display: "inline-block", width: 8, height: 8, background: c, marginRight: 8, verticalAlign: "0.05em" }} />;
}

/* ---------- LAYOUT BLOCKS ---------- */

function StatusBar() {
  const t = useTheme();
  const { tiny, mobile } = useViewport();
  return (
    <div style={{ borderBottom: `1px solid ${t.rule}`, background: t.bg, color: t.dim, fontSize: mobile ? 10 : 11, letterSpacing: "0.04em", textTransform: "uppercase", overflow: "hidden" }}>
      <div style={{ maxWidth: 1440, margin: "0 auto", padding: mobile ? "6px 14px" : "8px 20px", display: "flex", gap: mobile ? 10 : 16, alignItems: "center", justifyContent: "space-between", flexWrap: tiny ? "wrap" : "nowrap" }}>
        <div style={{ display: "flex", gap: mobile ? 10 : 16, alignItems: "center", flexWrap: "wrap" }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
            <span style={{ display: "inline-block", width: 6, height: 6, borderRadius: "50%", background: t.ok, boxShadow: `0 0 8px ${t.ok}` }} />
            <span>incident response · 24/7</span>
          </span>
          {!mobile && <span>·</span>}
          {!mobile && <a href="#contact" onClick={(e) => { e.preventDefault(); window.dispatchEvent(new CustomEvent("hb-open-contact")); }} style={{ color: t.dim, textDecoration: "none", cursor: "pointer" }}>contact ↗</a>}
        </div>
        <div style={{ display: "flex", gap: mobile ? 10 : 16, alignItems: "center", flexWrap: "wrap" }}>
          {!mobile && <span><Clock /></span>}
          {!mobile && <span>·</span>}
          <a href="tel:+19294580453" style={{ color: t.fg, textDecoration: "none" }}>{mobile ? "IR · +1·929·458·0453" : "IR HOTLINE +1·929·458·0453"}</a>
        </div>
      </div>
    </div>
  );
}

function Masthead() {
  const t = useTheme();
  const { narrow, tiny, mobile } = useViewport();
  const [menuOpen, setMenuOpen] = useState(false);
  // close drawer if viewport grows back past tiny
  useEffect(() => { if (!tiny && menuOpen) setMenuOpen(false); }, [tiny, menuOpen]);
  // lock body scroll while drawer is open
  useEffect(() => {
    if (!menuOpen) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") setMenuOpen(false); };
    window.addEventListener("keydown", onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener("keydown", onKey); };
  }, [menuOpen]);

  const NavItem = ({ children, href = "#", active, onClick }) => (
    <a href={href} onClick={onClick} style={{ color: active ? t.fg : t.dim, textDecoration: "none", fontSize: 12, letterSpacing: "0.06em", textTransform: "uppercase", padding: "6px 0", borderBottom: active ? `1px solid ${t.accent}` : "1px solid transparent" }}>{children}</a>
  );

  const openContact = (e) => {
    if (e) e.preventDefault();
    setMenuOpen(false);
    window.dispatchEvent(new CustomEvent("hb-open-contact"));
  };

  const NAV_ITEMS = [
    { label: "services", href: "#services", active: true },
    { label: "research", href: "#research" },
    { label: "retainer", href: "#retainer" },
    { label: "about", href: "#about" },
    { label: "detektix ↗", href: "https://detektix.com", external: true },
    { label: "contact", href: "#contact", onClick: openContact },
  ];

  return (
    <header style={{ borderBottom: `1px solid ${t.rule}`, background: t.bg, position: "sticky", top: 0, zIndex: 5, backdropFilter: "blur(6px)", WebkitBackdropFilter: "blur(6px)" }}>
      <div style={{ maxWidth: 1440, margin: "0 auto", padding: mobile ? "12px 14px" : "18px 20px", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
        <a href="#" style={{ display: "flex", alignItems: "center", gap: 12, color: t.fg, textDecoration: "none", minWidth: 0 }}>
          <Logo size={mobile ? 44 : 64} />
          <span style={{ display: "flex", flexDirection: "column", lineHeight: 1.1, minWidth: 0 }}>
            <span style={{ fontSize: mobile ? 14 : 16, fontWeight: 600, letterSpacing: "-0.01em" }}>honeybadger/sec</span>
            <span style={{ fontSize: mobile ? 9 : 10, color: t.dim, letterSpacing: "0.08em", textTransform: "uppercase", marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{mobile ? "ir · threat research" : "incident response · threat research"}</span>
          </span>
        </a>
        <nav style={{ display: "flex", gap: tiny ? 12 : 28, alignItems: "center", flexWrap: "wrap" }}>
          {!tiny && <NavItem active>services</NavItem>}
          {!tiny && <NavItem>research</NavItem>}
          {!narrow && <NavItem>retainer</NavItem>}
          {!narrow && <NavItem>about</NavItem>}
          {!narrow && <NavItem href="https://detektix.com">detektix ↗</NavItem>}
          {!narrow && <NavItem>contact</NavItem>}
          {!mobile && (
            <a href="#contact" onClick={openContact} style={{ marginLeft: tiny ? 0 : 8, padding: tiny ? "8px 14px" : "10px 18px", background: t.accent, color: t.bg, textDecoration: "none", fontSize: 12, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", display: "inline-flex", alignItems: "center", gap: 8, cursor: "pointer", border: "none", fontFamily: "inherit" }}>
              <span>contact us</span>
              <span>→</span>
            </a>
          )}
          {tiny && (
            <button
              type="button"
              aria-label={menuOpen ? "close menu" : "open menu"}
              aria-expanded={menuOpen}
              onClick={() => setMenuOpen(o => !o)}
              style={{ background: "transparent", border: `1px solid ${t.rule}`, color: t.fg, padding: "8px 10px", display: "inline-flex", flexDirection: "column", gap: 4, cursor: "pointer", fontFamily: "inherit" }}
            >
              <span style={{ width: 18, height: 1.5, background: t.fg, transform: menuOpen ? "translateY(3px) rotate(45deg)" : "none", transition: "transform 150ms" }} />
              <span style={{ width: 18, height: 1.5, background: t.fg, opacity: menuOpen ? 0 : 1, transition: "opacity 100ms" }} />
              <span style={{ width: 18, height: 1.5, background: t.fg, transform: menuOpen ? "translateY(-3px) rotate(-45deg)" : "none", transition: "transform 150ms" }} />
            </button>
          )}
        </nav>
      </div>

      {tiny && menuOpen && ReactDOM.createPortal(
        <div style={{ position: "fixed", inset: 0, top: 0, background: t.bg, zIndex: 200, display: "flex", flexDirection: "column", overflowY: "auto" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px 18px", borderBottom: `1px solid ${t.rule}` }}>
            <span style={{ color: t.dim, fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase" }}><span style={{ color: t.accent }}>§</span> menu</span>
            <button aria-label="close menu" onClick={() => setMenuOpen(false)} style={{ background: "transparent", border: "none", color: t.fg, fontSize: 22, cursor: "pointer", fontFamily: "inherit", padding: 4 }}>×</button>
          </div>
          <nav style={{ display: "flex", flexDirection: "column", padding: "8px 0" }}>
            {NAV_ITEMS.map(item => (
              <a
                key={item.label}
                href={item.href}
                target={item.external ? "_blank" : undefined}
                rel={item.external ? "noopener" : undefined}
                onClick={item.onClick ? item.onClick : () => setMenuOpen(false)}
                style={{ padding: "18px 22px", color: t.fg, textDecoration: "none", fontSize: 18, fontWeight: 500, letterSpacing: "-0.01em", borderBottom: `1px solid ${t.rule}`, display: "flex", alignItems: "center", justifyContent: "space-between" }}
              >
                <span>{item.label}</span>
                <span style={{ color: t.dim, fontSize: 18 }}>→</span>
              </a>
            ))}
          </nav>
          <div style={{ marginTop: "auto", padding: "20px 22px", borderTop: `1px solid ${t.rule}`, display: "flex", flexDirection: "column", gap: 12 }}>
            <a href="tel:+19294580453" style={{ background: t.accent, color: t.bg, padding: "16px 20px", textDecoration: "none", fontSize: 13, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
                <span style={{ width: 6, height: 6, background: t.bg, borderRadius: "50%" }} />
                <span>actively breached?</span>
              </span>
              <span>+1 929 458 0453</span>
            </a>
            <a href="#contact" onClick={openContact} style={{ border: `1px solid ${t.fg}`, color: t.fg, padding: "14px 20px", textDecoration: "none", fontSize: 12, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", textAlign: "center" }}>
              contact us
            </a>
          </div>
        </div>,
        document.body
      )}
    </header>
  );
}

function Logo({ size = 56 }) {
  const t = useTheme();
  const [imgOk, setImgOk] = useState(true);
  if (imgOk) {
    return (
      <img
        src="uploads/logo.png"
        alt="Honey Badger Security"
        width={size}
        height={size}
        onError={() => setImgOk(false)}
        style={{ display: "block", width: size, height: size, objectFit: "contain" }}
      />
    );
  }
  return (
    <svg width={size} height={size} viewBox="0 0 36 36" style={{ display: "block" }}>
      <rect x="0.5" y="0.5" width="35" height="35" fill="none" stroke={t.fg} strokeWidth="1" />
      <text x="18" y="14" textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="9" fontWeight="700" fill={t.fg} letterSpacing="0.5">HB</text>
      <line x1="6" y1="18" x2="30" y2="18" stroke={t.rule} strokeWidth="1" />
      <text x="18" y="28" textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="6" fontWeight="500" fill={t.accent} letterSpacing="1">SEC</text>
    </svg>
  );
}

/* ---------- TYPEWRITER ---------- */
// Cycles through the openers: types char-by-char, holds, then backspaces and
// picks a different opener. Returns the per-line text plus which line the
// caret is currently on. Respects prefers-reduced-motion.
function useTypewriterOpeners(openers) {
  const reducedMotion = useMemo(() => (
    typeof window !== "undefined"
    && typeof window.matchMedia === "function"
    && window.matchMedia("(prefers-reduced-motion: reduce)").matches
  ), []);

  const [openerIdx, setOpenerIdx] = useState(() => Math.floor(Math.random() * openers.length));
  const [charIdx, setCharIdx] = useState(reducedMotion ? Number.MAX_SAFE_INTEGER : 0);
  const [phase, setPhase] = useState("typing"); // typing | holding | deleting

  const target = useMemo(() => openers[openerIdx].join("\n"), [openers, openerIdx]);

  useEffect(() => {
    if (reducedMotion) return;
    let timeoutId;

    if (phase === "typing") {
      if (charIdx < target.length) {
        const nextChar = target[charIdx];
        // mild human-feel jitter; longer beat at line breaks
        const delay = nextChar === "\n" ? 220 : 30 + Math.random() * 50;
        timeoutId = setTimeout(() => setCharIdx(charIdx + 1), delay);
      } else {
        timeoutId = setTimeout(() => setPhase("holding"), 50);
      }
    } else if (phase === "holding") {
      timeoutId = setTimeout(() => setPhase("deleting"), 2200);
    } else if (phase === "deleting") {
      if (charIdx > 0) {
        timeoutId = setTimeout(() => setCharIdx(charIdx - 1), 18);
      } else {
        let next = openerIdx;
        if (openers.length > 1) {
          while (next === openerIdx) next = Math.floor(Math.random() * openers.length);
        }
        setOpenerIdx(next);
        setPhase("typing");
      }
    }

    return () => clearTimeout(timeoutId);
  }, [phase, charIdx, target, openers, openerIdx, reducedMotion]);

  const visible = reducedMotion ? target : target.slice(0, charIdx);
  const lines = visible.split("\n");
  while (lines.length < 3) lines.push("");
  const caretLine = reducedMotion ? 2 : (visible.match(/\n/g) || []).length;

  return { line1: lines[0], line2: lines[1], line3: lines[2], caretLine };
}

/* ---------- HERO ---------- */
function Hero() {
  const t = useTheme();
  const { narrow, tiny, mobile } = useViewport();
  // 25 openers — each: [line1, line2 (dimmed), line3 (final beat with caret)]
  const openers = useMemo(() => [
    ["when the alert", "at 03:14 says", "encrypted."],
    ["when your CFO emails", "at 06:02 asking", "is this real?"],
    ["when the SOC tells you", "they've been seeing this", "for six weeks."],
    ["when the wire instructions", "the controller followed", "weren't yours."],
    ["when the EDR shrugs and", "the only thing you trust", "is dialtone."],
    ["when legal asks", "exactly what was", "exfiltrated."],
    ["when the press calls", "before your", "incident lead does."],
    ["when the insurer wants", "a written timeline by", "end of business."],
    ["when the only Slack channel", "still working is the one", "on someone's phone."],
    ["when production is down,", "the runbook is on prod,", "and prod is locked."],
    ["when the post-mortem", "you wrote last quarter", "happened again."],
    ["when the ransom note", "names a deadline,", "and a price."],
    ["when the threat actor", "knows your tenant ID", "by heart."],
    ["when the auditor finds it", "before your", "detection stack does."],
    ["when the dev who", "had the only key", "left in March."],
    ["when the canary", "you forgot you planted", "finally chirps."],
    ["when the board calls", "an emergency session", "for tomorrow, 8am."],
    ["when an engineer says", "this isn't supposed to be", "reachable from the internet."],
    ["when the IOCs match", "an advisory you", "skimmed last Tuesday."],
    ["when the only person", "who knows that pipeline", "is on a flight."],
    ["when 'low severity'", "turns out to be", "domain admin."],
    ["when the breach disclosure", "clock starts at", "72 hours."],
    ["when the build server", "starts shipping", "to an address in Tashkent."],
    ["when your compliance posture", "and your reality", "stop matching."],
    ["when the customer's lawyer", "knows more about it", "than you do."],
    ["when the investigation", "is going to take longer", "than the outage."],
    ["when the threat hunter", "asks if you have", "a minute."],
    ["when the npm postinstall", "you greenlit on Friday", "wasn't from them."],
  ], []);
  const { line1, line2, line3, caretLine } = useTypewriterOpeners(openers);
  return (
    <section style={{ borderBottom: `1px solid ${t.rule}`, position: "relative", overflow: "hidden" }}>
      {/* full-bleed looping video background */}
      <video
        src="uploads/hero-loop.mp4"
        autoPlay
        loop
        muted
        playsInline
        preload={mobile ? "metadata" : "auto"}
        aria-hidden="true"
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: tiny ? "cover" : "contain", objectPosition: "center", zIndex: 0, opacity: tiny ? 0.35 : 0.55, background: t.bg, transform: tiny ? "none" : "scale(0.62)", transformOrigin: "center center" }}
      />
      {/* gradient + grain overlays for legibility */}
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, background: `linear-gradient(180deg, ${t.bg}cc 0%, ${t.bg}80 35%, ${t.bg}cc 100%)`, zIndex: 1, pointerEvents: "none" }} />
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, background: `radial-gradient(ellipse at 70% 30%, transparent 0%, ${t.bg} 75%)`, zIndex: 1, pointerEvents: "none" }} />

      <div style={{ maxWidth: 1440, margin: "0 auto", display: "grid", gridTemplateColumns: narrow ? "1fr" : "minmax(0, 1fr) 380px", position: "relative", zIndex: 2 }}>
        {/* LEFT: headline + console */}
        <div style={{ padding: mobile ? "40px 16px 36px" : tiny ? "56px 20px 44px" : "72px 32px 56px 20px", borderRight: narrow ? "none" : `1px solid ${t.rule}`, borderBottom: narrow ? `1px solid ${t.rule}` : "none" }}>
          <div style={{ color: t.dim, fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: mobile ? 20 : 28, display: "flex", gap: 16 }}>
            <span style={{ color: t.accent }}>§00</span>
            <span>opening statement</span>
            <span style={{ flex: 1, height: 1, background: t.rule, alignSelf: "center" }} />
          </div>
          <h1 style={{ fontSize: "clamp(32px, 8.5vw, 78px)", lineHeight: 0.98, letterSpacing: "-0.035em", fontWeight: 600, margin: 0, color: t.fg, overflowWrap: "break-word", minHeight: "calc(0.98em * 3)" }}>
            <span>{line1}{caretLine === 0 && <Caret />}</span>
            <br />
            <span style={{ color: t.dim }}>{line2}{caretLine === 1 && <Caret />}</span>
            <br />
            <span>{line3}{caretLine === 2 && <Caret />}</span>
          </h1>
          <p style={{ fontSize: mobile ? 15 : 17, lineHeight: 1.55, color: t.fg, maxWidth: 620, marginTop: mobile ? 24 : 36, marginBottom: 0 }}>
            Honey Badger Security is a small, deep-bench incident response firm. We don't sell software, we don't write whitepapers about ourselves, and we don't pitch your CFO on platforms.
            <br /><br />
            <span style={{ color: t.dim }}>We get on the phone. We contain the bleed. We tell you what happened, in writing, in language your board and your insurer will both accept.</span>
          </p>

          <div style={{ display: "flex", gap: mobile ? 12 : 16, marginTop: mobile ? 28 : 44, alignItems: "stretch", flexWrap: "wrap" }}>
            <a href="#retainer" style={{ background: t.accent, color: t.bg, padding: mobile ? "14px 18px" : "18px 28px", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: mobile ? 10 : 14, fontSize: mobile ? 12 : 13, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", flex: mobile ? "1 1 100%" : "0 1 auto", justifyContent: mobile ? "center" : "flex-start", flexWrap: "wrap" }}>
              <span style={{ width: 6, height: 6, background: t.bg, flexShrink: 0 }} />
              <span>sign an IR retainer</span>
              {!mobile && <span style={{ opacity: 0.7 }}>↳ 30-min scoping call</span>}
            </a>
            <a href="tel:+19294580453" style={{ border: `1px solid ${t.fg}`, color: t.fg, padding: mobile ? "14px 18px" : "18px 28px", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: mobile ? 10 : 14, fontSize: mobile ? 12 : 13, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", flex: mobile ? "1 1 100%" : "0 1 auto", justifyContent: mobile ? "center" : "flex-start" }}>
              <span style={{ width: 6, height: 6, background: t.danger, boxShadow: `0 0 8px ${t.danger}`, flexShrink: 0 }} />
              <span>{mobile ? "breached? · +1 929 458 0453" : "actively breached? · +1 929 458 0453"}</span>
            </a>
          </div>

          {!mobile && (
            <div style={{ display: "flex", gap: 28, marginTop: 52, color: t.dim, fontSize: 11, letterSpacing: "0.06em", textTransform: "uppercase", flexWrap: "wrap" }}>
              <span>partner-led engagements</span>
              <span>·</span>
              <span>court-ready forensics</span>
              <span>·</span>
              <span>insurer & counsel coordination</span>
            </div>
          )}
        </div>

        {/* RIGHT: live console */}
        <ConsolePanel />
      </div>

      {/* Stats row */}
      <div style={{ borderTop: `1px solid ${t.rule}`, display: "grid", gridTemplateColumns: mobile ? "1fr" : "repeat(3, 1fr)" }}>
        {STATS.map((s, i) => (
          <div key={s.k} style={{ padding: mobile ? "20px 16px" : "28px 20px", borderRight: !mobile && i < STATS.length - 1 ? `1px solid ${t.rule}` : "none", borderBottom: mobile && i < STATS.length - 1 ? `1px solid ${t.rule}` : "none", display: "flex", flexDirection: mobile ? "row" : "column", justifyContent: mobile ? "space-between" : "flex-start", alignItems: mobile ? "baseline" : "stretch", gap: mobile ? 12 : 8 }}>
            <div style={{ color: t.dim, fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", flex: mobile ? "0 0 auto" : "0 0 auto" }}>{s.k}</div>
            <div style={{ fontSize: mobile ? 26 : 36, fontWeight: 600, letterSpacing: "-0.02em", color: t.fg, fontVariantNumeric: "tabular-nums" }}>{s.v}</div>
            <div style={{ color: t.dim, fontSize: 12, textAlign: mobile ? "right" : "left", flex: mobile ? "1 1 auto" : "0 0 auto" }}>{s.note}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

function ConsolePanel() {
  const t = useTheme();
  const { mobile, narrow } = useViewport();
  const lines = [
    { c: t.dim, s: "$ hb-soc --tail engagements" },
    { c: t.dim, s: "[connecting to bastion-04 ...] ok" },
    { c: t.fg,  s: "2026-04-30 14:02:11Z  ENG-3041  ransomware    contained" },
    { c: t.fg,  s: "2026-04-30 11:48:55Z  ENG-3040  bec / wire    in-progress" },
    { c: t.fg,  s: "2026-04-29 22:17:03Z  ENG-3039  cloud-pivot   eradicated" },
    { c: t.fg,  s: "2026-04-29 09:31:42Z  ENG-3038  insider       remediated" },
    { c: t.dim, s: "—" },
    { c: t.accent, s: "$ hb-soc --threat-level" },
    { c: t.fg,  s: "ELEVATED  (ransomware affiliates active in legal & MSP)" },
    { c: t.dim, s: "$ _" },
  ];
  return (
    <div style={{ background: t.panel + "e6", backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)", color: t.fg, fontSize: mobile ? 11 : 12, lineHeight: 1.75, padding: mobile ? "16px 16px" : "20px 24px", display: "flex", flexDirection: "column", borderLeft: narrow ? "none" : `1px solid ${t.rule}`, borderTop: narrow ? `1px solid ${t.rule}` : "none" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingBottom: 14, borderBottom: `1px solid ${t.rule}`, marginBottom: 16 }}>
        <span style={{ color: t.dim, fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase" }}>live · soc · readonly</span>
        <span style={{ display: "flex", gap: 6 }}>
          <span style={{ width: 8, height: 8, background: t.danger }} />
          <span style={{ width: 8, height: 8, background: t.accent }} />
          <span style={{ width: 8, height: 8, background: t.ok }} />
        </span>
      </div>
      <div style={{ flex: 1, overflow: "hidden" }}>
        {lines.map((l, i) => (
          <div key={i} style={{ color: l.c, whiteSpace: mobile ? "normal" : "pre", overflow: "hidden", textOverflow: "ellipsis", overflowWrap: "anywhere" }}>{l.s}</div>
        ))}
        <div style={{ color: t.accent }}>▌</div>
      </div>
      <div style={{ borderTop: `1px solid ${t.rule}`, marginTop: 16, paddingTop: 14, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, fontSize: 11, color: t.dim }}>
        <div>retainer queue<br /><span style={{ color: t.fg, fontSize: 14 }}>2 slots / Q3</span></div>
        <div>median MTTR<br /><span style={{ color: t.fg, fontSize: 14 }}>4h 12m</span></div>
      </div>
    </div>
  );
}

/* ---------- SECTIONS ---------- */
function SectionHeader({ no, label, kicker }) {
  const t = useTheme();
  const { mobile } = useViewport();
  return (
    <div style={{ display: "flex", alignItems: "baseline", gap: mobile ? 12 : 24, padding: mobile ? "24px 16px 12px" : "32px 32px 16px", borderBottom: `1px solid ${t.rule}`, flexWrap: "wrap" }}>
      <span style={{ color: t.accent, fontSize: 11, letterSpacing: "0.12em" }}>§{no}</span>
      <span style={{ fontSize: 11, color: t.dim, letterSpacing: "0.12em", textTransform: "uppercase" }}>{label}</span>
      <span style={{ flex: 1, height: 1, background: t.rule, minWidth: 20 }} />
      {kicker && <span style={{ fontSize: 11, color: t.dim, letterSpacing: "0.06em", textTransform: "uppercase" }}>{kicker}</span>}
    </div>
  );
}

function Services() {
  const t = useTheme();
  const { narrow, tiny, mobile } = useViewport();
  return (
    <section id="services" style={{ borderBottom: `1px solid ${t.rule}` }}>
      <div style={{ maxWidth: 1440, margin: "0 auto" }}>
        <SectionHeader no="01" label="services" kicker="four lines, one team" />
        <div style={{ padding: mobile ? "32px 16px 20px" : "48px 20px 24px", display: "grid", gridTemplateColumns: narrow ? "1fr" : "minmax(0, 480px) 1fr", gap: tiny ? 16 : narrow ? 24 : 64, alignItems: "end" }}>
          <h2 style={{ fontSize: "clamp(24px, 5.5vw, 44px)", lineHeight: 1.05, letterSpacing: "-0.025em", fontWeight: 600, margin: 0, color: t.fg }}>
            Four things.<br />
            <span style={{ color: t.dim }}>Done by people who have done them before.</span>
          </h2>
          <p style={{ fontSize: mobile ? 13 : 14, color: t.dim, lineHeight: 1.6, margin: 0, maxWidth: 480 }}>
            Every engagement is led by a partner with at least a decade of in-the-room IR experience. No junior-led discovery, no offshore L1, no "platform" you'll never log into. If we can't add value within the first hour, we'll tell you and refund the call fee.
          </p>
        </div>
        {/* Table-like rows */}
        <div style={{ marginTop: 24 }}>
          {!narrow && (
            <div style={{ display: "grid", gridTemplateColumns: "68px minmax(0, 1.2fr) minmax(0, 0.9fr) minmax(0, 2fr) minmax(0, 1.1fr)", padding: "12px 20px", borderTop: `1px solid ${t.rule}`, borderBottom: `1px solid ${t.rule}`, color: t.dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", gap: 20 }}>
              <span>id</span><span>line</span><span>availability</span><span>scope</span><span>tags</span>
            </div>
          )}
          {SERVICES.map((s, i) => <ServiceRow key={s.id} s={s} idx={i} />)}
        </div>
      </div>
    </section>
  );
}

function ServiceRow({ s, idx }) {
  const t = useTheme();
  const { narrow, mobile } = useViewport();
  const [hover, setHover] = useState(false);
  if (narrow) {
    return (
      <div
        onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
        style={{ padding: mobile ? "20px 16px" : "24px 20px", borderTop: idx === 0 ? `1px solid ${t.rule}` : "none", borderBottom: `1px solid ${t.rule}`, background: hover ? t.panel : "transparent", transition: "background 120ms", cursor: "pointer" }}
      >
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 10, color: t.dim, fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", flexWrap: "wrap", gap: 8 }}>
          <span style={{ color: hover ? t.accent : t.dim }}>{s.id}</span>
          <span style={{ color: t.fg }}><span style={{ display: "inline-block", width: 6, height: 6, background: t.ok, marginRight: 8, verticalAlign: "0.1em" }} />{s.sla}</span>
        </div>
        <div style={{ color: t.fg, fontSize: mobile ? 19 : 22, fontWeight: 600, letterSpacing: "-0.015em", lineHeight: 1.15, marginBottom: 10 }}>{s.name}</div>
        <div style={{ color: t.dim, fontSize: mobile ? 13 : 14, lineHeight: 1.55, marginBottom: 14 }}>{s.scope}</div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
          {s.tags.map(tag => (
            <span key={tag} style={{ border: `1px solid ${t.rule}`, color: t.dim, fontSize: 11, padding: "3px 8px", letterSpacing: "0.04em" }}>{tag}</span>
          ))}
        </div>
      </div>
    );
  }
  return (
    <div
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ display: "grid", gridTemplateColumns: "68px minmax(0, 1.2fr) minmax(0, 0.9fr) minmax(0, 2fr) minmax(0, 1.1fr)", padding: "28px 20px", borderBottom: `1px solid ${t.rule}`, gap: 20, alignItems: "start", background: hover ? t.panel : "transparent", transition: "background 120ms", cursor: "pointer" }}
    >
      <span style={{ color: hover ? t.accent : t.dim, fontSize: 12, fontWeight: 500, letterSpacing: "0.04em" }}>{s.id}</span>
      <span style={{ color: t.fg, fontSize: "clamp(18px, 1.6vw, 22px)", fontWeight: 600, letterSpacing: "-0.015em", lineHeight: 1.15 }}>{s.name}</span>
      <span style={{ color: t.fg, fontSize: 13 }}>
        <span style={{ display: "inline-block", width: 6, height: 6, background: t.ok, marginRight: 8, verticalAlign: "0.1em" }} />
        {s.sla}
      </span>
      <span style={{ color: t.dim, fontSize: 14, lineHeight: 1.55 }}>{s.scope}</span>
      <span style={{ display: "flex", flexWrap: "wrap", gap: 6, alignItems: "flex-start" }}>
        {s.tags.map(tag => (
          <span key={tag} style={{ border: `1px solid ${t.rule}`, color: t.dim, fontSize: 11, padding: "3px 8px", letterSpacing: "0.04em" }}>{tag}</span>
        ))}
      </span>
    </div>
  );
}

/* ---------- RETAINER STRIP ---------- */
function RetainerStrip() {
  const t = useTheme();
  const { narrow, tiny, mobile } = useViewport();
  return (
    <section id="retainer" style={{ borderBottom: `1px solid ${t.rule}`, background: t.panel }}>
      <div style={{ maxWidth: 1440, margin: "0 auto", padding: mobile ? "36px 16px" : "56px 20px", display: "grid", gridTemplateColumns: tiny ? "1fr" : narrow ? "1fr 1fr" : "minmax(0, 1.4fr) 1fr 1fr 1fr", gap: mobile ? 20 : narrow ? 32 : 48, alignItems: "center" }}>
        <div>
          <div style={{ color: t.accent, fontSize: 11, letterSpacing: "0.12em", marginBottom: 12 }}>§02 / RETAINER</div>
          <h3 style={{ fontSize: "clamp(22px, 5vw, 32px)", margin: 0, letterSpacing: "-0.02em", color: t.fg, lineHeight: 1.15, fontWeight: 600 }}>
            The cheapest hour you'll buy this year is the one you buy <span style={{ color: t.accent }}>before</span> you need it.
          </h3>
        </div>
        <Pill k="Onboarding" v="≤ 5 business days" />
        <Pill k="Pre-paid hours" v="20 / 50 / 120" sub="annual blocks" />
        <Pill k="First-call SLA" v="60 minutes" sub="24 / 7 / 365" />
      </div>
    </section>
  );
}

function Pill({ k, v, sub }) {
  const t = useTheme();
  const { tiny, mobile } = useViewport();
  return (
    <div style={{ borderLeft: tiny ? "none" : `1px solid ${t.rule}`, borderTop: tiny ? `1px solid ${t.rule}` : "none", paddingLeft: tiny ? 0 : 24, paddingTop: tiny ? 16 : 0, minWidth: 0 }}>
      <div style={{ color: t.dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase" }}>{k}</div>
      <div style={{ color: t.fg, fontSize: mobile ? 22 : 28, fontWeight: 600, letterSpacing: "-0.02em", marginTop: 6, fontVariantNumeric: "tabular-nums", overflowWrap: "break-word" }}>{v}</div>
      {sub && <div style={{ color: t.dim, fontSize: 12, marginTop: 4 }}>{sub}</div>}
    </div>
  );
}

/* ---------- RESEARCH ---------- */
function Research() {
  const t = useTheme();
  const { narrow, mobile } = useViewport();
  const [email, setEmail] = useState("");
  const [sub, setSub] = useState(false);
  return (
    <section id="research" style={{ borderBottom: `1px solid ${t.rule}` }}>
      <div style={{ maxWidth: 1440, margin: "0 auto" }}>
        <SectionHeader no="03" label="threat research" kicker="coming soon" />
        <div style={{ display: "grid", gridTemplateColumns: narrow ? "1fr" : "minmax(0, 1.2fr) minmax(0, 1fr)" }}>
          {/* LEFT: pitch */}
          <div style={{ padding: mobile ? "36px 16px 44px" : "56px 20px 64px", borderRight: narrow ? "none" : `1px solid ${t.rule}`, borderBottom: narrow ? `1px solid ${t.rule}` : "none" }}>
            <div style={{ display: "inline-flex", alignItems: "center", gap: 10, padding: "6px 12px", border: `1px solid ${t.accent}`, color: t.accent, fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase", marginBottom: 28 }}>
              <span style={{ width: 6, height: 6, background: t.accent, animation: "hbpulse 1.4s ease-in-out infinite" }} />
              <span>publishing Q3 2026</span>
            </div>
            <h2 style={{ fontSize: "clamp(28px, 6vw, 52px)", lineHeight: 1.05, letterSpacing: "-0.025em", fontWeight: 600, margin: 0, color: t.fg }}>
              The research desk<br /><span style={{ color: t.dim }}>goes public this summer.</span>
            </h2>
            <p style={{ fontSize: 16, color: t.fg, lineHeight: 1.55, marginTop: 28, marginBottom: 0, maxWidth: 580 }}>
              We've been writing internal advisories for our retainer clients since 2016. Later this year we'll start publishing the sanitised versions — actor profiles, IOCs, and after-actions — to anyone who wants to read them.
            </p>
            <p style={{ fontSize: 14, color: t.dim, lineHeight: 1.6, marginTop: 18, marginBottom: 0, maxWidth: 580 }}>
              No marketing newsletter. No gated PDFs. RSS / STIX&nbsp;TAXII friendly. One email when issue 01 ships, then nothing unless something is on fire.
            </p>

            {/* signup */}
            <form
              onSubmit={(e) => { e.preventDefault(); if (email) setSub(true); }}
              style={{ marginTop: 36, display: "flex", flexWrap: "wrap", gap: 0, border: `1px solid ${t.rule}`, maxWidth: 520, alignItems: "stretch" }}
            >
              <span style={{ padding: "14px 16px", color: t.accent, fontSize: 12, letterSpacing: "0.08em", borderRight: `1px solid ${t.rule}`, alignSelf: "center" }}>$</span>
              <label htmlFor="research-email" style={{ position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0,0,0,0)", border: 0 }}>Email address</label>
              <input
                id="research-email"
                type="email"
                required
                placeholder="you@your-org.com"
                aria-label="Email address for research notifications"
                value={email}
                onChange={(e) => { setEmail(e.target.value); setSub(false); }}
                style={{ flex: 1, minWidth: mobile ? 120 : 180, background: "transparent", border: "none", outline: "none", color: t.fg, fontFamily: "inherit", fontSize: mobile ? 13 : 14, padding: "14px 14px" }}
              />
              <button type="submit" style={{ background: t.accent, color: t.bg, border: "none", padding: mobile ? "12px 16px" : "0 22px", fontFamily: "inherit", fontSize: 12, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase", cursor: "pointer", flex: mobile ? "1 1 100%" : "0 0 auto" }}>
                {sub ? "queued ✓" : "notify me"}
              </button>
            </form>
            <div style={{ marginTop: 12, color: t.dim, fontSize: 11, letterSpacing: "0.04em" }}>
              we will email once. unsubscribe is a one-click mailto. that’s it.
            </div>
          </div>

          {/* RIGHT: products card stack */}
          <div style={{ padding: mobile ? "24px 16px" : "32px 24px", background: t.panel, display: "flex", flexDirection: "column", gap: 24 }}>
            <div style={{ color: t.dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase" }}>also from honey badger</div>

            {/* DETEKTIX */}
            <div style={{ borderTop: `1px solid ${t.rule}`, paddingTop: 20 }}>
              <div style={{ display: "flex", alignItems: "baseline", gap: 12, marginBottom: 8, flexWrap: "wrap" }}>
                <h3 style={{ fontSize: "clamp(24px, 6vw, 32px)", margin: 0, fontWeight: 600, letterSpacing: "-0.025em", color: t.fg }}>detektix</h3>
                <span style={{ color: t.dim, fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase" }}>we catch data leaks before they spread</span>
              </div>
              <p style={{ color: t.dim, fontSize: 13, lineHeight: 1.6, margin: 0, marginBottom: 16, maxWidth: 480 }}>
                In the competitive Forex industry, your client data is your most valuable asset. Our innovative approach is refreshingly simple — catch data thieves in the act, not months later.
              </p>
              <div style={{ display: "flex", flexDirection: "column", gap: 14, marginBottom: 18 }}>
                {[
                  { h: "Instant Detection", b: "Detects PII leaks instantly, before data spreads." },
                  { h: "AI-Powered Engagement", b: "Generative AI simulates user behavior and interacts with attackers — gathering threat intel in real time." },
                  { h: "Stealthy Deception Layer", b: "PhantomID tokens are invisible to legitimate users and undetectable by attackers." },
                  { h: "Flexible Deployment", b: "Cloud, SaaS, and on-premises data systems." },
                ].map((it, i) => (
                  <div key={i} style={{ display: "grid", gridTemplateColumns: "24px 1fr", gap: 12, color: t.fg, fontSize: 13, lineHeight: 1.5 }}>
                    <span style={{ color: t.accent, fontVariantNumeric: "tabular-nums" }}>0{i + 1}</span>
                    <span><span style={{ color: t.fg, fontWeight: 600 }}>{it.h}.</span> <span style={{ color: t.dim }}>{it.b}</span></span>
                  </div>
                ))}
              </div>
              <a href="https://detektix.com" target="_blank" rel="noopener" style={{ display: "inline-flex", alignItems: "center", gap: 10, padding: "10px 16px", border: `1px solid ${t.fg}`, color: t.fg, textDecoration: "none", fontSize: 11, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase" }}>
                <span>detektix.com</span>
                <span style={{ color: t.accent }}>↗</span>
              </a>
            </div>

            {/* WHITESHROUD */}
            <div style={{ borderTop: `1px solid ${t.rule}`, paddingTop: 20 }}>
              <div style={{ display: "flex", alignItems: "baseline", gap: 12, marginBottom: 8, flexWrap: "wrap" }}>
                <h3 style={{ fontSize: "clamp(24px, 6vw, 32px)", margin: 0, fontWeight: 600, letterSpacing: "-0.025em", color: t.fg }}>whiteshroud</h3>
                <span style={{ color: t.ok, fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase" }}>open source</span>
              </div>
              <p style={{ color: t.dim, fontSize: 13, lineHeight: 1.6, margin: 0, marginBottom: 16, maxWidth: 480 }}>
                Tracker for the ongoing Shai-Hulud npm worm campaign. Live roster of compromised packages, maintainers, and IOCs — pulled from registry telemetry and our own honeypots, updated as the worm spreads.
              </p>
              <a href="https://whiteshroud.io" target="_blank" rel="noopener" style={{ display: "inline-flex", alignItems: "center", gap: 10, padding: "10px 16px", border: `1px solid ${t.fg}`, color: t.fg, textDecoration: "none", fontSize: 11, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase" }}>
                <span>whiteshroud.io</span>
                <span style={{ color: t.accent }}>↗</span>
              </a>
            </div>

            {/* BADGERINTEL */}
            <div style={{ borderTop: `1px solid ${t.rule}`, paddingTop: 20 }}>
              <div style={{ display: "flex", alignItems: "baseline", gap: 12, marginBottom: 8, flexWrap: "wrap" }}>
                <h3 style={{ fontSize: "clamp(24px, 6vw, 32px)", margin: 0, fontWeight: 600, letterSpacing: "-0.025em", color: t.fg }}>badgerintel feed</h3>
                <span style={{ color: t.dim, fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase" }}>curated threat intel</span>
              </div>
              <p style={{ color: t.dim, fontSize: 13, lineHeight: 1.6, margin: 0, marginBottom: 16, maxWidth: 480 }}>
                A curated intelligence feed tuned per industry — fintech, forex, gaming, SaaS, e-commerce. IOCs, actor TTPs, and emerging campaigns, filtered to what actually matters for your stack. Delivered as STIX/TAXII, JSON, or weekly briefing.
              </p>
              <a href="#contact" onClick={(e) => { e.preventDefault(); window.dispatchEvent(new CustomEvent("hb-open-contact")); }} style={{ display: "inline-flex", alignItems: "center", gap: 10, padding: "10px 16px", border: `1px solid ${t.fg}`, color: t.fg, textDecoration: "none", fontSize: 11, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase", cursor: "pointer", fontFamily: "inherit" }}>
                <span>contact for access</span>
                <span style={{ color: t.accent }}>→</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function FeaturedAdvisory({ a }) {
  const t = useTheme();
  return (
    <article style={{ padding: "40px 32px", display: "flex", flexDirection: "column", gap: 24 }}>
      <div style={{ display: "flex", gap: 16, alignItems: "center", color: t.dim, fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase" }}>
        <span style={{ color: t.accent }}>{a.id}</span>
        <span>·</span>
        <span>{a.date}</span>
        <span>·</span>
        <span><SevDot sev={a.sev} />{a.sev}</span>
        <span>·</span>
        <span>actor: <span style={{ color: t.fg }}>{a.actor}</span></span>
      </div>
      <h3 style={{ fontSize: 36, lineHeight: 1.1, letterSpacing: "-0.025em", fontWeight: 600, color: t.fg, margin: 0 }}>
        {a.title}
      </h3>
      <p style={{ fontSize: 14, color: t.dim, lineHeight: 1.6, margin: 0, maxWidth: 620 }}>
        Initial access via unauthenticated template-injection. Operators stage Cobalt Strike beacons within 22 minutes of foothold and pivot to ESXi within 4 hours. We've observed three confirmed engagements this week; two contained pre-encryption.
      </p>
      <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
        {a.sectors.map(s => <span key={s} style={{ border: `1px solid ${t.rule}`, color: t.dim, fontSize: 11, padding: "4px 10px", letterSpacing: "0.04em" }}>{s}</span>)}
      </div>
      <div style={{ display: "flex", gap: 24, alignItems: "center", marginTop: 8 }}>
        <a href="#" style={{ color: t.accent, textDecoration: "none", fontSize: 12, letterSpacing: "0.08em", textTransform: "uppercase", borderBottom: `1px solid ${t.accent}`, paddingBottom: 4 }}>read full advisory ↗</a>
        <span style={{ color: t.dim, fontSize: 11 }}>{a.reads} reads</span>
      </div>
    </article>
  );
}

function AdvisoryRow({ a }) {
  const t = useTheme();
  const [hover, setHover] = useState(false);
  return (
    <a href="#" onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} style={{ display: "block", padding: "20px 28px", borderBottom: `1px solid ${t.rule}`, textDecoration: "none", color: "inherit", background: hover ? t.panel : "transparent", transition: "background 120ms" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", color: t.dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 8 }}>
        <span style={{ color: hover ? t.accent : t.dim }}>{a.id}</span>
        <span>{a.date}</span>
      </div>
      <div style={{ color: t.fg, fontSize: 16, lineHeight: 1.35, letterSpacing: "-0.005em", marginBottom: 10 }}>{a.title}</div>
      <div style={{ display: "flex", gap: 12, alignItems: "center", color: t.dim, fontSize: 11, letterSpacing: "0.04em" }}>
        <span><SevDot sev={a.sev} />{a.sev}</span>
        <span>·</span>
        <span>{a.actor}</span>
        <span>·</span>
        <span>{a.sectors.join(" · ")}</span>
      </div>
    </a>
  );
}

/* ---------- FOOTER ---------- */
function Footer() {
  const t = useTheme();
  const { narrow, tiny, mobile } = useViewport();
  const cols = [
    { h: "services", items: ["incident response", "managed detection", "threat hunting", "retainer & tabletop", "expert witness"] },
    { h: "research",  items: ["coming soon · Q3 2026", "join the notify list", "responsible disclosure"] },
    { h: "company",   items: ["about", "team", "detektix ↗", "contact"] },
    { h: "contact",   items: ["IR hotline · 24/7", "+1 929 458 0453", "secure contact form"] },
  ];
  return (
    <footer style={{ borderTop: `1px solid ${t.rule}`, background: t.bg, color: t.dim, padding: mobile ? "32px 0 20px" : "48px 0 24px" }}>
      <div style={{ maxWidth: 1440, margin: "0 auto", padding: mobile ? "0 16px" : "0 20px" }}>
        <div style={{ display: "grid", gridTemplateColumns: tiny ? "1fr" : narrow ? "1fr 1fr" : "1.5fr repeat(4, 1fr)", gap: narrow ? 32 : 48, paddingBottom: 48, borderBottom: `1px solid ${t.rule}` }}>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 18 }}>
              <Logo size={48} />
              <span style={{ color: t.fg, fontSize: 16, fontWeight: 600 }}>honeybadger/sec</span>
            </div>
            <p style={{ fontSize: 13, lineHeight: 1.6, color: t.dim, margin: 0, maxWidth: 320 }}>
              Honey Badger Security Ltd. is a privately-held incident response firm founded in 2016. We are not VC-funded, we are not for sale, and we do not subcontract live engagements.
            </p>
            <div style={{ marginTop: 24, padding: "12px 14px", border: `1px dashed ${t.rule}`, color: t.fg, fontSize: 12 }}>
              <div style={{ color: t.dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 6 }}>warrant canary · {new Date().toISOString().slice(0,10)}</div>
              No national-security letters or gag orders received as of this date.
            </div>
          </div>
          {cols.map(c => (
            <div key={c.h}>
              <div style={{ color: t.fg, fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 16 }}>{c.h}</div>
              <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 10 }}>
                {c.items.map(i => (
                  <li key={i} style={{ fontSize: 13 }}>
                    <a href="#" style={{ color: t.dim, textDecoration: "none" }}>{i}</a>
                  </li>
                ))}
              </ul>
            </div>
          ))}
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", paddingTop: 24, color: t.dim, fontSize: mobile ? 10 : 11, letterSpacing: "0.06em", textTransform: "uppercase", flexWrap: "wrap", gap: 16 }}>
          <span>© 2016–2026 honey badger security ltd.</span>
          <span style={{ display: "flex", gap: mobile ? 14 : 20, flexWrap: "wrap" }}>
            <a href="#" style={{ color: t.dim, textDecoration: "none" }}>privacy</a>
            <a href="#" style={{ color: t.dim, textDecoration: "none" }}>terms</a>
            <a href="#" style={{ color: t.dim, textDecoration: "none" }}>security.txt ↗</a>
            <a href="#" style={{ color: t.dim, textDecoration: "none" }}>status ↗</a>
          </span>
        </div>
      </div>
    </footer>
  );
}

/* ---------- TWEAKS ---------- */
const DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "amber"
}/*EDITMODE-END*/;

function ContactField({ label, dim, children }) {
  return (
    <label style={{ display: "flex", flexDirection: "column", gap: 6 }}>
      <span style={{ color: dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase" }}>{label}</span>
      {children}
    </label>
  );
}

function ContactModal() {
  const t = useTheme();
  const { tiny, mobile } = useViewport();
  const [open, setOpen] = useState(false);
  const [form, setForm] = useState({ name: "", company: "", email: "", urgency: "retainer", message: "" });
  const [status, setStatus] = useState("idle"); // idle | sending | sent | error
  const [errorMsg, setErrorMsg] = useState("");
  useEffect(() => {
    const on = () => { setOpen(true); setStatus("idle"); setErrorMsg(""); };
    window.addEventListener("hb-open-contact", on);
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    window.addEventListener("keydown", onKey);
    return () => { window.removeEventListener("hb-open-contact", on); window.removeEventListener("keydown", onKey); };
  }, []);
  // body-scroll lock while modal is open
  useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = prev; };
  }, [open]);
  if (!open) return null;

  const submit = async (e) => {
    e.preventDefault();
    if (status === "sending") return;
    setStatus("sending");
    setErrorMsg("");
    try {
      const r = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(form),
      });
      if (!r.ok) {
        const data = await r.json().catch(() => ({}));
        throw new Error(data.error || `request failed (${r.status})`);
      }
      setStatus("sent");
    } catch (err) {
      setStatus("error");
      setErrorMsg(err.message || "could not send. please try again or call the hotline.");
    }
  };

  const inputStyle = { background: "transparent", border: `1px solid ${t.rule}`, color: t.fg, fontFamily: "inherit", fontSize: 16, padding: "12px 14px", outline: "none", width: "100%", boxSizing: "border-box" };
  const sending = status === "sending";

  return (
    <div onClick={() => setOpen(false)} role="dialog" aria-modal="true" aria-label="Contact form" style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.78)", backdropFilter: "blur(4px)", WebkitBackdropFilter: "blur(4px)", zIndex: 100, display: "flex", alignItems: mobile ? "stretch" : "center", justifyContent: "center", padding: mobile ? 0 : 20 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ background: t.bg, border: mobile ? "none" : `1px solid ${t.rule}`, color: t.fg, width: "100%", maxWidth: 560, maxHeight: mobile ? "100vh" : "90vh", overflow: "auto", fontFamily: "inherit" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: mobile ? "14px 18px" : "16px 24px", borderBottom: `1px solid ${t.rule}`, position: mobile ? "sticky" : "static", top: 0, background: t.bg, zIndex: 1 }}>
          <span style={{ color: t.dim, fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginRight: 12 }}><span style={{ color: t.accent }}>§</span> contact / honeybadger.sec</span>
          <button onClick={() => setOpen(false)} aria-label="Close contact form" style={{ background: "transparent", border: "none", color: t.dim, fontSize: 24, cursor: "pointer", padding: 0, fontFamily: "inherit", lineHeight: 1, flexShrink: 0 }}>×</button>
        </div>
        <div style={{ padding: mobile ? "24px 18px" : "32px 24px" }}>
          <h3 style={{ fontSize: mobile ? 22 : 28, margin: 0, marginBottom: 8, letterSpacing: "-0.025em", fontWeight: 600 }}>get in touch.</h3>
          <p style={{ color: t.dim, fontSize: 13, lineHeight: 1.55, marginTop: 0, marginBottom: 24 }}>
            For active incidents, call <a href="tel:+19294580453" style={{ color: t.fg, textDecoration: "none" }}>+1 929 458 0453</a>. Everything else — fill this in and we’ll reply within one business day.
          </p>
          {status === "sent" ? (
            <div style={{ border: `1px solid ${t.ok}`, padding: 20, color: t.fg, fontSize: 14, lineHeight: 1.55 }}>
              <span style={{ color: t.ok, fontWeight: 600 }}>message received.</span> we’ll reply within one business day. for active incidents, call <a href="tel:+19294580453" style={{ color: t.accent, textDecoration: "none" }}>+1 929 458 0453</a>.
            </div>
          ) : (
            <form onSubmit={submit} style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              <div style={{ display: "grid", gridTemplateColumns: tiny ? "1fr" : "1fr 1fr", gap: 16 }}>
                <ContactField label="Name" dim={t.dim}><input required autoComplete="name" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} style={inputStyle} /></ContactField>
                <ContactField label="Company" dim={t.dim}><input autoComplete="organization" value={form.company} onChange={(e) => setForm({ ...form, company: e.target.value })} style={inputStyle} /></ContactField>
              </div>
              <ContactField label="Email" dim={t.dim}><input type="email" required autoComplete="email" inputMode="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} style={inputStyle} /></ContactField>
              <ContactField label="What do you need?" dim={t.dim}>
                <select value={form.urgency} onChange={(e) => setForm({ ...form, urgency: e.target.value })} style={inputStyle}>
                  <option value="retainer">IR retainer / scoping call</option>
                  <option value="breach">Active breach — we need help now</option>
                  <option value="detektix">Detektix / canary tokens</option>
                  <option value="whiteshroud">Whiteshroud / open source</option>
                  <option value="other">Something else</option>
                </select>
              </ContactField>
              <ContactField label="Message" dim={t.dim}><textarea rows={5} required value={form.message} onChange={(e) => setForm({ ...form, message: e.target.value })} style={{ ...inputStyle, resize: "vertical", fontFamily: "inherit" }} /></ContactField>
              {status === "error" && (
                <div style={{ border: `1px solid ${t.danger}`, padding: 12, color: t.fg, fontSize: 13, lineHeight: 1.5 }}>
                  <span style={{ color: t.danger, fontWeight: 600 }}>could not send.</span> {errorMsg} for an active incident, call <a href="tel:+19294580453" style={{ color: t.accent, textDecoration: "none" }}>+1 929 458 0453</a>.
                </div>
              )}
              <button type="submit" disabled={sending} style={{ background: t.accent, color: t.bg, border: "none", padding: "14px 22px", fontFamily: "inherit", fontSize: 12, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase", cursor: sending ? "wait" : "pointer", alignSelf: tiny ? "stretch" : "flex-start", opacity: sending ? 0.6 : 1 }}>
                {sending ? "sending…" : "send message →"}
              </button>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}

function App() {
  const [tweaks, setTweak] = useTweaks(DEFAULTS);
  const theme = THEMES[tweaks.theme] || THEMES.amber;

  // body bg follows theme so margins match
  useEffect(() => {
    document.body.style.background = theme.bg;
    document.body.style.color = theme.fg;
  }, [theme]);

  return (
    <ThemeCtx.Provider value={theme}>
      <div style={{ background: theme.bg, color: theme.fg, fontFamily: "'JetBrains Mono', ui-monospace, monospace", minHeight: "100vh" }}>
        <StatusBar />
        <Masthead />
        <Hero />
        <Services />
        <RetainerStrip />
        <Research />
        <Footer />
      </div>
      <ContactModal />

      <TweaksPanel title="tweaks">
        <TweakSection title="Theme">
          <TweakRadio
            label="Accent"
            value={tweaks.theme}
            onChange={v => setTweak("theme", v)}
            options={[
              { value: "amber", label: "Amber" },
              { value: "cyan", label: "Cyan" },
              { value: "red",  label: "Red" },
              { value: "lime", label: "Lime" },
              { value: "paper", label: "Paper" },
            ]}
          />
        </TweakSection>
      </TweaksPanel>
    </ThemeCtx.Provider>
  );
}

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