<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>ProgrammerFish.com — since 2008</title>
  <meta name="description" content="ProgrammerFish.com — swimming since 2008, and still going. Quietly repositioning for what's next." />
  <meta name="theme-color" content="#07090c" media="(prefers-color-scheme: dark)" />
  <meta name="theme-color" content="#eef3f1" media="(prefers-color-scheme: light)" />
  <link rel="icon" href="/favicon.svg" type="image/svg+xml" />

  <!-- Open Graph -->
  <meta property="og:type" content="website" />
  <meta property="og:title" content="ProgrammerFish.com — since 2008" />
  <meta property="og:description" content="Swimming since 2008. Still going. Repositioning for what's next." />

  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet" />

  <!-- Set theme before first paint to avoid a flash of the wrong colour. -->
  <script>
    (function () {
      var KEY = "pf-theme";
      var stored = null;
      try { stored = localStorage.getItem(KEY); } catch (e) {}
      var sys = (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) ? "light" : "dark";
      document.documentElement.setAttribute("data-theme", stored || sys);
    })();
  </script>

  <style>
    :root {
      color-scheme: dark light;
      --ease: cubic-bezier(0.22, 1, 0.36, 1);

      /* ---- Dark (default) ---- */
      --bg:        #07090c;
      --ink:       #eef1ee;
      --muted:     rgba(238, 241, 238, 0.44);
      --faint:     rgba(238, 241, 238, 0.16);
      --accent:    #67e0cf;
      --glow-1:    rgba(103, 224, 207, 0.10);
      --glow-2:    rgba(47, 111, 104, 0.16);
      --glow-3:    rgba(20, 46, 66, 0.30);
      --vignette:  rgba(0, 0, 0, 0.55);
      --grain-opacity: 0.06;
      --grain-blend:   soft-light;
      --cursor-glow:   rgba(103, 224, 207, 0.55);
    }

    /* ---- Light ---- */
    :root[data-theme="light"] {
      --bg:        #eef3f1;
      --ink:       #0d1512;
      --muted:     rgba(13, 21, 18, 0.52);
      --faint:     rgba(13, 21, 18, 0.14);
      --accent:    #0d8f7f;
      --glow-1:    rgba(60, 190, 172, 0.22);
      --glow-2:    rgba(120, 200, 190, 0.20);
      --glow-3:    rgba(176, 205, 214, 0.34);
      --vignette:  rgba(90, 120, 118, 0.14);
      --grain-opacity: 0.05;
      --grain-blend:   multiply;
      --cursor-glow:   rgba(13, 143, 127, 0.40);
    }

    * { margin: 0; padding: 0; box-sizing: border-box; }
    html, body { height: 100%; }

    body {
      background: var(--bg);
      color: var(--ink);
      font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
      min-height: 100svh;
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      position: relative;
      overflow: hidden;
      -webkit-font-smoothing: antialiased;
      text-rendering: optimizeLegibility;
      transition: background-color 0.4s var(--ease), color 0.4s var(--ease);
    }

    /* ---- Atmosphere: layered radial glows that slowly breathe ---- */
    .sea {
      position: fixed;
      inset: -20%;
      z-index: 0;
      background:
        radial-gradient(42% 55% at 50% 8%,  var(--glow-1), transparent 70%),
        radial-gradient(60% 60% at 82% 88%, var(--glow-2), transparent 72%),
        radial-gradient(70% 70% at 12% 78%, var(--glow-3), transparent 75%),
        var(--bg);
      animation: drift 22s var(--ease) infinite alternate;
    }
    @keyframes drift {
      from { transform: translate3d(-1.5%, -1%, 0) scale(1.02); }
      to   { transform: translate3d(1.5%, 1.5%, 0)  scale(1.06); }
    }

    /* ---- Film grain ---- */
    .grain {
      position: fixed;
      inset: 0;
      z-index: 2;
      pointer-events: none;
      opacity: var(--grain-opacity);
      mix-blend-mode: var(--grain-blend);
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
    }

    /* ---- Vignette ---- */
    body::after {
      content: "";
      position: fixed;
      inset: 0;
      z-index: 1;
      pointer-events: none;
      background: radial-gradient(120% 90% at 50% 42%, transparent 55%, var(--vignette) 100%);
    }

    /* ---- Theme toggle ---- */
    .theme-toggle {
      position: fixed;
      top: clamp(1rem, 3vw, 1.6rem);
      right: clamp(1rem, 3vw, 1.6rem);
      z-index: 4;
      display: inline-flex;
      align-items: center;
      gap: 0.6em;
      font: inherit;
      font-size: 0.68rem;
      letter-spacing: 0.2em;
      text-transform: uppercase;
      color: var(--muted);
      background: transparent;
      border: 1px solid var(--faint);
      border-radius: 999px;
      padding: 0.55em 0.9em 0.55em 0.8em;
      cursor: pointer;
      transition: color 0.3s var(--ease), border-color 0.3s var(--ease), background-color 0.3s var(--ease);
    }
    .theme-toggle:hover,
    .theme-toggle:focus-visible {
      color: var(--accent);
      border-color: var(--accent);
      outline: none;
    }
    .theme-toggle .ic { width: 15px; height: 15px; display: block; }
    .theme-toggle .moon { display: none; }
    :root[data-theme="light"] .theme-toggle .sun  { display: none; }
    :root[data-theme="light"] .theme-toggle .moon { display: block; }
    .theme-toggle .label::after { content: "Light"; }
    :root[data-theme="light"] .theme-toggle .label::after { content: "Dark"; }

    main {
      position: relative;
      z-index: 3;
      width: 100%;
      max-width: 64rem;
      margin: 0 auto;
      padding: 8vmin 6vw;
    }

    /* wordmark */
    .wordmark {
      font-family: "Instrument Serif", Georgia, serif;
      font-weight: 400;
      line-height: 0.92;
      letter-spacing: -0.01em;
      white-space: nowrap;
      font-size: clamp(2.5rem, 12vw, 7.5rem);
      margin: 0 0 0.2em;
      opacity: 0;
      animation: rise 1.1s var(--ease) 0.12s forwards;
    }
    .wordmark .dot { font-style: italic; color: var(--accent); }

    /* the requested line: "2008 —" with a living cursor */
    .stamp {
      font-size: clamp(1rem, 3.4vw, 1.5rem);
      letter-spacing: 0.18em;
      display: inline-flex;
      align-items: baseline;
      justify-content: center;
      gap: 0.5em;
      opacity: 0;
      animation: rise 1.1s var(--ease) 0.3s forwards;
    }
    .stamp .dash { color: var(--muted); }
    .cursor {
      display: inline-block;
      width: 0.56em;
      height: 1.02em;
      transform: translateY(0.12em);
      background: var(--accent);
      box-shadow: 0 0 14px var(--cursor-glow);
      animation: blink 1.15s steps(1, end) infinite;
    }

    /* footer note — the "repositioning" signal */
    .note {
      margin-top: clamp(2.4rem, 7vh, 4rem);
      font-size: clamp(0.66rem, 1.8vw, 0.8rem);
      letter-spacing: 0.24em;
      text-transform: uppercase;
      color: var(--muted);
      opacity: 0;
      animation: rise 1.1s var(--ease) 0.48s forwards;
    }
    .note b { color: var(--accent); font-weight: 500; }
    .sep { color: var(--faint); margin: 0 0.7em; }

    @keyframes rise {
      from { opacity: 0; transform: translateY(14px); filter: blur(6px); }
      to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
    }
    @keyframes blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

    @media (prefers-reduced-motion: reduce) {
      .sea { animation: none; }
      .wordmark, .stamp, .note { animation: none; opacity: 1; filter: none; transform: none; }
      .cursor { animation: none; }
      body, .theme-toggle { transition: none; }
    }
  </style>
</head>
<body>
  <div class="sea" aria-hidden="true"></div>
  <div class="grain" aria-hidden="true"></div>

  <button class="theme-toggle" type="button" aria-label="Toggle light or dark theme">
    <svg class="ic sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4.2"/><path d="M12 2v2.5M12 19.5V22M2 12h2.5M19.5 12H22M4.9 4.9l1.8 1.8M17.3 17.3l1.8 1.8M19.1 4.9l-1.8 1.8M6.7 17.3l-1.8 1.8"/></svg>
    <svg class="ic moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 14.5A8 8 0 1 1 9.5 4a6.3 6.3 0 0 0 10.5 10.5z"/></svg>
    <span class="label"></span>
  </button>

  <main>
    <h1 class="wordmark">ProgrammerFish<span class="dot">.com</span></h1>

    <p class="stamp" aria-label="2008 to present, ongoing">
      <span>2008</span>
      <span class="dash">&mdash;</span>
      <span class="cursor" aria-hidden="true"></span>
    </p>

    <p class="note">Still swimming <span class="sep">/</span> <b>repositioning</b> for what&rsquo;s next</p>
  </main>

  <script>
    (function () {
      var KEY = "pf-theme";
      var root = document.documentElement;
      var btn = document.querySelector(".theme-toggle");
      if (!btn) return;
      btn.addEventListener("click", function () {
        var next = root.getAttribute("data-theme") === "light" ? "dark" : "light";
        root.setAttribute("data-theme", next);
        try { localStorage.setItem(KEY, next); } catch (e) {}
      });
    })();
  </script>
</body>
</html>
