/* ============================================================
   Leo Zhou · portfolio
   Horizontal rooms on a sliding track. One hobby per room.
   ============================================================ */

:root {
  --ink: #221c14;
  --paper: #fff6e5;
  --hero-bg: #ffe9b3;
  --geo-bg: #d7ecc8;
  --piste-bg: #fdfbf5;
  --chess-bg: #f3e3c3;
  --ski-bg: #cfe7f7;
  --lego-bg: #ffd23f;
  --arena-bg: #2e6db4;
  --stage-bg: #2b1c33;

  --red: #e6392f;
  --blue: #2b6bd9;
  --green: #2e9e5b;
  --yellow: #f2b705;
  --purple: #7b4bd8;
  --stage-ink: #ffe9c9;

  --border: 3px solid var(--ink);
  --shadow: 6px 6px 0 var(--ink);
  --radius: 16px;
  --font-display: "Bricolage Grotesque", sans-serif;
  --font-body: "Space Grotesk", sans-serif;
  --font-mono: "JetBrains Mono", monospace;
  --font-cr: "Lilita One", var(--font-display);
  --font-brick: "Shojumaru", var(--font-display);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.55;
  overflow: hidden;
}
/* film grain over everything */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 90; pointer-events: none;
  opacity: 0.05; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

::selection { background: var(--ink); color: var(--hero-bg); }

.mono { font-family: var(--font-mono); font-size: 0.8rem; }
strong { font-weight: 700; }
code { font-family: var(--font-mono); background: rgba(34,28,20,0.1); padding: 0.05em 0.35em; border-radius: 4px; font-size: 0.85em; }
kbd {
  font-family: var(--font-mono); font-size: 0.72rem;
  border: 2px solid currentColor; border-radius: 5px;
  padding: 0.05em 0.4em; margin: 0 0.1em;
  display: inline-block; line-height: 1.4;
}

h1, h2, h3 { font-family: var(--font-display); line-height: 1.02; font-weight: 800; }
h2 { font-size: clamp(2rem, 4vw, 3.2rem); letter-spacing: -0.02em; }
h3 { font-size: 1.2rem; }

/* ---------- world / track / rooms ---------- */
.world { width: 100vw; height: 100svh; overflow: hidden; }
.track {
  display: flex; height: 100%; width: 100%;
  transition: transform 0.65s cubic-bezier(0.77, 0, 0.18, 1);
  will-change: transform;
}
.room {
  position: relative;
  flex: 0 0 100%;
  height: 100svh;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
}
.room::-webkit-scrollbar { display: none; }

/* shown only while a room still has content below the fold */
.scroll-cue {
  position: fixed; z-index: 6;
  right: clamp(0.9rem, 3.5vw, 2.6rem); bottom: 1.15rem;
  background: #fffdf5; border: var(--border); border-radius: 999px;
  box-shadow: 3px 3px 0 var(--ink);
  padding: 0.34rem 0.8rem; font-size: 0.68rem; font-weight: 700;
  opacity: 0; pointer-events: none; transition: opacity 0.25s ease;
}
.scroll-cue.show { opacity: 1; animation: cue-bob 1.7s ease-in-out infinite; }
@keyframes cue-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(4px); } }

.room-inner {
  position: relative; z-index: 2;
  min-height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: 5.2rem clamp(1.2rem, 5vw, 5rem) 3.4rem;
  max-width: 1300px; margin: 0 auto;
}
.room-head { max-width: 680px; margin-bottom: 1.6rem; }
.kicker { font-weight: 700; margin-bottom: 0.6rem; opacity: 0.75; }
.blurb { margin-top: 0.7rem; font-size: 1.02rem; }

/* faded per-room motifs */
.motif { position: absolute; pointer-events: none; color: var(--ink); }
.motif-epees {
  width: min(70vmin, 560px); right: -4%; top: 12%;
  opacity: 0.07; transform: rotate(8deg);
}
.r-piste::before {
  content: "TOUCHÉ"; position: absolute; z-index: 0;
  right: -2%; bottom: 4%;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(6rem, 16vw, 15rem); letter-spacing: -0.02em;
  color: transparent; -webkit-text-stroke: 2px rgba(230, 57, 47, 0.12);
  transform: rotate(-4deg);
}
.r-chess::before {
  content: "♞"; position: absolute; z-index: 0;
  left: -4%; bottom: -12%;
  font-size: clamp(20rem, 55vmin, 34rem); line-height: 1;
  color: rgba(34, 28, 20, 0.06);
  transform: rotate(-10deg);
}

/* ---------- nav ---------- */
#nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.75rem clamp(1rem, 3vw, 2.5rem);
  background: rgba(255, 246, 229, 0.9);
  backdrop-filter: blur(10px);
  border-bottom: 3px solid var(--ink);
}
.nav-logo {
  font-family: var(--font-display); font-weight: 800; font-size: 1.35rem;
  color: var(--ink); text-decoration: none;
}
.nav-logo .blade { color: var(--red); font-style: italic; }
.nav-links { display: flex; gap: clamp(0.5rem, 1.6vw, 1.3rem); align-items: center; }
.nav-links a {
  color: var(--ink); text-decoration: none; font-weight: 700;
  border-bottom: 2px solid transparent;
}
.nav-links a:hover { border-bottom-color: var(--red); }
.nav-links a.active { border-bottom-color: var(--ink); }
.nav-cta {
  background: var(--ink); color: var(--paper) !important;
  padding: 0.25rem 0.8rem; border-radius: 999px; border-bottom: none !important;
}
.nav-cta:hover { background: var(--red); }
.progress { position: absolute; left: 0; right: 0; bottom: -3px; height: 3px; }
#progress-bar {
  display: block; height: 100%; width: 100%;
  background: var(--red);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.65s cubic-bezier(0.77, 0, 0.18, 1);
}

/* ---------- edges + dots ---------- */
.edge {
  position: fixed; top: 50%; transform: translateY(-50%); z-index: 49;
  width: 44px; height: 64px; border-radius: 12px;
  border: var(--border); background: rgba(255, 246, 229, 0.85);
  color: var(--ink); font-size: 1.6rem; font-weight: 700; cursor: pointer;
  box-shadow: 3px 3px 0 var(--ink);
  transition: transform 0.15s ease, opacity 0.3s ease;
  display: flex; align-items: center; justify-content: center;
  padding-bottom: 0.3rem;
}
.edge:hover { transform: translateY(calc(-50% - 2px)); }
.edge-l { left: 0.7rem; }
.edge-r { right: 0.7rem; }
.edge.off { opacity: 0; pointer-events: none; }

.dots {
  position: fixed; bottom: 1rem; left: 50%; transform: translateX(-50%);
  display: flex; gap: 8px; z-index: 50;
  background: rgba(255, 246, 229, 0.75); backdrop-filter: blur(6px);
  padding: 6px 10px; border-radius: 999px; border: 2px solid var(--ink);
}
.dot {
  width: 10px; height: 10px; border-radius: 50%;
  border: 2px solid var(--ink); background: transparent;
  cursor: pointer; padding: 0;
  transition: background 0.2s ease, transform 0.2s ease;
}
.dot.active { background: var(--ink); transform: scale(1.2); }

/* ---------- shared buttons ---------- */
.btn {
  display: inline-block; text-decoration: none; border-radius: 999px;
  padding: 0.65rem 1.4rem; font-weight: 700; font-size: 0.95rem;
  border: var(--border); color: var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 4px 4px 0 var(--ink);
  background: var(--paper); cursor: pointer;
  font-family: var(--font-body);
}
.btn:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--ink); }
.btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
.btn-solid { background: var(--red); color: #fff; }
.btn-big { font-size: 1.05rem; padding: 0.85rem 1.7rem; }
.btn-sm { font-size: 0.8rem; padding: 0.4rem 1rem; box-shadow: 3px 3px 0 var(--ink); }
.btn-stage { background: transparent; color: var(--stage-ink); border-color: var(--stage-ink); box-shadow: 4px 4px 0 rgba(255,233,201,0.35); }

/* ---------- hero ---------- */
.r-hero { background: var(--hero-bg); }
#field { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-inner {
  max-width: 1440px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  align-items: center;
  gap: 4rem;
}
.hero-copy { min-width: 0; }
.hero-name {
  font-size: 6rem;
  font-weight: 800; letter-spacing: 0;
  cursor: pointer; user-select: none; line-height: 0.95;
}
.hero-name span { display: inline-block; transition: transform 0.18s ease, color 0.18s ease; }
.hero-name:hover span { color: var(--red); }
.hero-name:hover span:nth-child(2n) { color: var(--blue); transform: translateY(-6px) rotate(-3deg); }
.hero-name:hover span:nth-child(3n) { color: var(--green); transform: translateY(4px) rotate(3deg); }
.hero-name:hover span:nth-child(5n) { color: var(--yellow); }
.hero-sub { max-width: 620px; font-size: 1.08rem; margin-top: 1rem; }
.hero-build { font-size: 1.05rem; margin-top: 0.35rem; min-height: 1.6em; }
.type { font-family: var(--font-mono); font-weight: 700; color: var(--blue); font-size: 0.95em; }
.caret { color: var(--red); animation: blink 1s steps(1) infinite; }
.hero-badges { display: flex; gap: 0.55rem; flex-wrap: wrap; margin-top: 1.3rem; }
.badge {
  font-weight: 700; border: var(--border); border-radius: 999px;
  padding: 0.25rem 0.8rem; box-shadow: 3px 3px 0 var(--ink);
  background: #fff; transform: rotate(-1deg);
}
.badge:nth-child(2n) { transform: rotate(1.4deg); }
.b-red { background: #ffd9d6; } .b-blue { background: #d6e4ff; }
.b-green { background: #d8f3e0; } .b-yellow { background: #fff1c2; }
.hero-actions { display: flex; gap: 0.9rem; margin-top: 1.7rem; flex-wrap: wrap; }
.hero-contact {
  display: flex; gap: 0.55rem; flex-wrap: wrap; align-items: center;
  margin-top: 0.9rem; font-size: 0.82rem; font-weight: 700;
}
.hero-contact a { border-bottom: 2px solid transparent; transition: border-color 0.15s, opacity 0.15s; }
.hero-contact a:hover { border-bottom-color: currentColor; }
.hero-contact span { opacity: 0.45; }
.hero-photo {
  position: relative; z-index: 3;
  transform: rotate(4deg);
  width: 100%;
  background: #fffdf5; border: var(--border);
  box-shadow: var(--shadow); padding: 11px 11px 0;
  margin: 0;
}
.hero-photo::before {
  content: ""; position: absolute; top: -14px; left: 50%;
  width: 96px; height: 26px; transform: translateX(-50%) rotate(-3deg);
  background: rgba(230, 57, 47, 0.35);
  border: 1px solid rgba(230, 57, 47, 0.5);
}
.hero-photo img {
  width: 100%; display: block; aspect-ratio: 3 / 4; object-fit: cover;
  border: 2px solid var(--ink);
}
.hero-photo figcaption { text-align: center; padding: 0.55rem 0 0.6rem; font-weight: 700; }

/* ---------- origin / atlas ---------- */
.r-geo {
  background:
    repeating-radial-gradient(circle at 85% 15%, transparent 0 46px, rgba(34,28,20,0.045) 46px 48px),
    repeating-radial-gradient(circle at 10% 90%, transparent 0 60px, rgba(34,28,20,0.035) 60px 62px),
    var(--geo-bg);
}
.atlas-layout { display: grid; grid-template-columns: 2.1fr 1fr; gap: 1.6rem; align-items: start; }

/* geoguessr round frame */
.r-geo .room-head { margin-bottom: 0.9rem; }
.r-geo .room-inner { padding-top: 4.6rem; }
.gg-frame {
  border: var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
  background: #cfeef7;
}
.gg-view { position: relative; }
.gg-scene { display: block; width: 100%; height: auto; }
.gg-compass {
  position: absolute; top: 0.7rem; left: 50%; transform: translateX(-50%); z-index: 4;
  display: flex; gap: 0.9rem; align-items: center;
  background: rgba(20, 24, 30, 0.72); color: #cfd6df;
  border-radius: 999px; padding: 0.25rem 1rem;
  font-weight: 700; letter-spacing: 0.05em;
}
.gg-compass b { color: #fff; border-bottom: 2px solid #e6392f; }
.gg-mini {
  position: absolute; right: 0.8rem; bottom: 0.8rem; z-index: 5;
  width: 42%;
  background: rgba(255, 253, 245, 0.97);
  border: 2.5px solid var(--ink); border-radius: 10px;
  box-shadow: 4px 4px 0 rgba(34, 28, 20, 0.55);
  padding: 0.5rem 0.6rem 0.4rem;
  transition: width 0.32s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.gg-mini:hover { width: 92%; }
.gg-result {
  background: #14181e; color: #f2f4f7;
  padding: 0.5rem 1rem 0.6rem;
  border-top: 3px solid var(--ink);
}
.gg-bar {
  height: 9px; border-radius: 999px; overflow: hidden;
  background: rgba(255, 255, 255, 0.18);
}
#gg-fill {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #f2b705, #8fce39);
  border-radius: 999px;
}
.gg-result-line { margin-top: 0.35rem; }
.gg-result-line strong { color: #ffe08a; }
.gg-points { color: #8fce39; font-size: 1rem; }
.atlas-head {
  display: flex; justify-content: space-between; align-items: center;
  font-weight: 700; margin-bottom: 0.35rem; flex-wrap: wrap; gap: 0.4rem;
  font-size: 0.68rem;
}
.atlas-count { color: var(--green); font-size: 0.95rem; }
.atlas-legend { display: flex; align-items: center; gap: 0.35rem; opacity: 0.9; }
.chip { width: 11px; height: 11px; border-radius: 3px; display: inline-block; border: 2px solid var(--ink); }
.chip-been { background: var(--green); }
.chip-not { background: #e4ddc8; }
.worldmap { position: relative; }
.worldmap svg { width: 100%; height: auto; display: block; }
.worldmap path {
  fill: #e4ddc8; stroke: #fffdf5; stroke-width: 0.5;
  transition: fill 0.2s ease;
}
.worldmap path.visited { fill: var(--green); }
.worldmap path:hover { fill: #c9bfa4; }
.worldmap path.visited:hover { fill: #237a46; }
.worldmap .micro-pin { fill: var(--green); stroke: #fffdf5; stroke-width: 1; pointer-events: none; }
.worldmap .arc-line {
  fill: none; stroke: var(--red); stroke-width: 2.2;
  stroke-dasharray: 6 7; animation: dashMove 1.2s linear infinite;
  pointer-events: none;
}
.worldmap .arc-dot { fill: var(--red); stroke: #fffdf5; stroke-width: 1.4; pointer-events: none; }
.map-tip {
  position: absolute; z-index: 5; pointer-events: none;
  background: var(--ink); color: var(--paper);
  padding: 0.25rem 0.6rem; border-radius: 6px;
  font-weight: 700; white-space: nowrap;
  opacity: 0; transition: opacity 0.12s ease;
}
.map-tip.show { opacity: 1; }
.map-tip .tick { color: #7fe0a7; }
.geo-text p { margin-bottom: 0.9rem; font-size: 0.98rem; }
.geo-facts { list-style: none; display: grid; gap: 0.35rem; margin-top: 0.9rem; font-weight: 700; }
.bollard-card {
  margin: 1.1rem 0 0; max-width: 340px;
  background: #fffdf5; border: var(--border); border-radius: 10px;
  box-shadow: 4px 4px 0 var(--ink); padding: 8px 8px 0;
  transform: rotate(-1.2deg);
}
.bollard-card img {
  width: 100%; display: block; border: 2px solid var(--ink); border-radius: 6px;
  max-height: clamp(80px, 13vh, 170px); object-fit: cover; object-position: center top;
}
.bollard-card figcaption { padding: 0.4rem 0.2rem 0.5rem; font-weight: 700; font-size: 0.68rem; }

/* ---------- fencing ---------- */
.r-piste { background: var(--piste-bg); }
.piste-stripes {
  position: absolute; inset: 0; pointer-events: none; opacity: 0.55; z-index: 1;
  background:
    linear-gradient(90deg, transparent 0 1.2%, var(--red) 1.2% 1.7%, transparent 1.7% 98.3%, var(--red) 98.3% 98.8%, transparent 98.8%),
    repeating-linear-gradient(0deg, transparent 0 120px, rgba(230,57,47,0.05) 120px 240px);
}
.fencing-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem;
  margin-bottom: 1.4rem;
}
.stat {
  border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: 0.1rem;
  transform: rotate(-0.6deg);
}
.stat:nth-child(2n) { transform: rotate(0.8deg); }
.s-red { background: #ffd9d6; } .s-blue { background: #d6e4ff; }
.s-green { background: #d8f3e0; } .s-yellow { background: #fff1c2; }
.stat-num { font-family: var(--font-display); font-size: 2.3rem; font-weight: 800; }
.stat-label { font-size: 0.85rem; }
.fencing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.bout-card {
  background: #fff; border: var(--border); border-radius: var(--radius);
  padding: 1.2rem 1.3rem; box-shadow: var(--shadow);
  transition: transform 0.2s ease;
}
.bout-card:hover { transform: translateY(-5px) rotate(-0.5deg); }
.bout-card h3 { margin-bottom: 0.4rem; }
.bout-card p { font-size: 0.92rem; }
.offpiste-label { margin-top: 1.1rem; font-weight: 700; opacity: 0.6; font-size: 0.72rem; letter-spacing: 0.04em; }
.offpiste-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.9rem; margin-top: 0.45rem; }
.offpiste {
  display: flex; gap: 0.7rem; align-items: flex-start;
  background: rgba(255, 253, 245, 0.75); border: var(--border); border-radius: 12px;
  padding: 0.7rem 0.85rem;
}
.offpiste-icon { font-size: 1.35rem; line-height: 1.2; }
.offpiste h3 { font-size: 0.98rem; margin-bottom: 0.25rem; }
.offpiste-role { display: block; font-size: 0.68rem; font-weight: 700; opacity: 0.55; }
.offpiste p { font-size: 0.83rem; }
/* ---------- chess (playable) ---------- */
.r-chess {
  background:
    repeating-conic-gradient(rgba(34,28,20,0.04) 0% 25%, transparent 0% 50%) 0 0 / 110px 110px,
    var(--chess-bg);
}
.chess-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(230px, 290px);
  gap: 1.8rem; align-items: start;
}
.board-wrap { display: flex; justify-content: center; }
.board {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  width: min(58vh, 100%, 560px);
  aspect-ratio: 1;
  border: var(--border); border-radius: 8px; overflow: hidden;
  box-shadow: var(--shadow);
  user-select: none;
}
.sq {
  display: flex; align-items: center; justify-content: center;
  font-size: clamp(1.3rem, 4.8vh, 2.4rem);
  cursor: pointer; position: relative;
  line-height: 1; min-width: 0; min-height: 0;
}
.sq .pc-w, .sq .pc-b { display: block; height: 1em; line-height: 1; }
.sq.light { background: #f6ecd4; }
.sq.dark { background: #a8bf7e; }
.sq.sel { outline: 3px solid var(--red); outline-offset: -3px; z-index: 1; }
.sq.last { box-shadow: inset 0 0 0 100px rgba(242, 183, 5, 0.28); }
.sq .pc-w { color: #fffdf5; text-shadow: 0 0 2px var(--ink), 0 2px 0 rgba(34,28,20,0.55); }
.sq .pc-b { color: #221c14; }
.sq.tgt::after {
  content: ""; position: absolute; width: 26%; height: 26%;
  border-radius: 50%; background: rgba(34,28,20,0.32);
}
.sq.tgt.cap::after {
  width: 88%; height: 88%; background: transparent;
  border: 4px solid rgba(230,57,47,0.75);
}
.chess-xlink, .geo-xlink { color: var(--blue); font-weight: 700; text-decoration-thickness: 2px; }
.chess-xlink:hover, .geo-xlink:hover { color: var(--red); }
.dossier { display: flex; flex-direction: column; gap: 0.9rem; }
.dossier-status { font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; }
.dossier-card {
  background: #fffdf5; border: var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 1.2rem 1.3rem;
}
.dossier-piece { font-size: 2.6rem; line-height: 1; display: block; }
.dossier-card h3 { margin: 0.4rem 0 0.3rem; }
.captures { min-height: 1.4em; letter-spacing: 0.1em; font-size: 1.05rem; }

/* ---------- work / ski ---------- */
.r-ski { background: linear-gradient(180deg, #b8dcf5 0%, var(--ski-bg) 45%, #eef7fd 100%); }
.mountains {
  position: absolute; left: 0; right: 0; top: 0; width: 100%; height: 300px; z-index: 0;
  /* Was cut off on a hard line where the svg ended; this lands it on the snow. */
  -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 99%);
          mask-image: linear-gradient(180deg, #000 62%, transparent 99%);
}
.mtn-far { fill: #9ec9e8; }
.mtn-near { fill: #7fb5dd; }
.mtn-cap { fill: #fff; }
.snow { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.flake {
  position: absolute; top: -4vh; color: #fff; user-select: none;
  animation: fall linear infinite;
  text-shadow: 0 1px 2px rgba(50,90,120,0.25);
}
.gates { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.9rem; }
.gate {
  background: #fffdf8; border: var(--border); border-radius: var(--radius);
  padding: 0.95rem 1.1rem; box-shadow: var(--shadow);
  transition: transform 0.2s ease;
}
.gate:hover { transform: translateY(-4px); }
.gate:nth-child(odd) { transform: rotate(-0.4deg); }
.gate:nth-child(even) { transform: rotate(0.4deg); }
.gate-date { color: var(--blue); font-weight: 700; margin-bottom: 0.2rem; }
.gate-loc { opacity: 0.65; margin-bottom: 0.5rem; }
.gate p { font-size: 0.82rem; line-height: 1.45; }
.gate h3 { font-size: 1.02rem; }
.gate-tags { margin-top: 0.5rem; color: var(--purple); font-weight: 700; }

/* ---------- projects / lego ---------- */
.r-lego { background: var(--lego-bg); }
.r-lego h2 {
  font-family: var(--font-brick); font-weight: 400;
  font-size: clamp(1.7rem, 3.4vw, 2.7rem);
  text-shadow: 3px 3px 0 rgba(230, 57, 47, 0.35);
}
.stud-bg {
  position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background-image: radial-gradient(circle at 50% 42%, rgba(34,28,20,0.10) 0 14px, rgba(255,255,255,0.18) 15px 17px, transparent 18px);
  background-size: 72px 72px;
}
.lego-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1.3rem; }
.lego-grid:not(.lego-grid-sm) { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
.lego-card {
  min-width: 0;
  position: relative; border-radius: 12px; padding: 1.7rem 1.4rem 1.2rem;
  border: var(--border); background: #fffdf5; box-shadow: var(--shadow);
  border-top-width: 6px;
  transition: transform 0.2s ease;
}
.lego-card:hover { transform: translateY(-6px); }
.lego-studs { position: absolute; top: -16px; left: 18px; display: flex; gap: 10px; }
.lego-studs span {
  width: 26px; height: 19px; border-radius: 6px 6px 3px 3px;
  border: 2px solid var(--ink); border-bottom: none;
  background: #b9b2a5; box-shadow: inset 0 -5px 0 rgba(0,0,0,0.25);
}
.lego-red { border-top-color: var(--red); }
.lego-red .lego-studs span { background: var(--red); }
.lego-yellow { border-top-color: var(--yellow); }
.lego-yellow .lego-studs span { background: var(--yellow); }
.lego-blue { border-top-color: var(--blue); }
.lego-blue .lego-studs span { background: var(--blue); }
.lego-card h3 { font-size: 1.25rem; }
.lego-sub { color: var(--red); font-weight: 700; margin-bottom: 0.6rem; }
.lego-card > p:not(.lego-sub):not(.lego-tags) { font-size: 0.88rem; }
.lego-card > p + p:not(.lego-tags):not(.lego-links) { margin-top: 0.65rem; }
.lego-tags { margin-top: 0.7rem; color: var(--blue); font-weight: 700; }


.workbench {
  margin-top: 1.6rem;
  border: 3px dashed var(--ink); border-radius: var(--radius);
  padding: 1rem 1.2rem 0.8rem;
  background: rgba(255, 253, 245, 0.55);
}
.workbench-label { font-weight: 700; margin-bottom: 0.7rem; }
.wip-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0.8rem; }
.lego-card h3 a, .wip h3 a {
  color: inherit; text-decoration: none;
  border-bottom: 3px solid transparent;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.lego-card h3 a:hover, .wip h3 a:hover { color: var(--red); border-bottom-color: var(--red); }
.wip {
  background: #fffdf5; border: 2px solid var(--ink); border-radius: 10px;
  padding: 0.8rem 0.9rem; box-shadow: 3px 3px 0 var(--ink);
  transition: transform 0.15s ease;
}
.wip:hover { transform: translateY(-3px); }
.wip-icon { font-size: 1.5rem; line-height: 1; display: block; margin-bottom: 0.3rem; }
.wip h3 { font-size: 0.98rem; }
.wip p { opacity: 0.75; margin-top: 0.15rem; font-size: 0.72rem; }
.wip-small { opacity: 0.75; }
.workbench-quote { margin-top: 0.7rem; opacity: 0.5; font-style: italic; }

/* ---------- deck / arena ---------- */
.r-arena {
  background: url("photos/coc-base.jpg") left 38% / cover no-repeat #3e7d3a;
  color: #fdf7ea;
}
.r-arena::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background:
    linear-gradient(180deg, rgba(10, 26, 10, 0.62) 0%, rgba(10, 26, 10, 0.3) 40%, rgba(10, 26, 10, 0.55) 100%);
}
.r-arena h2 {
  font-family: var(--font-cr); font-weight: 400; letter-spacing: 0.02em;
  color: #fff;
  text-shadow: 0 3px 0 #1c3a1b, 2px 0 0 #1c3a1b, -2px 0 0 #1c3a1b, 0 -2px 0 #1c3a1b;
}
.r-arena .kicker, .r-arena .blurb { text-shadow: 0 1px 0 rgba(0,0,0,0.45); }
.cr-deck {
  background:
    repeating-linear-gradient(90deg, rgba(0,0,0,0.06) 0 2px, transparent 2px 5px),
    linear-gradient(180deg, #b07b45, #8a5a2c);
  border: 4px solid #5f3c1c; border-radius: 16px;
  box-shadow: inset 0 3px 0 rgba(255,255,255,0.18), inset 0 -4px 0 rgba(0,0,0,0.25), 0 8px 0 rgba(0,0,0,0.35);
  padding: 0.9rem;
  width: min(820px, 94vw, calc((100svh - 385px) * 1.32));
  margin-left: auto;
}
.cr-tabs { display: flex; gap: 0.6rem; justify-content: center; margin: -0.9rem -0.9rem 0.7rem; padding: 0 1rem; }
.cr-tab {
  font-family: var(--font-display); font-weight: 800; font-size: 1.02rem;
  color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,0.45);
  background: linear-gradient(180deg, #8a5a2c, #6b4420);
  border: 3px solid #5f3c1c; border-top: none;
  border-radius: 0 0 12px 12px;
  padding: 0.45rem 1.6rem 0.5rem;
  opacity: 0.65;
}
.cr-tab.active {
  background: linear-gradient(180deg, #b07b45, #8a5a2c);
  opacity: 1;
}
.cr-toolbar {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 0.7rem; padding: 0 0.2rem;
}
.cr-tool {
  width: 40px; height: 34px; border-radius: 8px;
  background: linear-gradient(180deg, #6b4420, #55351a);
  border: 2px solid #422a12;
  display: flex; align-items: center; justify-content: center;
  font-size: 1rem;
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.15);
}
.cr-slots { display: flex; gap: 0.45rem; }
.cr-slots i {
  font-family: var(--font-display); font-style: normal; font-weight: 800;
  width: 40px; height: 34px; border-radius: 8px;
  background: linear-gradient(180deg, #6b4420, #55351a);
  border: 2px solid #422a12; color: #d9c3a5;
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.12);
}
.cr-slots i.on {
  background: linear-gradient(180deg, #ffd76b, #eaa62c);
  color: #5a3d0e; border-color: #fff;
  box-shadow: 0 0 10px rgba(255, 215, 107, 0.7);
}
.cr-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.7rem; }
.cr-card {
  position: relative; aspect-ratio: 3 / 4;
  border: 0; border-radius: 12px; padding: 4px;
  cursor: pointer; color: #fff;
  font-family: var(--font-body);
  transition: transform 0.12s ease;
  box-shadow: 0 5px 0 rgba(0,0,0,0.4);
  display: flex; flex-direction: column;
}
.cr-card:hover { transform: translateY(-6px) scale(1.03); }
.cr-card:active { transform: translateY(1px) scale(0.97); }
/* rarity = frame color */
.rar-common { background: linear-gradient(180deg, #cdd7e2, #8fa3b8); }
.rar-rare { background: linear-gradient(180deg, #ffc46b, #e07f12); }
.rar-epic { background: linear-gradient(180deg, #d9a6ff, #8b3fe0); }
.rar-legendary {
  background: conic-gradient(from 200deg, #58c8ff, #a06bff, #ff8ad3, #ffd76b, #7be0a7, #58c8ff);
  box-shadow: 0 0 16px 2px rgba(255, 214, 90, 0.65), 0 5px 0 rgba(0,0,0,0.4);
}
.cr-frame {
  flex: 1; border-radius: 9px 9px 3px 3px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(circle at 50% 30%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(160deg, #3f7fd1 0%, #235094 55%, #16335f 100%);
  position: relative;
}
.cr-frame::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 42%, rgba(255,255,255,0.22) 47%, transparent 55%);
}
.cr-art { font-size: clamp(2.1rem, 5vw, 3.4rem); line-height: 1; filter: drop-shadow(0 4px 2px rgba(0,0,0,0.4)); }
.cr-plate {
  margin-top: 4px; border-radius: 3px 3px 9px 9px;
  background: linear-gradient(180deg, #1c3d6e, #122a4e);
  padding: 0.32rem 0.2rem 0.38rem;
  display: flex; align-items: center; justify-content: center;
}
.cr-name {
  font-family: var(--font-cr); font-weight: 400;
  font-size: clamp(0.74rem, 1.5vw, 1rem);
  text-shadow: 0 2px 0 rgba(0,0,0,0.5);
  letter-spacing: 0.03em; text-align: center;
}
.cr-elixir {
  position: absolute; top: -10px; left: -10px; z-index: 3;
  width: 34px; height: 40px;
  background: radial-gradient(circle at 35% 28%, #f0a6ff 0 18%, #b44ee8 45%, #7a1fbe);
  border: 2.5px solid #fff;
  border-radius: 50% 50% 50% 50% / 62% 62% 40% 40%;
  color: #fff; font-weight: 700; font-family: var(--font-mono); font-size: 1.05rem;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 5px rgba(0,0,0,0.45);
  text-shadow: 0 2px 0 rgba(0,0,0,0.4);
}
.cr-up {
  margin-top: 4px; border-radius: 6px;
  background: linear-gradient(180deg, #23282e, #14181d);
  border: 2px solid #0c0f13;
  color: #e8eef4; font-size: 0.62rem; font-weight: 700;
  padding: 0.22rem 0.3rem;
  display: flex; align-items: center; justify-content: center; gap: 0.3rem;
  text-shadow: 0 1px 0 rgba(0,0,0,0.6);
}
.cr-up i {
  font-style: normal; color: #fff;
  background: linear-gradient(180deg, #66c4ff, #1f8ae0);
  border-radius: 4px; padding: 0 0.25rem;
  font-size: 0.6rem;
}
.cr-avg-line {
  text-align: center; margin-top: 0.8rem;
  font-family: var(--font-display); font-weight: 800; font-size: 1.05rem;
  color: #ff5ec8; text-shadow: 0 2px 0 rgba(0,0,0,0.45);
  display: flex; align-items: center; justify-content: center; gap: 0.4rem;
}
.cr-avg-line b { font-size: 1.15rem; }
.cr-deploy { text-align: center; min-height: 1.4em; margin-top: 0.2rem; }
.cr-drop {
  width: 14px; height: 17px; display: inline-block;
  background: radial-gradient(circle at 35% 28%, #f0a6ff 0 18%, #b44ee8 45%, #7a1fbe);
  border: 1.5px solid #fff;
  border-radius: 50% 50% 50% 50% / 62% 62% 40% 40%;
}
.cr-avg strong { color: #e8b7ff; font-size: 1rem; }
#deploy-line { font-weight: 700; color: #ffe08a; }

.lego-white { border-top-color: #dfe8ee; }
.lego-white .lego-studs span { background: #dfe8ee; }
.lego-green { border-top-color: #3fae4c; }
.lego-green .lego-studs span { background: #3fae4c; }
.lego-teal { border-top-color: #1f9ea8; }
.lego-teal .lego-studs span { background: #1f9ea8; }

.shelf-label { margin: 1.4rem 0 0.6rem; font-weight: 700; opacity: 0.7; }
.lego-grid-sm { gap: 1rem; }
.lego-card.compact { padding: 1.4rem 1.1rem 1rem; }
.lego-card.compact h3 { font-size: 1.05rem; }
.lego-card.compact .lego-sub { margin-bottom: 0.4rem; font-size: 0.68rem; }
.lego-card.compact > p:not(.lego-sub):not(.lego-tags) { font-size: 0.82rem; }
.lego-card.compact .lego-tags { font-size: 0.68rem; margin-top: 0.5rem; }
.lego-black { border-top-color: #2b2620; }
.lego-black .lego-studs span { background: #4a4238; }
.lego-navy { border-top-color: #1d3b6e; }
.lego-navy .lego-studs span { background: #1d3b6e; }

.lego-links { margin-top: 0.5rem; font-weight: 700; }
.lego-links a { color: var(--red); text-decoration: none; border-bottom: 2px solid currentColor; }
.lego-links a:hover { color: var(--ink); }

.geo-vestigo { margin-top: 0.9rem; font-size: 0.95rem; }
.geo-vestigo a { color: var(--red); font-weight: 700; text-decoration-thickness: 2px; }

/* hero live badge */
.hero-live { margin-top: 1.1rem; display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
/* Two live sites stack, so the second sits tight under the first rather than
   opening the same gap that separates it from the badges above. */
.hero-live + .hero-live { margin-top: 0.5rem; }
.hero-live > a {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-weight: 700; color: var(--ink); text-decoration: none;
  background: #fff; border: var(--border); border-radius: 999px;
  padding: 0.3rem 0.85rem; box-shadow: 3px 3px 0 var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.hero-live > a:hover { transform: translate(-2px, -2px); box-shadow: 5px 5px 0 var(--ink); }
.live-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--green);
  box-shadow: 0 0 0 0 rgba(46, 158, 91, 0.7);
  animation: livePulse 2s ease-out infinite;
}
.hero-live-note { opacity: 0.7; }
@keyframes livePulse {
  70% { box-shadow: 0 0 0 9px rgba(46, 158, 91, 0); }
  100% { box-shadow: 0 0 0 0 rgba(46, 158, 91, 0); }
}
.runner {
  position: absolute; font-size: 2.6rem; bottom: 12%; left: -80px;
  pointer-events: none; z-index: 5;
  filter: drop-shadow(3px 4px 0 rgba(0,0,0,0.3));
}
.tetromino {
  position: absolute; top: -60px; pointer-events: none; z-index: 5;
  border: 3px solid #10233f; border-radius: 4px;
}

/* ---------- contact / stage ---------- */
.r-stage {
  background:
    radial-gradient(ellipse 70% 30% at 50% 108%, rgba(255, 210, 63, 0.14), transparent 70%),
    radial-gradient(900px 500px at 50% 0%, #462b56, var(--stage-bg) 70%);
  color: var(--stage-ink);
}
.r-stage::before {
  content: ""; position: absolute; left: 50%; bottom: -18vmin; transform: translateX(-50%);
  width: 90vmin; height: 90vmin; border-radius: 50%; z-index: 0;
  background:
    radial-gradient(circle, transparent 0 30%, rgba(255,233,201,0.05) 30% 31%, transparent 31% 46%, rgba(255,233,201,0.05) 46% 47%, transparent 47% 62%, rgba(255,233,201,0.05) 62% 63%, transparent 63%);
}
.kit-silhouette {
  position: absolute; left: 50%; bottom: -2%; transform: translateX(-50%);
  width: min(64vmin, 560px); z-index: 0;
  color: rgba(255, 233, 201, 0.12);
}
.contact-inner { align-items: center; text-align: center; }
.contact-inner .room-head { margin-left: auto; margin-right: auto; }
.stage-lights { position: absolute; top: 0; left: 0; right: 0; height: 40vh; pointer-events: none; overflow: hidden; z-index: 1; }
.stage-lights span {
  position: absolute; top: -60px; width: 240px; height: 55vh;
  background: linear-gradient(180deg, rgba(255,220,120,0.28), transparent 80%);
  clip-path: polygon(45% 0, 55% 0, 100% 100%, 0 100%);
  transform-origin: top center;
  animation: sweep 7s ease-in-out infinite alternate;
}
.stage-lights span:nth-child(1) { left: 12%; }
.stage-lights span:nth-child(2) { left: 45%; animation-delay: -2.5s; background: linear-gradient(180deg, rgba(120,180,255,0.22), transparent 80%); }
.stage-lights span:nth-child(3) { left: 76%; animation-delay: -5s; background: linear-gradient(180deg, rgba(255,120,140,0.22), transparent 80%); }

.drumkit { display: flex; gap: 0.9rem; justify-content: center; flex-wrap: wrap; }
.drum {
  font-size: 1.7rem; width: 84px; height: 84px; border-radius: 50%;
  border: 3px solid var(--stage-ink); background: rgba(255,233,201,0.08);
  color: var(--stage-ink); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  transition: transform 0.08s ease, background 0.2s ease;
}
.drum span { font-size: 0.6rem; opacity: 0.8; }
.drum:hover { background: rgba(255,233,201,0.18); }
.drum.hit { transform: scale(0.88); background: rgba(255,233,201,0.35); }

/* now playing · vinyl */
.np {
  position: absolute; z-index: 3;
  left: clamp(1rem, 4vw, 4.5rem); bottom: clamp(1.5rem, 6vh, 4rem);
  width: clamp(150px, 14vw, 210px); margin: 0;
  transform: rotate(-3deg);
}
.np-cover {
  position: relative; z-index: 2;
  width: 100%; display: block;
  border: 3px solid var(--stage-ink); border-radius: 4px;
  box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.45);
}
.np-vinyl {
  position: absolute; z-index: 1; top: 4%; left: 12%;
  width: 92%; aspect-ratio: 1; border-radius: 50%;
  background:
    radial-gradient(circle, #d8b46a 0 13%, transparent 13%),
    conic-gradient(from 40deg, rgba(255,255,255,0.14) 0 22deg, transparent 22deg 158deg, rgba(255,255,255,0.1) 158deg 200deg, transparent 200deg),
    radial-gradient(circle, #1a140c 0 32%, #241c11 32% 34%, #1a140c 34% 52%, #241c11 52% 54%, #1a140c 54% 72%, #241c11 72% 74%, #1a140c 74% 100%);
  transition: transform 0.45s cubic-bezier(0.2, 0.8, 0.3, 1);
  will-change: transform, rotate;
}
.np:hover .np-vinyl {
  transform: translateX(46%);
  animation: spin 3s linear infinite;
}
/* right-side sleeve: mirrored, vinyl slides out to the left */
.np-r {
  left: auto; right: clamp(1rem, 4vw, 4.5rem);
  transform: rotate(3deg);
}
.np-r .np-vinyl { left: -4%; }
.np-r:hover .np-vinyl { transform: translateX(-46%); }
.np figcaption {
  margin-top: 0.55rem; font-size: 0.62rem; font-weight: 700;
  color: var(--stage-ink); opacity: 0.85;
}
@keyframes spin { to { rotate: 360deg; } }

.hotbar-wrap { margin: 1.6rem 0 0.4rem; }
.item-name {
  font-family: "Press Start 2P", var(--font-mono);
  font-size: 0.65rem; color: #fff; min-height: 1.4em;
  text-shadow: 2px 2px 0 #3f3f3f;
  opacity: 0; transition: opacity 0.2s ease;
  margin-bottom: 0.6rem;
}
.item-name.show { opacity: 1; }
.hotbar {
  display: inline-flex; padding: 4px; gap: 2px;
  background: #8b8b8b;
  border: 3px solid; border-color: #555 #fff #fff #555;
  box-shadow: 0 6px 0 rgba(0,0,0,0.35);
}
.slot {
  width: 50px; height: 50px; font-size: 1.5rem; cursor: pointer;
  background: #6b6b6b;
  border: 3px solid; border-color: #373737 #a8a8a8 #a8a8a8 #373737;
  display: flex; align-items: center; justify-content: center;
  transition: transform 0.08s ease;
}
.slot:hover { transform: translateY(-3px); }
.slot.selected { border-color: #fff; outline: 2px solid #fff; background: #7e7e7e; }
.kbd-row { margin-top: 0.7rem; opacity: 0.6; }

.contact-actions { display: flex; flex-direction: column; gap: 1rem; align-items: center; margin-top: 1.6rem; }
.contact-links { display: flex; gap: 0.8rem; flex-wrap: wrap; justify-content: center; }
.contact-inner .btn-solid { border-color: var(--stage-ink); box-shadow: 4px 4px 0 rgba(255,233,201,0.35); }

.footer { margin-top: 2.2rem; opacity: 0.7; }
.footer-fine { font-size: 0.62rem; opacity: 0.65; margin-top: 0.25rem; }
.footer-quote { margin-top: 0.3rem; font-style: italic; }

/* ---------- confetti ---------- */
.confetti {
  position: fixed; width: 10px; height: 14px; top: 0; left: 0;
  pointer-events: none; z-index: 100; border-radius: 2px;
}

/* ---------- animations ---------- */
@keyframes blink { 50% { opacity: 0; } }
@keyframes dashMove { to { stroke-dashoffset: -26; } }
@keyframes fall { to { transform: translateY(110vh) rotate(340deg); } }
@keyframes sweep { from { transform: rotate(-14deg); } to { transform: rotate(14deg); } }

/* ---------- responsive: stack vertically on small screens ---------- */
@media (max-width: 1250px) {
  .hero-inner { grid-template-columns: minmax(0, 1fr) 240px; gap: 2rem; }
  .hero-name { font-size: 4.5rem; }
  .np { position: static; margin: 1.4rem auto 0; transform: rotate(-2deg); }
}
@media (max-width: 1150px) {
  .chess-layout { grid-template-columns: 1fr; }
  .dossier { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .lego-grid { grid-template-columns: repeat(2, 1fr); }
  .wip-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  body { overflow: auto; }
  .world { width: auto; height: auto; overflow: visible; }
  .track { display: block; transform: none !important; }
  .room { height: auto; min-height: 100svh; overflow: visible; }
  .scroll-cue { display: none; }
  .nav-links a:not(.nav-cta) { display: none; }
  .dots, .edge { display: none; }
  .hero-inner { grid-template-columns: minmax(0, 1fr); gap: 1.6rem; }
  .hero-name { font-size: 3.4rem; }
  .hero-photo { transform: rotate(-2deg); margin: 0; width: 230px; max-width: 100%; }
  .atlas-layout { grid-template-columns: 1fr; }
  .fencing-stats { grid-template-columns: repeat(2, 1fr); }
  .fencing-grid { grid-template-columns: 1fr; }
  .offpiste-row { grid-template-columns: 1fr; }
  .gates { grid-template-columns: 1fr; }
  .lego-grid { grid-template-columns: 1fr; }
  .lego-grid:not(.lego-grid-sm) { grid-template-columns: minmax(0, 1fr); }
  .cr-grid { grid-template-columns: repeat(2, 1fr); }
  .wip-row { grid-template-columns: 1fr 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .snow, .stage-lights { display: none; }
}

/* ============================================================
   Contact room · the record collage
   Cut and pasted, not laid out. Sleeves overlap edge to edge so no
   background shows through, scales disagree by more than double, and
   each piece is treated: torn from paper, printed in one colour,
   screened into halftone dots, or left as it came.
   Drop a cover into photos/albums/<slug>.jpg; a missing file takes its
   whole figure out and the pile closes over the gap.
   ============================================================ */

.lp-wall {
  position: absolute; inset: -6%; overflow: hidden;
  pointer-events: none; z-index: 0;
  --px: 0; --py: 0;
}

/* The pile stays whole; this darkens it under the words instead of cutting a
   hole in it. Above every sleeve, below the grain, and far below the content. */
.lp-wall::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 98;
  background:
    radial-gradient(ellipse 78% 74% at 50% 48%, rgba(14, 9, 20, 0) 42%, rgba(14, 9, 20, 0.62) 100%),
    linear-gradient(180deg, rgba(14, 9, 20, 0.45), rgba(14, 9, 20, 0) 22% 76%, rgba(14, 9, 20, 0.55));
}

/* Newsprint over the whole pile. Without it twenty four photographs
   still read as twenty four photographs rather than one surface. */
.lp-wall::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 99;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  opacity: 0.11; mix-blend-mode: overlay;
}

.lp {
  position: absolute;
  left: var(--x); top: var(--y);
  width: var(--w); aspect-ratio: 1;
  z-index: calc(var(--i) + 1);
  filter: drop-shadow(0 16px 28px rgba(0, 0, 0, 0.6)) saturate(1.12) contrast(1.04);
  transform:
    translate3d(calc(var(--px) * var(--depth, 1)), calc(var(--py) * var(--depth, 1)), 0)
    rotate(var(--r));
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
  animation: lp-drift calc(20s + var(--i) * 1.1s) ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -800ms);
  will-change: transform;
}
.lp img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Three planes, so the pile parts when the pointer moves. */
.lp:nth-child(3n)   { --depth: 2.1; }
.lp:nth-child(3n+1) { --depth: 0.6; }

/* Torn out of the magazine, white deckle left on. */
/* No white backing: at these sizes the deckle read as holes punched in the
   collage rather than as paper. The torn edge alone carries the cut. */
.lp--paper {
  clip-path: polygon(2% 3%, 21% 0, 44% 4%, 68% 0, 88% 3%, 100% 20%, 97% 44%,
                     100% 70%, 96% 95%, 74% 100%, 49% 96%, 26% 100%, 5% 97%,
                     0 74%, 3% 47%, 0 22%);
}
/* Ripped straight out, no border. */
.lp--tear {
  clip-path: polygon(4% 0, 34% 5%, 62% 0, 96% 4%, 100% 31%, 95% 59%, 100% 92%,
                     67% 100%, 37% 95%, 6% 100%, 0 68%, 5% 37%, 0 8%);
}
/* A light print bias on a couple of pieces, not a colour swap. */
.lp--duo img { filter: saturate(1.25) contrast(1.1); }
.lp--halftone img { filter: contrast(1.12); }

@keyframes lp-drift {
  from { translate: 0 0; rotate: -0.5deg; }
  to   { translate: 0 -16px; rotate: 0.5deg; }
}

/* ---- drums, drawn rather than typed as emoji ---- */
.drum i {
  display: block; width: 32px; height: 26px; margin: 0 auto 3px;
  border: 2.5px solid currentColor; border-radius: 3px 3px 5px 5px;
  position: relative;
}
.drum i::before {
  content: ""; position: absolute; left: -3px; right: -3px; top: -2px; height: 6px;
  border: 2.5px solid currentColor; border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
}
.d-hat i, .d-crash i {
  height: 8px; border: none; border-radius: 50%;
  background: currentColor; opacity: 0.85; margin-top: 9px;
}
.d-crash i { width: 38px; height: 6px; }
.d-kick i { width: 38px; height: 30px; }

@media (prefers-reduced-motion: reduce) {
  .lp { animation: none; transition: none; }
}

/* Narrow screens: the sleeves are wallpaper, not content. Shrink them,
   drop the titles, and open the mask wider so nothing crowds the heading. */
@media (max-width: 900px) {
  .lp-wall {
    -webkit-mask-image: radial-gradient(ellipse 66% 48% at 50% 48%, transparent 54%, #000 100%);
            mask-image: radial-gradient(ellipse 66% 48% at 50% 48%, transparent 54%, #000 100%);
  }
  .lp-wall { opacity: 0.9; }
  .lp { width: calc(var(--w) * 1.5); }
}

/* The words sit on a collage, so they carry their own contrast rather than
   relying on whatever sleeve happens to be behind them. */
.r-stage .room-head h2,
.r-stage .room-head .blurb,
.r-stage .room-head .kicker,
.r-stage .contact-links,
.r-stage .foot-note,
.r-stage .kbd-row {
  text-shadow: 0 2px 10px rgba(16, 9, 22, 0.95), 0 0 28px rgba(16, 9, 22, 0.7);
}

/* ============================================================
   Terminal room
   Replaces the card deck. A real prompt: room names navigate, the
   project names open, and anything else is answered out of a written
   knowledge base rather than pretending to be a model.
   ============================================================ */

.r-term {
  background:
    radial-gradient(120% 90% at 50% -10%, #23202c 0%, #16141d 55%, #100e16 100%);
  color: #efe9dc;
}
.r-term .kicker { color: #8a8398; }
.r-term h2 { color: #f6f1e6; }
.term-inner { display: flex; flex-direction: column; }

.term {
  width: min(900px, 100%);
  margin-top: 1.4rem;
  border: 3px solid #0b0a10;
  border-radius: 12px;
  background: #fdfcf9;
  box-shadow: 0 26px 60px rgba(0, 0, 0, 0.55), 8px 8px 0 rgba(0, 0, 0, 0.35);
  overflow: hidden;
}

.term-bar {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.75rem;
  background: linear-gradient(180deg, #f2ede2, #e3ddd0);
  border-bottom: 2px solid #0b0a10;
  user-select: none;
}
.term-lights { display: flex; gap: 6px; }
.term-lights i { width: 12px; height: 12px; border-radius: 50%; border: 1px solid rgba(0, 0, 0, 0.26); }
.tl-r { background: #ff5f57; } .tl-y { background: #febc2e; } .tl-g { background: #28c840; }
.term-title { flex: 1; text-align: center; font-size: 0.74rem; opacity: 0.6; color: #2b2620; }

.term-body {
  padding: 0.9rem 1.05rem 1.1rem;
  height: min(46vh, 400px);
  overflow-y: auto;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  line-height: 1.6;
  color: #1d1a15;
  cursor: text;
}
.term-out { white-space: pre-wrap; word-break: break-word; }
.term-out p { margin: 0 0 0.35rem; }
.term-out a { color: #1f66c9; }
.t-dim { opacity: 0.58; }
.t-key { color: #b3261e; font-weight: 700; }
.t-ok  { color: #1c7c3f; }
.t-echo { opacity: 0.8; }

.term-line { display: flex; align-items: baseline; gap: 0.5rem; margin-top: 0.2rem; }
.term-prompt { color: #1c7c3f; font-size: 0.85rem; white-space: nowrap; }
.term-tilde { color: #1f66c9; }
.term-in {
  flex: 1; min-width: 0;
  border: none; outline: none; background: none;
  font: inherit; font-size: 0.85rem; color: inherit;
  caret-color: #b3261e;
}
.term-in::placeholder { color: #1d1a15; opacity: 0.32; }

@media (max-width: 900px) {
  .term-body { height: 42vh; font-size: 0.8rem; }
  .term-prompt { font-size: 0.8rem; }
}

/* The one joke. Loud on purpose, and skipped entirely under reduced motion. */
.jumpscare {
  position: fixed; inset: 0; z-index: 9999;
  display: grid; place-items: center;
  background: #b3261e;
  animation: jump-flash 620ms steps(2, end);
  pointer-events: none;
}
.jumpscare span {
  font-family: var(--font-mono);
  font-size: clamp(6rem, 26vw, 20rem);
  font-weight: 700;
  color: #fff;
}
@keyframes jump-flash {
  0%   { opacity: 0; }
  8%   { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; }
}
.jumpshake { animation: jump-shake 620ms cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes jump-shake {
  10%, 90% { transform: translate3d(-3px, 2px, 0) rotate(-0.4deg); }
  20%, 80% { transform: translate3d(6px, -4px, 0) rotate(0.6deg); }
  30%, 50%, 70% { transform: translate3d(-9px, 3px, 0) rotate(-0.7deg); }
  40%, 60% { transform: translate3d(9px, -3px, 0) rotate(0.7deg); }
}
@media (prefers-reduced-motion: reduce) {
  .jumpscare, .jumpshake { animation: none; }
}

/* The collage stays bright, so the words sit on their own surface rather than
   on a dimmed wall. Same chunky border and hard shadow as the rest of the site. */
.r-stage .contact-inner {
  background: rgba(17, 10, 24, 0.7);
  backdrop-filter: blur(10px) saturate(0.85);
  border: 3px solid rgba(246, 241, 230, 0.92);
  border-radius: 18px;
  box-shadow: 7px 7px 0 rgba(0, 0, 0, 0.5);
  padding: 1.1rem 1.4rem 1.3rem;
  width: min(560px, 100%);
  margin-inline: auto;
}
@media (max-width: 900px) {
  .r-stage .contact-inner {
    padding: 1.1rem 1rem 1.4rem;
    border-width: 2px;
    border-radius: 14px;
    /* Thinner here, because at this width the panel is the whole screen and an
       opaque one hides the collage completely. Blur plus the text shadows do
       the legibility work instead. */
    background: rgba(17, 10, 24, 0.42);
    backdrop-filter: blur(14px) saturate(0.8);
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.4);
  }
}

/* ============================================================
   Work room · the run
   A course you ski rather than a grid you read. The run descends,
   gates alternate either side of it, and a skier tracks your scroll
   down the path with their tracks cut in behind them.
   ============================================================ */

.r-ski .room-inner { position: relative; }

/* No inner scroller. The run is part of the page, so there is one scroll
   through the whole descent rather than a box inside a box. */
.run {
  position: relative;
  padding: 0.5rem 0 3rem;
}
/* The piste and the cut tracks share a path, so the skier is always on it. */
.run-svg {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: min(620px, 92%); height: 100%;
  pointer-events: none; z-index: 0;
}
.run-piste { fill: none; stroke: #fff; stroke-width: 84; stroke-linecap: round; opacity: 0.95; }
.run-track {
  fill: none; stroke: #8fb8dc; stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 6 10; opacity: 0.85;
}

.skier {
  position: absolute; top: 0; left: 0;
  font-size: 2.1rem; line-height: 1;
  z-index: 0; pointer-events: none;
  filter: drop-shadow(0 4px 5px rgba(30, 50, 70, 0.35));
  transition: transform 120ms linear;
  will-change: transform;
}

/* Gates alternate sides of the run, which is the zigzag you actually ski. */
.gates {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr;
  align-items: start;          /* without this they stretch to the row and touch */
  gap: 6rem 3rem;
  padding: 6rem 0.5rem 5rem;
}
.gate {
  position: relative;
  padding-top: 1.7rem;
  max-width: 330px;
}
.gate:nth-child(odd)  { grid-column: 1; justify-self: end;   transform: rotate(-0.6deg); }
.gate:nth-child(even) { grid-column: 2; justify-self: start; transform: rotate(0.6deg); }
/* Drop every gate below the one before it so the run reads as a descent. */
.gate:nth-child(even) { margin-top: 11rem; }
.gate:nth-child(odd):not(:first-child) { margin-top: 1rem; }
.gate:hover { transform: translateY(-5px) rotate(0deg); z-index: 4; }

/* The pole pair: red gate then blue, the way a course alternates. */
.gate::before {
  content: "";
  position: absolute; top: 0; left: 1.15rem;
  width: 10px; height: 22px;
  background: var(--red);
  clip-path: polygon(0 0, 100% 22%, 0 44%);
  box-shadow: 26px 0 0 -1px var(--blue);
}
.gate:nth-child(even)::before { background: var(--blue); box-shadow: 26px 0 0 -1px var(--red); }
.gate::after {
  content: "";
  position: absolute; top: 0; left: 1.15rem;
  width: 2px; height: 1.5rem;
  background: rgba(34, 28, 20, 0.45);
  box-shadow: 26px 0 0 0 rgba(34, 28, 20, 0.45);
}

@media (max-width: 900px) {
  .run-svg, .skier { display: none; }
  .gates { grid-template-columns: 1fr; padding: 1rem 0 2rem; gap: 1rem; }
  .gate {
    grid-column: 1 !important; justify-self: stretch !important;
    margin-top: 0 !important; transform: none !important; max-width: none;
  }
}

/* ============================================================
   Fencing · the box
   A scoring box, which is the thing you actually watch during a bout.
   The red lamp is lit because the last touch was his; 15-14 is the
   closest a bout can be won.
   ============================================================ */

.scorebox {
  font: inherit; color: inherit; cursor: pointer; appearance: none;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  width: min(680px, 100%);
  margin: 1.2rem auto 1.6rem;
  padding: 0.85rem 1.5rem;
  background: #232019;
  border: 3px solid var(--ink);
  border-radius: 999px;
  box-shadow: var(--shadow);
}
.sb-side { display: flex; align-items: center; gap: 0.85rem; }
.sb-away { flex-direction: row; }

.sb-name {
  color: #f4efe2; font-size: 0.92rem; font-weight: 700;
  letter-spacing: 0.22em;
}
.sb-score {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 4.5vw, 2.5rem);
  font-weight: 800; line-height: 1;
  color: var(--yellow);
  font-variant-numeric: tabular-nums;
}

/* The lamp. Lit on the left because that touch landed. */
.sb-lamp { width: 22px; height: 22px; border-radius: 5px; flex: none; }
.sb-red { background: #5c211d; box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.6); }
/* Lit only once the touch has landed. */
.scorebox.touched .sb-red {
  background: #ef4136;
  box-shadow: 0 0 16px 3px rgba(239, 65, 54, 0.75), inset 0 0 6px rgba(255, 255, 255, 0.4);
  animation: sb-pulse 2.4s ease-in-out infinite;
}
.sb-green { background: #1f3a2a; box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.6); }

@keyframes sb-pulse {
  0%, 100% { box-shadow: 0 0 16px 3px rgba(239, 65, 54, 0.75), inset 0 0 6px rgba(255,255,255,0.4); }
  50%      { box-shadow: 0 0 22px 6px rgba(239, 65, 54, 0.95), inset 0 0 6px rgba(255,255,255,0.55); }
}

@media (max-width: 700px) {
  .scorebox { gap: 0.6rem; padding: 0.7rem 1rem; border-radius: 26px; }
  .sb-side { gap: 0.5rem; }
  .sb-name { font-size: 0.72rem; letter-spacing: 0.14em; }
  .sb-lamp { width: 16px; height: 16px; }
}
@media (prefers-reduced-motion: reduce) { .sb-red { animation: none; } }

/* ============================================================
   Work room · the slope
   What is either side of the run: forest down the left, a working
   chairlift down the right, rocks poking through, and a few things
   worth finding. All flat vector, so it sits with the mountains.
   ============================================================ */

.slope-deco {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 0;
  overflow: hidden;
}
.deco {
  position: absolute;
  left: var(--x); top: var(--y);
  transform: translate(-50%, -50%) scale(var(--s, 1));
  transform-origin: center;
}
.deco svg { display: block; overflow: visible; }

/* Forest. Three tones so the trees read as depth rather than a pattern. */
.pine svg { width: 40px; }
.pine .p-trunk { fill: #6b4f36; }
.pine.t1 .p-body { fill: #2f6d4f; }
.pine.t2 .p-body { fill: #3f8560; opacity: 0.92; }
.pine.t3 .p-body { fill: #6aa88a; opacity: 0.75; }
.pine { filter: drop-shadow(0 5px 4px rgba(40, 70, 95, 0.18)); }

.rock svg { width: 46px; }
.rock path { fill: #9aa7b4; }
.rock { filter: drop-shadow(0 4px 3px rgba(40, 70, 95, 0.2)); }

/* ---- the chairlift ---- */
.lift { position: absolute; top: 0; bottom: 0; right: 3.5%; width: 90px; }
.lift-cable {
  position: absolute; top: 0; bottom: 0; left: 50%;
  width: 2px; background: #4a5b6b; opacity: 0.75;
}
.lift-pylon {
  position: absolute; left: 50%; top: var(--y);
  width: 4px; height: 74px; margin-left: -2px;
  background: #62717f; border-radius: 2px;
}
.lift-pylon::before {
  content: ""; position: absolute; top: -3px; left: -15px;
  width: 34px; height: 5px; background: #62717f; border-radius: 3px;
}
.lift-chair {
  position: absolute; left: 50%; top: var(--y);
  width: 30px; margin-left: -15px;
  animation: lift-ride 34s linear infinite;
  animation-delay: var(--d, 0s);
}
.ch-arm  { position: absolute; left: 14px; top: -10px; width: 2px; height: 14px; background: #4a5b6b; }
.ch-seat {
  position: absolute; top: 4px; left: 3px;
  width: 24px; height: 9px; border-radius: 2px 2px 5px 5px;
  background: var(--red); box-shadow: 0 3px 4px rgba(40, 70, 95, 0.25);
}
.ch-seat::after {
  content: ""; position: absolute; right: -1px; top: -8px;
  width: 3px; height: 10px; background: var(--red); border-radius: 2px;
}
/* Someone is on this one. */
.ch-legs { position: absolute; top: 12px; left: 7px; width: 3px; height: 11px; background: #2b3a48; border-radius: 2px; }
.ch-legs::after { content: ""; position: absolute; left: 8px; top: 0; width: 3px; height: 9px; background: #2b3a48; border-radius: 2px; }

@keyframes lift-ride {
  from { transform: translateY(0); }
  to   { transform: translateY(-40vh); }
}

/* ---- things worth finding ---- */
.egg { pointer-events: auto; cursor: help; transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1); }
.egg:hover { transform: translate(-50%, -56%) scale(calc(var(--s, 1) * 1.14)); }
.egg svg { width: 30px; }

.snowman svg { width: 30px; }
.snowman circle { fill: #fdfdfd; stroke: #c9d8e4; stroke-width: 0.8; }
.snowman .e-nose { fill: #ef8a2b; stroke: none; }
.snowman .e-eye { fill: #2b3a48; stroke: none; }

.lostski svg { width: 24px; }
.lostski rect { fill: var(--blue); }
.lostski .e-tip { fill: var(--blue); }

.yeti svg { width: 34px; }
.yeti path { fill: #eef6fb; }
.yeti .e-eye { fill: #2b3a48; }
.yeti .e-mouth { fill: none; stroke: #2b3a48; stroke-width: 1.4; stroke-linecap: round; }
/* Only really there if you look. */
.yeti { opacity: 0.55; }
.yeti:hover { opacity: 1; }

.sign svg { width: 30px; }
.sign rect { fill: #6b4f36; }
.sign .s-plate { fill: #f4c430; stroke: var(--ink); stroke-width: 1.4; }
.sign text { font: 700 6px var(--font-mono); fill: var(--ink); }

.glove svg { width: 20px; }
.glove path { fill: var(--red); }

@media (max-width: 900px) {
  .slope-deco { display: none; }   /* the run stacks on mobile, there are no sides */
}
@media (prefers-reduced-motion: reduce) {
  .lift-chair { animation: none; }
}

/* The clock, running until the last touch lands. */
.sb-clock {
  color: #ff7b72; font-size: 1.05rem; font-weight: 700; letter-spacing: 0.08em;
  animation: sb-blink 1s steps(1) infinite;
}
.scorebox.touched .sb-clock { animation: none; color: var(--green); }
.scorebox:hover { transform: translate(-1px, -1px); box-shadow: 7px 7px 0 var(--ink); }
.scorebox:focus-visible { outline: 3px solid var(--blue); outline-offset: 4px; }
@keyframes sb-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .sb-clock { animation: none; } }

/* The collage is inset past the room's edges, and an absolutely positioned
   child that overhangs still counts toward scroll height. Nothing in this room
   is meant to scroll on desktop, so clip it. Mobile still scrolls, because
   there the panel is genuinely taller than the screen. */
@media (min-width: 901px) {
  .r-stage { overflow-y: hidden; }
}
