/* global React, window */
const { useState, useEffect, useRef, useMemo } = React;

/* ============================================================
 * ICON SYSTEM — Lonesome Goat custom icons
 *
 * All icons are line-only, 24x24 viewBox, currentColor stroke.
 * Built with the same loose hand as the sketch placeholders so
 * they read like marks made with the same pen.
 * ============================================================ */

function Ico({ children, size = 24, stroke = 1.6, color = "currentColor", style }) {
  return (
    <svg
      viewBox="0 0 24 24"
      width={size}
      height={size}
      fill="none"
      stroke={color}
      strokeWidth={stroke}
      strokeLinecap="round"
      strokeLinejoin="round"
      style={{ display: 'inline-block', verticalAlign: 'middle', ...style }}
      aria-hidden="true">
      {children}</svg>);

}

/* — Field Desk drawer icons — */
function IcoLedger(p) {return (
    /* a stitched journal with a ribbon — Field Entries */
    <Ico {...p}>
    <path d="M5 4 L 5 21 L 7.4 19.6 L 9.8 21 L 12 19.6 L 14.2 21 L 16.6 19.6 L 19 21 L 19 4 L 12 4 Z" />
    <path d="M5 4 C 8 3, 16 3, 19 4" />
    <path d="M9 9 L 15 9 M 9 12 L 15 12 M 9 15 L 13 15" strokeWidth="1.2" />
  </Ico>);
}
function IcoPencil(p) {return (
    /* short carpenter pencil — Drafts */
    <Ico {...p}>
    <path d="M3 21 L 6 14 L 16 4 L 20 8 L 10 18 L 3 21 Z" />
    <path d="M14 6 L 18 10" strokeWidth="1.2" />
    <path d="M5 18 L 7 17" strokeWidth="1.2" />
  </Ico>);
}
function IcoFountainPen(p) {return (
    /* fountain pen tip — Sketches */
    <Ico {...p}>
    <path d="M4 20 L 9 15 L 17 7 C 19 5, 20 6, 19 8 L 11 16 L 6 20 Z" />
    <path d="M9 15 L 11 17" strokeWidth="1.2" />
    <path d="M11 16 L 13 14" strokeWidth="1.2" />
    <path d="M5 19 L 7 21" strokeWidth="1.2" />
  </Ico>);
}
function IcoEnvelope(p) {return (
    /* tied envelope — Letters */
    <Ico {...p}>
    <path d="M3 6 L 12 13 L 21 6" />
    <path d="M3 6 L 21 6 L 21 19 L 3 19 Z" />
    <path d="M3 19 L 9 13 M 21 19 L 15 13" strokeWidth="1.2" />
  </Ico>);
}

/* — Notebook tab icons — */
function IcoTypewriter(p) {return (
    /* Write — typewriter */
    <Ico {...p}>
    <path d="M6 7 L 18 7 L 18 4 L 6 4 Z" />
    <path d="M3 12 C 3 10, 4 10, 5 10 L 19 10 C 20 10, 21 10, 21 12 L 21 18 L 3 18 Z" />
    <path d="M7 14 L 7 14 M 10 14 L 10 14 M 13 14 L 13 14 M 16 14 L 16 14" strokeWidth="2" />
    <path d="M8 21 L 16 21" />
  </Ico>);
}
function IcoBook(p) {return (
    /* Read — open book */
    <Ico {...p}>
    <path d="M2 5 C 6 4, 9 5, 12 7 C 15 5, 18 4, 22 5 L 22 19 C 18 18, 15 19, 12 21 C 9 19, 6 18, 2 19 Z" />
    <path d="M12 7 L 12 21" />
    <path d="M5 9 L 9 9 M 5 12 L 9 12 M 15 9 L 19 9 M 15 12 L 19 12" strokeWidth="1" />
  </Ico>);
}
/* IcoFountainPen reused for "Sketch" tab */
/* IcoEnvelope reused for "Letter" tab */

/* — Decorative / utility — */
function IcoPin(p) {return (
    /* pushpin */
    <Ico {...p}>
    <path d="M12 3 L 12 13 L 6 17 L 18 17 L 12 13 Z" />
    <path d="M12 17 L 12 21" />
  </Ico>);
}
function IcoLamp(p) {return (
    <Ico {...p}>
    <path d="M5 3 L 19 3 L 17 9 L 7 9 Z" />
    <path d="M12 9 L 12 16" />
    <path d="M8 21 L 16 21" />
    <path d="M9 16 L 15 16 L 14 21 L 10 21 Z" />
  </Ico>);
}
function IcoStar(p) {return (
    <Ico {...p}>
    <path d="M12 4 L 14 9 L 19 9.5 L 15 13 L 16 18 L 12 15.5 L 8 18 L 9 13 L 5 9.5 L 10 9 Z" />
  </Ico>);
}
function IcoX(p) {return (
    <Ico {...p}>
    <path d="M5 5 L 19 19 M 19 5 L 5 19" />
  </Ico>);
}
function IcoChevron({ dir = "right", ...p }) {
  const rot = dir === "left" ? 180 : dir === "down" ? 90 : dir === "up" ? -90 : 0;
  return (
    <Ico {...p} style={{ ...(p.style || {}), transform: `rotate(${rot}deg)` }}>
      <path d="M9 6 L 15 12 L 9 18" />
    </Ico>);

}
function IcoLocation(p) {return (
    <Ico {...p}>
    <path d="M12 22 C 6 15, 5 11, 5 9 A 7 7 0 0 1 19 9 C 19 11, 18 15, 12 22 Z" />
    <path d="M12 9 a 2 2 0 1 0 0.1 0" strokeWidth="1.2" />
  </Ico>);
}
function IcoCheck(p) {return (
    <Ico {...p}>
    <path d="M5 12 L 10 17 L 19 7" />
  </Ico>);
}
/* Crumpled-paper-in-wastebasket — replaces the generic trashcan with
   something that fits the field-journal aesthetic. A small crumpled
   ball peeks above the rim of an open bin. */
function IcoTrash(p) {return (
    <Ico {...p}>
    {/* crumpled paper ball, peeking above the rim */}
    <path d="M 9.5 6 Q 8.5 4.8 10 4.2 Q 11 3.4 12.5 3.6 Q 14.2 3.4 14.7 5 Q 15.3 6.3 14 7 Q 12.5 7.6 11 7.4 Q 9.8 7 9.5 6 Z" />
    {/* a couple of fold creases on the ball */}
    <path d="M 11 4.8 L 12.2 5.7 M 13 4.6 L 13.5 5.6" strokeWidth="0.7" opacity="0.6" />
    {/* basket open top (perspective ellipse) */}
    <ellipse cx="12" cy="9.4" rx="6" ry="1.4" />
    {/* basket walls — slight taper inward */}
    <path d="M 6 9.4 L 7.5 20.5 L 16.5 20.5 L 18 9.4" />
    {/* basket bottom (subtle curve) */}
    <path d="M 7.5 20.5 Q 12 21.4 16.5 20.5" strokeWidth="1" opacity="0.65" />
    {/* basket vertical strokes — texture/depth */}
    <path d="M 9.6 11.5 L 10.5 19 M 14.4 11.5 L 13.5 19" strokeWidth="0.7" opacity="0.45" />
  </Ico>);
}

/* ============================================================
 * LOGOS
 * - Bone version used in moonlight
 * - Goat-only mark for accents
 * - Horizontal lockup auto-flips by mode
 * No more circle/coin medallion anywhere.
 * ============================================================ */

function LogoLong({ height = 48, dark }) {
  const src = dark ? "assets/lg-bone.png" : "assets/lg-long.png";
  return <img src={src} alt="Lonesome Goat" style={{ height, width: 'auto', display: 'block' }} />;
}
function LogoStayLonesome({ height = 220, dark }) {
  const src = dark ? "assets/lg-stay-lonesome-bone.png" : "assets/lg-stay-lonesome-dark.png";
  return <img src={src} alt="Stay Lonesome — Lonesome Goat" style={{ height, width: 'auto', display: 'block' }} />;
}
function LogoGoat({ size = 80, tone }) {
  // tone: "gold" (default) | "ink" | "bone"
  let filter = 'none';
  if (tone === "ink") filter = "brightness(0) saturate(100%) invert(15%) sepia(18%) saturate(800%) hue-rotate(180deg)";
  if (tone === "bone") filter = "brightness(0) saturate(100%) invert(91%) sepia(8%) saturate(548%) hue-rotate(8deg) brightness(98%) contrast(86%)";
  return <img src="assets/lg-goat-only.png" alt="" style={{ width: size, height: 'auto', display: 'block', filter }} />;
}
function LogoSquare({ size = 120, dark }) {
  const src = dark ? "assets/lg-bone.png" : "assets/lg-square.png";
  return <img src={src} alt="Lonesome Goat" style={{ width: size, height: 'auto', display: 'block' }} />;
}

/* ============================================================
 * SUN / MOON SCENE TOGGLE — circular landscape that flips
 * Daylight: gold sun cresting silhouette ridge, goat mark on it
 * Moonlight: bone moon, deep ink sky, stars, goat in bone
 * ============================================================ */
function SunMoonToggle({ dark, onChange, size = 56 }) {
  return (
    <button
      className="sunmoon"
      onClick={() => onChange(!dark)}
      aria-label={dark ? "Switch to daylight" : "Switch to moonlight"}
      data-mode={dark ? "moon" : "sun"}
      title={dark ? "Click for daylight" : "Click for moonlight"}
      style={{ width: size, height: size, borderStyle: "none" }}>
      
      <span className="sunmoon__scene" aria-hidden="true" style={{ borderWidth: "0px", opacity: "1", fontFamily: "Arial", lineHeight: "0" }}>
        {dark ? <MoonScene size={size} /> : <SunScene size={size} />}
      </span>
    </button>);

}
function SunScene({ size }) {
  return (
    <svg viewBox="0 0 56 56" width={size} height={size} style={{ strokeWidth: "0px", opacity: "1" }}>
      <defs>
        <clipPath id="sun-clip"><circle cx="28" cy="28" r="26" /></clipPath>
      </defs>
      <g clipPath="url(#sun-clip)">
        {/* sky */}
        <rect x="0" y="0" width="56" height="56" fill="#F3EAD7" />
        <rect x="0" y="0" width="56" height="36" fill="url(#sky-grad)" />
        <defs>
          <linearGradient id="sky-grad" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor="#E0D3B0" />
            <stop offset="1" stopColor="#F3EAD7" />
          </linearGradient>
        </defs>
        {/* sun */}
        <circle cx="28" cy="22" r="9" fill="#C89A4E" />
        <circle cx="28" cy="22" r="11" fill="none" stroke="#C89A4E" strokeWidth="0.7" opacity="0.4" />
        {/* far ridge */}
        <path d="M0 38 L 8 34 L 16 36 L 24 32 L 32 35 L 40 30 L 48 33 L 56 31 L 56 56 L 0 56 Z" fill="#1F2937" opacity="0.3" />
        {/* near ridge — silhouette with tiny goat mark */}
        <path d="M0 44 L 6 40 L 14 44 L 22 38 L 30 42 L 38 38 L 46 42 L 56 40 L 56 56 L 0 56 Z" fill="#1F2937" />
      </g>
      <circle cx="28" cy="28" r="26" fill="none" stroke="#1F2937" strokeWidth="1.4" />
    </svg>);

}
function MoonScene({ size }) {
  return (
    <svg viewBox="0 0 56 56" width={size} height={size}>
      <defs>
        <clipPath id="moon-clip"><circle cx="28" cy="28" r="26" /></clipPath>
      </defs>
      <g clipPath="url(#moon-clip)">
        {/* sky */}
        <rect x="0" y="0" width="56" height="56" fill="#0e1419" />
        <rect x="0" y="0" width="56" height="42" fill="url(#night-grad)" />
        <defs>
          <linearGradient id="night-grad" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor="#070a0e" />
            <stop offset="1" stopColor="#13191f" />
          </linearGradient>
        </defs>
        {/* stars */}
        <circle cx="10" cy="10" r="0.6" fill="#e8d9b4" opacity="0.9" />
        <circle cx="44" cy="8" r="0.5" fill="#e8d9b4" opacity="0.7" />
        <circle cx="46" cy="20" r="0.4" fill="#e8d9b4" opacity="0.6" />
        <circle cx="14" cy="22" r="0.4" fill="#e8d9b4" opacity="0.5" />
        <circle cx="36" cy="14" r="0.4" fill="#e8d9b4" opacity="0.7" />
        {/* crescent moon */}
        <g transform="translate(28 22)">
          <circle r="9" fill="#e8d9b4" />
          <circle cx="3" cy="-2" r="8" fill="#0e1419" />
        </g>
        {/* far ridge */}
        <path d="M0 38 L 8 34 L 16 36 L 24 32 L 32 35 L 40 30 L 48 33 L 56 31 L 56 56 L 0 56 Z" fill="#1a2330" />
        {/* near ridge */}
        <path d="M0 44 L 6 40 L 14 44 L 22 38 L 30 42 L 38 38 L 46 42 L 56 40 L 56 56 L 0 56 Z" fill="#06090d" />
      </g>
      <circle cx="28" cy="28" r="26" fill="none" stroke="#C89A4E" strokeWidth="1.4" />
    </svg>);

}

/* ============================================================
 * NAV / FOOTER
 * ============================================================ */
function Nav({ route, go, dark, setDark }) {
  const [menuOpen, setMenuOpen] = React.useState(false);
  const links = [
  { id: "home", label: "Home" },
  { id: "desk", label: "Field Desk" },
  { id: "notes", label: "Goat Notes" },
  { id: "manifesto", label: "Manifesto" },
  { id: "about", label: "About" }];

  const handleNav = (id) => {
    setMenuOpen(false);
    go(id);
  };

  // Lock body scroll while the mobile drawer is open so the page doesn't jiggle
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [menuOpen]);

  return (
    <nav className="lg-nav">
      <div className="lg-nav__inner">
        <div className="lg-nav__brand" onClick={() => handleNav("home")}>
          <LogoLong height={56} dark={dark} />
        </div>
        <div className="lg-nav__links">
          {links.map((l) =>
          <span
            key={l.id}
            className={"lg-nav__link" + (route.startsWith(l.id) ? " lg-nav__link--active" : "")}
            onClick={() => handleNav(l.id)}>
            {l.label}</span>
          )}
        </div>
        <div className="lg-nav__cta">
          <SunMoonToggle dark={dark} onChange={setDark} />
          <button
            type="button"
            className={"lg-nav__hamburger" + (menuOpen ? " lg-nav__hamburger--open" : "")}
            onClick={() => setMenuOpen((o) => !o)}
            aria-label={menuOpen ? "Close menu" : "Open menu"}
            aria-expanded={menuOpen}>
            <span /><span /><span />
          </button>
        </div>
      </div>
      {/* Mobile drawer — slides down beneath the nav, full width.
          Closed/hidden on desktop via CSS. */}
      <div className={"lg-nav__drawer" + (menuOpen ? " lg-nav__drawer--open" : "")}>
        {links.map((l) =>
          <span
            key={l.id}
            className={"lg-nav__drawer-link" + (route.startsWith(l.id) ? " lg-nav__drawer-link--active" : "")}
            onClick={() => handleNav(l.id)}>
            {l.label}
          </span>
        )}
      </div>
      {menuOpen && <div className="lg-nav__scrim" onClick={() => setMenuOpen(false)} aria-hidden="true" />}
    </nav>);

}

function Footer({ go, dark }) {
  return (
    <footer className="lg-foot">
      <div className="lg-foot__inner">
        <div>
          <LogoLong height={48} dark={dark} />
          <p style={{ marginTop: 14, maxWidth: 320 }}>
            A field guide for the overconnected and under-adventured.
            Less noise. More fire. Better stories.
          </p>
          <p className="script" style={{ fontSize: 32, marginTop: 18, color: 'var(--ink)', lineHeight: 1.1 }}>Stay Lonesome.</p>
        </div>
        <div>
          <h4>Index</h4>
          <a onClick={() => go("home")}>Home</a>
          <a onClick={() => go("desk")}>Field Desk</a>
          <a onClick={() => go("notes")}>Goat Notes</a>
          <a onClick={() => go("manifesto")}>Manifesto</a>
          <a onClick={() => go("about")}>About</a>
        </div>
        <div>
          <h4>The Mailbag</h4>
          <p>One letter a month. No noise. New entries, road reports, occasional whiskey opinions.</p>
          <form onSubmit={(e) => {e.preventDefault();alert("Filed. Welcome to the mailbag.");}} style={{ display: 'flex', gap: 8, marginTop: 12 }}>
            <input className="ritual-line" placeholder="your@address" style={{ flex: 1 }} />
            <button className="btn btn--ghost" type="submit">Send</button>
          </form>
          <p style={{ marginTop: 24, fontSize: 12, letterSpacing: '0.2em', textTransform: 'uppercase', color: 'var(--ink-faint)' }}>
            Est. West Texas · MMXXV
          </p>
        </div>
      </div>
    </footer>);

}

/* ============================================================
 * SIGN-OFF + ORNAMENT
 * ============================================================ */
function SignOff({ size = 40 }) {
  return <span className="script" style={{ fontFamily: '"Homemade Apple", "Caveat", cursive', fontSize: size, color: 'var(--ink)', lineHeight: 1, display: 'inline-block', transform: 'rotate(-2deg)' }}>Lonesome Goat</span>;
}
function GoatOrnament({ size = 18, opacity = 0.6, tone = "auto" }) {
  let filter = "none";
  if (tone === "bone") filter = "brightness(0) saturate(100%) invert(91%) sepia(8%) saturate(548%) hue-rotate(8deg) brightness(98%) contrast(86%)";
  return <img src="assets/lg-goat-only.png" alt="" aria-hidden="true" style={{ width: size, height: 'auto', display: 'inline-block', verticalAlign: 'middle', opacity, filter }} />;
}

/* ============================================================
 * TAPED PHOTO
 * ============================================================ */
function TapedPhoto({ caption, ratio = "4 / 3", style, src }) {
  return (
    <div className="taped" style={style}>
      {src ?
      <div style={{ aspectRatio: ratio, backgroundImage: `url(${src})`, backgroundSize: 'cover', backgroundPosition: 'center' }} /> :

      <div className="photo-ph" data-caption="photograph" style={{ aspectRatio: ratio }} />
      }
      {caption && <div className="taped__caption">{caption}</div>}
    </div>);

}

/* ============================================================
 * SKETCH — Audubon / Sibley plate style
 *
 * Thin pen weight, deliberate single-line strokes, single ink wash
 * for shading, label in print caps with a small specimen number.
 * No scribble, no doubled lines. Each plate has its own composition
 * with a baseline, the subject, optional wash, and a typeset label.
 * ============================================================ */
function Sketch({ kind = "mountains", caption, height = 180, label, framed }) {
  // v2 plate-system frame: border + divider + big spaced title at bottom.
  // Auto-on for hero-size plates (>=130px) so inline mini-sketches stay clean.
  const fullPlate = framed ?? (height >= 130);
  const ink = "var(--ink)";
  const wash = "var(--ink-soft)";
  const accent = "var(--gold-deep)";

  /* Each plate is composed with:
   *   - a hairline baseline (--rule)
   *   - the subject in 1.2px ink lines
   *   - a low-opacity wash to suggest mass
   *   - a printed label & specimen no.
   */

  const plates = {
    mountains: {
      labelDefault: "RANGE · CHINATI",
      no: "PL. I",
      title: "RANGE",
      svg:
      <g>
          {/* wash — distant ridge */}
          <path d="M30 84 L 70 64 L 100 76 L 140 56 L 180 70 L 220 50 L 260 66 L 300 56 L 330 70 L 330 110 L 30 110 Z" fill={wash} opacity="0.12" />
          {/* far ridge line */}
          <path d="M30 84 L 70 64 L 100 76 L 140 56 L 180 70 L 220 50 L 260 66 L 300 56 L 330 70" fill="none" stroke={ink} strokeWidth="1" opacity="0.55" />
          {/* near ridge wash */}
          <path d="M30 110 L 50 100 L 80 112 L 120 84 L 160 110 L 200 90 L 240 116 L 280 96 L 320 110 L 330 108 L 330 140 L 30 140 Z" fill={wash} opacity="0.22" />
          {/* near ridge line */}
          <path d="M30 110 L 50 100 L 80 112 L 120 84 L 160 110 L 200 90 L 240 116 L 280 96 L 320 110 L 330 108" fill="none" stroke={ink} strokeWidth="1.2" />
          {/* sun behind ridge */}
          <circle cx="270" cy="68" r="8" fill="none" stroke={accent} strokeWidth="0.8" />
          {/* baseline */}
          <line x1="20" y1="148" x2="340" y2="148" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    truck: {
      labelDefault: "PICKUP · DUSTED",
      no: "PL. II",
      title: "PICKUP",
      svg:
      <g>
          {/*
           * Boxy pickup, facing LEFT. Fully orthogonal — every corner is 90°.
           * Front face (grille + headlight) → flat hood → square cab
           * (vertical walls, flat roof) → flat bed → vertical tailgate.
           */}

          {/* body wash */}
          <path d="M 50 130 L 50 88 L 160 88 L 160 56 L 240 56 L 240 92 L 315 92 L 315 130 Z"
                fill={wash} opacity="0.22" />

          {/* main silhouette */}
          <path d="M 50 130 L 50 88 L 160 88 L 160 56 L 240 56 L 240 92 L 315 92 L 315 130 L 50 130 Z"
                fill="none" stroke={ink} strokeWidth="1.6" />

          {/* rocker / running board */}
          <line x1="50" y1="130" x2="315" y2="130" stroke={ink} strokeWidth="1.0" opacity="0.7" />

          {/* SIDE WINDOW (cab) */}
          <rect x="170" y="64" width="62" height="22" fill="var(--paper)" stroke={ink} strokeWidth="1.0" />
          <line x1="201" y1="64" x2="201" y2="86" stroke={ink} strokeWidth="0.7" opacity="0.7" />

          {/* hood seam at base of cab */}
          <line x1="50" y1="88" x2="160" y2="88" stroke={ink} strokeWidth="0.6" opacity="0.45" />

          {/* bed rail */}
          <line x1="240" y1="92" x2="315" y2="92" stroke={ink} strokeWidth="0.9" opacity="0.75" />

          {/* tailgate hinge */}
          <line x1="315" y1="100" x2="315" y2="124" stroke={ink} strokeWidth="0.8" opacity="0.7" />

          {/* DOOR cut + handle */}
          <line x1="200" y1="88" x2="200" y2="130" stroke={ink} strokeWidth="0.7" opacity="0.55" />
          <line x1="194" y1="110" x2="204" y2="110" stroke={ink} strokeWidth="0.9" />

          {/* HEADLIGHT (round, on front face) */}
          <circle cx="55" cy="100" r="4.2" fill="var(--paper)" stroke={ink} strokeWidth="1.0" />
          <circle cx="55" cy="100" r="1.7" fill={ink} opacity="0.75" />

          {/* GRILLE (horizontal bars on the front face) */}
          <line x1="50" y1="114" x2="64" y2="114" stroke={ink} strokeWidth="0.8" />
          <line x1="50" y1="119" x2="64" y2="119" stroke={ink} strokeWidth="0.8" />
          <line x1="50" y1="124" x2="64" y2="124" stroke={ink} strokeWidth="0.8" />

          {/* WHEELS — bold, prominent */}
          <circle cx="104" cy="130" r="18" fill="var(--paper)" stroke={ink} strokeWidth="1.6" />
          <circle cx="104" cy="130" r="9"  fill={wash} opacity="0.45" stroke={ink} strokeWidth="1" />
          <circle cx="104" cy="130" r="2.4" fill={ink} />
          <line x1="104" y1="121" x2="104" y2="124" stroke={ink} strokeWidth="0.7" />
          <line x1="104" y1="136" x2="104" y2="139" stroke={ink} strokeWidth="0.7" />

          <circle cx="271" cy="130" r="18" fill="var(--paper)" stroke={ink} strokeWidth="1.6" />
          <circle cx="271" cy="130" r="9"  fill={wash} opacity="0.45" stroke={ink} strokeWidth="1" />
          <circle cx="271" cy="130" r="2.4" fill={ink} />
          <line x1="271" y1="121" x2="271" y2="124" stroke={ink} strokeWidth="0.7" />
          <line x1="271" y1="136" x2="271" y2="139" stroke={ink} strokeWidth="0.7" />

          {/* dust kick behind */}
          <path d="M 322 138 q 6 -2 14 0 M 322 144 q 8 -2 16 0"
                fill="none" stroke={accent} strokeWidth="0.6" opacity="0.5" strokeDasharray="2 3" />

          {/* baseline */}
          <line x1="20" y1="148" x2="340" y2="148" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    fire: {
      labelDefault: "CAMPFIRE · 3rd LOG",
      title: "CAMPFIRE",
      no: "PL. III",
      svg:
      <g>
          {/* wash plume */}
          <path d="M168 130 C 142 104, 152 78, 176 56 C 170 72, 188 76, 184 62 C 196 76, 210 92, 198 116 C 216 104, 222 92, 216 76 C 230 96, 222 122, 184 132 Z" fill={accent} fillOpacity="0.18" />
          {/* main flame outline — single deliberate line */}
          <path d="M168 130 C 142 104, 152 78, 176 56 C 170 72, 188 76, 184 62 C 196 76, 210 92, 198 116" fill="none" stroke={ink} strokeWidth="1.4" />
          <path d="M184 130 C 206 116, 218 96, 210 76 C 222 92, 232 96, 222 116" fill="none" stroke={ink} strokeWidth="1.1" />
          <path d="M152 130 C 142 116, 138 102, 152 90 C 148 102, 162 104, 156 114" fill="none" stroke={ink} strokeWidth="1" opacity="0.85" />
          {/* logs */}
          <path d="M84 138 L 244 138" stroke={ink} strokeWidth="1.6" />
          <path d="M108 146 L 224 124" stroke={ink} strokeWidth="1.4" />
          <path d="M226 148 L 130 124" stroke={ink} strokeWidth="1.2" />
          <ellipse cx="84" cy="138" rx="4" ry="3" fill="none" stroke={ink} strokeWidth="0.8" />
          <ellipse cx="244" cy="138" rx="4" ry="3" fill="none" stroke={ink} strokeWidth="0.8" />
          {/* sparks */}
          <path d="M114 36 l 1 4 M 214 22 l 1 4 M 250 46 l 1 4 M 74 56 l 1 4" stroke={ink} strokeWidth="0.8" />
          {/* baseline */}
          <line x1="20" y1="156" x2="340" y2="156" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    map: {
      labelDefault: "ROUTE · BACK COUNTRY",
      title: "ROUTE",
      no: "PL. IV",
      svg:
      <g>
          {/* folded paper — irregular edges */}
          <path d="M36 28 L 88 22 L 142 30 L 198 24 L 252 32 L 320 26 L 322 132 L 268 138 L 196 130 L 134 138 L 78 130 L 36 136 Z" fill={wash} fillOpacity="0.14" stroke={ink} strokeWidth="0.9" />
          {/* fold creases — vertical and horizontal */}
          <path d="M122 24 L 122 136" stroke={ink} strokeWidth="0.4" strokeDasharray="1 5" opacity="0.4" />
          <path d="M222 26 L 222 134" stroke={ink} strokeWidth="0.4" strokeDasharray="1 5" opacity="0.4" />
          <path d="M36 80 L 322 80" stroke={ink} strokeWidth="0.4" strokeDasharray="1 5" opacity="0.35" />

          {/* a couple of mountain ridges as map symbols */}
          <path d="M60 70 l 6 -10 l 6 10 Z" fill="none" stroke={ink} strokeWidth="0.7" />
          <path d="M76 70 l 5 -8 l 5 8 Z" fill="none" stroke={ink} strokeWidth="0.7" opacity="0.7" />
          <path d="M260 60 l 6 -10 l 6 10 Z" fill="none" stroke={ink} strokeWidth="0.7" />

          {/* river — meandering */}
          <path d="M40 116 q 30 -8 50 -2 t 60 -8 t 70 -2 t 90 -10" fill="none" stroke={ink} strokeWidth="0.9" opacity="0.5" />
          <path d="M40 119 q 30 -8 50 -2 t 60 -8 t 70 -2 t 90 -10" fill="none" stroke={ink} strokeWidth="0.5" opacity="0.4" />

          {/* dirt road — dashed, takes a real turn */}
          <path d="M52 100 q 30 -22 60 -8 q 26 12 50 -10 q 26 -22 50 0 q 30 28 60 4 q 24 -20 50 -8" fill="none" stroke={ink} strokeWidth="1.4" strokeDasharray="6 4" />

          {/* waypoint markers */}
          <circle cx="62" cy="100" r="3" fill="var(--paper)" stroke={ink} strokeWidth="1" />
          <circle cx="62" cy="100" r="1" fill={ink} />
          <text x="68" y="96" fill="var(--ink-soft)" fontFamily='"Cutive Mono", monospace' fontSize="7" letterSpacing="1.5">A</text>

          <path d="M168 70 l 0 8 M 164 78 l 8 0 Z" stroke={ink} strokeWidth="1.2" />
          <path d="M168 70 m -4 0 a 4 4 0 1 0 8 0 a 4 4 0 1 0 -8 0" fill="var(--paper)" stroke={ink} strokeWidth="0.8" />
          <text x="176" y="74" fill="var(--ink-soft)" fontFamily='"Cutive Mono", monospace' fontSize="7" letterSpacing="1.5">CAMP</text>

          <path d="M286 92 l -4 -7 l 8 0 Z" fill={ink} />
          <text x="262" y="106" fill="var(--ink-soft)" fontFamily='"Cutive Mono", monospace' fontSize="7" letterSpacing="1.5">B</text>

          {/* mileage tick along the road */}
          <path d="M104 80 l 3 -3 m -3 3 l -3 -3" stroke={ink} strokeWidth="0.7" />
          <path d="M222 90 l 3 -3 m -3 3 l -3 -3" stroke={ink} strokeWidth="0.7" />

          {/* compass rose */}
          <g transform="translate(290 44)">
            <circle r="11" fill="var(--paper)" stroke={ink} strokeWidth="0.8" />
            <path d="M0 -11 L 0 11 M -11 0 L 11 0" stroke={ink} strokeWidth="0.5" opacity="0.6" />
            <path d="M0 -11 L -3 0 L 0 -3 L 3 0 Z" fill={ink} />
            <text x="0" y="-13" textAnchor="middle" fill="var(--ink-soft)" fontFamily='"Cutive Mono", monospace' fontSize="6">N</text>
          </g>

          {/* scale bar */}
          <g transform="translate(46 144)">
            <path d="M0 0 L 60 0" stroke={ink} strokeWidth="1" />
            <path d="M0 -3 L 0 3 M 20 -3 L 20 3 M 40 -3 L 40 3 M 60 -3 L 60 3" stroke={ink} strokeWidth="0.8" />
            <text x="0" y="12" fill="var(--ink-soft)" fontFamily='"Cutive Mono", monospace' fontSize="7" letterSpacing="1.5">0     2     4 MI</text>
          </g>

          {/* baseline */}
          <line x1="20" y1="170" x2="340" y2="170" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    kettle: {
      labelDefault: "MUG · BLACK COFFEE",
      title: "BLACK COFFEE",
      no: "PL. V",
      svg:
      <g>
          {/*
          * Stoneware coffee mug — short, fat, with a thick handle.
          * Centered ~180,98. Steam rises in three calm curls.
          */}
          {/* steam — drawn first so it sits behind the rim */}
          <path d="M158 50 c -4 -10, 6 -14, -2 -26 c 6 6, 4 14, 2 22" fill="none" stroke={ink} strokeWidth="0.9" opacity="0.55" />
          <path d="M180 42 c -4 -10, 6 -14, -2 -28 c 6 6, 4 16, 2 24" fill="none" stroke={ink} strokeWidth="1" opacity="0.7" />
          <path d="M204 50 c -4 -10, 6 -14, -2 -26 c 6 6, 4 14, 2 22" fill="none" stroke={ink} strokeWidth="0.9" opacity="0.55" />

          {/* mug wash — body */}
          <path d="M132 70 L 230 70 L 224 138 L 138 138 Z" fill={wash} opacity="0.20" />

          {/* mug body — slight taper inward toward the bottom */}
          <path d="M132 70 L 230 70 L 224 138 L 138 138 Z" fill="none" stroke={ink} strokeWidth="1.5" />

          {/* rim ellipse */}
          <ellipse cx="181" cy="70" rx="49" ry="6" fill="var(--paper)" stroke={ink} strokeWidth="1.4" />
          {/* coffee surface — dark ellipse just below rim */}
          <ellipse cx="181" cy="72" rx="44" ry="5" fill={ink} opacity="0.85" />
          {/* highlight glint on coffee */}
          <path d="M156 70 q 8 -3 18 -1" stroke="var(--paper)" strokeWidth="0.8" fill="none" opacity="0.6" />

          {/* handle — thick D-shape on right */}
          <path d="M230 84 q 30 4, 30 28 q 0 24 -30 28" fill="none" stroke={ink} strokeWidth="1.5" />
          <path d="M230 92 q 22 4, 22 24 q 0 18 -22 22" fill="none" stroke={ink} strokeWidth="0.7" opacity="0.5" />

          {/* base ellipse — bottom curve */}
          <path d="M138 138 q 43 7, 86 0" fill="none" stroke={ink} strokeWidth="1" />

          {/* a stamped maker's mark on the side */}
          <circle cx="166" cy="118" r="4" fill="none" stroke={ink} strokeWidth="0.6" opacity="0.5" />
          <text x="166" y="120" textAnchor="middle" fill="var(--ink-soft)" fontFamily='"Cutive Mono", monospace' fontSize="4" letterSpacing="0.5">SL</text>

          {/* baseline */}
          <line x1="20" y1="156" x2="340" y2="156" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    compass: {
      labelDefault: "COMPASS · BRASS",
      title: "TRUE NORTH",
      no: "PL. VI",
      svg:
      <g>
          {/* wash */}
          <circle cx="180" cy="92" r="56" fill={accent} fillOpacity="0.12" />
          {/* outer ring */}
          <circle cx="180" cy="92" r="56" fill="none" stroke={ink} strokeWidth="1.4" />
          <circle cx="180" cy="92" r="46" fill="none" stroke={ink} strokeWidth="0.5" strokeDasharray="2 3" opacity="0.6" />
          {/* needle */}
          <path d="M180 44 L 188 92 L 180 140 L 172 92 Z" fill="none" stroke={ink} strokeWidth="1.2" />
          <path d="M180 44 L 188 92 L 172 92 Z" fill={ink} />
          {/* pin */}
          <circle cx="180" cy="92" r="3" fill={ink} />
          {/* ticks */}
          <path d="M180 38 L 180 44 M 180 140 L 180 146 M 124 92 L 130 92 M 230 92 L 236 92" stroke={ink} strokeWidth="1" />
          {/* baseline */}
          <line x1="20" y1="156" x2="340" y2="156" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    whiskey: {
      labelDefault: "WHISKEY · LATE NIGHT LIBATION",
      no: "PL. VII",
      svg:
      <g>
          {/*
           * Old-fashioned glass with one large square ice cube.
           * Slightly tapered glass walls with subtle base curve, perspective
           * ellipse top, amber whiskey wash filling the lower portion, and
           * an isometric ice cube floating in the liquid.
           */}

          {/* baseline */}
          <line x1="20" y1="178" x2="340" y2="178" stroke={ink} strokeWidth="0.6" opacity="0.45" />

          {/* whiskey amber wash inside glass */}
          <path d="M 134 80 L 226 80 L 224 156 L 136 156 Z" fill={accent} opacity="0.42" />

          {/* glass walls (slight taper) + base curve */}
          <path d="M 128 44 L 134 158 Q 180 168 226 158 L 232 44"
                fill="none" stroke={ink} strokeWidth="1.6" />
          <path d="M 134 158 Q 180 152 226 158" fill="none" stroke={ink} strokeWidth="0.8" opacity="0.6" />

          {/* glass top rim — open ellipse */}
          <ellipse cx="180" cy="44" rx="52" ry="5" fill="var(--paper)" opacity="0.35" />
          <ellipse cx="180" cy="44" rx="52" ry="5" fill="none" stroke={ink} strokeWidth="1.5" />

          {/* whiskey liquid surface (perspective ellipse) */}
          <ellipse cx="180" cy="80" rx="46" ry="4" fill={accent} opacity="0.6" />
          <ellipse cx="180" cy="80" rx="46" ry="4" fill="none" stroke={ink} strokeWidth="0.8" opacity="0.7" />

          {/* ICE CUBE — large square, isometric (front, top, right faces visible) */}
          {/* cube body fill */}
          <path d="M 160 120 L 160 80 L 172 72 L 212 72 L 212 112 L 200 120 Z"
                fill="var(--paper)" opacity="0.92" />
          {/* top face */}
          <path d="M 160 80 L 200 80 L 212 72 L 172 72 Z"
                fill="var(--paper)" stroke={ink} strokeWidth="1.0" />
          {/* right face (subtle shadow) */}
          <path d="M 200 80 L 212 72 L 212 112 L 200 120 Z"
                fill={wash} opacity="0.18" stroke={ink} strokeWidth="1.0" />
          {/* front face */}
          <path d="M 160 80 L 200 80 L 200 120 L 160 120 Z"
                fill="none" stroke={ink} strokeWidth="1.2" />
          {/* outer cube silhouette emphasis */}
          <path d="M 160 120 L 160 80 L 172 72 L 212 72 L 212 112 L 200 120 Z"
                fill="none" stroke={ink} strokeWidth="1.4" />
          {/* small ice fissure lines (texture) */}
          <line x1="172" y1="92" x2="180" y2="100" stroke={ink} strokeWidth="0.5" opacity="0.4" />
          <line x1="186" y1="86" x2="192" y2="92" stroke={ink} strokeWidth="0.5" opacity="0.35" />
          <line x1="166" y1="106" x2="172" y2="112" stroke={ink} strokeWidth="0.5" opacity="0.35" />

          {/* glass highlights — bright stroke left, dim right */}
          <line x1="138" y1="64" x2="142" y2="148" stroke="var(--paper)" strokeWidth="1.4" opacity="0.5" />
          <line x1="222" y1="64" x2="218" y2="148" stroke={ink} strokeWidth="0.5" opacity="0.3" />

          {/* condensation droplets */}
          <circle cx="148" cy="130" r="1" fill={ink} opacity="0.3" />
          <circle cx="218" cy="142" r="0.9" fill={ink} opacity="0.3" />
          <circle cx="156" cy="148" r="0.7" fill={ink} opacity="0.3" />

          {/* shadow under glass */}
          <ellipse cx="180" cy="170" rx="60" ry="3" fill={ink} opacity="0.15" />
        </g>

    },
    sunset: {
      labelDefault: "SUNSET · LAST LIGHT",
      no: "PL. VIII",
      svg:
      <g>
          {/* faint horizon wash bands */}
          <path d="M30 84 L 330 84 L 330 96 L 30 96 Z" fill={accent} opacity="0.18" />
          <path d="M30 96 L 330 96 L 330 110 L 30 110 Z" fill={accent} opacity="0.10" />
          {/* sun — half over horizon, low and heavy */}
          <circle cx="180" cy="100" r="22" fill={accent} opacity="0.32" />
          <circle cx="180" cy="100" r="22" fill="none" stroke={ink} strokeWidth="1.2" />
          {/* horizon line — long, calm */}
          <line x1="30" y1="100" x2="330" y2="100" stroke={ink} strokeWidth="1.4" />
          {/* sun rays — short ticks above the horizon */}
          <path d="M180 70 l 0 6 M 158 76 l 2 6 M 202 76 l -2 6 M 138 84 l 4 4 M 222 84 l -4 4" stroke={ink} strokeWidth="0.8" opacity="0.55" />
          {/* far hills below the horizon */}
          <path d="M30 100 q 30 18, 60 8 q 30 -8, 70 14 q 40 18, 80 0 q 30 -12, 90 12 L 330 130 L 30 130 Z" fill={wash} opacity="0.18" />
          <path d="M30 100 q 30 18, 60 8 q 30 -8, 70 14 q 40 18, 80 0 q 30 -12, 90 12" fill="none" stroke={ink} strokeWidth="0.9" opacity="0.5" />
          {/* a few birds */}
          <path d="M86 60 q 4 -3 8 0 q 4 -3 8 0" fill="none" stroke={ink} strokeWidth="0.7" />
          <path d="M240 50 q 3 -2 6 0 q 3 -2 6 0" fill="none" stroke={ink} strokeWidth="0.6" />
          <path d="M270 64 q 3 -2 6 0 q 3 -2 6 0" fill="none" stroke={ink} strokeWidth="0.6" />
          {/* baseline */}
          <line x1="20" y1="156" x2="340" y2="156" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    stars: {
      labelDefault: "NIGHT · NO MOON",
      no: "PL. IX",
      svg:
      <g>
          {/* sky frame — light wash */}
          <path d="M30 24 L 330 24 L 330 122 L 30 122 Z" fill={ink} opacity="0.05" />
          <path d="M30 24 L 330 24 L 330 122 L 30 122 Z" fill="none" stroke={ink} strokeWidth="0.8" opacity="0.5" />
          {/* milky way — diagonal wash band */}
          <path d="M44 36 L 312 116" stroke={ink} strokeWidth="14" opacity="0.05" strokeLinecap="round" />
          <path d="M44 36 L 312 116" stroke={ink} strokeWidth="6" opacity="0.06" strokeLinecap="round" />
          {/* constellation — Orion-ish */}
          {[
        [80, 50], [88, 64], [104, 58], [112, 72], [120, 88], [132, 96], [148, 90]].
        map(([cx, cy], i) =>
        <circle key={i} cx={cx} cy={cy} r="1.4" fill={ink} />
        )}
          <path d="M80 50 L 88 64 L 104 58 L 112 72 L 120 88 L 132 96 L 148 90" stroke={ink} strokeWidth="0.5" opacity="0.4" />
          {/* scattered stars — varied size */}
          {[
        [60, 38, 0.8], [178, 44, 1.6], [210, 32, 1], [248, 58, 0.8], [276, 40, 1.2], [296, 70, 0.9],
        [200, 80, 1.1], [228, 96, 0.7], [270, 108, 1], [298, 100, 0.6], [180, 110, 0.8],
        [62, 76, 0.7], [40, 52, 0.9], [42, 98, 0.8], [156, 40, 0.8], [316, 52, 1.1],
        [314, 90, 0.7], [196, 108, 0.6], [244, 82, 0.8]].
        map(([cx, cy, r], i) =>
        <circle key={"s" + i} cx={cx} cy={cy} r={r} fill={ink} />
        )}
          {/* shooting star */}
          <path d="M250 36 L 280 50" stroke={ink} strokeWidth="0.9" />
          <circle cx="280" cy="50" r="1.6" fill={ink} />
          {/* horizon silhouette */}
          <path d="M30 122 q 30 -10 60 -2 q 30 8 60 -6 q 30 -14 70 0 q 40 14 80 -4 q 20 -8 30 -2 L 330 122 Z" fill={ink} opacity="0.55" />
          {/* baseline */}
          <line x1="20" y1="146" x2="340" y2="146" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    agave: {
      labelDefault: "AGAVE · DESERT",
      no: "PL. X",
      svg:
      <g>
          {/* center wash */}
          <ellipse cx="180" cy="120" rx="80" ry="14" fill={wash} opacity="0.15" />
          {/* agave leaves — long pointed swords radiating from a center base */}
          {/* draw each leaf as two outline curves meeting at the tip */}
          {[
        { tip: [180, 30], left: [160, 118], right: [200, 118] },
        { tip: [120, 40], left: [150, 118], right: [166, 116] },
        { tip: [240, 42], left: [194, 116], right: [210, 118] },
        { tip: [80, 72], left: [140, 120], right: [156, 118] },
        { tip: [280, 74], left: [204, 118], right: [220, 120] },
        { tip: [60, 108], left: [130, 124], right: [148, 120] },
        { tip: [300, 108], left: [212, 120], right: [230, 124] },
        { tip: [150, 28], left: [170, 118], right: [178, 118] },
        { tip: [210, 28], left: [182, 118], right: [190, 118] }].
        map((leaf, i) =>
        <g key={i}>
              <path
            d={`M ${leaf.left[0]} ${leaf.left[1]} Q ${(leaf.tip[0] + leaf.left[0]) / 2 - 4} ${(leaf.tip[1] + leaf.left[1]) / 2 + 4} ${leaf.tip[0]} ${leaf.tip[1]} Q ${(leaf.tip[0] + leaf.right[0]) / 2 + 4} ${(leaf.tip[1] + leaf.right[1]) / 2 + 4} ${leaf.right[0]} ${leaf.right[1]}`}
            fill={accent}
            fillOpacity="0.10"
            stroke={ink}
            strokeWidth="1" />
          
              {/* leaf midline */}
              <path
            d={`M ${(leaf.left[0] + leaf.right[0]) / 2} ${(leaf.left[1] + leaf.right[1]) / 2} L ${leaf.tip[0]} ${leaf.tip[1]}`}
            stroke={ink}
            strokeWidth="0.4"
            opacity="0.45" />
          
            </g>
        )}
          {/* center rosette */}
          <ellipse cx="180" cy="118" rx="14" ry="4" fill={ink} opacity="0.6" />
          {/* a few thorns at tips */}
          <path d="M180 30 l 0 -3 M 120 40 l -2 -3 M 240 42 l 2 -3 M 80 72 l -3 -2 M 280 74 l 3 -2" stroke={ink} strokeWidth="0.8" />
          {/* baseline */}
          <line x1="20" y1="156" x2="340" y2="156" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    ocotillo: {
      labelDefault: "OCOTILLO · BLOOM",
      no: "PL. XI",
      svg:
      <g>
          {/*
          * Ocotillo — a base clump with tall, thin, slightly curved arms
          * radiating up. Each arm tipped with a small red bloom.
          */}
          {/* ground wash */}
          <ellipse cx="180" cy="142" rx="60" ry="6" fill={wash} opacity="0.18" />
          {/* base */}
          <path d="M158 138 q 22 -6 44 0" fill="none" stroke={ink} strokeWidth="1.2" />
          {/* arms — tall whippy lines, each gently curved differently */}
          {[
        { d: "M168 140 C 162 110, 156 80, 150 30", bloom: [150, 30] },
        { d: "M174 140 C 172 110, 168 78, 166 26", bloom: [166, 26] },
        { d: "M180 140 C 180 108, 180 76, 180 22", bloom: [180, 22] },
        { d: "M186 140 C 188 110, 192 78, 196 26", bloom: [196, 26] },
        { d: "M192 140 C 198 110, 206 80, 212 32", bloom: [212, 32] },
        { d: "M162 138 C 150 112, 134 88, 118 56", bloom: [118, 56] },
        { d: "M198 138 C 212 112, 230 86, 246 60", bloom: [246, 60] },
        { d: "M156 138 C 138 116, 116 96, 96 80", bloom: [96, 80] },
        { d: "M204 138 C 224 116, 248 96, 270 84", bloom: [270, 84] }].
        map((arm, i) =>
        <g key={i}>
              <path d={arm.d} fill="none" stroke={ink} strokeWidth="1.1" />
              {/* tiny side leaves — small ticks along each arm */}
              <path
            d={`M${arm.bloom[0] + 1} ${arm.bloom[1] + 18} l 4 -1 M${arm.bloom[0] - 2} ${arm.bloom[1] + 34} l -4 -1`}
            stroke={ink}
            strokeWidth="0.5"
            opacity="0.5" />
          
              {/* red flame bloom at tip */}
              <path
            d={`M${arm.bloom[0]} ${arm.bloom[1]} q -2 -4, 0 -8 q 2 4, 0 8`}
            fill={accent}
            stroke={ink}
            strokeWidth="0.7" />
          
            </g>
        )}
          {/* baseline */}
          <line x1="20" y1="156" x2="340" y2="156" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    },
    storm: {
      labelDefault: "STORM · WEST WIND",
      no: "PL. XII",
      svg:
      <g>
          {/* sky base */}
          <path d="M30 26 L 330 26 L 330 86 L 30 86 Z" fill={ink} opacity="0.04" />
          {/* big cloud mass — bumpy underline */}
          <path d="M40 70 q 14 -28 42 -22 q 14 -28 50 -18 q 22 -22 56 -10 q 28 -22 60 -4 q 24 -8 40 8 q 16 18, 4 30 L 40 74 Z" fill={wash} opacity="0.30" />
          <path d="M40 70 q 14 -28 42 -22 q 14 -28 50 -18 q 22 -22 56 -10 q 28 -22 60 -4 q 24 -8 40 8 q 16 18, 4 30" fill="none" stroke={ink} strokeWidth="1.3" />
          {/* secondary smaller cloud */}
          <path d="M210 92 q 8 -14 22 -10 q 10 -14 26 -6 q 12 -8 18 4 q 6 12 -6 18 L 214 100 Z" fill={wash} opacity="0.25" />
          <path d="M210 92 q 8 -14 22 -10 q 10 -14 26 -6 q 12 -8 18 4 q 6 12 -6 18" fill="none" stroke={ink} strokeWidth="1" />
          {/* rain — slanted dashes (wind) */}
          {Array.from({ length: 22 }).map((_, i) => {
          const x = 50 + i * 12;
          const y = 80 + i % 3 * 4;
          return <path key={i} d={`M${x} ${y} l -6 14`} stroke={ink} strokeWidth="0.7" opacity="0.6" />;
        })}
          {/* lightning bolt */}
          <path d="M170 76 L 158 110 L 172 110 L 162 138 L 184 102 L 170 102 L 180 76 Z" fill={accent} stroke={ink} strokeWidth="1" />
          {/* horizon — distant ridge taking the wind */}
          <path d="M30 138 q 30 -8 60 -2 q 30 6 70 -10 q 40 -16 80 -2 q 30 10 90 0" fill="none" stroke={ink} strokeWidth="0.9" opacity="0.5" />
          {/* baseline */}
          <line x1="20" y1="158" x2="340" y2="158" stroke={ink} strokeWidth="0.6" opacity="0.45" />
        </g>

    }
  };

  const plate = plates[kind] || plates.mountains;
  const lbl = label || plate.labelDefault;

  return (
    <figure style={{ margin: 0, color: 'var(--ink)' }}>
      <svg className="sketch sketch--plate" viewBox="0 0 360 200" style={{ height, width: '100%' }}>
        {plate.svg}
        {/* label block */}
        <text
          x="20" y="186"
          fill="var(--ink-soft)"
          fontFamily='"Cutive Mono", "Courier New", monospace'
          fontSize="9"
          letterSpacing="2">
          
          {lbl}
        </text>
        <text
          x="340" y="186" textAnchor="end"
          fill="var(--ink-faint)"
          fontFamily='"Cutive Mono", "Courier New", monospace'
          fontSize="9"
          letterSpacing="2">
          
          {plate.no}
        </text>
      </svg>
      {caption && <figcaption className="hand" style={{ fontFamily: '"Caveat", cursive', fontSize: 18, color: 'var(--ink-soft)', textAlign: 'center', marginTop: 4 }}>{caption}</figcaption>}
    </figure>);

}

/* ============================================================
 * FIELD LINE / COORD STRIP
 * ============================================================ */
function FieldLine({ label, value }) {
  return (
    <div className="field-line">
      <span className="field-line__label">{label}</span>
      <span className="field-line__val">{value}</span>
    </div>);

}
function CoordStrip({ note }) {
  return (
    <div style={{ display: 'flex', gap: 18, flexWrap: 'wrap', alignItems: 'center', fontFamily: 'var(--f-mono)', fontSize: 12, letterSpacing: '0.2em', color: 'var(--ink-soft)', textTransform: 'uppercase' }}>
      <span>{note.no}</span>
      <GoatOrnament size={14} opacity={0.5} />
      <span>{note.date}</span>
      <GoatOrnament size={14} opacity={0.5} />
      <span>{note.location}</span>
      {note.coords && <>
        <GoatOrnament size={14} opacity={0.5} />
        <span>{note.coords}</span>
      </>}
    </div>);

}

/* ============================================================
 * CATEGORY TOKENS (used everywhere)
 * ============================================================ */
const CATEGORIES = {
  entries: { id: "entries", label: "Field Entries", short: "Entries", color: "var(--cat-gold)", Icon: IcoLedger, hint: "Published entries — your Goat Notes." },
  drafts: { id: "drafts", label: "Drafts", short: "Drafts", color: "var(--cat-sage)", Icon: IcoPencil, hint: "Working notes. Auto-saved as you write." },
  sketches: { id: "sketches", label: "Sketches", short: "Sketches", color: "var(--cat-clay)", Icon: IcoFountainPen, hint: "Doodles and field sketches." },
  letters: { id: "letters", label: "Letters", short: "Letters", color: "var(--cat-wax)", Icon: IcoEnvelope, hint: "Letters sent — not blog posts." }
};

Object.assign(window, {
  Nav, Footer, TapedPhoto, Sketch, FieldLine, CoordStrip,
  LogoLong, LogoSquare, LogoStayLonesome, LogoGoat, GoatOrnament, SignOff, SunMoonToggle,
  // icons
  Ico, IcoLedger, IcoPencil, IcoFountainPen, IcoEnvelope,
  IcoTypewriter, IcoBook, IcoPin, IcoLamp, IcoStar, IcoX, IcoChevron,
  IcoLocation, IcoCheck, IcoTrash,
  CATEGORIES
});