// Experiments.jsx — three side projects with custom animated thumbnails.
// Each thumbnail is a small purpose-built illustration that hints at the tool's job.
// Animations are gated by the `animate` prop (Tweaks: experimentAnim).

function Experiments({ animate = true }) {
  const items = [
    {
      key: "sitewatch",
      name: "sitewatch.io",
      logo: "/assets/logos/sitewatch.svg",
      tagline: "HTTP, DNS, and SSL developer toolbox in the browser.",
      desc: "Inspect requests, debug headers, check certificates, and look up DNS records. Built for the kind of debugging that usually means opening five different tabs.",
      tags: ["Next.js", "TypeScript", "Tailwind"],
      thumb: <SitewatchThumb animate={animate} />,
      tint: "linear-gradient(135deg, color-mix(in oklab, var(--accent) 18%, var(--surface)), var(--surface))",
    },
    {
      key: "markdwn",
      name: "markdwn.dev",
      logo: "/assets/logos/markdwn.svg",
      tagline: "Convert any web page to clean markdown. Built for LLMs, notes, and second brains.",
      desc: "Paste a URL, get a markdown file. Built because I kept needing this and bookmarklets weren't cutting it.",
      tags: ["JavaScript", "Readability"],
      thumb: <MarkdwnThumb animate={animate} />,
      tint: "linear-gradient(135deg, color-mix(in oklab, var(--fg) 6%, var(--surface)), var(--surface))",
    },
    {
      key: "cnvrt",
      name: "cnvrt.dev",
      logo: "/assets/logos/cnvrt.svg",
      tagline: "Tiny unit converter with a 7-segment dot-matrix look.",
      desc: "Pure static page. No tracking, no framework, no settings menu. Just numbers, the way an old calculator would show them.",
      tags: ["React", "Vite"],
      thumb: <CnvrtThumb animate={animate} />,
      tint: "linear-gradient(135deg, #1a1d25, #0e1015)",
      dark: true,
    },
  ];

  return (
    <section id="experiments" style={exStyles.section}>
      <div style={exStyles.inner}>
        <div style={exStyles.head}>
          <div>
            <div className="eyebrow" style={{ marginBottom: 10 }}>
              Experiments · evenings &amp; weekends
            </div>
            <h2 style={exStyles.title}>
              Small tools I built because<br />I wanted them to exist.
            </h2>
            <p style={exStyles.subtitle}>
              These are not my main work — just things I tinker with after hours.
              They're rough on purpose.
            </p>
          </div>
        </div>

        <div className="exp-grid" style={exStyles.grid}>
          {items.map(it => <ExperimentCard key={it.key} item={it} />)}
        </div>
      </div>
    </section>
  );
}

function ExperimentCard({ item }) {
  const [hover, setHover] = React.useState(false);
  const canHover = window.matchMedia("(hover: hover)").matches;
  return (
    <a href={`https://${item.name}`} target="_blank" rel="noopener noreferrer" className="exp-card"
       onMouseEnter={canHover ? () => setHover(true) : undefined}
       onMouseLeave={canHover ? () => setHover(false) : undefined}
       style={{
         ...ecStyles.card,
         ...(hover ? ecStyles.cardHover : null),
       }}>
      <div style={{
        ...ecStyles.thumb,
        background: item.tint,
      }}>
        {item.thumb}
      </div>
      <div style={ecStyles.body}>
        <div style={ecStyles.titleRow}>
          <span style={ecStyles.nameRow}>
            {item.logo && (
              <img src={item.logo} alt="" style={ecStyles.logo}
                   onError={(e) => { e.target.style.display = "none"; }} />
            )}
            <span style={ecStyles.name}>{item.name}</span>
          </span>
          <i data-lucide="arrow-up-right"
             style={{ width: 16, height: 16, color: "var(--fg-quaternary)" }}></i>
        </div>
        <p style={ecStyles.tagline}>{item.tagline}</p>
        <p style={ecStyles.desc}>{item.desc}</p>
        <div style={ecStyles.tags}>
          {item.tags.map(t => <span key={t} className="tag">{t}</span>)}
        </div>
      </div>
    </a>
  );
}

/* ─── sitewatch.io thumbnail ───────────────────────────────────────────────── */
/* A stack of monitored endpoints with status dots that pulse and a tiny latency
   sparkline that scrolls. */
function SitewatchThumb({ animate }) {
  const rows = [
    { host: "api.acme.co",      check: "86ms",   status: "ok",   delay: "0s" },
    { host: "acme.co/auth",     check: "124ms",  status: "ok",   delay: "0.4s" },
    { host: "ssl · acme.co",    check: "92d",    status: "warn", delay: "0.8s" },
    { host: "dns · mx record",  check: "valid",  status: "ok",   delay: "1.2s" },
  ];
  const dot = {
    ok:   "var(--green-500, #1f9d55)",
    warn: "var(--amber-500, #c97a0e)",
    err:  "var(--red-500, #d4341f)",
  };
  return (
    <div style={swThumb.wrap}>
      <style>{`
        @keyframes sw-pulse {
          0%, 80%, 100% { transform: scale(1); box-shadow: 0 0 0 0 currentColor; }
          40%           { transform: scale(1.4); box-shadow: 0 0 0 6px transparent; }
        }
        @keyframes sw-spark {
          0%   { transform: translateX(0); }
          100% { transform: translateX(-50%); }
        }
      `}</style>
      <div style={swThumb.head}>
        <span style={swThumb.headDot}></span>
        <span style={swThumb.headDot}></span>
        <span style={swThumb.headDot}></span>
        <span style={swThumb.headLabel}>monitor · live</span>
      </div>
      <ul style={swThumb.list}>
        {rows.map(r => (
          <li key={r.host} style={swThumb.row}>
            <span style={{
              ...swThumb.dot,
              color: dot[r.status],
              background: dot[r.status],
              animation: animate ? `sw-pulse 2.2s ${r.delay} infinite var(--ease-out, ease-out)` : "none",
            }}></span>
            <span style={swThumb.host}>{r.host}</span>
            <span style={swThumb.check}>{r.check}</span>
          </li>
        ))}
      </ul>
      <div style={swThumb.sparkWrap}>
        <svg viewBox="0 0 400 28" style={{
          width: "200%", height: 28, display: "block",
          animation: animate ? "sw-spark 6s linear infinite" : "none",
        }} preserveAspectRatio="none">
          <path d="M0,18 L20,14 L40,16 L60,8 L80,12 L100,6 L120,18 L140,10 L160,14 L180,9 L200,17 L220,11 L240,15 L260,7 L280,13 L300,18 L320,9 L340,15 L360,11 L380,14 L400,18"
                fill="none" stroke="var(--accent)" strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" />
          <path d="M400,18 L420,14 L440,16 L460,8 L480,12 L500,6 L520,18 L540,10 L560,14 L580,9 L600,17 L620,11 L640,15 L660,7 L680,13 L700,18 L720,9 L740,15 L760,11 L780,14 L800,18"
                fill="none" stroke="var(--accent)" strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" />
        </svg>
      </div>
    </div>
  );
}
const swThumb = {
  wrap: {
    position: "absolute", inset: 14,
    background: "color-mix(in oklab, var(--surface) 92%, transparent)",
    border: "1px solid var(--border-subtle)",
    borderRadius: 8,
    overflow: "hidden",
    display: "flex", flexDirection: "column",
    boxShadow: "0 4px 12px rgba(0,0,0,0.04)",
  },
  head: {
    display: "flex", alignItems: "center", gap: 6,
    padding: "8px 12px",
    borderBottom: "1px solid var(--border-subtle)",
    background: "var(--bg-subtle)",
  },
  headDot: { width: 7, height: 7, borderRadius: "50%", background: "var(--border-strong)" },
  headLabel: {
    marginLeft: "auto",
    fontFamily: "var(--font-mono)", fontSize: 10,
    color: "var(--fg-tertiary)", letterSpacing: "-0.011em",
  },
  list: { listStyle: "none", margin: 0, padding: "6px 0", flex: 1 },
  row: {
    display: "grid",
    gridTemplateColumns: "14px minmax(0, 1fr) auto",
    alignItems: "center",
    gap: 8,
    padding: "5px 12px",
    fontFamily: "var(--font-mono)", fontSize: 10.5,
    lineHeight: 1.3,
  },
  dot: {
    width: 6, height: 6, borderRadius: "50%",
    display: "inline-block",
    transformOrigin: "center",
  },
  host: {
    color: "var(--fg)", letterSpacing: "-0.011em",
    whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
  },
  check: {
    color: "var(--fg-tertiary)", fontVariantNumeric: "tabular-nums",
    whiteSpace: "nowrap",
  },
  sparkWrap: {
    borderTop: "1px solid var(--border-subtle)",
    overflow: "hidden",
    background: "var(--bg-subtle)",
  },
};

/* ─── markdwn.dev thumbnail ────────────────────────────────────────────────── */
/* A faux browser pane on the left with content blocks, an arrow, and a
   monospaced markdown column on the right with a typing cursor. */
function MarkdwnThumb({ animate }) {
  return (
    <div style={mdThumb.wrap}>
      <style>{`
        @keyframes md-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
        @keyframes md-type  {
          0%   { width: 0; }
          15%  { width: 100%; }
          85%  { width: 100%; }
          100% { width: 100%; }
        }
      `}</style>
      <div style={mdThumb.col}>
        <div style={mdThumb.colHead}>
          <span style={mdThumb.urlBar}>example.com/post</span>
        </div>
        <div style={mdThumb.colBody}>
          <div style={{...mdThumb.line, width: "70%", height: 6, background: "var(--fg)", opacity: 0.85}}></div>
          <div style={{...mdThumb.line, width: "45%", height: 4, background: "var(--fg-tertiary)"}}></div>
          <div style={{ height: 6 }}></div>
          <div style={{...mdThumb.line, width: "100%"}}></div>
          <div style={{...mdThumb.line, width: "92%"}}></div>
          <div style={{...mdThumb.line, width: "78%"}}></div>
          <div style={{ height: 5 }}></div>
          <div style={{...mdThumb.line, width: "100%"}}></div>
          <div style={{...mdThumb.line, width: "85%"}}></div>
        </div>
      </div>

      <div style={mdThumb.arrow}>
        <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
          <circle cx="11" cy="11" r="10.5" stroke="var(--border-strong)" />
          <path d="M7 11 L15 11 M12 8 L15 11 L12 14"
                stroke="var(--fg)" strokeWidth="1.4" fill="none"
                strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>

      <div style={{...mdThumb.col, ...mdThumb.colMd}}>
        <div style={mdThumb.colHead}>
          <span style={{...mdThumb.urlBar, fontFamily: "var(--font-mono)"}}>post.md</span>
        </div>
        <div style={mdThumb.mdBody}>
          <div style={mdThumb.mdLine}><span style={mdThumb.synAccent}># </span>The title of the post</div>
          <div style={{...mdThumb.mdLine, color: "var(--fg-tertiary)"}}>by Author · May 17</div>
          <div style={{ height: 4 }}></div>
          <div style={mdThumb.mdLine}>Body copy goes here with</div>
          <div style={mdThumb.mdLine}>
            <span style={mdThumb.synAccent}>**</span>strong<span style={mdThumb.synAccent}>**</span> and a&nbsp;
            <span style={mdThumb.synAccent}>[link](…)</span>
          </div>
          <div style={mdThumb.mdLine}>
            <span style={mdThumb.synAccent}>&gt; </span>
            <span style={{
              display: "inline-block",
              overflow: "hidden", whiteSpace: "nowrap",
              verticalAlign: "bottom",
              animation: animate ? "md-type 3.6s steps(28) infinite" : "none",
              maxWidth: "100%",
            }}>and even a blockquote.</span>
            <span style={{
              display: "inline-block", width: 5, height: 11,
              background: "var(--accent)", marginLeft: 1,
              verticalAlign: "text-bottom",
              animation: animate ? "md-blink 1s infinite" : "none",
            }}></span>
          </div>
        </div>
      </div>
    </div>
  );
}
const mdThumb = {
  wrap: {
    position: "absolute", inset: 14,
    display: "grid",
    gridTemplateColumns: "1fr 28px 1fr",
    alignItems: "stretch",
    gap: 0,
  },
  col: {
    background: "color-mix(in oklab, var(--surface) 96%, transparent)",
    border: "1px solid var(--border-subtle)",
    borderRadius: 8,
    overflow: "hidden",
    display: "flex", flexDirection: "column",
    boxShadow: "0 4px 12px rgba(0,0,0,0.04)",
  },
  colMd: { background: "var(--bg-subtle)" },
  colHead: {
    padding: "6px 10px",
    borderBottom: "1px solid var(--border-subtle)",
  },
  urlBar: {
    fontFamily: "var(--font-mono)", fontSize: 9,
    color: "var(--fg-tertiary)", letterSpacing: "-0.011em",
  },
  colBody: { padding: "10px 12px", display: "flex", flexDirection: "column", gap: 4 },
  line: { height: 4, borderRadius: 2, background: "var(--border-strong)" },
  arrow: {
    display: "flex", alignItems: "center", justifyContent: "center",
  },
  mdBody: {
    padding: "10px 12px",
    fontFamily: "var(--font-mono)",
    fontSize: 10,
    lineHeight: 1.45,
    color: "var(--fg)",
    display: "flex", flexDirection: "column",
    overflow: "hidden",
  },
  mdLine: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "clip" },
  synAccent: { color: "var(--accent)" },
};

/* ─── cnvrt.dev thumbnail ──────────────────────────────────────────────────── */
/* A dot-matrix display showing unit conversions, rotating through a few values. */
function CnvrtThumb({ animate }) {
  // 5×7 dot patterns for the characters we need.
  // Each char is a string of 35 chars (5 cols × 7 rows), '#' = lit, '.' = off.
  const FONT = {
    "0": "01110;10001;10011;10101;11001;10001;01110",
    "1": "00100;01100;00100;00100;00100;00100;01110",
    "2": "01110;10001;00001;00010;00100;01000;11111",
    "3": "11110;00001;00001;01110;00001;00001;11110",
    "4": "00010;00110;01010;10010;11111;00010;00010",
    "5": "11111;10000;11110;00001;00001;10001;01110",
    "6": "00110;01000;10000;11110;10001;10001;01110",
    "7": "11111;00001;00010;00100;01000;01000;01000",
    "8": "01110;10001;10001;01110;10001;10001;01110",
    "9": "01110;10001;10001;01111;00001;00010;01100",
    ".": "00000;00000;00000;00000;00000;00110;00110",
    " ": "00000;00000;00000;00000;00000;00000;00000",
    "k": "10000;10000;10010;10100;11000;10100;10010",
    "m": "00000;00000;11010;10101;10101;10101;10101",
    "i": "00100;00000;01100;00100;00100;00100;01110",
    "l": "01100;00100;00100;00100;00100;00100;01110",
    "e": "00000;00000;01110;10001;11111;10000;01110",
    "f": "00011;00100;00100;01111;00100;00100;00100",
    "t": "00100;00100;11111;00100;00100;00100;00011",
    "n": "00000;00000;11110;10001;10001;10001;10001",
    "c": "00000;00000;01110;10001;10000;10001;01110",
    "→": "00000;00100;00010;11111;00010;00100;00000",
    "=": "00000;00000;11111;00000;11111;00000;00000",
  };

  const STEPS = [
    { from: "1 mi",  to: "1.609 km" },
    { from: "100 ft", to: "30.48 m" },
    { from: "1 in",   to: "2.54 cm" },
    { from: "1 km",   to: "0.621 mi" },
  ];

  const [stepIdx, setStepIdx] = React.useState(0);
  React.useEffect(() => {
    if (!animate) return;
    const id = setInterval(() => setStepIdx(i => (i + 1) % STEPS.length), 2400);
    return () => clearInterval(id);
  }, [animate]);

  const step = STEPS[stepIdx];

  const renderText = (text, key) => {
    const chars = [...text];
    return (
      <div style={cnvThumb.textRow} key={key}>
        {chars.map((ch, i) => {
          const pat = FONT[ch] || FONT[" "];
          const rows = pat.split(";");
          return (
            <div key={i} style={cnvThumb.glyph}>
              {rows.map((rowStr, r) => (
                <div key={r} style={cnvThumb.glyphRow}>
                  {[...rowStr].map((bit, c) => (
                    <div key={c} style={{
                      ...cnvThumb.dot,
                      background: bit === "1" ? "#ffb547" : "rgba(255,180,71,0.07)",
                      boxShadow: bit === "1" ? "0 0 4px rgba(255,180,71,0.5)" : "none",
                    }}></div>
                  ))}
                </div>
              ))}
            </div>
          );
        })}
      </div>
    );
  };

  return (
    <div style={cnvThumb.wrap}>
      <style>{`
        @keyframes cnv-flicker { 0%, 100% { opacity: 1; } 50% { opacity: 0.92; } }
      `}</style>
      <div style={cnvThumb.bezel}>
        <div style={{
          ...cnvThumb.screen,
          animation: animate ? "cnv-flicker 4s infinite" : "none",
        }}>
          <div style={cnvThumb.scanlines}></div>
          <div style={cnvThumb.label}>cnvrt · v1</div>
          <div key={stepIdx} style={cnvThumb.matrix}>
            {renderText(step.from, "from")}
            {renderText("→", "arrow")}
            {renderText(step.to, "to")}
          </div>
          <div style={cnvThumb.dots}>
            {STEPS.map((_, i) => (
              <span key={i} style={{
                ...cnvThumb.pip,
                background: i === stepIdx ? "#ffb547" : "rgba(255,180,71,0.18)",
              }}></span>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
const cnvThumb = {
  wrap: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center" },
  bezel: {
    width: "78%", height: "78%",
    background: "#0a0c10",
    border: "1px solid rgba(255,255,255,0.06)",
    borderRadius: 10,
    padding: 10,
    boxShadow: "0 1px 0 rgba(255,255,255,0.04) inset, 0 8px 24px rgba(0,0,0,0.4)",
  },
  screen: {
    width: "100%", height: "100%",
    background: "radial-gradient(circle at 50% 40%, #1a1208 0%, #0a0805 80%)",
    borderRadius: 5,
    position: "relative",
    overflow: "hidden",
    display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
    gap: 8,
  },
  scanlines: {
    position: "absolute", inset: 0, pointerEvents: "none",
    backgroundImage: "repeating-linear-gradient(0deg, rgba(0,0,0,0.18) 0 1px, transparent 1px 3px)",
  },
  label: {
    position: "absolute", top: 6, left: 8,
    fontFamily: "var(--font-mono)", fontSize: 8,
    color: "rgba(255,180,71,0.55)", letterSpacing: "0.1em", textTransform: "uppercase",
  },
  matrix: { display: "flex", alignItems: "center", gap: 4 },
  textRow: { display: "flex", gap: 1 },
  glyph: { display: "flex", flexDirection: "column", gap: 1 },
  glyphRow: { display: "flex", gap: 1 },
  dot: { width: 2, height: 2, borderRadius: "50%" },
  dots: {
    position: "absolute", bottom: 6, display: "flex", gap: 4,
  },
  pip: { width: 4, height: 4, borderRadius: "50%" },
};

const exStyles = {
  section: {
    padding: "var(--sec-y, 96px) 0",
    borderTop: "1px solid var(--border-subtle)",
  },
  inner: { maxWidth: 1080, margin: "0 auto", padding: "0 max(20px, 5vw)" },
  head: { marginBottom: 48, maxWidth: 720 },
  title: {
    fontFamily: "var(--font-display)", fontSize: 40, fontWeight: 600,
    letterSpacing: "-0.024em", lineHeight: 1.08, color: "var(--fg)", margin: 0,
    textWrap: "balance",
  },
  subtitle: {
    marginTop: 18, maxWidth: 520,
    fontSize: 16, lineHeight: 1.55, color: "var(--fg-tertiary)",
    letterSpacing: "-0.011em",
  },
  grid: {
    display: "grid",
    gridTemplateColumns: "repeat(3, 1fr)",
    gap: 20,
  },
};

const ecStyles = {
  card: {
    display: "flex", flexDirection: "column",
    textDecoration: "none", color: "inherit",
    background: "transparent",
    border: "1px solid transparent",
    borderRadius: 14,
    overflow: "hidden",
    transition: "transform 220ms cubic-bezier(.16,1,.30,1), box-shadow 220ms cubic-bezier(.16,1,.30,1), border-color 220ms, background 220ms",
  },
  cardHover: {
    transform: "translateY(-2px)",
    boxShadow: "var(--shadow-lg)",
    borderColor: "var(--border)",
    background: "var(--surface)",
  },
  thumb: {
    position: "relative",
    aspectRatio: "16 / 10",
    overflow: "hidden",
  },
  body: { padding: "22px 22px 24px", display: "flex", flexDirection: "column", gap: 8, flex: 1 },
  titleRow: {
    display: "flex", justifyContent: "space-between", alignItems: "center", gap: 8,
  },
  nameRow: {
    display: "flex", alignItems: "center", gap: 8,
  },
  logo: {
    width: 18, height: 18, borderRadius: 4, flexShrink: 0,
  },
  name: {
    fontFamily: "var(--font-mono)",
    fontSize: 15, fontWeight: 500, letterSpacing: "-0.011em",
    color: "var(--fg)",
  },
  tagline: {
    fontFamily: "var(--font-display)",
    fontSize: 17, fontWeight: 500, lineHeight: 1.35,
    letterSpacing: "-0.014em",
    color: "var(--fg)", margin: 0,
    textWrap: "balance",
  },
  desc: {
    fontSize: 13.5, lineHeight: 1.55, color: "var(--fg-tertiary)",
    margin: "2px 0 0", maxWidth: "none",
  },
  tags: { display: "flex", gap: 6, flexWrap: "wrap", marginTop: "auto", paddingTop: 14 },
};

window.Experiments = Experiments;
