// ─── Playful portfolio ──────────────────────────────────────────────────────
// Particle hero, custom cursor (optional), magnetic buttons, bouncy reveals.

function Playful({ accent, fontPair, dark, motion }) {
  const D = window.DJIBY;
  const bg = dark ? "#08080d" : "#f5f3ee";
  const fg = dark ? "#fff" : "#0a0a14";
  const muted = dark ? "rgba(255,255,255,.6)" : "rgba(10,10,20,.6)";
  const card = dark ? "#13131a" : "#fff";
  const line = dark ? "rgba(255,255,255,.08)" : "rgba(0,0,0,.08)";
  const display = fontPair === "geist" ? "'Geist', sans-serif" : "'Space Grotesk', sans-serif";
  const mono = "'JetBrains Mono', monospace";

  const word = useTypewriter(["the curious.", "the web.", "uptime.", "scale."], 65, 1300);

  // ── Click a skill → filter Selected Projects by that technology ──
  // A project counts as "done with" a skill if any of its tags matches the
  // skill name or one of its aliases below.
  const SKILL_ALIASES = {
    "JavaScript": ["JavaScript", "JS", "Next.js", "React", "Node"],
    "TypeScript": ["TypeScript", "TS"],
    "Java": ["Java"],
    "Python": ["Python"],
    "C": ["C", "C99"],
    "PHP": ["PHP"],
    "React": ["React", "Next.js"],
    "HTML / CSS": ["HTML", "CSS", "Bootstrap"],
    "PostgreSQL": ["PostgreSQL", "Postgres"],
    "Docker": ["Docker"],
    "Git": ["Git"],
    "Spring Boot": ["Spring Boot", "Spring"],
  };
  const matchSkill = (name, p) => {
    const al = (SKILL_ALIASES[name] || [name]).map(a => a.toLowerCase());
    return p.tags.some(t => al.includes(t.toLowerCase()));
  };
  // Which skills actually have ≥1 matching project (only those are clickable).
  const matchedSkills = useMemo(() => {
    const set = new Set();
    D.skills.forEach(s => { if (D.projects.some(p => matchSkill(s.name, p))) set.add(s.name); });
    return set;
  }, []);
  // Default ("proud") view: projects flagged featured:true in data.jsx,
  // falling back to ALL projects if none are flagged. Edit data.jsx to curate.
  const proud = D.projects.filter(p => p.featured);
  const defaultProjects = proud.length ? proud : D.projects;

  const RESET_SECS = 60;
  const [filter, setFilter] = useState(null); // { name, color } | null
  const [secs, setSecs] = useState(0);
  useEffect(() => {
    if (!filter) return;
    setSecs(RESET_SECS);
    let s = RESET_SECS;
    const iv = setInterval(() => {
      s -= 1; setSecs(s);
      if (s <= 0) { clearInterval(iv); setFilter(null); }
    }, 1000);
    return () => clearInterval(iv);
  }, [filter]);

  const pickSkill = (name, color) => {
    if (!matchedSkills.has(name)) return;
    setFilter({ name, color });
    requestAnimationFrame(() => {
      const el = document.getElementById("work");
      if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 16, behavior: "smooth" });
    });
  };
  const visibleProjects = filter ? D.projects.filter(p => matchSkill(filter.name, p)) : defaultProjects;

  return (
    <div style={{ background: bg, color: fg, minHeight: "100vh", fontFamily: display, overflow: "hidden", position: "relative" }}>
      {motion >= 2 && <CustomCursor accent={accent} enabled />}

      {/* NAV */}
      <nav style={{
        position: "absolute", top: 0, left: 0, right: 0, zIndex: 30,
        padding: "clamp(20px,3vw,30px) clamp(28px,6vw,72px)",
        display: "flex", justifyContent: "space-between", alignItems: "center",
        background: "transparent",
      }}>
        <a href="#hi" className="brandMark" style={{
          display: "inline-flex", alignItems: "center", gap: 10,
          color: "inherit", textDecoration: "none",
          padding: "4px 4px 4px 0",
        }}>
          <span style={{
            width: 30, height: 30, borderRadius: 8, flexShrink: 0,
            background: `linear-gradient(135deg, ${accent}, #5b8cff)`,
            display: "grid", placeItems: "center", color: "#fff",
            fontSize: 14, fontWeight: 800,
          }}>D</span>
          <span style={{
            fontWeight: 700, letterSpacing: "-.02em", fontSize: 18,
            display: "inline-flex", alignItems: "baseline",
          }}>
            <span>djiby</span>
            <span style={{
              fontFamily: mono, fontSize: 11, fontWeight: 500,
              color: muted, marginLeft: 6, letterSpacing: ".05em",
            }}>/dev</span>
          </span>
        </a>
        <div style={{
          display: "flex", gap: 4, padding: 5, borderRadius: 999,
          background: dark ? "rgba(255,255,255,.04)" : "rgba(0,0,0,.04)",
          border: `1px solid ${line}`,
        }} className="heroNav">
          {[["About", "#about"], ["Experience", "#experience"], ["Writing", "#writing"]].map(([t, h]) => (
            <a key={t} href={h} className="heroNavLink" style={{
              textDecoration: "none", color: muted, fontSize: 14, fontWeight: 500,
              padding: "8px 16px", borderRadius: 999,
              transition: "color .25s, background .25s",
            }}>{t}</a>
          ))}
        </div>
      </nav>

      {/* HERO */}
      <section id="hi" style={{
        position: "relative", minHeight: "100vh",
        padding: "clamp(120px,14vh,180px) clamp(28px,6vw,72px) clamp(110px,16vh,160px)",
        display: "flex", flexDirection: "column", justifyContent: "center",
        overflow: "hidden",
      }}>
        {/* Constellation / particle bg */}
        <div style={{ position: "absolute", inset: 0, opacity: motion >= 1 ? .6 : 0, zIndex: 0 }}>
          <ParticleField color={accent} count={70} speed={0.25} />
        </div>
        {/* radial accent wash */}
        <div style={{
          position: "absolute", inset: 0, zIndex: 0, pointerEvents: "none",
          background: `radial-gradient(60% 50% at 78% 18%, ${accent}33, transparent 70%), radial-gradient(50% 45% at 8% 88%, #22d3ee22, transparent 70%)`,
        }} />

        <div style={{ position: "relative", zIndex: 1, maxWidth: 1180, width: "100%", margin: "0 auto" }}>
          {/* kicker */}
          <Reveal y={16}>
            <p style={{
              fontFamily: mono, fontSize: 14, color: accent, letterSpacing: ".04em",
              margin: "0 0 26px", display: "inline-flex", alignItems: "center", gap: 8,
            }}>
              <span style={{
                width: 7, height: 7, borderRadius: "50%", background: accent,
                boxShadow: `0 0 0 4px ${accent}2e`, animation: "pulse 1.8s ease-in-out infinite",
              }} />
              // software developer
            </p>
          </Reveal>

          {/* status chips */}
          <Reveal y={16} delay={80}>
            <div style={{ display: "flex", gap: 10, flexWrap: "wrap", marginBottom: "clamp(28px,4vw,40px)" }}>
              {[
                { t: "Open to work", c: accent, glow: true,
                  icon: <path d="M12 2l2.6 6.3L21 9l-5 4.3L17.5 20 12 16.5 6.5 20 8 13.3 3 9l6.4-.7z" /> },
                { t: "Edinburgh", c: "#22d3ee",
                  icon: <g fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" /><circle cx="12" cy="10" r="3" /></g> },
                { t: "1+ year shipping", c: "#f59e0b",
                  icon: <g fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M13 2L3 14h7l-1 8 10-12h-7z" /></g> },
              ].map((s, i) => (
                <span key={i} className="heroChip" style={{
                  display: "inline-flex", alignItems: "center", gap: 8,
                  padding: "8px 15px", borderRadius: 999, fontSize: 13, fontWeight: 600,
                  color: s.c, background: s.c + "1f", border: `1px solid ${s.c}4d`,
                  "--cg": s.c,
                }}>
                  <svg viewBox="0 0 24 24" fill="currentColor" style={{ width: 14, height: 14 }}>{s.icon}</svg>
                  {s.t}
                </span>
              ))}
            </div>
          </Reveal>

          {/* headline */}
          <h1 style={{
            fontFamily: display, fontWeight: 700, fontSize: "clamp(72px, 14vw, 200px)",
            letterSpacing: "-.045em", lineHeight: .88, margin: 0,
          }}>
            <Reveal y={40}><span style={{ display: "block" }}>Building</span></Reveal>
            <Reveal y={40} delay={120}>
              <span style={{ display: "block" }}>things for</span>
            </Reveal>
            <Reveal y={40} delay={200}>
              <span style={{ display: "block" }}>
                <span style={{
                  background: `linear-gradient(110deg, ${accent}, #5b8cff 38%, #22d3ee)`,
                  backgroundSize: "220% 220%",
                  WebkitBackgroundClip: "text", backgroundClip: "text", color: "transparent",
                  animation: "gradient 7s ease-in-out infinite", fontStyle: "italic",
                  whiteSpace: "nowrap",
                }}>{word || "\u00A0"}</span>
                <span style={{ color: "#22d3ee", animation: "blink 1s steps(2) infinite" }}>|</span>
              </span>
            </Reveal>
          </h1>

          {/* intro */}
          <Reveal delay={320}>
            <p style={{
              fontFamily: display, fontSize: "clamp(20px,2.4vw,26px)", fontWeight: 400,
              color: muted, lineHeight: 1.5, maxWidth: 640,
              margin: "clamp(36px,5vw,56px) 0 clamp(28px,4vw,40px)",
            }}>
              Hey <span style={{ display: "inline-block", animation: "wave 2.4s ease-in-out infinite", transformOrigin: "70% 70%" }}>👋</span> I&rsquo;m{" "}
              <span style={{ color: fg, fontWeight: 700 }}>Djiby</span>, a software developer.
              A generalist developer who has worked across the stack, with a clear direction toward systems, infrastructure, and networking.
            </p>
          </Reveal>

          {/* actions */}
          <Reveal delay={420}>
            <div style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
              <a href="#work" className="hov heroCta heroCta-primary" style={{
                padding: "17px 26px", background: fg, color: bg, borderRadius: 999,
                fontSize: 15, fontWeight: 600, textDecoration: "none",
                display: "inline-flex", alignItems: "center", gap: 9,
                transition: "transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s",
              }}>
                <span>View my work</span>
                <span className="heroArrow" style={{ fontSize: 18, transition: "transform .3s cubic-bezier(.2,.7,.2,1)" }}>→</span>
              </a>
              <a href="#hire" className="hov heroTalk" style={{
                position: "relative", overflow: "hidden", isolation: "isolate",
                padding: "17px 26px", borderRadius: 999,
                fontSize: 15, fontWeight: 600, textDecoration: "none", color: "#fff",
                background: `linear-gradient(110deg, ${accent}, #5b8cff 55%, #22d3ee)`,
                backgroundSize: "180% 180%", animation: "gradient 5s ease infinite",
                display: "inline-flex", alignItems: "center", gap: 9,
                transition: "transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s",
                "--cg": accent,
              }}>
                <span style={{
                  width: 8, height: 8, borderRadius: "50%", background: "#34d77a", flexShrink: 0,
                  boxShadow: "0 0 0 3px rgba(52,215,122,.25)", animation: "pulse 2s infinite",
                }} />
                <span>Get in touch</span>
                <span className="heroTalkArrow" style={{ fontSize: 18, transition: "transform .25s cubic-bezier(.2,.7,.2,1)" }}>→</span>
              </a>
            </div>
          </Reveal>
        </div>

        {/* scroll cue */}
        {motion >= 1 && (
          <div style={{
            position: "absolute", left: "50%", bottom: 26, transform: "translateX(-50%)", zIndex: 1,
            display: "flex", flexDirection: "column", alignItems: "center", gap: 9,
            fontFamily: mono, fontSize: 10, letterSpacing: ".3em", color: muted,
          }}>
            SCROLL
            <span style={{
              width: 1, height: 34, background: `linear-gradient(${accent}, transparent)`,
              transformOrigin: "top", animation: "scrollHint 2s ease-in-out infinite",
            }} />
          </div>
        )}
      </section>

      {/* MARQUEE — "now reading" tech showcase */}
      <NowReadingMarquee accent={accent} dark={dark} fg={fg} muted={muted} card={card} line={line} bg={bg} />


      {/* ABOUT */}
      <PSection id="about" tag="// about" title="A little bit about me" accent={accent} fg={fg} muted={muted} line={line}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 60, alignItems: "center" }}>
          <Reveal>
            <div style={{
              position: "relative", aspectRatio: "1", width: "100%", maxWidth: 640,
              borderRadius: 32, overflow: "hidden",
              background: `linear-gradient(135deg, ${accent}33, #22d3ee22)`,
              border: `1px solid ${line}`,
            }}>
              <img
                src="assets/djiby-photo.webp"
                alt="Djiby"
                style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block" }}
              />

              {/* Floating credential — top right, real status card */}
              <div style={{
                position: "absolute", top: 20, right: 20, zIndex: 2, pointerEvents: "none",
                padding: "10px 14px 11px",
                background: dark ? "rgba(15,15,23,.85)" : "rgba(255,255,255,.92)",
                color: fg,
                borderRadius: 14,
                border: `1px solid ${dark ? "rgba(255,255,255,.1)" : "rgba(0,0,0,.08)"}`,
                backdropFilter: "blur(12px)",
                boxShadow: dark
                  ? "0 8px 24px rgba(0,0,0,.4)"
                  : "0 8px 24px rgba(0,0,0,.08)",
                fontFamily: display,
                display: "flex", alignItems: "center", gap: 10,
                animation: "float 5s ease-in-out infinite",
                minWidth: 180,
              }}>
                <span style={{
                  width: 8, height: 8, borderRadius: "50%", background: "#22c55e",
                  boxShadow: "0 0 0 4px rgba(34,197,94,.2)",
                  animation: "pulse 2s infinite", flexShrink: 0,
                }} />
                <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.2 }}>
                  <span style={{ fontSize: 13, fontWeight: 700, letterSpacing: "-.01em" }}>
                    Open to work
                  </span>
                  <span style={{ fontSize: 11, color: muted, marginTop: 2, fontFamily: mono }}>
                    junior · grad roles
                  </span>
                </div>
              </div>

              {/* Floating credential — middle left, location with map pin */}
              <div style={{
                position: "absolute", top: "50%", left: 18, zIndex: 2, pointerEvents: "none",
                transform: "translateY(-50%)",
                padding: "8px 12px 8px 10px",
                background: card, color: fg,
                borderRadius: 12,
                border: `1px solid ${line}`,
                fontFamily: display,
                fontSize: 12, fontWeight: 600,
                display: "inline-flex", alignItems: "center", gap: 8,
                animation: "float 6.5s ease-in-out infinite",
                boxShadow: dark
                  ? "0 6px 16px rgba(0,0,0,.35)"
                  : "0 6px 16px rgba(0,0,0,.08)",
              }}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
                     stroke={accent} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" />
                  <circle cx="12" cy="10" r="3" />
                </svg>
                Edinburgh
                <span style={{ color: muted, fontFamily: mono, fontSize: 11 }}>
                  55.95° N
                </span>
              </div>

              {/* Floating credential — bottom right, "now building" w/ ticker */}
              <div style={{
                position: "absolute", bottom: 22, right: 22, zIndex: 2, pointerEvents: "none",
                padding: "10px 14px",
                background: accent, color: "#fff",
                borderRadius: 14,
                boxShadow: `0 10px 24px ${accent}66`,
                fontFamily: display,
                display: "flex", alignItems: "center", gap: 10,
                animation: "float 5.5s ease-in-out infinite",
              }}>
                <span style={{
                  width: 22, height: 22, borderRadius: 6,
                  background: "rgba(255,255,255,.2)",
                  display: "grid", placeItems: "center",
                  fontSize: 11, fontWeight: 800,
                }}>06</span>
                <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.2 }}>
                  <span style={{ fontSize: 10, opacity: .85, letterSpacing: ".12em", textTransform: "uppercase", fontWeight: 700 }}>
                    Next up
                  </span>
                  <span style={{ fontSize: 14, fontWeight: 700, letterSpacing: "-.01em" }}>
                    Lex compiler
                  </span>
                </div>
              </div>
            </div>
          </Reveal>
          <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
            <Reveal delay={120}>
              <p style={{ fontSize: 28, fontWeight: 400, lineHeight: 1.4, margin: 0, letterSpacing: "-.01em" }}>
                I&rsquo;m Djiby, a software developer. The web taught me to build {" "}
                <span style={{ color: accent, fontWeight: 700 }}>systems and security</span>{" "}
                are where my curiosity settled.
              </p>
            </Reveal>
            <Reveal delay={200}>
              <p style={{ fontSize: 16, color: muted, lineHeight: 1.65, margin: 0 }}>{D.bio}</p>
            </Reveal>
            <Reveal delay={280}>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
                {[
                  { n: "BCN → EDI", l: "Barcelona born, Edinburgh built" },
                  { n: "C2 · C2 · C1", l: "Catalan, Spanish, English" },
                  { n: "A2 · A1 · A1", l: "French, Mandarin, Japanese" },
                  { n: "cosmopolitan", l: "multiethnic background, wider lens on the world" },
                  { n: "proud co-author", l: "of my son, my best work yet" },
                  { n: "if I can’t explain it", l: "I don’t know it yet" },
                ].map((s, i) => (
                  <div key={i} className="hov" style={{
                    padding: 18, borderRadius: 16, background: card, border: `1px solid ${line}`,
                    transition: "transform .3s, border-color .3s",
                  }}
                    onMouseEnter={e => { e.currentTarget.style.transform = "translateY(-3px) rotate(-1deg)"; e.currentTarget.style.borderColor = accent + "66"; }}
                    onMouseLeave={e => { e.currentTarget.style.transform = "translateY(0) rotate(0)"; e.currentTarget.style.borderColor = line; }}
                  >
                    <div style={{
                      fontSize: "clamp(19px, 2vw, 24px)",
                      fontWeight: 800, color: accent, letterSpacing: "-.03em",
                      lineHeight: 1.1, textWrap: "balance",
                      fontFamily: display,
                    }}>{s.n}</div>
                    <div style={{ fontSize: 13, color: muted, marginTop: 6, lineHeight: 1.4 }}>{s.l}</div>
                  </div>
                ))}
              </div>
            </Reveal>
          </div>
        </div>
      </PSection>

      {/* SKILLS */}
      <PSection id="skills" tag="// stack" title="The things I use the most to build!" accent={accent} fg={fg} muted={muted} line={line}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 16 }}>
          {D.skills.map((s, i) => {
            const dc = s.color || [accent, "#22d3ee", "#f59e0b", "#34d399", "#ef4444", "#a78bfa"][i % 6];
            const clickable = matchedSkills.has(s.name);
            return (
              <Reveal key={s.name} delay={i * 60}>
                <div
                  className="hov"
                  role={clickable ? "button" : undefined}
                  tabIndex={clickable ? 0 : undefined}
                  onClick={clickable ? () => pickSkill(s.name, dc) : undefined}
                  onKeyDown={clickable ? (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); pickSkill(s.name, dc); } } : undefined}
                  style={{
                  padding: 28, borderRadius: 24, background: card, border: `1px solid ${line}`,
                  position: "relative", overflow: "hidden",
                  height: "100%", cursor: clickable ? "pointer" : "default",
                  transition: "transform .35s cubic-bezier(.2,.7,.2,1.4), border-color .3s, box-shadow .3s",
                }}
                  onMouseEnter={e => {
                    e.currentTarget.style.transform = `translateY(-6px)`;
                    e.currentTarget.style.borderColor = dc + "66";
                    e.currentTarget.style.boxShadow = `0 12px 28px ${dc}1f`;
                    const cue = e.currentTarget.querySelector(".skillCue");
                    if (cue) { cue.style.opacity = "1"; cue.style.transform = "translateX(0)"; }
                  }}
                  onMouseLeave={e => {
                    e.currentTarget.style.transform = `translateY(0)`;
                    e.currentTarget.style.borderColor = line;
                    e.currentTarget.style.boxShadow = "none";
                    const cue = e.currentTarget.querySelector(".skillCue");
                    if (cue) { cue.style.opacity = "0"; cue.style.transform = "translateX(-4px)"; }
                  }}
                >
                  {/* corner sticker */}
                  <div style={{
                    position: "absolute", top: 14, right: 14,
                    width: 44, height: 44, borderRadius: "50%",
                    background: dc, color: "#fff", fontWeight: 800, fontSize: 14,
                    display: "grid", placeItems: "center",
                    boxShadow: `0 6px 18px ${dc}55`,
                  }}>
                    {String(i + 1).padStart(2, "0")}
                  </div>
                  <div style={{ fontSize: 36, fontWeight: 800, letterSpacing: "-.03em", marginTop: 8, marginBottom: 18, lineHeight: 1 }}>
                    {s.name}
                  </div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                    {s.tags.map(t => (
                      <span key={t} style={{
                        fontSize: 12, fontWeight: 600, padding: "5px 11px",
                        background: dc + "1a", color: dc,
                        borderRadius: 999,
                      }}>{t}</span>
                    ))}
                  </div>
                  {clickable && (
                    <div className="skillCue" style={{
                      marginTop: 16, fontSize: 12, fontWeight: 600, color: dc,
                      display: "inline-flex", alignItems: "center", gap: 6,
                      opacity: 0, transform: "translateX(-4px)",
                      transition: "opacity .3s, transform .3s",
                    }}>
                      See projects <span>→</span>
                    </div>
                  )}
                </div>
              </Reveal>
            );
          })}
        </div>
      </PSection>

      {/* PROJECTS */}
      <PSection id="work" tag="// work" title="Selected projects" accent={accent} fg={fg} muted={muted} line={line}>
        <ProjectFilterBar
          filter={filter} secs={secs} total={RESET_SECS}
          count={visibleProjects.length}
          onReset={() => setFilter(null)}
          fg={fg} muted={muted} card={card} line={line} mono={mono} dark={dark}
        />
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 22 }}>
          {visibleProjects.map((p, i) => {
            const statusList = Array.isArray(p.status) ? p.status : [p.status];
            const colorOf = (s) =>
              s === "Live"        ? "#22c55e" :
              s === "Completed"   ? "#a78bfa" :
              s === "In progress" ? "#f59e0b" :
              s === "Planning"    ? "#3b82f6" :
              s === "Unavailable" ? (dark ? "#9ca3af" : "#6b7280") :
                                    muted;
            const primaryStatus = statusList[statusList.length - 1];
            const primaryColor = colorOf(primaryStatus);
            return (
              <Reveal key={p.id} delay={i * 60}>
                <div className="projWrap" style={{
                  position: "relative", height: "100%",
                  "--pc": p.color,
                }}>
                  {/* Aura glow */}
                  <span className="projAura" aria-hidden="true" style={{
                    position: "absolute", inset: -2, borderRadius: 26,
                    background: `radial-gradient(60% 70% at 30% 0%, ${p.color}55, transparent 60%), radial-gradient(60% 70% at 80% 100%, ${p.color}33, transparent 60%)`,
                    filter: "blur(28px)", opacity: .55,
                    pointerEvents: "none", zIndex: 0,
                    transition: "opacity .4s, filter .4s",
                  }} />
                  <a href={p.live} className="hov projCard" style={{
                    display: "flex", flexDirection: "column",
                    borderRadius: 22, overflow: "hidden", height: "100%",
                    background: dark ? "#0f0f17" : "#fff",
                    border: `1px solid ${line}`,
                    color: "inherit", textDecoration: "none", position: "relative", zIndex: 1,
                    transition: "transform .35s cubic-bezier(.2,.7,.2,1), border-color .3s, box-shadow .3s",
                  }}>
                  {/* TOP BAR: index + status */}
                  <div style={{
                    display: "flex", justifyContent: "space-between", alignItems: "center",
                    padding: "14px 20px", borderBottom: `1px solid ${line}`,
                    background: `linear-gradient(90deg, ${p.color}14, transparent)`,
                  }}>
                    <span style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <span style={{
                        width: 28, height: 28, borderRadius: 8, background: p.color, color: "#fff",
                        display: "grid", placeItems: "center", fontWeight: 800, fontSize: 12,
                        fontFamily: mono,
                      }}>{p.id}</span>
                      <span style={{ fontSize: 11, color: muted, fontFamily: mono, letterSpacing: ".1em" }}>
                        {p.year.toUpperCase()} · {p.role.toUpperCase()}
                      </span>
                    </span>
                    <span style={{
                      display: "inline-flex", alignItems: "center", gap: 6,
                    }}>
                      {statusList.map((s) => {
                        const sc = colorOf(s);
                        return (
                          <span key={s} style={{
                            fontSize: 11, fontWeight: 600,
                            padding: "4px 10px", borderRadius: 999,
                            background: sc + "1a", color: sc,
                            border: `1px solid ${sc}33`,
                            display: "inline-flex", alignItems: "center", gap: 6,
                          }}>
                            <span style={{
                              width: 6, height: 6, borderRadius: "50%", background: sc,
                              animation: s === "Live" ? "pulse 2s infinite" : "none",
                            }} />
                            {s}
                          </span>
                        );
                      })}
                    </span>
                  </div>

                  {/* BODY */}
                  <div style={{ padding: "22px 22px 18px", flex: 1, display: "flex", flexDirection: "column" }}>
                    <h3 style={{
                      fontSize: 26, fontWeight: 800, letterSpacing: "-.02em", lineHeight: 1.1,
                      margin: "0 0 8px",
                    }}>{p.title}</h3>
                    <p style={{
                      fontSize: 14, color: muted, lineHeight: 1.5, margin: "0 0 16px",
                    }}>{p.blurb}</p>

                    {/* Highlights — the substance */}
                    <ul style={{
                      listStyle: "none", padding: 0, margin: "0 0 18px",
                      display: "flex", flexDirection: "column", gap: 6,
                    }}>
                      {p.highlights.map((h, k) => (
                        <li key={k} style={{
                          display: "flex", gap: 10, alignItems: "flex-start",
                          fontSize: 13, color: muted, lineHeight: 1.5,
                        }}>
                          <span style={{
                            color: p.color, marginTop: 2, fontWeight: 700, flex: "0 0 auto",
                          }}>→</span>
                          {h}
                        </li>
                      ))}
                    </ul>

                    {/* Tags */}
                    <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: "auto" }}>
                      {p.tags.map(t => (
                        <span key={t} style={{
                          fontSize: 11, fontWeight: 600, padding: "4px 10px",
                          background: p.color + "14", color: p.color,
                          borderRadius: 999, border: `1px solid ${p.color}26`,
                        }}>{t}</span>
                      ))}
                    </div>
                  </div>

                  {/* FOOTER actions */}
                  <div style={{
                    display: "flex", justifyContent: "space-between", alignItems: "center",
                    padding: "14px 20px", borderTop: `1px solid ${line}`,
                    background: dark ? "rgba(255,255,255,.02)" : "rgba(0,0,0,.02)",
                  }}>
                    <span className="projCta" style={{
                      display: "inline-flex", alignItems: "center", gap: 8,
                      fontSize: 13, fontWeight: 700, color: p.color,
                      transition: "gap .3s",
                    }}>
                      Open project
                      <span className="projCtaArrow" style={{
                        transition: "transform .3s cubic-bezier(.2,.7,.2,1)",
                      }}>→</span>
                    </span>
                    <span style={{ display: "flex", gap: 8 }}>
                      <span title="View code" style={{
                        width: 30, height: 30, borderRadius: 8,
                        background: dark ? "rgba(255,255,255,.05)" : "rgba(0,0,0,.05)",
                        color: fg, display: "grid", placeItems: "center",
                      }}>
                        <BrandIcon name="github" size={14} />
                      </span>
                      {statusList.includes("Live") && (
                        <span title="Live" style={{
                          width: 30, height: 30, borderRadius: 8,
                          background: primaryColor, color: "#fff",
                          display: "grid", placeItems: "center",
                          fontSize: 13, fontWeight: 700,
                        }}>↗</span>
                      )}
                    </span>
                  </div>
                  </a>
                </div>
              </Reveal>
            );
          })}
        </div>

        <style>{`
          .projWrap{ transition: transform .35s cubic-bezier(.2,.7,.2,1); }
          .projWrap:hover{ transform: translateY(-6px); }
          .projWrap:hover .projAura{ opacity: 1; filter: blur(36px); }
          .projWrap:hover .projCard{
            border-color: var(--pc, ${accent})88;
            box-shadow: 0 20px 50px var(--pc, ${accent})33;
          }
          .projWrap:hover .projCta{ gap: 12px; }
          .projWrap:hover .projCtaArrow{ transform: translateX(3px); }
        `}</style>
      </PSection>

      {/* EXPERIENCE — vertical timeline */}
      <PSection id="experience" tag="// journey" title="Where I've been" accent={accent} fg={fg} muted={muted} line={line}>
        <div style={{ position: "relative", paddingLeft: 32 }}>
          <div style={{
            position: "absolute", left: 7, top: 8, bottom: 8, width: 2,
            background: `linear-gradient(${accent}, transparent)`,
          }} />
          {D.experience.map((e, i) => (
            <Reveal key={i} delay={i * 100}>
              <div style={{ position: "relative", paddingBottom: 40 }}>
                <span style={{
                  position: "absolute", left: -32, top: 6, width: 16, height: 16, borderRadius: "50%",
                  background: i === 0 ? accent : card, border: `2px solid ${accent}`,
                  boxShadow: `0 0 0 6px ${accent}22`,
                }} />
                <div style={{ fontSize: 12, color: accent, fontFamily: mono, letterSpacing: ".05em", marginBottom: 6 }}>
                  {e.when}
                </div>
                <div style={{ fontSize: 24, fontWeight: 700, letterSpacing: "-.01em" }}>
                  {e.role}
                </div>
                <div style={{ fontSize: 14, color: muted, marginTop: 4 }}>
                  {e.org} · {e.where}
                </div>
                <div style={{ marginTop: 12, maxWidth: 640, display: "flex", flexDirection: "column", gap: 8 }}>
                  {(e.bullets || [e.blurb]).map((b, j) => (
                    <div key={j} style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
                      <span style={{ color: accent, fontSize: 13, marginTop: 2, flexShrink: 0 }}>→</span>
                      <span style={{ fontSize: 15, color: muted, lineHeight: 1.6 }}>{b}</span>
                    </div>
                  ))}
                </div>
              </div>
            </Reveal>
          ))}
        </div>
      </PSection>

      {/* TESTIMONIALS — chat bubbles — commented out for now */}
      {false && (
      <PSection id="words" tag="// what they say" title="Kind words" accent={accent} fg={fg} muted={muted} line={line}>
        <Reveal>
          <div style={{
            maxWidth: 760, margin: "0 auto",
            background: card, border: `1px solid ${line}`, borderRadius: 28,
            overflow: "hidden",
            boxShadow: dark ? "0 24px 60px rgba(0,0,0,.35)" : "0 24px 60px rgba(0,0,0,.08)",
          }}>
            {/* chat header */}
            <div style={{
              display: "flex", alignItems: "center", gap: 12,
              padding: "14px 20px", borderBottom: `1px solid ${line}`,
              background: dark ? "rgba(255,255,255,.02)" : "rgba(0,0,0,.02)",
            }}>
              <span style={{ display: "inline-flex", gap: 6 }}>
                <span style={{ width: 10, height: 10, borderRadius: "50%", background: "#ef4444" }} />
                <span style={{ width: 10, height: 10, borderRadius: "50%", background: "#f59e0b" }} />
                <span style={{ width: 10, height: 10, borderRadius: "50%", background: "#22c55e" }} />
              </span>
              <span style={{ fontFamily: mono, fontSize: 12, color: muted, marginLeft: 6 }}>
                #references &nbsp;·&nbsp; 3 people are talking
              </span>
              <span style={{ marginLeft: "auto", fontSize: 11, color: muted, fontFamily: mono }}>
                <span style={{ color: "#22c55e" }}>●</span> live
              </span>
            </div>

            {/* messages */}
            <div style={{ padding: "28px 24px 20px", display: "flex", flexDirection: "column", gap: 22 }}>
              {D.testimonials.map((t, i) => {
                const bubbleColors = [accent, "#22d3ee", "#f59e0b"];
                const bc = bubbleColors[i % bubbleColors.length];
                return (
                  <Reveal key={i} delay={i * 140} y={16}>
                    <div style={{ display: "flex", gap: 12, alignItems: "flex-start" }}>
                      <span style={{
                        flex: "0 0 auto",
                        width: 40, height: 40, borderRadius: "50%",
                        background: `linear-gradient(135deg, ${bc}, ${bc}aa)`,
                        display: "grid", placeItems: "center",
                        color: "#fff", fontWeight: 800, fontSize: 15,
                        boxShadow: `0 4px 12px ${bc}55`,
                      }}>{t.who[0]}</span>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginBottom: 6 }}>
                          <span style={{ fontWeight: 700, fontSize: 14 }}>{t.who}</span>
                          <span style={{ fontSize: 11, color: muted }}>{t.role}</span>
                          <span style={{ fontSize: 11, color: muted, marginLeft: "auto", fontFamily: mono }}>
                            {["just now", "2m", "5m"][i]}
                          </span>
                        </div>
                        <div className="hov" style={{
                          padding: "14px 18px",
                          background: i % 2 === 0
                            ? (dark ? "rgba(255,255,255,.04)" : "rgba(0,0,0,.03)")
                            : `${bc}1a`,
                          borderRadius: "4px 18px 18px 18px",
                          fontSize: 16, lineHeight: 1.5,
                          borderLeft: `3px solid ${bc}`,
                          maxWidth: "fit-content",
                          transition: "transform .25s",
                        }}
                          onMouseEnter={e => e.currentTarget.style.transform = "translateX(4px)"}
                          onMouseLeave={e => e.currentTarget.style.transform = "translateX(0)"}
                        >
                          {t.quote}
                        </div>
                        {/* reactions */}
                        <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
                          {["❤️", "🔥", "👏"].slice(0, i + 1).map((r, k) => (
                            <span key={k} style={{
                              fontSize: 11, padding: "3px 8px",
                              background: dark ? "rgba(255,255,255,.05)" : "rgba(0,0,0,.04)",
                              border: `1px solid ${line}`, borderRadius: 99,
                              display: "inline-flex", gap: 4, alignItems: "center",
                            }}>{r} <span style={{ color: muted, fontSize: 10 }}>{[7, 4, 3, 5, 6][i * 3 + k] || 3}</span></span>
                          ))}
                        </div>
                      </div>
                    </div>
                  </Reveal>
                );
              })}

              {/* typing indicator */}
              <Reveal delay={500} y={8}>
                <div style={{ display: "flex", gap: 12, alignItems: "center", marginTop: 4, paddingLeft: 52 }}>
                  <span style={{
                    display: "inline-flex", gap: 4, padding: "10px 14px",
                    background: dark ? "rgba(255,255,255,.04)" : "rgba(0,0,0,.03)",
                    borderRadius: "4px 14px 14px 14px",
                  }}>
                    <Dot accent={muted} delay="0s" />
                    <Dot accent={muted} delay=".2s" />
                    <Dot accent={muted} delay=".4s" />
                  </span>
                  <span style={{ fontSize: 12, color: muted, fontStyle: "italic" }}>
                    more references on the way — ask me
                  </span>
                </div>
              </Reveal>
            </div>

            {/* composer */}
            <div style={{
              padding: "14px 20px", borderTop: `1px solid ${line}`,
              display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: muted,
              background: dark ? "rgba(255,255,255,.02)" : "rgba(0,0,0,.02)",
            }}>
              <span style={{ fontFamily: mono, color: accent }}>›</span>
              <a href={`mailto:${D.email}`} style={{ color: muted, textDecoration: "none" }}
                onMouseEnter={e => e.currentTarget.style.color = accent}
                onMouseLeave={e => e.currentTarget.style.color = muted}
              >
                say something nice ↗
              </a>
              <span style={{ marginLeft: "auto", fontFamily: mono, fontSize: 11 }}>
                press <kbd style={{ background: card, border: `1px solid ${line}`, padding: "1px 6px", borderRadius: 4, color: fg }}>⏎</kbd>
              </span>
            </div>
          </div>
        </Reveal>

        <style>{`@keyframes dotPulse{0%,80%,100%{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}`}</style>
      </PSection>
      )}

      {/* BLOG */}
      <PSection id="writing" tag="// writing" title="Recent thoughts" accent={accent} fg={fg} muted={muted} line={line}>
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          {D.posts.map((p, i) => (
            <Reveal key={i} delay={i * 80}>
              <a href={p.link || "#"} className="hov" style={{
                display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 24, alignItems: "center",
                padding: "24px 28px", borderRadius: 20, background: card, border: `1px solid ${line}`,
                color: "inherit", textDecoration: "none",
                transition: "transform .3s, border-color .3s, background .3s",
              }}
                onMouseEnter={e => { e.currentTarget.style.transform = "translateX(8px)"; e.currentTarget.style.borderColor = accent + "66"; }}
                onMouseLeave={e => { e.currentTarget.style.transform = "translateX(0)"; e.currentTarget.style.borderColor = line; }}
              >
                <span style={{
                  fontSize: 11, padding: "5px 12px", borderRadius: 999,
                  background: accent + "22", color: accent, fontWeight: 600,
                }}>{p.kicker}</span>
                <div>
                  <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: "-.01em" }}>{p.title}</div>
                  <div style={{ fontSize: 12, color: muted, marginTop: 4 }}>{p.date} · {p.read} read</div>
                </div>
                <span style={{ fontSize: 24, color: accent }}>→</span>
              </a>
            </Reveal>
          ))}
        </div>
      </PSection>

      {/* CONTACT */}
      <section id="hire" style={{ padding: "120px 32px", position: "relative", overflow: "hidden" }}>
        <div style={{
          position: "absolute", inset: 0, background: `radial-gradient(circle at 30% 50%, ${accent}22, transparent 60%)`,
          pointerEvents: "none",
        }} />
        <Reveal>
          <div style={{ fontSize: 12, color: accent, fontFamily: mono, letterSpacing: ".2em", marginBottom: 16, textAlign: "center" }}>
            // GET IN TOUCH
          </div>
          <h2 style={{
            fontSize: "clamp(64px, 11vw, 180px)", fontWeight: 800, letterSpacing: "-.045em",
            lineHeight: .92, margin: 0, textAlign: "center",
          }}>
            Let&rsquo;s build<br />
            <span style={{
              background: `linear-gradient(120deg, ${accent}, #22d3ee, #f59e0b)`,
              backgroundSize: "200% 200%", WebkitBackgroundClip: "text", backgroundClip: "text", color: "transparent",
              animation: "gradient 6s ease infinite", fontStyle: "italic",
            }}>something!</span>
          </h2>
        </Reveal>
        <Reveal delay={150}>
          <div style={{ display: "flex", justifyContent: "center", marginTop: 40 }}>
            <a href={`mailto:${D.email}`} className="hov ctaMail" style={{
              display: "inline-flex", alignItems: "center", gap: 14, padding: "20px 36px",
              fontSize: 22, fontWeight: 600, color: bg, background: fg, borderRadius: 999,
              textDecoration: "none", boxShadow: `0 20px 60px ${accent}44`,
              position: "relative", overflow: "hidden",
              transition: "transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s",
            }}>
              <span className="ctaStar" style={{
                fontSize: 22, display: "inline-block",
                transition: "transform .5s cubic-bezier(.2,.7,.2,1)",
              }}>✦</span>
              <span>{D.email}</span>
              <span className="ctaArrow" style={{
                fontSize: 22, display: "inline-flex", alignItems: "center", width: 26, justifyContent: "flex-start",
                transition: "transform .3s cubic-bezier(.2,.7,.2,1)",
              }}>→</span>
            </a>
          </div>
        </Reveal>
        <Reveal delay={250}>
          <div style={{ display: "flex", justifyContent: "center", gap: 8, marginTop: 32, flexWrap: "wrap" }}>
           {[
              { k: "GitHub",   handle: "Lancelcode", href: "https://github.com/Lancelcode",
                brand: dark ? "#fff" : "#181717", glow: "#4c1d95", icon: <BrandIcon name="github" /> },
              { k: "LinkedIn", handle: "djiby", href: "https://www.linkedin.com/in/djiby-sow-rebollo/",
                brand: "#0A66C2", glow: "#0A66C2", icon: <BrandIcon name="linkedin" /> },
              { k: "X",        handle: "Lancelcode", href: "https://x.com/Lancelcode",
                brand: dark ? "#fff" : "#000", glow: "#cbd5e1", icon: <BrandIcon name="x" /> },
            ].map(({ k, handle, href, brand, glow, icon }) => (
              <a key={k} href={href} target="_blank" rel="noopener noreferrer" className="hov socialPill" style={{
                padding: "12px 22px", borderRadius: 999, border: `1.5px solid ${line}`,
                color: fg, textDecoration: "none", fontSize: 14, fontWeight: 500,
                display: "inline-flex", gap: 10, alignItems: "center",
                background: card,
                "--glow": glow,
                transition: "transform .3s cubic-bezier(.2,.7,.2,1), border-color .3s, box-shadow .3s",
              }}>
                <span className="socialIcon" style={{
                  display: "inline-flex", alignItems: "center", color: brand,
                  transition: "transform .35s cubic-bezier(.2,.7,.2,1)",
                }}>{icon}</span>
                <span>{k}</span>
                <span style={{ color: muted }}>@{handle}</span>
                <span className="socialArrow" style={{
                  fontSize: 14, color: muted, marginLeft: 2,
                  transition: "transform .3s cubic-bezier(.2,.7,.2,1), color .3s",
                }}>↗</span>
              </a>
            ))}
          </div>
        </Reveal>
        <div style={{ textAlign: "center", fontSize: 11, color: muted, marginTop: 80, fontFamily: mono, letterSpacing: ".15em" }}>
          © 2026 DJIBY · MADE WITH ♥ IN EDINBURGH · STILL TAKING CAFFEINE
        </div>
      </section>

      <style>{`
        @keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
        @keyframes wave{0%,100%{transform:rotate(0)}25%{transform:rotate(20deg)}75%{transform:rotate(-12deg)}}
        @keyframes gradient{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
        @keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(34,197,94,.6)}50%{box-shadow:0 0 0 8px rgba(34,197,94,0)}}
        @keyframes scrollHint{0%,100%{transform:scaleY(0);transform-origin:top}50%{transform:scaleY(1);transform-origin:top}}
        @keyframes blink{50%{opacity:0}}
        @keyframes filterIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}
        @keyframes marqueeL{from{transform:translateX(0)}to{transform:translateX(-50%)}}
        .ctaMail:hover{transform:translateY(-3px);box-shadow:0 28px 80px ${accent}66}
        .ctaMail:hover .ctaStar{transform:rotate(180deg) scale(1.15)}
        .ctaMail:hover .ctaArrow{transform:translateX(6px)}
        .ctaMail:active{transform:translateY(-1px) scale(.99)}
        .socialPill:hover{transform:translateY(-3px);border-color:var(--glow);box-shadow:0 12px 30px color-mix(in srgb, var(--glow) 45%, transparent)}
        .socialPill:hover .socialIcon{transform:scale(1.15) rotate(-6deg)}
        .socialPill:hover .socialArrow{transform:translate(3px,-3px);color:var(--glow)}
        .heroCta-primary:hover{transform:translateY(-2px);box-shadow:0 18px 44px ${accent}66}
        .heroCta-primary:hover .heroArrow{transform:translateX(5px)}
        .heroCta-primary:active{transform:translateY(0)}
        .heroNavLink:hover{color:${fg} !important;background:${dark ? "rgba(255,255,255,.06)" : "rgba(0,0,0,.06)"}}
        .heroChip{transition:transform .25s cubic-bezier(.2,.7,.2,1),box-shadow .25s;cursor:default}
        .heroChip:hover{transform:translateY(-2px);box-shadow:0 8px 22px color-mix(in srgb, var(--cg) 38%, transparent)}
        .heroTalk::before{content:"";position:absolute;inset:0;z-index:-1;
          background:linear-gradient(120deg,transparent 20%,rgba(255,255,255,.35) 50%,transparent 80%);
          transform:translateX(-130%);transition:transform .6s cubic-bezier(.2,.7,.2,1)}
        .heroTalk:hover::before{transform:translateX(130%)}
        .heroTalk:hover{transform:translateY(-2px);box-shadow:0 12px 30px color-mix(in srgb, var(--cg) 55%, transparent)}
        .heroTalk:hover .heroTalkArrow{transform:translateX(3px)}
        .heroTalk:active{transform:translateY(0) scale(.98)}
        .brandMark{transition:transform .25s cubic-bezier(.2,.7,.2,1)}
        .brandMark:hover{transform:translateX(2px)}
      `}</style>
    </div>
  );
}

function ProjectFilterBar({ filter, secs, total, count, onReset, fg, muted, card, line, mono, dark }) {
  if (!filter) return null;
  const c = filter.color;
  const R = 15, CIRC = 2 * Math.PI * R;
  const frac = Math.max(0, Math.min(1, secs / total));
  const ss = String(Math.max(0, secs)).padStart(2, "0");
  return (
    <div style={{
      display: "flex", alignItems: "center", justifyContent: "space-between",
      gap: 20, flexWrap: "wrap",
      padding: "16px 20px", marginBottom: 28,
      borderRadius: 16, background: card,
      border: `1px solid ${line}`, borderLeft: `4px solid ${c}`,
      animation: "filterIn .45s cubic-bezier(.2,.7,.2,1)",
    }}>
      {/* left: what you're viewing */}
      <div style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
        <span style={{
          fontFamily: mono, fontSize: 11, letterSpacing: ".12em", textTransform: "uppercase",
          color: muted,
        }}>
          You&rsquo;re looking at projects done with
        </span>
        <span style={{
          display: "inline-flex", alignItems: "center", gap: 8,
          padding: "6px 14px", borderRadius: 999,
          background: c + "1f", color: c, border: `1px solid ${c}55`,
          fontWeight: 700, fontSize: 15,
        }}>
          <span style={{ width: 8, height: 8, borderRadius: "50%", background: c }} />
          {filter.name}
          <span style={{ color: muted, fontWeight: 500, fontSize: 12 }}>
            · {count} {count === 1 ? "project" : "projects"}
          </span>
        </span>
      </div>

      {/* right: countdown + reset CTA */}
      <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
        <span style={{ fontSize: 12, color: muted, textAlign: "right", maxWidth: 220, lineHeight: 1.4 }}>
          Take a look before it switches back to my&nbsp;favourites
        </span>
        <button
          onClick={onReset}
          className="resetBtn"
          style={{
            display: "inline-flex", alignItems: "center", gap: 10,
            padding: "8px 8px 8px 16px", borderRadius: 999,
            background: dark ? "rgba(255,255,255,.05)" : "rgba(0,0,0,.04)",
            border: `1px solid ${line}`, color: fg,
            font: "inherit", fontSize: 13, fontWeight: 600, cursor: "pointer",
            transition: "transform .25s cubic-bezier(.2,.7,.2,1), border-color .25s, background .25s",
          }}
          onMouseEnter={e => { e.currentTarget.style.transform = "translateY(-2px)"; e.currentTarget.style.borderColor = c + "88"; }}
          onMouseLeave={e => { e.currentTarget.style.transform = "translateY(0)"; e.currentTarget.style.borderColor = line; }}
        >
          <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
            <span className="resetSpin" style={{ fontSize: 14, lineHeight: 1 }}>↺</span>
            Back to my best
          </span>
          {/* countdown ring */}
          <span style={{ position: "relative", width: 38, height: 38, flexShrink: 0, display: "grid", placeItems: "center" }}>
            <svg width="38" height="38" viewBox="0 0 38 38" style={{ transform: "rotate(-90deg)" }}>
              <circle cx="19" cy="19" r={R} fill="none" stroke={dark ? "rgba(255,255,255,.12)" : "rgba(0,0,0,.1)"} strokeWidth="3" />
              <circle cx="19" cy="19" r={R} fill="none" stroke={c} strokeWidth="3" strokeLinecap="round"
                strokeDasharray={CIRC} strokeDashoffset={CIRC * (1 - frac)}
                style={{ transition: "stroke-dashoffset 1s linear" }} />
            </svg>
            <span style={{
              position: "absolute", fontFamily: mono, fontSize: 11, fontWeight: 700, color: fg,
              fontVariantNumeric: "tabular-nums",
            }}>{ss}</span>
          </span>
        </button>
      </div>
    </div>
  );
}

function PSection({ id, tag, title, accent, fg, muted, line, children }) {
  return (
    <section id={id} style={{ padding: "100px 32px", maxWidth: 1280, margin: "0 auto" }}>
      <Reveal>
        <div style={{
          fontSize: 12, fontFamily: "'JetBrains Mono', monospace", color: accent,
          letterSpacing: ".2em", textTransform: "uppercase", marginBottom: 12,
        }}>{tag}</div>
        <h2 style={{
          fontSize: "clamp(40px, 6vw, 80px)", fontWeight: 800, letterSpacing: "-.04em",
          lineHeight: 1, margin: "0 0 56px", textWrap: "balance",
        }}>{title}</h2>
      </Reveal>
      {children}
    </section>
  );
}

function Dot({ accent, delay }) {
  return <span style={{
    width: 6, height: 6, borderRadius: "50%", background: accent,
    display: "inline-block",
    animation: `dotPulse 1.2s ${delay} infinite`,
  }} />;
}

// ─── "Now reading" annotation marquee ──────────────────────────────────────
// A calm scrolling row of branded tech pills with a fixed center beacon.
// The pill nearest the center beam gets highlighted, and a personal one-liner
// annotation appears below the marquee — feels editorial and adds real signal.
function NowReadingMarquee({ accent, dark, fg, muted, card, line, bg }) {
  const techs = [
    { label: "JavaScript", color: "#F7DF1E", note: "the language I reach for first." },
    { label: "TypeScript", color: "#3178C6", note: "saves me from myself." },
    { label: "Java",       color: "#f89820", note: "love how objects compose. happy to let the GC worry for me." },
    { label: "Python",     color: "#3776AB", note: "the right tool for AI work and scripts." },
    { label: "C",          color: "#5C6BC0", note: "the language I admire most. unforgiving and honest." },
    { label: "PHP",        color: "#777BB4", note: "it's fine. got the job done on GreenScore." },
    { label: "React",      color: "#61DAFB", note: "I think in components now." },
    { label: "Spring",     color: "#6DB33F", note: "still earning my stripes here." },
    { label: "Node",       color: "#8CC84B", note: "great for fast iteration on the server." },
    { label: "Postgres",   color: "#336791", note: "my default database for everything." },
    { label: "Docker",     color: "#2496ED", note: "every project runs in a container." },
    { label: "HTML",       color: "#E34F26", note: "the foundation. semantics matter." },
    { label: "CSS",        color: "#1572B6", note: "the design tool I use most." },
    { label: "Git",        color: "#F05032", note: "save early, save often." },
  ];

  const trackRef = useRef(null);
  const [active, setActive] = useState({ label: techs[0].label, color: techs[0].color, note: techs[0].note });

  useEffect(() => {
    let raf;
    const tick = () => {
      const center = window.innerWidth / 2;
      const items = trackRef.current ? trackRef.current.querySelectorAll("[data-mq]") : [];
      let best = null, bestDist = Infinity;
      items.forEach(it => {
        const r = it.getBoundingClientRect();
        const c = r.left + r.width / 2;
        const d = Math.abs(c - center);
        if (d < bestDist) { bestDist = d; best = it; }
        it.toggleAttribute("data-active", d < r.width / 2 + 4);
      });
      if (best) {
        const idx = parseInt(best.getAttribute("data-mq"), 10);
        const t = techs[idx];
        if (t && t.label !== active.label) setActive(t);
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [active.label]);

  const dup = [...techs, ...techs, ...techs];

  return (
    <div style={{
      position: "relative", overflow: "hidden",
      borderTop: `1px solid ${line}`, borderBottom: `1px solid ${line}`,
      background: dark
        ? `linear-gradient(180deg, rgba(255,255,255,.02), rgba(255,255,255,.04))`
        : `linear-gradient(180deg, rgba(0,0,0,.02), rgba(0,0,0,.04))`,
    }}>
      {/* Edge fades */}
      <div style={{
        position: "absolute", inset: 0, pointerEvents: "none", zIndex: 3,
        background: `linear-gradient(90deg, ${bg} 0%, transparent 12%, transparent 88%, ${bg} 100%)`,
      }} />

      {/* Center beacon — vertical pulse line marking the "reading" spot */}
      <div aria-hidden="true" style={{
        position: "absolute", left: "50%", top: 0, bottom: 0, width: 1, zIndex: 2,
        background: `linear-gradient(180deg, transparent, ${accent}66, transparent)`,
        transform: "translateX(-50%)", pointerEvents: "none",
      }} />
      <div aria-hidden="true" style={{
        position: "absolute", left: "50%", top: 22, width: 6, height: 6,
        borderRadius: "50%", background: accent,
        transform: "translate(-50%, -50%)", zIndex: 4,
        boxShadow: `0 0 0 4px ${accent}33, 0 0 16px ${accent}88`,
      }} />

      {/* Pill track */}
      <div style={{ padding: "30px 0 24px", overflow: "hidden", whiteSpace: "nowrap" }}>
        <div ref={trackRef} style={{
          display: "inline-flex", gap: 14, alignItems: "center", paddingRight: 14,
          animation: "marqueeL 60s linear infinite",
          flexShrink: 0,
        }}>
          {dup.map((t, i) => {
            const realIdx = i % techs.length;
            return (
              <span key={i} data-mq={realIdx} className="nrmPill" style={{
                padding: "10px 18px", borderRadius: 999,
                border: `1.5px solid ${t.color}55`,
                color: t.color, background: card,
                fontWeight: 600, fontSize: 15,
                display: "inline-flex", alignItems: "center", gap: 8,
                flexShrink: 0,
                transition: "transform .25s cubic-bezier(.2,.7,.2,1), border-color .25s, background .25s, box-shadow .25s",
                "--pc": t.color,
              }}>
                <span style={{
                  width: 6, height: 6, borderRadius: "50%", background: t.color,
                }} />
                {t.label}
              </span>
            );
          })}
        </div>
      </div>

      {/* Annotation strip */}
      <div style={{
        padding: "10px 24px 18px", borderTop: `1px dashed ${line}`,
        display: "flex", alignItems: "center", justifyContent: "center", gap: 16,
        fontSize: 13, minHeight: 38,
      }}>
        <span style={{
          fontFamily: "'JetBrains Mono', monospace", fontSize: 11,
          color: muted, letterSpacing: ".18em", textTransform: "uppercase",
        }}>
          ↑ analysing
        </span>
        <span style={{
          display: "inline-flex", alignItems: "center", gap: 8,
          padding: "2px 10px", borderRadius: 999,
          background: active.color + "1a",
          color: active.color, fontWeight: 700,
          transition: "background .25s, color .25s",
        }}>
          <span style={{
            width: 6, height: 6, borderRadius: "50%", background: active.color,
            animation: "pulse 2s infinite",
          }} />
          {active.label}
        </span>
        <span key={active.label} style={{
          color: fg, fontStyle: "italic", letterSpacing: "-.005em",
          animation: "noteFade .4s ease",
        }}>
          {active.note}
        </span>
      </div>

      <style>{`
        .nrmPill[data-active]{
          transform: scale(1.12) translateY(-2px);
          border-color: var(--pc) !important;
          background: color-mix(in srgb, var(--pc) 14%, transparent) !important;
          box-shadow: 0 8px 24px color-mix(in srgb, var(--pc) 30%, transparent);
        }
        @keyframes noteFade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}
      `}</style>
    </div>
  );
}

function BrandIcon({ name, size = 16 }) {
  const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "currentColor", style: { display: "block" } };
  if (name === "github") {
    return (
      <svg {...common}>
        <path d="M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.11.79-.25.79-.55 0-.27-.01-1-.02-1.96-3.2.7-3.87-1.54-3.87-1.54-.52-1.33-1.28-1.69-1.28-1.69-1.05-.72.08-.71.08-.71 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.71 1.26 3.37.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.47.11-3.06 0 0 .97-.31 3.18 1.18.92-.26 1.91-.39 2.89-.39.98 0 1.97.13 2.89.39 2.21-1.49 3.18-1.18 3.18-1.18.63 1.59.23 2.77.11 3.06.74.81 1.19 1.84 1.19 3.1 0 4.43-2.69 5.41-5.25 5.69.41.36.77 1.06.77 2.13 0 1.54-.01 2.78-.01 3.16 0 .31.21.67.8.55C20.21 21.39 23.5 17.08 23.5 12 23.5 5.65 18.35.5 12 .5z"/>
      </svg>
    );
  }
  if (name === "linkedin") {
    return (
      <svg {...common}>
        <path d="M4.98 3.5C4.98 4.88 3.87 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1s2.48 1.12 2.48 2.5zM0 8h5v16H0V8zm7.5 0H12v2.2h.07c.66-1.25 2.28-2.57 4.7-2.57 5.02 0 5.95 3.3 5.95 7.6V24h-5v-7.1c0-1.7-.03-3.88-2.36-3.88-2.37 0-2.73 1.85-2.73 3.76V24h-5V8z"/>
      </svg>
    );
  }
  if (name === "x") {
    return (
      <svg {...common}>
        <path d="M18.244 2H21.5l-7.5 8.57L23 22h-6.84l-5.36-7.02L4.6 22H1.34l8.03-9.18L1 2h7.02l4.84 6.39L18.24 2zm-1.2 18.2h1.8L7.04 3.7H5.12L17.05 20.2z"/>
      </svg>
    );
  }
  return null;
}

window.Playful = Playful;
