<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Lydia by Kevin Church and Max Riffner</title>
  <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&display=swap" rel="stylesheet">
  <style>
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    body {
      background-color: #ffffff;
      font-family: 'Space Grotesk', sans-serif;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 24px 16px 48px;
      overflow-y: scroll;
    }

    /* ── Header ── */
    #site-header {
      width: 100%;
      max-width: 1000px;
      margin-bottom: 20px;
    }
    #site-header img {
      width: 100%;
      display: block;
    }

    /* ── Viewer ── */
    #viewer {
      width: 100%;
      max-width: 1000px;
      display: flex;
      flex-direction: column;
      align-items: center;
      border: 2px solid #111111;
    }

    /* ── Comic image ── */
    #comic-wrap {
      position: relative;
      width: 100%;
      background: #fff;
      line-height: 0;
    }
    #comic-img {
      width: 100%;
      display: block;
    }

    /* Large click-through prev/next overlays on image */
    .img-nav {
      position: absolute;
      top: 0;
      width: 20%;
      height: 100%;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      opacity: 0;
      transition: opacity 0.15s;
    }
    .img-nav:hover { opacity: 1; }
    #img-prev { left: 0; background: linear-gradient(to right, rgba(0,0,0,0.2), transparent); }
    #img-next { right: 0; background: linear-gradient(to left, rgba(0,0,0,0.2), transparent); }
    .img-nav svg { fill: #111; width: 32px; height: 32px; filter: drop-shadow(0 1px 3px rgba(255,255,255,0.6)); }

    /* ── Toolbar below image ── */
    #toolbar {
      width: 100%;
      background: #f0f0f0;
      border-top: 2px solid #111111;
      padding: 12px 16px;
      display: flex;
      align-items: center;
      gap: 10px;
      flex-wrap: wrap;
    }

    /* Prev / Next buttons */
    .nav-btn {
      background: #ffffff;
      border: 1.5px solid #111111;
      color: #111111;
      font-family: 'Space Grotesk', sans-serif;
      font-weight: 600;
      font-size: 14px;
      padding: 6px 14px;
      cursor: pointer;
      border-radius: 4px;
      transition: background 0.15s;
      white-space: nowrap;
      line-height: 1;
    }
    .nav-btn:hover:not(:disabled) { background: #e0e0e0; }
    .nav-btn:disabled { opacity: 0.3; cursor: default; }

    /* Date / counter info */
    #info {
      flex: 1;
      text-align: center;
      color: #111111;
      min-width: 0;
    }
    #comic-date {
      font-size: 15px;
      font-weight: 600;
      display: block;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      margin-bottom: 20px;
    }
    #comic-note {
      font-size: 12px;
      font-style: italic;
      opacity: 0.7;
      margin-top: -16px;
      margin-bottom: 20px;
      display: block;
      min-height: 0;
    }
    #comic-note:empty { display: none; }
    #comic-note a {
      color: #111111;
      text-decoration: underline;
    }
    #comic-note a:hover { opacity: 0.6; }
    #comic-counter {
      font-size: 11px;
      opacity: 0.5;
      margin-top: 2px;
      display: block;
    }

    /* Jump to # input */
    #jump-wrap {
      display: flex;
      align-items: center;
      gap: 5px;
      color: #111111;
      font-size: 13px;
      white-space: nowrap;
    }
    #jump-input {
      width: 52px;
      padding: 5px 6px;
      font-family: 'Space Grotesk', sans-serif;
      font-size: 13px;
      border: 1.5px solid #111111;
      border-radius: 4px;
      background: #ffffff;
      color: #111111;
      text-align: center;
      outline: none;
    }
    #jump-input::placeholder { color: rgba(0,0,0,0.3); }
    #jump-input:focus { border-color: #111111; background: #f8f8f8; }

    /* First / Last links */
    .edge-link {
      color: rgba(0,0,0,0.45);
      font-size: 12px;
      cursor: pointer;
      text-decoration: underline;
      white-space: nowrap;
      background: none;
      border: none;
      font-family: 'Space Grotesk', sans-serif;
      padding: 0;
    }
    .edge-link:hover { color: #111111; }

    /* keyboard hint */
    #kb-hint {
      width: 100%;
      text-align: center;
      color: rgba(0,0,0,0.35);
      font-size: 11px;
      margin-top: 10px;
    }
#permalink {
  width: 100%;
  max-width: 1000px;
  text-align: center;
  color: #111111;
  font-size: 13px;
  margin-top: 12px;
}
#permalink a {
  color: #111111;
  text-decoration: underline;
}
#permalink a:hover {
  opacity: 0.6;
}
    #comic-img.loading { opacity: 0.5; }

    @media (max-width: 520px) {
      #jump-wrap, .edge-link { display: none; }
    }
  </style>
</head>
<body>

<header id="site-header">
  <img src="https://www.agreeablecomics.com/lydia/comics/lydia-header.jpg" alt="Lydia">
</header>

<div id="viewer">
  <div id="comic-wrap">
    <img id="comic-img" alt="Lydia comic strip">
    <div class="img-nav" id="img-prev" title="Previous (←)">
      <svg viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
    </div>
    <div class="img-nav" id="img-next" title="Next (→)">
      <svg viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
    </div>
  </div>

  <div id="toolbar">
    <button class="edge-link" id="btn-first">First</button>
    <button class="nav-btn" id="btn-prev">← Prev</button>
    <div id="info">
      <span id="comic-date"></span>
      <span id="comic-note"></span>
      <span id="comic-counter"></span>
    </div>
    <button class="nav-btn" id="btn-next">Next →</button>
    <button class="edge-link" id="btn-last">Last</button>
    <div id="jump-wrap">
      <label for="jump-input">#</label>
      <input type="number" id="jump-input" min="1" placeholder="…" title="Jump to comic number">
    </div>
  </div>
</div>

<p id="kb-hint">← → arrow keys to navigate</p>
<p id="permalink">Download the complete strip with the bonus full-length story "Let Them Eat Cake" <a href="https://www.agreeablecomics.com/lydia/comics/Lydia-The-More-Than-Complete-Edition.pdf">here</a>.</p>

<script>
const BASE = 'https://www.agreeablecomics.com/lydia/comics/';

const COMICS = [
  '2009-05-01.jpg',
  '2009-05-04.png',
  '2009-05-06-09_000002.png',
  '2009-05-08.png',
  '2009-05-11.png',
  '2009-05-13.png',
  '2009-05-15.png',
  '2009-05-18.png',
  '2009-05-20.png',
  '2009-05-22.png',
  '2009-05-26.png',
  '2009-05-27-09_000011.png',
  '2009-05-29-09_000012.png',
  '2009-06-01-09_000013.png',
  '2009-06-03-09_000014.png',
  '2009-06-05-09_000015.png',
  '2009-06-08-09_000016.png',
  '2009-06-10-09_000017.png',
  '2009-06-12.png',
  '2009-06-15-09_000019.png',
  '2009-06-17-09_000020.png',
  '2009-06-19-09_000021.png',
  '2009-06-22-09_000022.png',
  '2009-06-24.png',
  '2009-06-26-09_000024.png',
  '2009-06-29-09_000025.png',
  '2009-07-01-09_000026.png',
  '2009-07-03-09_000027.png',
  '2009-07-06-09_000028.png',
  '2009-07-08-09_000029.png',
  '2009-07-10-09_000030.png',
  '2009-07-13-09_000031.png',
  '2009-07-15-09_000032.png',
  '2009-07-17-09_000033.png',
  '2009-07-20-09_000034.png',
  '2009-07-22-09_000035.png',
  '2009-07-24.png',
  '2009-07-27-09_000037.png',
  '2009-07-29-09_000038.png',
  '2009-07-31-09_000039.png',
  '2010-07-13.png',
  '2010-08-28.png'
];

const MONTHS = [
  'January','February','March','April','May','June',
  'July','August','September','October','November','December'
];

function parseDate(filename) {
  const m = filename.match(/^(\d{4})-(\d{2})-(\d{2})/);
  if (!m) return filename.replace(/\.[^.]+$/, '');
  const y = parseInt(m[1], 10);
  let mo = parseInt(m[2], 10);
  let d = parseInt(m[3], 10);
  if (mo > 12 && d <= 12) { const tmp = mo; mo = d; d = tmp; }
  if (mo < 1 || mo > 12) return filename.replace(/\.[^.]+$/, '');
  return `${MONTHS[mo - 1]} ${d}, ${y}`;
}

let current = 0;
let notesMap = new Map();

function loadNotes() {
  fetch('lydia-notes.csv')
    .then(r => r.ok ? r.text() : '')
    .then(text => {
      text.split('\n').forEach(line => {
        line = line.trim();
        if (!line || line.startsWith('#')) return;
        const comma = line.indexOf(',');
        if (comma === -1) return;
        const filename = line.slice(0, comma).trim();
        const note = line.slice(comma + 1).trim().replace(/^"|"$/g, '');
        if (filename && note) notesMap.set(filename, note);
      });
    })
    .catch(() => {});
}

const img       = document.getElementById('comic-img');
const dateEl    = document.getElementById('comic-date');
const noteEl    = document.getElementById('comic-note');
const counterEl = document.getElementById('comic-counter');
const btnPrev   = document.getElementById('btn-prev');
const btnNext   = document.getElementById('btn-next');
const btnFirst  = document.getElementById('btn-first');
const btnLast   = document.getElementById('btn-last');
const imgPrev   = document.getElementById('img-prev');
const imgNext   = document.getElementById('img-next');
const jumpInput = document.getElementById('jump-input');

jumpInput.max = COMICS.length;

function goTo(n, pushHash) {
  n = Math.max(0, Math.min(COMICS.length - 1, n));
  current = n;
  window.scrollTo(0, 0);
  const filename = COMICS[current];
  img.classList.add('loading');
  img.onload = () => img.classList.remove('loading');
  img.onerror = () => img.classList.remove('loading');
  img.src = BASE + encodeURIComponent(filename);
  img.alt = `Lydia — ${parseDate(filename)}`;
  dateEl.textContent = parseDate(filename);
  noteEl.innerHTML = notesMap.get(filename) || '';
  counterEl.textContent = `#${current + 1} of ${COMICS.length}`;
  btnPrev.disabled = current === 0;
  imgPrev.style.display = current === 0 ? 'none' : '';
  btnNext.disabled = current === COMICS.length - 1;
  imgNext.style.display = current === COMICS.length - 1 ? 'none' : '';
  btnFirst.disabled = current === 0;
  btnLast.disabled = current === COMICS.length - 1;
  if (pushHash !== false) {
    history.replaceState(null, '', '#' + (current + 1));
  }
  jumpInput.value = '';
}

btnPrev.addEventListener('click', () => goTo(current - 1));
btnNext.addEventListener('click', () => goTo(current + 1));
btnFirst.addEventListener('click', () => goTo(0));
btnLast.addEventListener('click', () => goTo(COMICS.length - 1));
imgPrev.addEventListener('click', () => goTo(current - 1));
imgNext.addEventListener('click', () => goTo(current + 1));

jumpInput.addEventListener('keydown', (e) => {
  if (e.key === 'Enter') {
    const n = parseInt(jumpInput.value, 10);
    if (!isNaN(n)) goTo(n - 1);
  }
});

document.addEventListener('keydown', (e) => {
  if (e.target === jumpInput) return;
  if (e.key === 'ArrowLeft')  goTo(current - 1);
  if (e.key === 'ArrowRight') goTo(current + 1);
  if (e.key === 'Home') goTo(0);
  if (e.key === 'End')  goTo(COMICS.length - 1);
});

function loadFromHash() {
  const hash = window.location.hash;
  if (hash && hash.length > 1) {
    const n = parseInt(hash.slice(1), 10);
    if (!isNaN(n) && n >= 1 && n <= COMICS.length) {
      goTo(n - 1, false);
      return;
    }
  }
  goTo(0, false);
}

window.addEventListener('hashchange', () => {
  const n = parseInt(window.location.hash.slice(1), 10);
  if (!isNaN(n)) goTo(n - 1, false);
});

loadNotes();
loadFromHash();
</script>
</body>
</html>
