/* =========================================================================
   DukeGames — "the shelf": a single-screen game collection
   - Whole app fits one viewport (100dvh); the page itself never scrolls.
   - Game switching is a CSS radio group (#g1..#g5 ~ .app); no JS needed.
   - Studio / Community / Contact are native [popover] panels (Esc closes).
   - Per-game colour comes from --acc / --stage, set by the checked radio.
   Fonts are self-hosted (CSP font-src 'self'): see src/fonts.
   ========================================================================= */

@font-face {
  font-family: "Bricolage Grotesque";
  src: url("../fonts/BricolageGrotesque-Variable.woff2") format("woff2");
  font-weight: 400 800;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/IBMPlexMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/IBMPlexMono-Medium.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Silkscreen";
  src: url("../fonts/Silkscreen-Bold.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  --base: #1e1f22;
  --d1: #2b2d31;
  --d2: #313338;
  --d3: #383a40;
  --line: rgba(255, 255, 255, 0.07);
  --txt: #f2f3f5;
  --soft: #dbdee1;
  --dim: #b5bac1;
  --mute: #949ba4;
  --blurple: #5865f2;
  --blurple-dark: #4752c4;
  --blurple-hi: #949cf7;
  --ease: cubic-bezier(0.22, 0.8, 0.24, 1);
  --font: "Bricolage Grotesque", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
  --pixel: "Silkscreen", var(--mono);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  overflow: hidden;
  background: var(--base);
  color: var(--txt);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
}

h1,
h2,
h3,
p,
ul,
dl,
dd,
figure {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

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

.sr-only,
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 50;
  padding: 10px 14px;
  border-radius: 6px;
  background: var(--blurple);
  color: #fff;
  font-weight: 600;
  transition: top 0.15s;
}
.skip-link:focus {
  top: 12px;
}

.mono {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- app shell */
.app {
  --acc: #8ed15c;
  --stage: #10180e;
  --acc-ink: #111214;
  display: grid;
  grid-template-rows: 64px minmax(0, 1fr) 148px;
  height: 100vh;
  height: 100dvh;
}
#g2:checked ~ .app { --acc: #f0a85b; --stage: #15110d; }
#g3:checked ~ .app { --acc: #4fd6b0; --stage: #0f1a12; }
#g4:checked ~ .app { --acc: #5cc8ff; --stage: #0a0f1e; }
#g5:checked ~ .app { --acc: #ff5c6c; --stage: #0d1120; }

/* ---------------------------------------------------------------- header */
.hd {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 0 28px;
  background: var(--base);
  border-bottom: 1px solid rgba(0, 0, 0, 0.35);
}
.mark {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--pixel);
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.mark img {
  display: block;
  width: 38px;
  height: 38px;
  border-radius: 10px;
}
.hd__tag {
  padding-left: 20px;
  border-left: 1px solid var(--line);
  color: var(--mute);
  font-size: 14px;
}
.hd__nav {
  display: flex;
  gap: 6px;
  margin-left: auto;
}
.hd__nav a,
.hd__nav button {
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 12px;
  font-size: 14px;
  font-weight: 500;
  color: var(--mute);
  transition: color 0.15s;
}
.hd__nav a {
  color: var(--txt);
  box-shadow: inset 0 -2px var(--blurple);
}
.hd__nav button:hover {
  color: var(--txt);
}
.hd__disc {
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 14px;
  border-radius: 6px;
  background: var(--blurple);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  transition: background 0.15s;
}
.hd__disc:hover {
  background: var(--blurple-dark);
}

/* ---------------------------------------------------------------- selected game */
.main {
  position: relative;
  min-height: 0;
}
.game {
  display: none;
  grid-template-columns: minmax(0, 1fr) 42px 268px;
  height: 100%;
  animation: game-in 0.22s ease-out;
}
#g1:checked ~ .app .game--1,
#g2:checked ~ .app .game--2,
#g3:checked ~ .app .game--3,
#g4:checked ~ .app .game--4,
#g5:checked ~ .app .game--5 {
  display: grid;
}
@keyframes game-in {
  from {
    opacity: 0;
  }
}

/* The art always shows whole (contain); a blurred copy fills any gap. */
.stage {
  position: relative;
  overflow: hidden;
  background: var(--stage);
}
.stage__bg {
  position: absolute;
  inset: -48px;
  width: calc(100% + 96px);
  height: calc(100% + 96px);
  object-fit: cover;
  filter: blur(32px) brightness(0.55) saturate(1.1);
}
.stage__cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.px {
  image-rendering: pixelated;
}
.stage::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 38%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent);
  pointer-events: none;
}
.stage__no {
  position: absolute;
  left: 24px;
  top: 22px;
  z-index: 1;
  padding: 5px 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.45);
  color: rgba(255, 255, 255, 0.85);
}

/* In-game screenshots: three tiny thumbnails live on the coloured spine
   (cover, in-game 1, in-game 2). Hovering or focusing one shows it big over
   the art, zooming out from the spine. The thumbnails never move, so the
   hover can't flicker. */
.stage__view {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
  opacity: 0;
  transform: scale(0.2);
  transform-origin: 100% 50%;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.5s var(--ease);
}
.game:has(.spine__shot--1:hover, .spine__shot--1:focus-visible) .stage__view--1,
.game:has(.spine__shot--2:hover, .spine__shot--2:focus-visible) .stage__view--2 {
  opacity: 1;
  transform: none;
}

/* Hovering (or tabbing into) the spine widens it and grows the thumbnails so
   they're easy to check. The spine only ever gets bigger under the pointer,
   so the hover stays stable while it animates. */
.game {
  transition: grid-template-columns 0.4s var(--ease);
}
.game:has(.spine:hover, .spine:focus-within) {
  grid-template-columns: minmax(0, 1fr) 176px 268px;
}
.game:has(.spine:hover, .spine:focus-within) .spine__shots {
  gap: 10px;
}
.game:has(.spine:hover, .spine:focus-within) .spine__shot img {
  width: 148px;
  height: 83px;
  border-radius: 4px;
}
/* Expanded spine reads horizontally: number on top, title at the bottom.
   They fade in after the widening so the flip from vertical isn't seen. */
.game:has(.spine:hover, .spine:focus-within) .spine__label {
  writing-mode: horizontal-tb;
  transform: none;
  max-width: 148px;
  font-size: 11px;
  line-height: 1.35;
  letter-spacing: 0.1em;
  text-align: center;
  animation: spine-label-in 0.25s 0.3s both;
}
@keyframes spine-label-in {
  from {
    opacity: 0;
  }
}

/* Coloured spine between the art and the info sheet */
.spine {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  padding: 18px 0;
  font-size: 10px;
  background: var(--acc);
  color: var(--acc-ink);
}
.spine__label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-weight: 600;
}
.spine__shots {
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: gap 0.4s var(--ease);
}
.spine__shot {
  margin: 0;
  padding: 2px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.18);
  transition: background 0.15s, box-shadow 0.15s;
}
.spine__shot img {
  display: block;
  width: 34px;
  height: 19px;
  object-fit: cover;
  border-radius: 2px;
  transition: width 0.4s var(--ease), height 0.4s var(--ease), border-radius 0.4s;
}
.spine__shot:hover,
.spine__shot:focus-visible {
  background: var(--acc-ink);
  box-shadow: 0 0 0 1px var(--acc-ink);
}
.spine__shot:focus-visible {
  outline: none;
}

/* Info sheet */
.sheet {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  padding: 26px 22px 20px;
  background: linear-gradient(180deg, var(--d2), var(--d1));
  scrollbar-width: thin;
}
.sheet .mono {
  color: var(--blurple-hi);
}
.sheet h1 {
  margin-top: 10px;
  font-size: 29px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}
.sheet h1 small {
  display: block;
  margin-top: 5px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--acc);
}
.desc {
  margin-top: 14px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--soft);
}
.about {
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--d3);
}
.about h2 {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mute);
}
.about p {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  overflow: hidden;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--dim);
}
.facts {
  margin: 14px 0 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.facts > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 12.5px;
}
.facts dt {
  color: var(--mute);
}
.facts dd {
  text-align: right;
}
.lnk {
  color: var(--blurple-hi);
  border-bottom: 1px solid rgba(148, 156, 247, 0.45);
}
.lnk:hover {
  color: #fff;
  border-bottom-color: #fff;
}

.go {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
  margin-top: auto;
  height: 50px;
  padding: 0 16px;
  border-radius: 8px;
  background: var(--blurple);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  transition: background 0.15s, filter 0.15s;
}
.go:hover {
  background: var(--blurple-dark);
}
.go span {
  transition: transform 0.15s;
}
.go:hover span {
  transform: translateX(4px);
}
.sheet .go {
  background: var(--acc);
  color: var(--acc-ink);
}
.sheet .go:hover {
  background: var(--acc);
  filter: brightness(1.1);
}
.sheet .go:focus-visible {
  outline-color: var(--txt);
}
.go + p {
  margin-top: 8px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--mute);
}

/* ---------------------------------------------------------------- shelf */
.shelf {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  background: var(--d1);
  border-top: 1px solid rgba(0, 0, 0, 0.35);
}
.item {
  position: relative;
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  padding: 0 18px;
  border-right: 1px solid var(--line);
  cursor: pointer;
  color: var(--mute);
  transition: background 0.15s, color 0.15s;
}
.item:last-child {
  border-right: 0;
}
.item::before {
  content: "";
  position: absolute;
  left: -1px;
  right: 0;
  top: -1px;
  height: 3px;
  background: var(--i-acc);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.2s;
}
.item--1 { --i-acc: #8ed15c; }
.item--2 { --i-acc: #f0a85b; }
.item--3 { --i-acc: #4fd6b0; }
.item--4 { --i-acc: #5cc8ff; }
.item--5 { --i-acc: #ff5c6c; }
.item img {
  display: block;
  width: 96px;
  height: 54px;
  object-fit: cover;
  filter: saturate(0.55) brightness(0.75);
  transition: filter 0.15s;
}
.item b {
  display: block;
  overflow: hidden;
  margin-top: 5px;
  font-size: 16px;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--txt);
  opacity: 0.75;
}
.item small {
  display: block;
  overflow: hidden;
  margin-top: 4px;
  font-size: 13px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.item:hover {
  background: rgba(78, 80, 88, 0.3);
}
.item:hover img {
  filter: none;
}
#g1:checked ~ .app .item--1,
#g2:checked ~ .app .item--2,
#g3:checked ~ .app .item--3,
#g4:checked ~ .app .item--4,
#g5:checked ~ .app .item--5 {
  background: var(--d3);
  color: var(--txt);
}
#g1:checked ~ .app .item--1::before,
#g2:checked ~ .app .item--2::before,
#g3:checked ~ .app .item--3::before,
#g4:checked ~ .app .item--4::before,
#g5:checked ~ .app .item--5::before {
  transform: scaleX(1);
}
#g1:checked ~ .app .item--1 img,
#g2:checked ~ .app .item--2 img,
#g3:checked ~ .app .item--3 img,
#g4:checked ~ .app .item--4 img,
#g5:checked ~ .app .item--5 img {
  filter: none;
}
#g1:checked ~ .app .item--1 b,
#g2:checked ~ .app .item--2 b,
#g3:checked ~ .app .item--3 b,
#g4:checked ~ .app .item--4 b,
#g5:checked ~ .app .item--5 b {
  opacity: 1;
}
/* The radios themselves are visually hidden; show their focus on the shelf */
#g1:focus-visible ~ .app .item--1,
#g2:focus-visible ~ .app .item--2,
#g3:focus-visible ~ .app .item--3,
#g4:focus-visible ~ .app .item--4,
#g5:focus-visible ~ .app .item--5 {
  outline: 2px solid var(--blurple-hi);
  outline-offset: -4px;
}

/* ---------------------------------------------------------------- panels */
.pop {
  position: fixed;
  inset: 72px 24px auto auto;
  width: 400px;
  max-width: calc(100vw - 24px);
  max-height: calc(100dvh - 96px);
  overflow-y: auto;
  margin: 0;
  padding: 28px;
  border: 0;
  border-radius: 10px;
  background: var(--d2);
  color: var(--txt);
  font-family: var(--font);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}
.pop--contact {
  z-index: 1000;
}
.pop-scrim {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: rgba(12, 11, 10, 0.5);
}
.pop::backdrop {
  background: rgba(12, 11, 10, 0.5);
}
.pop__top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.pop .mono {
  color: var(--blurple-hi);
}
.pop__close {
  font-size: 13px;
  color: var(--mute);
}
.pop__close:hover {
  color: var(--txt);
}
.pop h2 {
  margin-top: 16px;
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.pop p {
  margin-top: 12px;
  font-size: 16px;
  line-height: 1.55;
  color: var(--dim);
}
.pop .go {
  margin-top: 24px;
  width: 100%;
}
.pop ul {
  margin-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.pop li a,
.pop li button {
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 15px;
  color: var(--soft);
  text-align: left;
}
.pop li a:hover,
.pop li button:hover {
  color: var(--blurple-hi);
}

/* Contact form (inside the Contact panel) */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 18px;
}
.contact-form input,
.contact-form textarea {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: var(--base);
  color: var(--txt);
  font: inherit;
  font-size: 15px;
  resize: vertical;
}
.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: var(--mute);
}
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--blurple);
}
.contact-form .go {
  margin-top: 6px;
  justify-content: center;
}
.hp-field {
  position: absolute;
  left: -9999px;
}
/* Turnstile takes no space until it actually shows a checkbox */
.turnstile:empty {
  display: none;
}
#form-status {
  min-height: 1.4em;
  margin-top: 4px;
  font-size: 14px;
  color: var(--soft);
}

/* Cookie consent */
.consent-banner {
  position: fixed;
  left: 20px;
  bottom: 164px;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: 560px;
  padding: 14px 16px;
  border-radius: 10px;
  background: var(--d2);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
  font-size: 14px;
  line-height: 1.45;
  color: var(--dim);
}
.consent-banner[hidden] {
  display: none;
}
.consent-banner a {
  color: var(--blurple-hi);
}
.consent-actions {
  display: flex;
  gap: 8px;
  flex: 0 0 auto;
}
.btn {
  height: 36px;
  padding: 0 14px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  transition: background 0.15s;
}
.btn-primary {
  background: var(--blurple);
  color: #fff;
}
.btn-primary:hover {
  background: var(--blurple-dark);
}
.btn-ghost {
  background: var(--d3);
  color: var(--soft);
}
.btn-ghost:hover {
  background: #404249;
}

/* ---------------------------------------------------------------- shorter screens */
@media (max-height: 780px) {
  .app {
    grid-template-rows: 56px minmax(0, 1fr) 118px;
  }
  .about {
    display: none;
  }
  .item {
    grid-template-columns: 88px minmax(0, 1fr);
  }
  .item img {
    width: 88px;
    height: 50px;
  }
  .sheet {
    padding: 20px 20px 18px;
  }
  .consent-banner { bottom: 132px; }
}

/* ---------------------------------------------------------------- narrower windows */
@media (max-width: 1180px) {
  .hd__tag {
    display: none;
  }
  .item {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
    padding: 10px 12px;
  }
  .item img {
    width: 100%;
    height: 54px;
  }
  .item b {
    margin-top: 0;
    font-size: 14px;
  }
  .item small {
    display: none;
  }
}
@media (max-width: 1000px) {
  .stage__view,
  .spine__shots {
    display: none;
  }
}

/* ---------------------------------------------------------------- phones */
@media (max-width: 760px) {
  .app {
    grid-template-rows: 56px minmax(0, 1fr) 92px;
  }
  .hd {
    gap: 12px;
    padding: 0 16px;
  }
  .hd__disc,
  .hd__nav a {
    display: none;
  }
  .mark {
    font-size: 16px;
    gap: 9px;
  }
  .mark img {
    width: 32px;
    height: 32px;
    border-radius: 8px;
  }
  .hd__nav button {
    padding: 0 8px;
    font-size: 13px;
  }
  .game {
    grid-template-columns: 1fr;
    grid-template-rows: 200px 30px minmax(0, 1fr);
  }
  .stage__no {
    display: none;
  }
  .spine {
    flex-direction: row;
    padding: 0 16px;
  }
  .spine__label {
    writing-mode: horizontal-tb;
    transform: none;
  }
  .sheet {
    padding: 18px 16px 14px;
  }
  .sheet h1 {
    margin-top: 8px;
    font-size: 28px;
  }
  .sheet h1 small {
    font-size: 15px;
  }
  .desc {
    margin-top: 10px;
    font-size: 14.5px;
  }
  .about {
    display: none;
    margin-top: 12px;
  }
  .about p {
    -webkit-line-clamp: 4;
    line-clamp: 4;
  }
  .facts > div {
    font-size: 13px;
  }
  .go + p {
    display: none;
  }
  .item {
    gap: 4px;
    padding: 8px 6px;
    text-align: center;
  }
  .item img {
    height: 44px;
  }
  .item b {
    font-size: 11px;
  }
  .item .mono {
    display: none;
  }
  .pop {
    inset: 64px 12px auto 12px;
    width: auto;
    max-width: none;
  }
  .consent-banner {
    left: 12px;
    right: 12px;
    bottom: 104px;
    flex-direction: column;
    align-items: stretch;
  }
}

/* Tall phones have room for the About text */
@media (max-width: 760px) and (min-height: 880px) {
  .about {
    display: block;
  }
}

@media (prefers-reduced-motion: reduce) {
  .game {
    animation: none;
  }
  *,
  *::before,
  *::after {
    transition: none !important;
  }
}
