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

function useMobile() {
  const [mobile, setMobile] = useState(() => window.matchMedia("(max-width: 760px)").matches);
  useEffect(() => {
    const mq = window.matchMedia("(max-width: 760px)");
    const handler = (e) => setMobile(e.matches);
    mq.addEventListener("change", handler);
    return () => mq.removeEventListener("change", handler);
  }, []);
  return mobile;
}

// ─────────────────────────────────────────────────────────────────────────────
// TWEAKS
// ─────────────────────────────────────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "rainbow",
  "density": "regular",
  "logoStyle": "slant",
  "font": "plex",
  "typewriter": true
} /*EDITMODE-END*/;

const PALETTES = {
  rainbow: {
    bg: "#000",
    fg: "#e7e5e2",
    dim: "#777",
    border: "#3a3a3a",
    accent1: "#ff6b9d", // pink — section heads
    accent2: "#7ee3ff", // cyan — links/nav
    accent3: "#ffd866", // amber — counts/badges
    accent4: "#a3e635", // lime — meta
    accent5: "#fb923c", // orange — emphasis
    name: "RAINBOW"
  },
  green: {
    bg: "#000",
    fg: "#9fff9f",
    dim: "#3d6b3d",
    border: "#1a3a1a",
    accent1: "#00ff66",
    accent2: "#9fff00",
    accent3: "#66ff99",
    accent4: "#33cc33",
    accent5: "#00ff66",
    name: "GREEN PHOSPHOR"
  },
  amber: {
    bg: "#0a0500",
    fg: "#ffb000",
    dim: "#7a4d00",
    border: "#3a2200",
    accent1: "#ffcc33",
    accent2: "#ffe066",
    accent3: "#ff7700",
    accent4: "#ffb000",
    accent5: "#ff9d33",
    name: "AMBER PHOSPHOR"
  },
  mono: {
    bg: "#000",
    fg: "#e5e5e5",
    dim: "#666",
    border: "#333",
    accent1: "#ffffff",
    accent2: "#cccccc",
    accent3: "#999999",
    accent4: "#bbbbbb",
    accent5: "#ffffff",
    name: "MONO"
  }
};

const DENSITY = {
  cramped: { fontSize: 12, lineHeight: 1.25, gap: 6 },
  regular: { fontSize: 14, lineHeight: 1.45, gap: 10 },
  spacious: { fontSize: 16, lineHeight: 1.7, gap: 14 }
};

const FONTS = {
  plex: `"IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace`,
  jb: `"JetBrains Mono", ui-monospace, Menlo, Consolas, monospace`,
  vt: `"VT323", "IBM Plex Mono", ui-monospace, monospace`
};

// ─────────────────────────────────────────────────────────────────────────────
// ASCII LOGOS
// ─────────────────────────────────────────────────────────────────────────────
// Big font (figlet "big") — the requested header look. Composed full-width (no smush) for clean alignment.
const LOGO_BIG = String.raw`
 __  __            _____    _____      _   _            _______  _____    ____   _   _
|  \/  |    /\    |  __ \  / ____|    | \ | |    /\    |__   __||_   _|  / __ \ | \ | |
| \  / |   /  \   | |  | || (___      |  \| |   /  \      | |    | |    | |  | ||  \| |
| |\/| |  / /\ \  | |  | | \___ \     | . ' |  / /\ \     | |    | |    | |  | || . ' |
| |  | | / ____ \ | |__| | ____) |    | |\  | / ____ \    | |   _| |_   | |__| || |\  |
|_|  |_|/_/    \_\|_____/ |_____/     |_| \_|/_/    \_\   |_|  |_____|   \____/ |_| \_|
`.replace(/^\n/, "");

const LOGO_SLANT = String.raw`
    __  ______    ____  _____    _   _____  ______________  _   __
   /  |/  /   |  / __ \/ ___/   / | / /   |/_  __/  _/ __ \/ | / /
  / /|_/ / /| | / / / /\__ \   /  |/ / /| | / /  / // / / /  |/ /
 / /  / / ___ |/ /_/ /___/ /  / /|  / ___ |/ / _/ // /_/ / /|  /
/_/  /_/_/  |_/_____//____/  /_/ |_/_/  |_/_/ /___/\____/_/ |_/
`.replace(/^\n/, "");

const LOGO_BLOCK = String.raw`
 __  __    _    ____  ____    _   _    _  _____ ___  ___   _   _
|  \/  |  / \  |  _ \/ ___|  | \ | |  / \|_   _|_ _|/ _ \ | \ | |
| |\/| | / _ \ | | | \___ \  |  \| | / _ \ | |  | || | | ||  \| |
| |  | |/ ___ \| |_| |___) | | |\  |/ ___ \| |  | || |_| || |\  |
|_|  |_/_/   \_\____/|____/  |_| \_/_/   \_\_| |___|\___/ |_| \_|
`.replace(/^\n/, "");

const LOGO_SMALL = String.raw`
 __  __   _   ___  ___   _  _   _ _____ ___  ___   _  _
|  \/  | /_\ |   \/ __| | \| | /_\_   _|_ _|/ _ \ | \| |
| |\/| |/ _ \| |) \__ \ | .' |/ _ \| |  | || (_) || .' |
|_|  |_/_/ \_\___/|___/ |_|\_/_/ \_\_| |___|\___/ |_|\_|
`.replace(/^\n/, "");

const LOGOS = { big: LOGO_BIG, slant: LOGO_SLANT, block: LOGO_BLOCK, small: LOGO_SMALL };

// ─────────────────────────────────────────────────────────────────────────────
// CONTENT
// ─────────────────────────────────────────────────────────────────────────────
const NAV = [
{ id: "main", label: "MAIN" },
{ id: "about", label: "ABOUT" },
{ id: "projects", label: "PROJECTS" },
{ id: "writing", label: "WRITING" },
{ id: "reading", label: "READING" },
{ id: "photos", label: "PHOTOS" },
{ id: "contact", label: "CONTACT" }];


const PROJECTS = [
{
  name: "MORNINGPERSON.AI",
  year: "2026",
  blurb: "your tailor-made morning report — grab your monday by the balls. see what's ahead before the kids wake up.",
  href: "#",
  tag: "shipping"
},
{
  name: "POSTLISTE.AI",
  year: "2026",
  blurb: "pulls every available record from norwegian municipal public registers. gives small and mid-size businesses a proactive edge in their sales work.",
  href: "#",
  tag: "under development"
},
{
  name: "ELEKTRONISK-TINGLYSING",
  year: "2026",
  blurb: "making electronic property registration simpler for small and mid-size businesses.",
  href: "#",
  tag: "under development"
},
{
  name: "REP'D",
  year: "2026",
  blurb: "workout timer app. build sessions from multiple timer types — intervals, amraps, emoms, rest. stack them, run them.",
  href: "http://treningstimer-app.vercel.app",
  tag: "live"
},
{
  name: "BONDE",
  year: "2026",
  blurb: "high-end chess merch built around a distinct pawn logo. the weakest piece on the board — but with enormous potential.",
  href: "#",
  tag: "building"
},
{
  name: "WORDLE.LOL",
  year: "2024",
  blurb: "i had the idea, he has the repo. fair trade.",
  href: "https://wordle.lol",
  tag: "shared custody"
}];


const WRITING = [
{ title: "why the optimists are usually right (eventually)", date: "may '26", n: 47 },
{ title: "building houses taught me how to ship software", date: "apr '26", n: 33 },
{ title: "notes from a 4am workday", date: "mar '26", n: 91 },
{ title: "ålesund is a state of mind", date: "feb '26", n: 12 }];


const READING = [
{ title: "the diary of a bookseller", author: "bythell", state: "reading" },
{ title: "a confederacy of dunces", author: "toole", state: "reading" },
{ title: "poor charlie's almanack", author: "munger", state: "reading" },
{ title: "endure", author: "hutchinson", state: "reading" },
{ title: "the creative act", author: "rubin", state: "reading" },
{ title: "collective suicide", author: "paasilinna", state: "done" },
{ title: "shoe dog", author: "knight", state: "done" },
{ title: "never finished", author: "goggins", state: "done" },
{ title: "walden", author: "thoreau", state: "done" }];


const PHOTOS = [
{ label: "fjord trail, summer", src: "photos/cropped_1.png", dim: "320x240" },
{ label: "formal night", src: "photos/cropped_2.png", dim: "240x320" },
{ label: "summit, bad weather", src: "photos/cropped_3.png", dim: "320x240" },
{ label: "ski touring", src: "photos/cropped_4.png", dim: "320x240" },
{ label: "cycling", src: "photos/cropped_5.png", dim: "320x240" }];


const LINKS = [
{ label: "EMAIL", href: "mailto:mads@nation.no", hint: "mads@nation.no" },
{ label: "LINKEDIN", href: "https://www.linkedin.com/in/mads-toll%C3%A5s-nation-77b60420/", hint: "mads tollås nation" },
{ label: "INSTAGRAM", href: "https://instagram.com/madsnation", hint: "@madsnation" },
{ label: "FACEBOOK", href: "https://facebook.com/nati0n", hint: "/nati0n" }];


const BOOT_LINES = [
"[ ok ] establishing uplink to mads.nation ............ done",
"[ ok ] loading personality.exe (beta build 1.67) ..... done",
"[ ok ] mounting /offspring (3 dependents) ............ ok",
"[ ok ] caffeine subsystem ............................ critical",
"[ ok ] optimism daemon ............................... running",
"> welcome."];


// ─────────────────────────────────────────────────────────────────────────────
// PRIMITIVES
// ─────────────────────────────────────────────────────────────────────────────
function Hr({ char = "-", color }) {
  // Fill the row with the char without forcing horizontal scroll.
  return (
    <div
      aria-hidden="true"
      style={{
        color: color || "var(--border)",
        overflow: "hidden",
        whiteSpace: "nowrap",
        userSelect: "none",
        lineHeight: 1,
        padding: "6px 0"
      }}>
      
      {char.repeat(400)}
    </div>);

}

function L({ href = "#", children, color, onClick }) {
  // CAPS-LOCK link styled like a BBS hyperlink: [LABEL]
  return (
    <a
      href={href}
      onClick={onClick}
      target={href.startsWith("http") ? "_blank" : undefined}
      rel="noreferrer"
      style={{
        color: color || "var(--a2)",
        textDecoration: "none",
        textTransform: "uppercase",
        letterSpacing: ".02em",
        cursor: "pointer"
      }}
      onMouseEnter={(e) => e.currentTarget.style.textDecoration = "underline"}
      onMouseLeave={(e) => e.currentTarget.style.textDecoration = "none"}>
      
      {children}
    </a>);

}

function SectionHead({ children, color }) {
  return (
    <div
      style={{
        color: color || "var(--a1)",
        textTransform: "uppercase",
        letterSpacing: ".06em",
        marginTop: "1.4em",
        marginBottom: ".4em"
      }}>
      
      {">> "}{children}
    </div>);

}

// Typewriter — types a list of lines into a fixed-height pre block.
function Typewriter({ lines, speed = 18, lineDelay = 120, onDone }) {
  const [out, setOut] = useState("");
  const [done, setDone] = useState(false);
  useEffect(() => {
    let cancelled = false;
    let buf = "";
    let i = 0; // line idx
    let j = 0; // char idx
    function tick() {
      if (cancelled) return;
      const line = lines[i];
      if (line === undefined) {
        setDone(true);
        onDone && onDone();
        return;
      }
      if (j < line.length) {
        buf += line[j];
        j++;
        setOut(buf);
        setTimeout(tick, speed);
      } else {
        buf += "\n";
        i++;
        j = 0;
        setOut(buf);
        setTimeout(tick, lineDelay);
      }
    }
    tick();
    return () => {cancelled = true;};
  }, []); // eslint-disable-line
  return (
    <pre style={{
      margin: 0,
      whiteSpace: "pre-wrap",
      color: "var(--a4)",
      minHeight: `${(lines.length + 1) * 1.5}em`
    }}>
      {out}
      <span className="caret" style={{ color: "var(--a3)" }}>{done ? "█" : "▌"}</span>
    </pre>);

}

function Marquee({ items, color }) {
  const text = items.join("   ◆   ");
  return (
    <div style={{
      overflow: "hidden",
      whiteSpace: "nowrap",
      color: color || "var(--a3)",
      padding: "4px 0",
      borderTop: "1px dashed var(--border)",
      borderBottom: "1px dashed var(--border)"
    }}>
      <div className="marq" style={{ display: "inline-block", paddingLeft: "100%" }}>
        {text}   ◆   {text}
      </div>
    </div>);

}


// ─────────────────────────────────────────────────────────────────────────────
// SECTIONS
// ─────────────────────────────────────────────────────────────────────────────
function Header({ logoStyle }) {
  const logo = LOGOS[logoStyle] || LOGO_BIG;
  const wrapRef = useRef(null);
  const preRef = useRef(null);
  const [scale, setScale] = useState(1);
  const [preH, setPreH] = useState(0);

  useEffect(() => {
    if (!wrapRef.current || !preRef.current) return;
    const obs = new ResizeObserver(() => {
      const s = Math.min(1, wrapRef.current.offsetWidth / preRef.current.scrollWidth);
      setScale(s);
      setPreH(preRef.current.scrollHeight);
    });
    obs.observe(wrapRef.current);
    return () => obs.disconnect();
  }, [logo]);

  return (
    <div
      ref={wrapRef}
      style={{
        paddingTop: 18,
        paddingBottom: 6,
        height: preH ? preH * scale + 24 : undefined,
        overflow: "hidden"
      }}>
      <pre
        ref={preRef}
        aria-label="MADS NATION"
        style={{
          margin: 0,
          color: "var(--a1)",
          fontFamily: "Courier New, Courier, monospace",
          fontSize: "14px",
          lineHeight: 1.2,
          letterSpacing: 0,
          whiteSpace: "pre",
          display: "inline-block",
          transformOrigin: "top left",
          transform: `scale(${scale})`
        }}>{logo}</pre>
    </div>);
}

function Nav({ gap = "0 18px", sepMargin = 18 }) {
  return (
    <div style={{ display: "flex", flexWrap: "wrap", gap, padding: "4px 0" }}>
      {NAV.map((n, i) =>
      <span key={n.id}>
          <L href={`#${n.id}`} color={i === 0 ? "var(--a1)" : "var(--a2)"}>
            {n.label}
          </L>
          {i < NAV.length - 1 && <span style={{ color: "var(--dim)", marginLeft: sepMargin }}>|</span>}
        </span>
      )}
    </div>);

}

function StatusBars() {
  // Two compact rows of IRC-style stats — original copy, not copying SoGamed labels.
  return (
    <div>
      <div style={{ padding: "4px 0", color: "var(--fg)" }}>
        <span style={{ color: "var(--a1)" }}>STATUS:</span>{" "}
        <span style={{ color: "var(--a3)" }}>shipping</span>
        {" · "}
        <span style={{ color: "var(--a1)" }}>OFFSPRING:</span>{" "}
        <span style={{ color: "var(--a3)" }}>3</span>
        {" · "}
        <span style={{ color: "var(--a1)" }}>LOCATION:</span>{" "}
        <span style={{ color: "var(--a4)" }}>ålesund, nor</span>{" "}
        <span style={{ color: "var(--dim)" }}>(62.47°N, 6.15°E)</span>
        {" · "}
        <span style={{ color: "var(--a1)" }}>UPTIME:</span>{" "}
        <span style={{ color: "var(--a3)" }}>39 yrs</span>{" "}
        <span style={{ color: "var(--dim)" }}>(stable)</span>
      </div>
      <div style={{ padding: "4px 0", color: "var(--fg)" }}>
        <span style={{ color: "var(--a1)" }}>BUILT:</span>{" "}
        <span style={{ color: "var(--a4)" }}>houses</span>{" "}
        <span style={{ color: "var(--dim)" }}>(prev)</span>
        {" · "}
        <span style={{ color: "var(--a4)" }}>technology & companies</span>{" "}
        <span style={{ color: "var(--dim)" }}>(now)</span>
        {" · "}
        <span style={{ color: "var(--a1)" }}>FUEL:</span>{" "}
        <span style={{ color: "var(--a5)" }}>coffee · curiosity · spite</span>
        {" · "}
        <span style={{ color: "rgb(163, 230, 53)" }}></span>{" "}
        <span style={{ color: "var(--a2)" }}></span>{" "}
        <span style={{ color: "var(--dim)" }}></span>
      </div>
      <div style={{ padding: "4px 0", color: "var(--fg)" }}>
        <span style={{ color: "var(--a1)" }}>NOW:</span>{" "}
        <span style={{ color: "var(--fg)" }}>a startup in the oven, a marathon in mind, strength and prosperity on the inside and love on the outside.</span>
      </div>
    </div>);

}

function GuestbookBar() {
  const [val, setVal] = useState("");
  const [status, setStatus] = useState(null); // null | "sending" | "ok" | "err"

  async function submit() {
    if (!val.trim() || status === "sending") return;
    setStatus("sending");
    try {
      const res = await fetch("/api/guestbook", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message: val.trim() })
      });
      setStatus(res.ok ? "ok" : "err");
      if (res.ok) setVal("");
    } catch {
      setStatus("err");
    }
  }

  return (
    <div style={{ display: "flex", flexWrap: "wrap", alignItems: "center", gap: 10, padding: "6px 0" }}>
      <span style={{ color: "var(--a3)" }}>guest@mads.nation:~$</span>
      <span style={{ color: "var(--dim)" }}>echo</span>
      <input
        type="text"
        value={val}
        onChange={(e) => { setVal(e.target.value); setStatus(null); }}
        onKeyDown={(e) => { if (e.key === "Enter") submit(); }}
        placeholder="say hi, and leave your name"
        style={{
          background: "#0a0a0a",
          border: "1px solid var(--border)",
          color: "var(--fg)",
          font: "inherit",
          padding: "2px 6px",
          minWidth: 220,
          flex: "0 1 320px",
          outline: "none"
        }} />
      <span style={{ color: "var(--dim)" }}>{">"}</span>
      <span style={{ color: "var(--dim)" }}>guestbook.log</span>
      <L href="#" onClick={(e) => { e.preventDefault(); submit(); }}>[SEND]</L>
      <L href="#contact">[CONTACT]</L>
      <L href="#now">[NOW]</L>
      {status === "sending" && <span style={{ color: "var(--dim)" }}>sending...</span>}
      {status === "ok"      && <span style={{ color: "var(--a4)" }}>← logged ✓</span>}
      {status === "err"     && <span style={{ color: "var(--a5)" }}>← failed ✗</span>}
    </div>);
}

function About() {
  return (
    <section id="about">
      <SectionHead>about.txt</SectionHead>
      <div style={{ color: "var(--fg)" }}>
        father of 3.{" "}
        <span style={{ color: "var(--dim)" }}>(the loudest threshold of love.)</span>
      </div>
      <div style={{ color: "var(--fg)" }}>
        based in <span style={{ color: "var(--a4)" }}>ålesund, norway</span>.
      </div>
      <div style={{ color: "var(--fg)" }}>
        known for{" "}
        <span style={{ color: "var(--a3)" }}>building houses</span>{" "}
        <span style={{ color: "var(--dim)" }}>in ålesund. home for families. </span>
      </div>
      <div style={{ color: "var(--fg)" }}>
        now <span style={{ color: "var(--a3)" }}>building technology &amp; companies</span>.
        same job, different tools.
      </div>
      <div style={{ color: "var(--fg)", marginTop: ".4em" }}>
        <span style={{ color: "var(--a5)" }}>tech savy</span>{" / "}
        <span style={{ color: "var(--a5)" }}>optimistic</span>{" / "}
        <span style={{ color: "var(--a5)" }}>business minded</span>{" / "}
        <span style={{ color: "var(--a5)" }}>entrepreneurial</span>
      </div>
    </section>);

}

function Education() {
  const edu = [
    {
      school: "NTNU / NHH",
      location: "Trondheim & Bergen, NO",
      degree: "MSc Technology Management",
      years: "2026–2027",
      state: "ongoing",
      notes: ["AI strategy & change management", "tech-driven innovation"]
    },
    {
      school: "Barcelona GSE",
      location: "Barcelona, ES",
      degree: "MSc Economics",
      years: "2011–2012",
      state: "done",
      notes: ["innovation economics · game theory · econometrics", "innovation policy & management"]
    },
    {
      school: "Hawaii Pacific University",
      location: "Honolulu, HI",
      degree: "BA Psychology",
      years: "2007–2010",
      state: "done",
      notes: ["GPA 3.74 / 4.00", "social & cross-cultural psychology · cognition"]
    }
  ];
  const stateColor = { ongoing: "var(--a3)", done: "var(--a4)" };
  return (
    <section id="education">
      <SectionHead>education.txt</SectionHead>
      <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
        {edu.map((e) =>
        <li key={e.school} style={{ marginBottom: ".8em" }}>
            <div>
              <span style={{ color: "var(--dim)" }}>[</span>
              <span style={{ color: stateColor[e.state], width: "4.5em", display: "inline-block", textAlign: "center" }}>{e.state}</span>
              <span style={{ color: "var(--dim)" }}>]</span>{" "}
              <span style={{ color: "var(--a2)" }}>{e.school}</span>{" "}
              <span style={{ color: "var(--dim)" }}>{e.location}</span>{" "}
              <span style={{ color: "var(--dim)" }}>— {e.years}</span>
            </div>
            <div style={{ paddingLeft: "6.5em", color: "var(--fg)" }}>{e.degree}</div>
            {e.notes.map((n, i) =>
            <div key={i} style={{ paddingLeft: "6.5em", color: "var(--dim)" }}>↳ {n}</div>
            )}
          </li>
        )}
      </ul>
    </section>);
}

function Projects() {
  return (
    <section id="projects">
      <SectionHead>projects.dir</SectionHead>
      <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
        {PROJECTS.map((p, i) =>
        <li key={p.name} style={{ marginBottom: "1em" }}>
            <div>
              <span style={{ color: "var(--a3)" }}>{String(i + 1).padStart(2, "0")}.</span>{" "}
              <L href={p.href} color="var(--a2)">{p.name}</L>{" "}
              <span style={{ color: "var(--dim)" }}>[{p.year}]</span>{" "}
              <span style={{ color: "var(--a4)" }}>({p.tag})</span>
            </div>
            <div style={{ color: "var(--fg)", paddingLeft: "4ch", textWrap: "pretty" }}>
              {p.blurb}
            </div>
          </li>
        )}
      </ul>
    </section>);

}

function Writing() {
  return (
    <section id="writing">
      <SectionHead>writing/</SectionHead>
      <div style={{ color: "var(--dim)", marginBottom: ".4em" }}>
        // placeholder titles — i'll publish for real soon. drafts in /tmp.
      </div>
      <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
        {WRITING.map((w) =>
        <li key={w.title} style={{ marginBottom: ".2em" }}>
            <span style={{ color: "var(--dim)" }}>· </span>
            <L href="#" color="var(--a2)">{w.title}</L>{" "}
            <span style={{ color: "var(--a3)" }}>({w.n})</span>{" "}
            <span style={{ color: "var(--dim)" }}>— {w.date}</span>
          </li>
        )}
      </ul>
      <div style={{ marginTop: ".5em" }}>
        <L href="#">[ALL POSTS]</L>{" "}
        <span style={{ color: "var(--dim)" }}>·</span>{" "}
        <L href="#">[RSS]</L>
      </div>
    </section>);

}

function Work() {
  const jobs = [
    { company: "Nation Eiendom AS", role: "chairman / founder", years: "2011–", state: "current", note: "real estate development on undervalued properties" },
    { company: "1904 Eiendom",      role: "CEO",                years: "2020–", state: "current", note: "buy-to-rent residential — 8 units, stable affordable housing" },
    { company: "Lampholmen AS",     role: "sales · strategy",   years: "2012–2025", state: "done", note: "full-stack operator — sales, project dev, business development" },
    { company: "AI Works AS",       role: "co-founder",         years: "2023",      state: "exit", note: "AI agent for internal comms · exit: sold shares" },
  ];
  const stateColor = { current: "var(--a3)", done: "var(--a4)", exit: "var(--a2)" };
  return (
    <section id="work">
      <SectionHead>work.txt</SectionHead>
      <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
        {jobs.map((j) =>
        <li key={j.company} style={{ marginBottom: ".4em" }}>
            <span style={{ color: "var(--dim)" }}>[</span>
            <span style={{ color: stateColor[j.state], width: "4.5em", display: "inline-block", textAlign: "center" }}>{j.state}</span>
            <span style={{ color: "var(--dim)" }}>]</span>{" "}
            <span style={{ color: "var(--a2)" }}>{j.company}</span>{" "}
            <span style={{ color: "var(--fg)" }}>{j.role}</span>{" "}
            <span style={{ color: "var(--dim)" }}>— {j.years}</span>
            <div style={{ paddingLeft: "6.5em", color: "var(--dim)" }}>↳ {j.note}</div>
          </li>
        )}
      </ul>
    </section>);
}

function Reading() {
  const stateColor = { reading: "var(--a3)", done: "var(--a4)", queued: "var(--dim)" };
  return (
    <section id="reading">
      <SectionHead>reading.log</SectionHead>
      <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
        {READING.map((b) =>
        <li key={b.title}>
            <span style={{ color: "var(--dim)" }}>[</span>
            <span style={{ color: stateColor[b.state], width: "5em", display: "inline-block", textAlign: "center" }}>
              {b.state}
            </span>
            <span style={{ color: "var(--dim)" }}>]</span>{" "}
            <span style={{ color: "var(--fg)" }}>{b.title}</span>{" "}
            <span style={{ color: "var(--dim)" }}>— {b.author}</span>
          </li>
        )}
      </ul>
    </section>);

}

function Photos() {
  return (
    <section id="photos">
      <SectionHead>photo.log</SectionHead>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))", gap: 10 }}>
        {PHOTOS.map((p, i) => {
          const [w, h] = p.dim.split("x").map(Number);
          const ratio = h / w;
          return (
            <figure key={i} style={{ margin: 0 }}>
              <div style={{ width: "100%", paddingTop: `${ratio * 100}%`, position: "relative", border: "1px dashed var(--border)" }}>
                <img
                  src={p.src}
                  alt={p.label}
                  style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
              </div>
              <figcaption style={{ marginTop: 4, color: "var(--fg)", fontSize: ".9em" }}>
                <span style={{ color: "var(--a2)" }}>▸</span> {p.label}
              </figcaption>
            </figure>);
        })}
      </div>
      <div style={{ marginTop: ".6em" }}>
        <L href="#">[FULL ROLL]</L>{" "}
        <span style={{ color: "var(--dim)" }}>(disk usage: 3.4 gb)</span>
      </div>
    </section>);
}

function cssVar(c) {
  return `var(--${c})`;
}

function Contact() {
  return (
    <section id="contact">
      <SectionHead color="var(--a5)">contact.sh</SectionHead>
      <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
        {LINKS.map((lnk) =>
        <li key={lnk.label} style={{ marginBottom: ".2em" }}>
            <span style={{ color: "var(--dim)" }}>$</span>{" "}
            <L href={lnk.href} color="var(--a2)">[{lnk.label}]</L>{" "}
            <span style={{ color: "var(--dim)" }}>→ {lnk.hint}</span>
          </li>
        )}
      </ul>
    </section>);

}

function Now() {
  // Live clock — Ålesund time, updating every second.
  const [t, setT] = useState(new Date());
  useEffect(() => {
    const id = setInterval(() => setT(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const aalesund = t.toLocaleString("en-GB", {
    timeZone: "Europe/Oslo",
    hour12: false,
    weekday: "short",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit"
  });
  return (
    <section id="now" style={{ marginTop: "1.2em" }}>
      <SectionHead color="var(--a4)">/now</SectionHead>
      <div style={{ color: "var(--fg)" }}>
        <span style={{ color: "var(--a3)" }}>local time (cet):</span>{" "}
        <span style={{ color: "var(--a4)" }}>{aalesund}</span>
      </div>
      <div style={{ color: "var(--fg)" }}>
        <span style={{ color: "var(--a3)" }}>currently:</span>{" "}
        cooking <span style={{ color: "var(--a5)" }}>morningperson.ai</span> ·
        scaling <span style={{ color: "var(--a5)" }}>postliste.ai</span> ·
        launching <span style={{ color: "var(--a5)" }}>elektronisk-tinglysing.no</span> for the people ·
        building <span style={{ color: "var(--a5)" }}>BONDE</span> high-end chess merch ·
        teaching <span style={{ color: "var(--a5)" }}>kid #2</span> to read.
      </div>
    </section>);

}

function Footer() {
  return (
    <div style={{ padding: "1em 0", color: "var(--dim)", display: "flex", flexWrap: "wrap", gap: "0 18px" }}>
      <span>mads.nation © {new Date().getFullYear()}</span>
      <span>built in ålesund @ 62°N</span>
      <span>no cookies. no tracking. design inspired by sogamed & tekst TV.</span>
    </div>);
}

// ─────────────────────────────────────────────────────────────────────────────
// APP
// ─────────────────────────────────────────────────────────────────────────────
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const pal = PALETTES[t.palette] || PALETTES.rainbow;
  const dens = DENSITY[t.density] || DENSITY.regular;
  const font = FONTS[t.font] || FONTS.plex;
  const [bootDone, setBootDone] = useState(!t.typewriter);
  const isMobile = useMobile();

  useEffect(() => {setBootDone(!t.typewriter);}, [t.typewriter]);

  // Set CSS vars on :root for the whole tree.
  useEffect(() => {
    const r = document.documentElement.style;
    r.setProperty("--bg", pal.bg);
    r.setProperty("--fg", pal.fg);
    r.setProperty("--dim", pal.dim);
    r.setProperty("--border", pal.border);
    r.setProperty("--a1", pal.accent1);
    r.setProperty("--a2", pal.accent2);
    r.setProperty("--a3", pal.accent3);
    r.setProperty("--a4", pal.accent4);
    r.setProperty("--a5", pal.accent5);
    r.setProperty("--font", font);
    r.setProperty("--fs", dens.fontSize + "px");
    r.setProperty("--lh", String(dens.lineHeight));
    document.body.style.background = pal.bg;
    document.body.style.color = pal.fg;
  }, [t.palette, t.density, t.font]);

  return (
    <div style={{
      fontFamily: font,
      fontSize: dens.fontSize,
      lineHeight: dens.lineHeight,
      background: pal.bg,
      color: pal.fg,
      minHeight: "100vh",
      padding: "0 18px 28px 18px",
      maxWidth: 1180,
      margin: "0 auto"
    }}>
      <Header logoStyle={t.logoStyle} />
      <Hr char="=" />
      <Nav gap={isMobile ? "0 8px" : "0 18px"} sepMargin={isMobile ? 8 : 18} />
      <Hr char="-" />
      {isMobile ? <>
        {t.typewriter &&
        <>
          <div style={{ padding: "10px 0" }}>
            <Typewriter
            key="boot"
            lines={BOOT_LINES}
            speed={14}
            lineDelay={90}
            onDone={() => setBootDone(true)} />
          </div>
          <Hr char="·" />
        </>}
        <StatusBars />
        <Hr char="-" />
        <GuestbookBar />
        <Hr char="=" />
        <div style={{ opacity: bootDone ? 1 : 0.25, transition: "opacity .4s ease" }}>
          <About />
          <Now />
          <Work />
          <Education />
          <Projects />
          <Writing />
          <Reading />
          <Photos />
          <Contact />
        </div>
      </> : <>
        <StatusBars />
        <Hr char="-" />
        <GuestbookBar />
        <Hr char="=" />
        {t.typewriter &&
        <>
          <div style={{ padding: "10px 0" }}>
            <Typewriter
            key="boot"
            lines={BOOT_LINES}
            speed={14}
            lineDelay={90}
            onDone={() => setBootDone(true)} />
          </div>
          <Hr char="·" />
        </>}
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "1.35fr 1fr",
            gap: 36,
            marginTop: 10,
            opacity: bootDone ? 1 : 0.25,
            transition: "opacity .4s ease"
          }}
          className="cols">
          <div>
            <About />
            <Education />
            <Projects />
            <Writing />
          </div>
          <div>
            <Now />
            <Work />
            <Reading />
            <Photos />
            <Contact />
          </div>
        </div>
      </>}

      <Hr char="=" />
      <Marquee items={[
      "now hiring co-conspirators",
      "morningperson.ai is live",
      "postliste.ai serves 2000+ kommuner",
      "wordle.lol still standing",
      "ålesund > silicon valley (fight me)",
      "say hi: mads@nation.no"]
      } />
      <Footer />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Look" />
        <TweakRadio
          label="Palette" value={t.palette}
          options={["rainbow", "green", "amber", "mono"]}
          onChange={(v) => setTweak("palette", v)} />
        
        <TweakRadio
          label="Logo" value={t.logoStyle}
          options={["big", "slant", "block", "small"]}
          onChange={(v) => setTweak("logoStyle", v)} />
        
        <TweakRadio
          label="Density" value={t.density}
          options={["cramped", "regular", "spacious"]}
          onChange={(v) => setTweak("density", v)} />
        
        <TweakSection label="Type" />
        <TweakRadio
          label="Font" value={t.font}
          options={["plex", "jb", "vt"]}
          onChange={(v) => setTweak("font", v)} />
        
        <TweakSection label="FX" />
        <TweakToggle
          label="Typewriter intro" value={t.typewriter}
          onChange={(v) => setTweak("typewriter", v)} />
        
      </TweaksPanel>
    </div>);

}

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