:root {
  --ink: #1a1c2c;
  --paper: #f6ecd2;
  --wood: #3a2616;
  --wood-2: #4d331d;
  --rim: #8a6a4a;
  --gold: #ffcd75;
  --red: #b13e53;
  --steel: #c2c3c7;
  --grey: #c6c6c6;
  --text: #f4e9d8;
  --link: #8fd3ff;
  --pixel: 'Press Start 2P', monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: #0b0d1a radial-gradient(#ffffff1c 1px, transparent 1px) 0 0 / 24px 24px;
  color: var(--ink);
  font: 15px/1.5 Verdana, Geneva, sans-serif;
}

:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

.skip-link { position: absolute; left: -999px; }
.skip-link:focus { left: 8px; top: 8px; z-index: 10; background: var(--gold); padding: 8px; }

.site { max-width: 980px; margin: 16px auto; border: 4px ridge var(--rim); background: #140f0b; }

/* ---------- Header scene ---------- */
.site__header { position: relative; }

.scene {
  --unit: 4px;
  --px: var(--unit);
  --ground: 22px;
  position: relative;
  height: 250px;
  overflow: hidden;
  background: linear-gradient(#070a1c 0 22%, #0d1430 22% 44%, #14204a 44% 64%, #1d2c5e 64% 82%, #283a70 82%);
}
.scene svg { display: block; width: calc(var(--w) * var(--px)); height: calc(var(--h) * var(--px)); }
.scene i { position: absolute; display: block; }

.title {
  position: absolute; top: 24px; left: 0; right: 0; margin: 0; padding: 0 12px;
  text-align: center; font: 22px/1.5 var(--pixel); color: var(--gold);
  text-shadow: 3px 3px 0 var(--red), 6px 6px 0 var(--ink);
}
.title small { display: block; margin-top: 6px; font-size: 10px; color: var(--steel); text-shadow: 2px 2px 0 var(--ink); }

.moon { position: absolute; top: 16px; right: 5%; --px: 3px; filter: drop-shadow(0 0 10px #fff3c488); }
.star { width: 2px; height: 2px; background: #fff; animation: twinkle 3s steps(2) infinite; }

.trees, .front { position: absolute; left: 0; right: 0; bottom: var(--ground); }
.spr { position: absolute; bottom: 0; }
.tree { --px: calc(var(--unit) * 1.4 * var(--s, 1)); }

.ground {
  position: absolute; left: 0; right: 0; bottom: 0; height: var(--ground);
  background:
    repeating-linear-gradient(90deg, #3f8f5f 0 4px, transparent 4px 12px) top / 100% 4px no-repeat,
    linear-gradient(#2e6b4f 0 8px, #3b2a1f 8px 15px, #2c1f17 15px);
}

/* Two-frame sprites: the frames take turns being visible. */
.frames { position: relative; }
.frames > svg:first-child { animation: frame-a var(--speed, .5s) steps(1) infinite; }
.frames > svg + svg { position: absolute; top: 0; left: 0; visibility: hidden; animation: frame-b var(--speed, .5s) steps(1) infinite; }

.campfire { --speed: .4s; }
.campfire::before {
  content: ''; position: absolute; left: 50%; bottom: 0;
  width: calc(var(--px) * 34); height: calc(var(--px) * 34); transform: translate(-50%, 45%);
  background: radial-gradient(#ef7d5766, transparent 65%); animation: glow 1.6s ease-in-out infinite alternate;
}

/* Two fencers take turns: one thrusts while the other stands in guard. */
.fencers { width: calc(var(--px) * 40); height: calc(var(--px) * 15); --speed: 2.4s; }
.fencer { position: absolute; bottom: 0; animation: step-a 2.4s steps(1) infinite; }
.fencer--a { left: 0; }
.fencer--b { right: 0; transform: scaleX(-1); animation-name: step-b; }
/* Where the blades meet: first half the red fencer thrusts, second half the white one. */
.clash {
  left: calc(var(--px) * 14); bottom: calc(var(--px) * 9); width: var(--px); height: var(--px);
  background: #fff; box-shadow: 0 0 6px 3px var(--gold); opacity: 0; animation: clash 2.4s steps(1) infinite;
}
.clash--a { left: calc(var(--px) * 25); animation-delay: 1.2s; }

/* Tio sits a little in the foreground, so he can be big enough to recognise.
   He sits by the fire, strolls over to the fencers, sits again and strolls back,
   staying in the open ground between them so he never walks in front of the art. */
.front .tio {
  --speed: 3s;
  --tio-a: calc(24% + var(--px) * 14); /* just right of the campfire */
  --tio-b: calc(52% - var(--px) * 20); /* just left of the fencers */
  z-index: 2; left: var(--tio-a); bottom: calc(var(--px) * -4);
  animation: tio-move 30s linear infinite;
}
.tio-sit { animation: tio-sit 30s steps(1, end) infinite; }
/* opacity, not visibility: the sprite frames inside set their own visibility */
.tio-walk { position: absolute; left: 0; bottom: var(--px); opacity: 0; animation: tio-walk 30s steps(1, end) infinite; }
.tio-walk .frames { --speed: .3s; }
@keyframes tio-move { 0%, 30% { left: var(--tio-a); } 50%, 75% { left: var(--tio-b); } 95%, 100% { left: var(--tio-a); } }
@keyframes tio-sit { 0% { opacity: 1; } 30% { opacity: 0; } 50% { opacity: 1; } 75% { opacity: 0; } 95% { opacity: 1; } }
@keyframes tio-walk {
  0% { opacity: 0; }
  30% { opacity: 1; transform: none; }
  50% { opacity: 0; }
  75% { opacity: 1; transform: scaleX(-1); }
  95% { opacity: 0; }
}

.firefly {
  width: 3px; height: 3px; background: #e9ff70; box-shadow: 0 0 6px 2px #e9ff7088;
  opacity: 0; animation: float 7s ease-in-out infinite;
}

@keyframes frame-a { 0% { visibility: visible; } 50% { visibility: hidden; } }
@keyframes frame-b { 0% { visibility: hidden; } 50% { visibility: visible; } }
@keyframes twinkle { 50% { opacity: .3; } }
@keyframes glow { to { opacity: .6; transform: translate(-50%, 45%) scale(.9); } }
@keyframes step-a { 0% { translate: 0; } 50% { translate: calc(var(--px) * 2) 0; } }
@keyframes step-b { 0% { translate: calc(var(--px) * -2) 0; } 50% { translate: 0; } }
@keyframes clash { 0% { opacity: 1; } 6% { opacity: 0; } }
@keyframes float {
  0% { opacity: 0; transform: translate(0, 0); }
  40% { opacity: 1; transform: translate(12px, -40px); }
  100% { opacity: 0; transform: translate(-6px, -90px); }
}

/* ---------- Marquee ---------- */
.marquee {
  overflow: hidden; white-space: nowrap; padding: 8px 0 8px 12px;
  background: var(--ink); border-block: 3px solid var(--red);
  color: var(--gold); font: 10px/1 var(--pixel);
}
/* The text is in there twice (see app.js); sliding by half makes a seamless loop. */
/* It waits a moment on page load, so the first words can be read before they slide away. */
.marquee span { display: inline-block; animation: marquee 22s linear 2.5s infinite; }
.marquee b { font-weight: normal; padding-right: 3em; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- Layout ---------- */
.layout { display: grid; grid-template-columns: 200px 1fr; gap: 16px; padding: 16px; }
.sidebar, .widgets, .nav { display: flex; flex-direction: column; gap: 12px; }
/* On wide screens the sidebar travels along while scrolling; on short screens it scrolls on its own. */
@media (min-width: 721px) {
  /* 100vh is enlarged by the page zoom, so divide it back out to really fit the screen. */
  .sidebar { position: sticky; top: 16px; align-self: start; max-height: calc(100vh / var(--zoom, 1) - 32px); overflow-y: auto; scrollbar-width: thin; }
}
.nav { gap: 6px; }

.nav a, .btn, .mine-box {
  display: block; padding: 9px 10px; margin: 0;
  font: 9px/1.4 var(--pixel); text-transform: uppercase; text-decoration: none; color: var(--ink);
  background: var(--grey); border: 3px outset #eee; cursor: pointer;
}
.nav a:hover, .btn:hover { filter: brightness(1.08); }
.nav a:active, .btn:active { border-style: inset; }
.btn--gold, .mine-box { background: var(--gold); border-color: #ffe6a8; }
.mine-box { cursor: default; display: flex; justify-content: space-between; align-items: center; }
.mine-box b { background: var(--ink); color: var(--gold); padding: 3px 6px; }

.widget { margin: 0; padding: 8px; background: #050505; border: 3px inset #555; color: var(--steel); text-align: center; font: 8px/1.6 var(--pixel); }
.widget p { margin: 4px 0; }
.counter { font-size: 16px; letter-spacing: 2px; color: #ff3b3b; text-shadow: 0 0 6px #ff3b3b; }

.lcd { padding: 10px; background: #9bbc0f; color: #0f380f; border: 4px solid #3a3a3a; border-radius: 6px; box-shadow: inset 0 0 0 2px #8bac0f; font: 8px/1.7 var(--pixel); }
.lcd p { margin: 0; }
.lcd__bar { height: 10px; margin: 6px 0; border: 2px solid #0f380f; }
.lcd__bar i { display: block; height: 100%; width: 0; background: #0f380f; }

/* ---------- Content ---------- */
.intro { background: var(--paper); border: 4px double var(--wood-2); padding: 4px 20px 12px; }
h2 { font: 14px/1.5 var(--pixel); color: var(--red); }
.intro h3 { font: 10px/1.5 var(--pixel); color: var(--wood-2); }
.intro li { margin-bottom: 4px; }
.loading { color: var(--text); font: 10px var(--pixel); }

/* Each category panel sets these variables; the default is the dark wood look. */
.cat {
  --cat-bg: linear-gradient(var(--wood-2), var(--wood));
  --cat-border: 3px ridge var(--rim);
  --cat-head: #00000040;
  --cat-title: var(--gold);
  --cat-title-shadow: none;
  --cat-text: var(--text);
  --cat-rule: 2px dashed #6b4a2e;
  --cat-link: var(--link);
  margin-top: 20px; padding: 0 18px 4px; color: var(--cat-text); background: var(--cat-bg); border: var(--cat-border);
}
.cat h2 {
  display: flex; gap: 12px; align-items: center; margin: 0 -18px; padding: 12px 18px;
  color: var(--cat-title); text-shadow: var(--cat-title-shadow); background: var(--cat-head); border-bottom: var(--cat-rule);
}
.cat__note { margin: 12px 0 0; font-style: italic; }
.cat .shops a { color: var(--cat-link); }
.cat .item { border-bottom: var(--cat-rule); }
.cat .item:last-child { border-bottom: 0; }

/* HEMA: a riveted steel plate */
.cat--hema {
  --cat-bg: linear-gradient(160deg, #4a5262, #2a2f3b 60%, #1f232c);
  --cat-border: 4px ridge #a3acbb;
  --cat-head:
    radial-gradient(circle at 7px 50%, #c9d0db 2px, transparent 3px),
    radial-gradient(circle at calc(100% - 7px) 50%, #c9d0db 2px, transparent 3px),
    repeating-linear-gradient(90deg, #ffffff08 0 2px, transparent 2px 5px), #00000030;
  --cat-title: #eef1f6;
  --cat-title-shadow: 2px 2px 0 var(--red);
  --cat-text: #e3e7ee;
  --cat-rule: 2px solid #5f6c7d;
  --cat-link: #a8d8ff;
}

/* Bushcraft: forest canvas with a stitched seam */
.cat--bushcraft {
  --cat-bg: repeating-linear-gradient(45deg, #ffffff06 0 2px, transparent 2px 6px), linear-gradient(#34482f, #1f2c1d);
  --cat-border: 4px double #a8885a;
  --cat-head: #00000035;
  --cat-title: #ecdcab;
  --cat-text: #edf1e4;
  --cat-rule: 2px dashed #a8885a88;
  --cat-link: #c6e88a;
}

/* Homelab: an old green terminal with scanlines */
.cat--homelab {
  --cat-bg: repeating-linear-gradient(#ffffff07 0 1px, transparent 1px 3px), #07110a;
  --cat-border: 4px solid #3a3d3a;
  --cat-head: #0d2414;
  --cat-title: #39ff6a;
  --cat-title-shadow: 0 0 6px #39ff6a99;
  --cat-text: #b9f5c6;
  --cat-rule: 1px dashed #1f6f35;
  --cat-link: #6fffd2;
  box-shadow: inset 0 0 30px #39ff6a1a;
}
.cat--homelab h2::before { content: 'C:\\>'; font-size: 10px; }
.cat--homelab h2::after { content: '_'; animation: cursor 1s steps(1) infinite; }
.cat--homelab .item h3 { color: #dfffe6; }
@keyframes cursor { 50% { opacity: 0; } }

/* Maken: a green circuit board with copper traces */
.cat--maken {
  --cat-bg:
    linear-gradient(90deg, #d9954622 2px, transparent 2px) 0 0 / 48px 48px,
    linear-gradient(#d9954622 2px, transparent 2px) 0 0 / 48px 48px,
    radial-gradient(circle, #d995463a 3px, transparent 4px) -24px -24px / 48px 48px,
    #0f4a2a;
  --cat-border: 4px solid #c8873a;
  --cat-head: #0a3a20;
  --cat-title: #f3b462;
  --cat-text: #e6f2e6;
  --cat-rule: 2px solid #c8873a66;
  --cat-link: #ffd38a;
}

/* Smidse: charcoal with embers glowing at the bottom */
.cat--smidse {
  --cat-bg: radial-gradient(ellipse at 50% 115%, #ef7d5766, transparent 60%), linear-gradient(#2c2622, #161210);
  --cat-border: 4px ridge #6b5a4a;
  --cat-head: #00000040;
  --cat-title: #ff9b4a;
  --cat-title-shadow: 0 0 8px #ef7d57;
  --cat-text: #f1e4d8;
  --cat-rule: 2px dashed #5a463a;
  --cat-link: #ffc285;
}

/* LEGO: a blue baseplate with studs and a yellow brick edge */
.cat--lego {
  --cat-bg: radial-gradient(circle at 10px 10px, #ffffff1c 5px, #00000030 6px, transparent 7px) 0 0 / 20px 20px, #0a4aa6;
  --cat-border: 6px solid #f2cd37;
  --cat-head: #c91a09;
  --cat-title: #fff;
  --cat-title-shadow: 2px 2px 0 #6a0d04;
  --cat-text: #f2f6ff;
  --cat-rule: 3px solid #f2cd37;
  --cat-link: #ffe680;
}

/* Gezelschapsspelletjes: green felt on a wooden game table */
.cat--spelletjes {
  --cat-bg: radial-gradient(ellipse at 50% 40%, #2e8152, #184a2f 80%);
  --cat-border: 6px ridge #8a5a2e;
  --cat-head: #00000030;
  --cat-title: #fff3c4;
  --cat-text: #eef7ee;
  --cat-rule: 2px dashed #ffffff30;
  --cat-link: #ffe39a;
}
.cat--spelletjes h2::after { content: '♠ ♥ ♦ ♣'; margin-left: auto; font-size: 12px; color: #ffffff80; }

/* DIY: a workshop pegboard with hazard-stripe edging */
.cat--diy {
  --cat-bg: radial-gradient(circle, #2a1a0e 2px, transparent 3px) 0 0 / 18px 18px, linear-gradient(#9a6a3c, #7d5530);
  --cat-border: 6px solid transparent;
  --cat-head: #00000045;
  --cat-title: #ffd84a;
  --cat-title-shadow: 2px 2px 0 #1a1c2c;
  --cat-text: #fff6ea;
  --cat-rule: 2px dashed #ffd84a66;
  --cat-link: #ffe680;
  --cat-frame-bg: #f4efe6; --cat-frame-border: 3px solid #1f6f3a;
  --cat-btn-bg: #ffd84a; --cat-btn-edge: #fff09a;
  border-image: repeating-linear-gradient(45deg, #ffd84a 0 10px, #1a1c2c 10px 20px) 6;
}

/* Altijd welkom: striped gift wrap with a gold edge */
.cat--altijd {
  --cat-bg: repeating-linear-gradient(45deg, #ffffff0a 0 12px, transparent 12px 24px), #6e1b26;
  --cat-border: 4px solid #f2cd37;
  --cat-head: #00000030;
  --cat-title: #ffe9a8;
  --cat-text: #fbecec;
  --cat-rule: 2px dashed #f2cd3766;
  --cat-link: #ffe680;
}

.item { display: grid; grid-template-columns: 110px 1fr; gap: 16px; padding: 16px 0; }
.item:last-child { border-bottom: 0; }
.item__img { width: 110px; height: 90px; display: grid; place-items: center; overflow: hidden; font-size: 40px;
  background: var(--cat-frame-bg, var(--paper)); border: var(--cat-frame-border, 3px solid var(--ink));
  border-radius: var(--cat-frame-radius, 0); box-shadow: var(--cat-frame-shadow, none); }
.cat .btn--gold { background: var(--cat-btn-bg, var(--gold)); border-color: var(--cat-btn-edge, #ffe6a8); color: var(--cat-btn-text, var(--ink)); }

/* Picture frames and buttons per topic */
.cat--hema {
  --cat-frame-bg: linear-gradient(160deg, #dfe4ec, #aeb6c3); --cat-frame-border: 3px ridge #c9d0db;
  --cat-btn-bg: #c9d0db; --cat-btn-edge: #eef1f6;
}
.cat--bushcraft {
  --cat-frame-bg: #ecdcab; --cat-frame-border: 3px dashed #6b4a2e;
  --cat-btn-bg: #d8b36a; --cat-btn-edge: #f0d9a0;
}
.cat--homelab {
  --cat-frame-bg: #0b1a0f; --cat-frame-border: 2px solid #39ff6a; --cat-frame-shadow: 0 0 8px #39ff6a66;
  --cat-btn-bg: #0d2414; --cat-btn-edge: #39ff6a; --cat-btn-text: #39ff6a;
}
.cat--maken {
  --cat-frame-bg: #1a5e36; --cat-frame-border: 3px solid #c8873a;
  --cat-btn-bg: #d99546; --cat-btn-edge: #f3b462;
}
.cat--smidse {
  --cat-frame-bg: radial-gradient(circle at 50% 120%, #ef7d5766, #2c2622 70%); --cat-frame-border: 3px solid #ef7d57; --cat-frame-shadow: 0 0 10px #ef7d5766;
  --cat-btn-bg: #ef7d57; --cat-btn-edge: #ffb08a;
}
.cat--lego {
  --cat-frame-bg: #f4f4f4; --cat-frame-border: 3px solid #c91a09;
  --cat-btn-bg: #f2cd37; --cat-btn-edge: #fff09a;
}
.cat--spelletjes {
  --cat-frame-bg: #fffaf0; --cat-frame-border: 3px solid #fff; --cat-frame-radius: 8px; --cat-frame-shadow: 3px 3px 0 #0000004d;
  --cat-btn-bg: #fff3c4; --cat-btn-edge: #fffbe8;
}
.cat--altijd {
  --cat-frame-bg: #fff1d6; --cat-frame-border: 3px solid #f2cd37;
}
/* Pixel-art category icons scale with the text like an emoji would. */
/* Icons get their own emoji font and a tight line box, so they centre on the pixel-font text
   instead of sitting on its baseline (the pixel font draws its letters high in the line). */
.icon { display: inline-flex; align-items: center; line-height: 1; font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif; }
.cat h2 { line-height: 1; }
/* Measured: the pixel font's letters centre at 43.5% of the line, emojis at ~55.5% and the sprites at 50%,
   so nudge the heading icons up to sit level with the letters. */
.cat h2 .icon { transform: translateY(-0.12em); }
.cat h2 .icon:has(svg) { transform: translateY(-0.1em); }
.icon svg { display: block; height: 1.1em; width: auto; aspect-ratio: var(--w) / var(--h); }
.cat--lego h2 .icon svg { filter: drop-shadow(1px 0 #fff) drop-shadow(-1px 0 #fff) drop-shadow(0 1px #fff) drop-shadow(0 -1px #fff); }

/* A photo replaces the emoji inside the same cream, black-bordered frame. */
.item__img { position: relative; }
.item__img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; }
.item__img.has-pic img { opacity: 1; }
.item__img.has-pic span { display: none; }
.item h3 { margin: 0 0 4px; font-size: 17px; color: #fff; }
.item p { margin: 0 0 8px; }
.item .btn { display: inline-block; }
/* "Ik koop dit!": a pixel gift box that hops when you point at the button */
.item .btn--claim { display: inline-flex; align-items: center; gap: 10px; padding: 8px 14px 8px 10px; font-size: 10px; }
.btn--claim svg { width: 24px; height: 22px; filter: drop-shadow(1px 1px 0 #1a1c2c80); }
.btn--claim:hover svg { animation: hop .5s steps(2) infinite alternate; }
@keyframes hop { to { transform: translateY(-3px); } }
.meta { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 6px; font-size: 13px; }
.meta dt { display: inline; font-weight: bold; }
.meta dd { display: inline; margin: 0 0 0 4px; }
.shops { font-size: 13px; }
.is-claimed { opacity: .55; }
.stamp { display: inline-block; padding: 6px 8px; font: 10px var(--pixel); color: #ff6b6b; border: 3px solid #ff6b6b; transform: rotate(-3deg); }
.always { font: 9px/1.6 var(--pixel); color: var(--gold); }
.mine { font: 9px/1.6 var(--pixel); color: #9be564; }

/* The footer is a LEGO wall (bricks are built in sprites.js). */
.lego { display: flex; flex-direction: column-reverse; margin: -12px -12px 12px; padding-top: 5px; }
.lego__row { display: flex; }
.brick {
  position: relative; flex: var(--studs); height: 16px; background: var(--c);
  box-shadow: inset 0 3px #ffffff40, inset -3px -3px #00000040;
}
.brick::before {
  content: ''; position: absolute; left: 0; right: 0; top: -5px; height: 5px;
  background: linear-gradient(90deg, transparent 22%, var(--c) 22% 78%, transparent 78%) 0 0 / calc(100% / var(--studs)) 100%;
  filter: brightness(1.15);
}
.lego:not(.is-building) .brick { opacity: 0; }
.lego.is-building .brick { animation: drop .25s calc(var(--i) * 25ms) both; }
@keyframes drop { from { opacity: 0; transform: translateY(-30px); } to { opacity: 1; transform: none; } }

.footer { padding: 12px; text-align: center; font-size: 12px; color: #a99; }

/* ---------- Claim dialog ---------- */
dialog { width: calc(100% - 32px); max-width: 380px; padding: 0; background: var(--grey); border: 4px outset #ddd; }
dialog::backdrop { background: #000a; }
dialog h2 { margin: 0; padding: 6px 10px; font-size: 10px; color: #fff; background: linear-gradient(90deg, #000080, #1084d0); }
dialog form > :not(h2) { margin: 12px; }
dialog label { display: block; font-size: 13px; font-weight: bold; }
dialog input { display: block; width: 100%; margin-top: 4px; padding: 6px; font: inherit; border: 2px inset #eee; }
.error { min-height: 1em; font-size: 13px; color: #b00; }
.dialog__actions { display: flex; justify-content: flex-end; gap: 8px; }

/* ---------- Small screens ---------- */
@media (max-width: 720px) {
  .site { margin: 0; border-width: 0 0 4px; }
  .scene { --unit: 2px; height: 180px; }
  .title { top: 14px; font-size: 13px; }
  .title small { font-size: 8px; }
  .layout { grid-template-columns: 1fr; padding: 12px; }
  .nav { flex-direction: row; flex-wrap: wrap; }
  .widgets { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .mine-box { grid-column: 1 / -1; }
  .item { grid-template-columns: 72px 1fr; gap: 12px; }
  .item__img { width: 72px; height: 64px; font-size: 28px; }
}

/* Slightly bigger on computer screens. */
@media (min-width: 1100px) { :root { --zoom: 1.1; } body { zoom: var(--zoom); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before { animation: none !important; }
  .lego .brick { opacity: 1 !important; }
}
