/* NoZLan 2026 — dark cyberpunk portfolio.
   Hand-written, no build step. Mobile first.

   The palette is measured from the NoZLan banner artwork: near-black with a
   purple/blue nebula, olive hexagons, and small glowing voxels in cyan,
   magenta and amber. Orange stays the brand colour; the rest are accents. */

:root {
  --bg:         #0b0c0e;
  --surface:    #15171a;
  --surface-2:  #1c1f23;
  --line:       #26292e;
  --ink:        #e8e9ea;
  --ink-dim:    #9aa0a6;
  --ink-faint:  #6b7178;

  --accent:     #ff9900;
  --accent-dim: #c47500;
  --amber:      #e69e5a;
  --cyan:       #4fd6e8;
  --magenta:    #e8408a;
  --violet:     #7b5cff;

  --nebula-deep: #120f12;
  --nebula-mid:  #403948;
  --nebula-blue: #59698f;
  --hex:         #8a7d3a;

  --radius: 10px;
  --maxw:   1360px;

  /* Honeycomb lattice: one hexagon plus the vertical spur below it, which
     meets the next tile's top vertex so it repeats seamlessly both ways.
     36 x 62 rather than the geometrically exact 34.64 x 60 — on whole pixels
     the strokes stay crisp, where before they straddled two pixels and
     anti-aliasing turned them into what looked like dotted lines. */
  --hex-tile-w: 36px;
  --hex-tile-h: 62px;
  --hexagons: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='62' viewBox='0 0 36 62'%3E%3Cg fill='none' stroke='%238a7d3a' stroke-width='1.5' stroke-linejoin='round'%3E%3Cpath d='M18 1 L35 11 L35 31 L18 41 L1 31 L1 11 Z'/%3E%3Cpath d='M18 41 L18 61'/%3E%3C/g%3E%3C/svg%3E");
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  /* The margin starfield is positioned against this, so it spans the whole
     document and scrolls along with the content. */
  position: relative;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.65 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a   { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 18px; }
.narrow { max-width: 760px; }

/* Shared decorative layers -------------------------------------------- */

.nebula { position: relative; overflow: hidden; isolation: isolate; }
.nebula::before,
.nebula::after { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: -1; }
.nebula::before {
  background: radial-gradient(130% 190% at 14% 130%,
              var(--nebula-blue) 0%, var(--nebula-mid) 32%, var(--nebula-deep) 62%, var(--bg) 85%);
  opacity: .9;
}
.nebula::after { background-image: var(--hexagons); background-size: var(--hex-tile-w) var(--hex-tile-h); opacity: .35; }

/* Floating voxels — the little glowing squares from the artwork. */
.voxels { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 0; }
.voxels i {
  position: absolute; display: block; width: 5px; height: 5px;
  background: var(--cyan); box-shadow: 0 0 8px currentColor; color: var(--cyan);
  animation: drift 14s ease-in-out infinite;
}
/* Colour and size cycle on a 4/3/5 rhythm so the pattern never repeats
   visibly, however many particles a section contains. */
.voxels i:nth-child(4n+2) { background: var(--magenta); color: var(--magenta); }
.voxels i:nth-child(4n+3) { background: var(--amber);   color: var(--amber); }
.voxels i:nth-child(4n+4) { background: var(--violet);  color: var(--violet); }

.voxels i:nth-child(3n+2) { width: 4px; height: 4px; }
.voxels i:nth-child(3n+3) { width: 3px; height: 3px; }

.voxels i:nth-child(5n+1) { animation-duration: 14s; animation-delay:  -2s; }
.voxels i:nth-child(5n+2) { animation-duration: 19s; animation-delay:  -7s; }
.voxels i:nth-child(5n+3) { animation-duration: 23s; animation-delay: -11s; }
.voxels i:nth-child(5n+4) { animation-duration: 17s; animation-delay: -15s; }
.voxels i:nth-child(5n+5) { animation-duration: 26s; animation-delay:  -4s; }

@keyframes drift {
  0%, 100% { transform: translate3d(0, 0, 0);        opacity: .35; }
  50%      { transform: translate3d(0, -14px, 0);    opacity: 1;   }
}

/* Starfield in the empty margins beside the 1360px content column.
   Drawn as repeating gradients rather than elements: the density then stays
   even however long the page is, and because it's absolutely positioned over
   the whole document it scrolls with the content instead of sticking to the
   screen. Only shown once the margins are wide enough to be worth filling. */
.voxels-page {
  position: absolute; top: 0; bottom: 0; left: 0; right: 0;
  z-index: -1; display: none; pointer-events: none; overflow: hidden;
}
@media (min-width: 1560px) { .voxels-page { display: block; } }

/* Each layer is exactly as wide as the margin, so it can only repeat downwards
   — one thin column of dots per layer, never a grid. The columns sit at
   irregular percentages across the margin and their vertical spacings are
   primes, so no two ever line up and the repeat is thousands of pixels away. */
.voxels-page::before,
.voxels-page::after {
  content: ""; position: absolute; top: 0; bottom: 0;
  width: calc(50% - 680px);
  background-repeat: repeat-y;
  background-image:
    radial-gradient(circle at  6%  37px, var(--cyan)    0 1.6px, transparent 1.7px),
    radial-gradient(circle at 11% 268px, var(--cyan)    0 1.1px, transparent 1.2px),
    radial-gradient(circle at 19% 211px, var(--magenta) 0 1.2px, transparent 1.3px),
    radial-gradient(circle at 27%  88px, var(--amber)   0 1.4px, transparent 1.5px),
    radial-gradient(circle at 23% 401px, var(--amber)   0 1.0px, transparent 1.1px),
    radial-gradient(circle at 41% 342px, var(--violet)  0 1.1px, transparent 1.2px),
    radial-gradient(circle at 52% 149px, var(--cyan)    0 1.9px, transparent 2.0px),
    radial-gradient(circle at 57% 512px, var(--cyan)    0 1.2px, transparent 1.3px),
    radial-gradient(circle at 63% 476px, var(--violet)  0 1.3px, transparent 1.4px),
    radial-gradient(circle at 74% 263px, var(--magenta) 0 1.5px, transparent 1.6px),
    radial-gradient(circle at 70% 690px, var(--magenta) 0 1.0px, transparent 1.1px),
    radial-gradient(circle at 86% 604px, var(--amber)   0 1.0px, transparent 1.1px),
    radial-gradient(circle at 93% 418px, var(--cyan)    0 1.2px, transparent 1.3px),
    radial-gradient(circle at 97% 155px, var(--violet)  0 1.4px, transparent 1.5px);
  /* Pairs share a tile height, so the second dot lands at an odd fraction of
     the first one's spacing and the column stops reading as evenly stepped. */
  background-size:
    100% 389px, 100% 389px, 100% 457px, 100% 523px, 100% 523px,
    100% 601px, 100% 677px, 100% 677px, 100% 743px, 100% 829px,
    100% 829px, 100% 907px, 100% 971px, 100% 971px;
  opacity: .55;
  animation: starfield 150s linear infinite;
}
.voxels-page::before { left: 0; }
/* Mirrored, slower, and started well into its cycle. Without that head start
   the two margins line up at the same heights on load, which is visible even
   across the full width of the page. Because each layer's tile is a different
   size, one delay shifts all fourteen by different amounts. */
.voxels-page::after {
  right: 0; transform: scaleX(-1);
  animation-duration: 205s; animation-delay: -87s;
}

/* Every layer travels exactly one tile height, so each loops seamlessly — and
   because the tiles differ, the columns drift at nine different speeds. */
@keyframes starfield {
  from { background-position:
           0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0,
           0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0; }
  to   { background-position:
           0 389px, 0 389px, 0 457px, 0 523px, 0 523px,
           0 601px, 0 677px, 0 677px, 0 743px, 0 829px,
           0 829px, 0 907px, 0 971px, 0 971px; }
}

/* header --------------------------------------------------------------- */

.site-head {
  position: sticky; top: 0; z-index: 50;
  background: rgba(11,12,14,.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(255,153,0,.14);
}
.site-head::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(120% 180% at 12% 140%, rgba(89,105,143,.55) 0%, rgba(64,57,72,.35) 38%, transparent 70%),
    var(--hexagons);
  background-size: auto, var(--hex-tile-w) var(--hex-tile-h);
  opacity: .5;
}
.head-inner {
  position: relative; z-index: 1;
  max-width: var(--maxw); margin: 0 auto; padding: 0 18px;
  display: flex; align-items: center; gap: 18px; min-height: 66px;
}

.logo { display: flex; align-items: center; flex: 0 0 auto; }
.logo:hover { text-decoration: none; }
/* Stacked tight to wide: a near-white core, warming through amber into the
   orange bloom. Going straight to orange is what made it look merely tinted. */
.logo img {
  filter: drop-shadow(0 0  1px rgba(255,248,235,.5))
          drop-shadow(0 0  3px rgba(255,232,195,.42))
          drop-shadow(0 0  8px rgba(255,200,120,.38))
          drop-shadow(0 0 18px rgba(255,163,30,.32))
          drop-shadow(0 0 38px rgba(255,153,0,.22))
          drop-shadow(0 0 72px rgba(255,145,0,.13));
  transition: filter .3s ease;
  /* A sign that's never quite steady. Slow enough that you only notice it
     if you look straight at it. */
  animation: sign-flicker 7s ease-in-out infinite;
}
.logo:hover img {
  filter: drop-shadow(0 0  1px rgba(255,252,245,.75))
          drop-shadow(0 0  4px rgba(255,240,215,.65))
          drop-shadow(0 0 10px rgba(255,210,140,.55))
          drop-shadow(0 0 24px rgba(255,170,45,.45))
          drop-shadow(0 0 50px rgba(255,153,0,.32))
          drop-shadow(0 0 92px rgba(255,145,0,.2));
}
@keyframes sign-flicker {
  0%, 100% { opacity: 1;   }
  47%      { opacity: .93; }
  52%      { opacity: 1;   }
}

/* Cut from the original full-resolution artwork, so it carries real
   transparency and sits flush to the bottom of the bar. */
.mascot {
  height: 66px; width: auto;
  align-self: flex-end; margin-bottom: -1px;
  pointer-events: none;
  filter: drop-shadow(0 0 18px rgba(255,153,0,.28));
}

.nav { display: flex; gap: 4px; align-items: center; }
.nav a {
  position: relative; color: var(--ink-dim); padding: 8px 12px;
  border-radius: 6px; font-size: 15px; white-space: nowrap;
}
/* Each section keeps its own neon colour, lit faintly and brought up on
   hover or when you're in that section. */
.nav a { --neon: var(--cyan); }
.nav a:nth-of-type(2) { --neon: var(--violet); }
.nav a:nth-of-type(3) { --neon: var(--magenta); }

/* Lit like real neon: a pale core with the colour bleeding outwards in three
   widening halos. Tinting the text itself down instead just looks like coloured
   text, which is what this used to do. */
.nav a {
  color: color-mix(in srgb, var(--neon) 78%, #fff);
  text-shadow:
    0 0  4px color-mix(in srgb, var(--neon) 90%, transparent),
    0 0 14px color-mix(in srgb, var(--neon) 60%, transparent),
    0 0 34px color-mix(in srgb, var(--neon) 32%, transparent);
  transition: color .2s ease, text-shadow .2s ease, background .2s ease;
}
.nav a:hover, .nav a.on {
  color: color-mix(in srgb, var(--neon) 30%, #fff);
  text-decoration: none;
  /* No background of any kind. Anything painted behind the text — flat fill or
     soft wash — outlines the link's box, and a neon tube has no box. The light
     itself carries the state. */
  text-shadow:
    0 0  4px #fff,
    0 0 12px var(--neon),
    0 0 28px var(--neon),
    0 0 58px color-mix(in srgb, var(--neon) 55%, transparent);
}
.nav a.on::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 2px; height: 2px;
  background: color-mix(in srgb, var(--neon) 55%, #fff); border-radius: 2px;
  box-shadow: 0 0 8px var(--neon), 0 0 20px var(--neon);
}

.search-mini { margin-left: auto; }
.search-mini input {
  background: rgba(21,23,26,.8); border: 1px solid var(--line); color: var(--ink);
  border-radius: 999px; padding: 7px 14px; font-size: 14px; width: 150px;
  transition: width .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.search-mini input:focus {
  outline: none; border-color: var(--cyan); width: 210px;
  box-shadow: 0 0 0 1px rgba(79,214,232,.3), 0 0 16px rgba(79,214,232,.22);
}

.menu { margin-left: auto; }
.menu summary {
  list-style: none; cursor: pointer; padding: 8px 10px; border-radius: 6px;
  color: var(--ink-dim); font-size: 22px; line-height: 1;
}
.menu summary::-webkit-details-marker { display: none; }
.menu[open] summary { color: var(--accent); }
.menu-panel {
  position: absolute; left: 0; right: 0; background: var(--surface);
  border-bottom: 1px solid var(--line); padding: 10px 18px 16px;
  display: flex; flex-direction: column; gap: 2px;
  box-shadow: 0 12px 30px rgba(0,0,0,.5);
}
.menu-panel a { padding: 11px 6px; color: var(--ink); font-size: 16px; }
.menu-panel form { margin-top: 8px; }
.menu-panel input {
  width: 100%; background: var(--bg); border: 1px solid var(--line);
  color: var(--ink); border-radius: 8px; padding: 10px 12px; font-size: 16px;
}

@media (max-width: 860px) { .nav-desktop, .mascot { display: none; } }
@media (min-width: 861px) { .menu { display: none; } .nav-desktop { display: flex; } }

/* homepage hero — the one place the neon goes full ---------------------- */

.hero {
  position: relative; overflow: hidden; isolation: isolate;
  border-bottom: 1px solid var(--line); margin-bottom: 30px;
  background: var(--bg);
}
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(120% 170% at 22% 120%,
              var(--violet) 0%, var(--nebula-blue) 22%, var(--nebula-mid) 45%,
              var(--nebula-deep) 68%, var(--bg) 88%);
  opacity: .82;
}
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image: var(--hexagons), repeating-linear-gradient(
      to bottom, rgba(255,255,255,.03) 0 1px, transparent 1px 3px);
  background-size: var(--hex-tile-w) var(--hex-tile-h), auto;
  opacity: .3;
  /* fade the lattice out towards the middle so the text stays clean */
  -webkit-mask-image: radial-gradient(120% 130% at 50% 60%, transparent 18%, #000 72%);
  mask-image: radial-gradient(120% 130% at 50% 60%, transparent 18%, #000 72%);
}

.hero-inner {
  position: relative; z-index: 3;
  max-width: var(--maxw); margin: 0 auto; padding: 46px 18px 40px;
  display: grid; gap: 18px; align-items: center;
  grid-template-columns: 1fr;
}
.hero h1 {
  margin: 0; font-size: clamp(28px, 6vw, 52px); font-weight: 600; letter-spacing: -.8px;
  text-shadow: 0 0 26px rgba(255,153,0,.35), 0 0 60px rgba(123,92,255,.25);
}
.hero h1 .glow { color: var(--accent); text-shadow: 0 0 18px rgba(255,153,0,.75); }
.hero p { margin: 10px 0 0; color: #c3c7cc; font-size: 16px; max-width: 52ch; }
.hero .hero-cta { margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap; }

.hero-art { position: relative; z-index: 2; justify-self: center; }
.hero-art img {
  width: 100%; max-width: 440px; height: auto;
  filter: drop-shadow(0 0 40px rgba(123,92,255,.45)) drop-shadow(0 0 16px rgba(255,153,0,.2));
}

@media (min-width: 900px) {
  .hero-inner { grid-template-columns: 1fr; padding: 58px 18px 52px; padding-right: 46%; }
  /* Anchored flush into the bottom-right corner, so where the artwork runs off
     the edge it reads as deliberate framing rather than a bad crop. */
  .hero-art {
    position: absolute; right: 0; bottom: 0; z-index: 2;
    width: 48%; max-width: 660px; justify-self: end;
  }
  .hero-art img { max-width: 100%; width: 100%; display: block; }
}

/* scrolling photo band ------------------------------------------------- */

.band {
  position: relative; overflow: hidden; width: 100%;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background: #06070a; margin-bottom: 34px;
}
/* soft fades at both edges so photos slide in and out instead of popping */
.band::before, .band::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 90px; z-index: 2;
  pointer-events: none;
}
.band::before { left: 0;  background: linear-gradient(to right, #06070a, transparent); }
.band::after  { right: 0; background: linear-gradient(to left,  #06070a, transparent); }

.band-track {
  display: flex; gap: 4px; width: max-content;
  animation: band-drift 120s linear infinite;
}
.band:hover .band-track { animation-play-state: paused; }

.band-item {
  flex: 0 0 auto; display: block; height: 210px; position: relative;
  border-radius: 4px; overflow: hidden;
}
.band-item img { height: 100%; width: auto; object-fit: cover; display: block; }
.band-item::after {
  content: ""; position: absolute; inset: 0; border-radius: 4px; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(79,214,232,.28);
  transition: box-shadow .25s ease;
}
.band-item:nth-child(4n+2)::after { box-shadow: inset 0 0 0 1px rgba(232,64,138,.28); }
.band-item:nth-child(4n+3)::after { box-shadow: inset 0 0 0 1px rgba(123,92,255,.28); }
.band-item:nth-child(4n+4)::after { box-shadow: inset 0 0 0 1px rgba(255,153,0,.26); }

.band-item:hover::after            { box-shadow: inset 0 0 0 2px var(--cyan),    0 0 24px rgba(79,214,232,.5); }
.band-item:nth-child(4n+2):hover::after { box-shadow: inset 0 0 0 2px var(--magenta), 0 0 24px rgba(232,64,138,.5); }
.band-item:nth-child(4n+3):hover::after { box-shadow: inset 0 0 0 2px var(--violet),  0 0 24px rgba(123,92,255,.5); }
.band-item:nth-child(4n+4):hover::after { box-shadow: inset 0 0 0 2px var(--accent),  0 0 24px rgba(255,153,0,.46); }

/* Track holds the list twice, so shifting by half its width loops seamlessly.
   Moves left-to-right: starts half-shifted and returns to zero. */
@keyframes band-drift {
  from { transform: translate3d(-50%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}
@media (max-width: 700px) { .band-item { height: 140px; } .band::before, .band::after { width: 46px; } }

/* photo grid ----------------------------------------------------------- */

.grid {
  display: grid; gap: 4px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr));
}
@media (min-width: 700px)  { .grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 6px; } }
@media (min-width: 1100px) { .grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); } }

.tile {
  position: relative; display: block; background: var(--surface);
  border-radius: 6px; overflow: hidden; aspect-ratio: 3/4;
  transition: box-shadow .25s ease;
}
.tile img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .45s cubic-bezier(.2,.7,.3,1);
}
.tile:hover img { transform: scale(1.04); }

/* Standing neon edge, cycling through the artwork's accent colours so a grid
   reads as a lit-up wall rather than a set of plain boxes. Kept low-opacity
   so it frames the photo instead of competing with it; hover lights it up. */
.tile::after {
  content: ""; position: absolute; inset: 0; border-radius: 6px; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(79,214,232,.30);
  transition: box-shadow .25s ease;
}
.tile:nth-child(4n+2)::after { box-shadow: inset 0 0 0 1px rgba(232,64,138,.30); }
.tile:nth-child(4n+3)::after { box-shadow: inset 0 0 0 1px rgba(123,92,255,.30); }
.tile:nth-child(4n+4)::after { box-shadow: inset 0 0 0 1px rgba(255,153,0,.28); }

.tile:hover::after            { box-shadow: inset 0 0 0 2px var(--cyan),    0 0 24px rgba(79,214,232,.45); }
.tile:nth-child(4n+2):hover::after { box-shadow: inset 0 0 0 2px var(--magenta), 0 0 24px rgba(232,64,138,.45); }
.tile:nth-child(4n+3):hover::after { box-shadow: inset 0 0 0 2px var(--violet),  0 0 24px rgba(123,92,255,.45); }
.tile:nth-child(4n+4):hover::after { box-shadow: inset 0 0 0 2px var(--accent),  0 0 24px rgba(255,153,0,.42); }

/* convention cards ----------------------------------------------------- */

.cards {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
}
.card {
  position: relative; display: block; border-radius: var(--radius);
  overflow: hidden; background: var(--surface); aspect-ratio: 16/10;
  transition: box-shadow .25s ease;
}
.card > img {
  width: 100%; height: 100%; object-fit: cover; opacity: .72;
  transition: opacity .3s, transform .5s ease;
}
.card:hover > img { opacity: 1; transform: scale(1.05); }
.card:hover { text-decoration: none; }

/* Same cycling neon edge as the photo tiles, so a page of convention cards
   reads as one lit-up wall rather than a different component. */
.card::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius);
  pointer-events: none; z-index: 3; transition: box-shadow .25s ease;
  box-shadow: inset 0 0 0 1px rgba(79,214,232,.30);
}
.card:nth-child(4n+2)::after { box-shadow: inset 0 0 0 1px rgba(232,64,138,.30); }
.card:nth-child(4n+3)::after { box-shadow: inset 0 0 0 1px rgba(123,92,255,.30); }
.card:nth-child(4n+4)::after { box-shadow: inset 0 0 0 1px rgba(255,153,0,.28); }

.card:hover::after            { box-shadow: inset 0 0 0 2px var(--cyan),    0 0 26px rgba(79,214,232,.45); }
.card:nth-child(4n+2):hover::after { box-shadow: inset 0 0 0 2px var(--magenta), 0 0 26px rgba(232,64,138,.45); }
.card:nth-child(4n+3):hover::after { box-shadow: inset 0 0 0 2px var(--violet),  0 0 26px rgba(123,92,255,.45); }
.card:nth-child(4n+4):hover::after { box-shadow: inset 0 0 0 2px var(--accent),  0 0 26px rgba(255,153,0,.42); }

/* Article and gallery cards get the same cycle. */
.post {
  position: relative;
}
.post::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius);
  pointer-events: none; transition: box-shadow .25s ease;
  box-shadow: inset 0 0 0 1px rgba(79,214,232,.22);
}
.post:nth-child(4n+2)::after { box-shadow: inset 0 0 0 1px rgba(232,64,138,.22); }
.post:nth-child(4n+3)::after { box-shadow: inset 0 0 0 1px rgba(123,92,255,.22); }
.post:nth-child(4n+4)::after { box-shadow: inset 0 0 0 1px rgba(255,153,0,.22); }

.post:hover::after            { box-shadow: inset 0 0 0 2px var(--cyan),    0 0 22px rgba(79,214,232,.35); }
.post:nth-child(4n+2):hover::after { box-shadow: inset 0 0 0 2px var(--magenta), 0 0 22px rgba(232,64,138,.35); }
.post:nth-child(4n+3):hover::after { box-shadow: inset 0 0 0 2px var(--violet),  0 0 22px rgba(123,92,255,.35); }
.post:nth-child(4n+4):hover::after { box-shadow: inset 0 0 0 2px var(--accent),  0 0 22px rgba(255,153,0,.35); }
/* hexagon corner marker */
.card::before {
  content: ""; position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 15px; height: 26px; pointer-events: none; opacity: .55;
  background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='26' viewBox='0 0 18 31'%3E%3Cpath d='M9 1l7.5 4.5v9L9 19l-7.5-4.5v-9z' fill='none' stroke='%23ff9900' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat;
}
.card-body {
  position: absolute; inset: auto 0 0 0; padding: 30px 14px 12px; z-index: 2;
  background: linear-gradient(transparent, rgba(0,0,0,.88));
}
.card-title { color: #fff; font-weight: 600; font-size: 16px; line-height: 1.3; }
.card-meta  { color: var(--ink-dim); font-size: 13px; margin-top: 3px;
              display: flex; align-items: center; gap: 6px; }
.flag { width: 16px !important; height: 11px !important; border-radius: 2px;
        display: inline-block; object-fit: cover; flex: 0 0 auto; }

/* articles ------------------------------------------------------------- */

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin: 36px 0 14px;
}
.section-head h2 {
  margin: 0; font-size: 19px; font-weight: 600; letter-spacing: -.2px;
  display: flex; align-items: center; gap: 9px;
}
.section-head h2::before {
  content: ""; width: 11px; height: 19px; flex: 0 0 auto;
  background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='19' viewBox='0 0 18 31'%3E%3Cpath d='M9 1l7.5 4.5v9L9 19l-7.5-4.5v-9z' fill='%23ff9900'/%3E%3C/svg%3E") no-repeat center;
}
.section-head a  { font-size: 14px; color: var(--ink-dim); }
.section-head a:hover { color: var(--accent); }

.posts { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.post {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column;
  transition: border-color .22s ease, box-shadow .22s ease;
}
.post:hover { text-decoration: none; }
.post-thumb { aspect-ratio: 16/9; background: var(--surface-2); overflow: hidden; }
/* Same treatment as the convention cards: held back until you point at it. */
.post-thumb img {
  width: 100%; height: 100%; object-fit: cover; opacity: .72;
  transition: opacity .3s ease, transform .5s ease;
}
.post:hover .post-thumb img { opacity: 1; transform: scale(1.05); }
.post-body { padding: 13px 15px 16px; }
.post h3 { margin: 0 0 5px; font-size: 16px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.post p  { margin: 0; color: var(--ink-dim); font-size: 14px; }
.post .meta { color: var(--ink-faint); font-size: 12.5px; margin-top: 9px; }

.prose { font-size: 17px; line-height: 1.75; }
.prose h2 { font-size: 22px; margin: 32px 0 10px; }
.prose p  { margin: 0 0 18px; }
.prose img { border-radius: var(--radius); margin: 22px 0; }
.prose a { text-decoration: underline; }
.prose blockquote {
  margin: 22px 0; padding: 12px 18px; border-left: 3px solid var(--accent);
  background: var(--surface); color: var(--ink-dim); border-radius: 0 8px 8px 0;
  box-shadow: -6px 0 18px rgba(255,153,0,.1);
}
.prose .half, .prose .full { margin-bottom: 0; }
.prose .half > p:last-child, .prose .full > p:last-child { margin-bottom: 18px; }
.prose figure { margin: 22px 0; }
.embed { position: relative; padding-bottom: 56.25%; height: 0; margin: 22px 0; }
.embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: var(--radius); }

/* Foto's in de tekst. De leeskolom is smal; een foto mag daarbuiten treden,
   want daar gaat deze site over. */
.prose .md-photo { margin: 28px calc(-1 * clamp(0px, 4vw, 60px)); }
.prose .md-photo img { margin: 0; width: 100%; }
.prose .md-photo figcaption {
  margin-top: 8px; font-size: 14px; color: var(--ink-dim); text-align: center;
}
.prose .md-gallery { margin: 28px calc(-1 * clamp(0px, 6vw, 90px)); }
.prose .md-missing { color: var(--magenta); font-size: 14px; }
.prose ul, .prose ol { margin: 0 0 18px; padding-left: 22px; }
.prose li { margin-bottom: 6px; }
.prose h3 { font-size: 19px; margin: 26px 0 8px; }
.prose code {
  background: var(--surface-2); padding: 2px 6px; border-radius: 4px;
  font-size: .9em; font-family: ui-monospace, Consolas, monospace;
}
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 32px 0; }

.page-title { font-size: clamp(24px, 4vw, 36px); font-weight: 600; margin: 26px 0 6px; letter-spacing: -.4px; }
.page-sub   { color: var(--ink-dim); margin: 0 0 24px; font-size: 15px; }

/* photo page ----------------------------------------------------------- */

.photo-stage {
  background: #000; display: flex; align-items: center; justify-content: center;
  min-height: 50vh; border-bottom: 1px solid var(--line);
  box-shadow: inset 0 -40px 80px -40px rgba(123,92,255,.3);
}
.photo-stage img { max-height: 82vh; width: auto; object-fit: contain; }

.tags { display: flex; flex-wrap: wrap; gap: 7px; margin: 14px 0; }
.tag {
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-dim);
  padding: 5px 11px; border-radius: 999px; font-size: 13.5px;
  transition: border-color .2s, color .2s, box-shadow .2s;
}
.tag:hover { color: var(--ink); border-color: var(--cyan); text-decoration: none;
             box-shadow: 0 0 14px rgba(79,214,232,.25); }
.tag.location { border-color: var(--accent-dim); color: var(--accent); }
.tag.group    { border-color: #6d3a3a; }
.tag.character{ border-color: #6d3a5c; }
.tag.artist   { border-color: #3a6d47; }

/* pagination ----------------------------------------------------------- */

.pager { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin: 34px 0 46px; }
.pager a, .pager span {
  min-width: 40px; text-align: center; padding: 8px 11px; border-radius: 7px;
  border: 1px solid var(--line); color: var(--ink-dim); font-size: 14px;
}
.pager a:hover { border-color: var(--cyan); color: var(--ink); text-decoration: none;
                 box-shadow: 0 0 14px rgba(79,214,232,.22); }
.pager .on { background: var(--accent); border-color: var(--accent); color: #14100a;
             font-weight: 600; box-shadow: 0 0 18px rgba(255,153,0,.4); }
.pager .gap { border: 0; }

/* footer --------------------------------------------------------------- */

.site-foot {
  position: relative; overflow: hidden; isolation: isolate;
  margin-top: 70px; border-top: 1px solid var(--line);
  box-shadow: 0 -1px 0 rgba(255,153,0,.14);
}
.site-foot::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(110% 200% at 82% 130%,
              var(--nebula-blue) 0%, var(--nebula-mid) 30%, var(--nebula-deep) 60%, var(--bg) 84%);
  opacity: .85;
}
.site-foot::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image: var(--hexagons); background-size: var(--hex-tile-w) var(--hex-tile-h); opacity: .3;
}

.foot-inner {
  position: relative; z-index: 3;
  max-width: var(--maxw); margin: 0 auto; padding: 30px 18px 20px;
  display: grid; gap: 22px; grid-template-columns: 1fr;
}
/* Left unlit on purpose: the glowing sign belongs at the top of the page,
   and repeating it down here only competes with it. */
.foot-brand img { height: 30px; width: auto; filter: drop-shadow(0 0 14px rgba(255,153,0,.3)); }
.foot-brand p { color: var(--ink-dim); font-size: 14px; margin: 12px 0 0; max-width: 42ch; }

.foot-cols { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
.foot-cols h3 {
  margin: 0 0 9px; font-size: 12.5px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent);
}
.foot-cols ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.foot-cols a { color: var(--ink-dim); font-size: 14.5px; }
.foot-cols a:hover { color: var(--ink); text-decoration: none; }

.foot-art {
  position: absolute; right: 12px; bottom: 0; z-index: 2;
  height: 236px; width: auto; pointer-events: none; opacity: .95;
  filter: drop-shadow(0 0 30px rgba(89,105,143,.5));
}
@media (max-width: 1000px) { .foot-art { height: 180px; opacity: .35; right: -20px; } }
@media (max-width: 640px)  { .foot-art { display: none; } }

.foot-base {
  position: relative; z-index: 3;
  max-width: var(--maxw); margin: 0 auto; padding: 14px 18px 30px;
  border-top: 1px solid rgba(255,255,255,.07);
  display: flex; flex-wrap: wrap; gap: 10px 18px; justify-content: space-between;
  color: var(--ink-faint); font-size: 13px;
}
.foot-base a { color: var(--ink-dim); }

@media (min-width: 780px) {
  .foot-inner { grid-template-columns: 1.1fr 1.4fr; gap: 36px; padding: 34px 18px 22px; }
}
/* Keep the link columns clear of the illustration on wide screens. */
@media (min-width: 1001px) {
  .foot-inner { padding-right: 300px; }
}

/* lightbox ------------------------------------------------------------- */

dialog.lightbox {
  border: 0; padding: 0; background: rgba(0,0,0,.96); color: var(--ink);
  max-width: 100vw; max-height: 100vh; width: 100vw; height: 100vh;
}
dialog.lightbox::backdrop { background: rgba(0,0,0,.9); }
.lb-stage { display: flex; align-items: center; justify-content: center; height: 100%; }
.lb-stage img { max-width: 96vw; max-height: 88vh; width: auto; height: auto; object-fit: contain; }
.lb-close, .lb-prev, .lb-next {
  position: fixed; background: rgba(20,22,26,.75); border: 1px solid var(--line);
  color: var(--ink); border-radius: 999px; cursor: pointer;
  width: 46px; height: 46px; font-size: 20px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.lb-close { top: 16px; right: 16px; }
.lb-prev  { left: 14px;  top: 50%; transform: translateY(-50%); }
.lb-next  { right: 14px; top: 50%; transform: translateY(-50%); }
.lb-close:hover, .lb-prev:hover, .lb-next:hover {
  border-color: var(--cyan); color: var(--cyan); box-shadow: 0 0 18px rgba(79,214,232,.3);
}
.lb-bar {
  position: fixed; left: 0; right: 0; bottom: 0; padding: 12px 18px;
  display: flex; gap: 14px; align-items: center;
  background: linear-gradient(transparent, rgba(0,0,0,.85)); font-size: 14px;
}
/* Counter hard left, the two actions together on the right. */
.lb-bar .lb-count { margin-right: auto; }
.lb-bar a { white-space: nowrap; }
.lb-dl {
  border: 1px solid var(--accent); border-radius: 999px; padding: 5px 14px;
  transition: background .2s ease, box-shadow .2s ease;
}
.lb-dl:hover {
  background: rgba(255,153,0,.14); text-decoration: none;
  box-shadow: 0 0 16px rgba(255,153,0,.3);
}

/* misc ----------------------------------------------------------------- */

.notice {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px; margin: 20px 0;
}
.adult-gate { text-align: center; padding: 46px 18px; }
.adult-gate .tile-blur { filter: blur(26px); }

.empty { color: var(--ink-faint); padding: 40px 0; text-align: center; }
.empty img { height: 190px; width: auto; margin: 0 auto 16px; opacity: .8; }

.btn {
  display: inline-block; background: var(--accent); color: #14100a;
  padding: 10px 20px; border-radius: 8px; font-weight: 600; border: 0;
  cursor: pointer; font-size: 15px;
  box-shadow: 0 0 20px rgba(255,153,0,.3);
}
.btn:hover { background: #ffa726; text-decoration: none; box-shadow: 0 0 28px rgba(255,153,0,.45); }
.btn-quiet {
  background: rgba(21,23,26,.7); color: var(--ink); border: 1px solid var(--line);
  box-shadow: none;
}
.btn-quiet:hover { background: var(--surface-2); border-color: var(--cyan);
                   box-shadow: 0 0 18px rgba(79,214,232,.22); }

input[type=text], input[type=email], input[type=search], input[type=password] {
  background: var(--surface); border: 1px solid var(--line); color: var(--ink);
  border-radius: 8px; padding: 11px 13px; font-size: 16px; width: 100%;
}
input:focus { outline: none; border-color: var(--cyan);
              box-shadow: 0 0 0 1px rgba(79,214,232,.25); }

/* Everything decorative stops for people who ask for less motion. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .voxels { display: none; }
  /* The starfield holds still rather than vanishing — it never moved much
     anyway, and the empty margins look bare without it. */
  .voxels-page::before, .voxels-page::after { opacity: .32; }
}
