/*
 * Every color is sampled from the brand logo
 * (brand-logo-000-badger-000-simple-raw in the asset repo):
 * the fur's blacks and grays, the blue-gray it sits on as the subtle accent,
 * and the amber of its eyes as the strong one — kept for calls to action.
 */
:root {
  /* blacks */
  --black: #000000;
  --bg: #141418;
  --surface: #2b2b33;
  --surface-raised: #35353e;

  /* grays, darkest to lightest */
  --gray-700: #717989;
  --gray-500: #94989f;
  --gray-300: #c8d0da;
  --gray-100: #d6dde5;

  /* accent 1, subtle: the logo's background */
  --blue-gray: #404b61;

  /* accent 2, strong: the eyes. For calls to action only. */
  --amber: #f2a94e;
  --amber-bright: #fcba66;
  --amber-deep: #be864b;

  --ink: var(--gray-100);
  --ink-body: var(--gray-300);
  --muted: var(--gray-500);
  --line: var(--surface-raised);

  --max: 64rem;
  --gutter: 1.25rem;
  --radius: 0.75rem;
  color-scheme: dark;
}

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

/* `hidden` means hidden, even on an element whose class sets a display. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* The brand link and "See our games" jump between the two sections. */
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink-body);
  font: 1.0625rem/1.6 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

a {
  color: var(--ink);
  text-decoration-color: var(--blue-gray);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}
a:hover { text-decoration-color: var(--amber); }

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

h1, h2, h3 { color: var(--ink); }

.site-header,
.container,
.site-footer {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: 1.25rem;
  padding-bottom: 1.25rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
}

/* On the home page the header floats over the carousel's first slide, with
   the brand in the top left corner rather than in the content column. */
.site-header-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  max-width: none;
  padding: 1rem;
}

/* Above the carousel's seam, which reaches into this section's top padding. */
#studio {
  position: relative;
  z-index: 1;
}

/* Top and bottom only: the sides are .container's gutter, which a shorthand
   here would zero — invisible on a desktop, flush to the edge on a phone. */
.hero {
  padding-top: 5rem;
  padding-bottom: 4rem;
}

.hero-with-logo {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}

/* The logo on a disc of the blue-gray it was drawn on. The disc is only the
   gradient, which fades into the page — no border-radius, which would clip
   the ears: the badger is wider than tall and they sit in the corners. */
.hero-logo {
  flex: none;
  width: 240px;
  height: 240px;
  padding: 1.75rem;
  background: radial-gradient(circle, var(--blue-gray) 0%, var(--blue-gray) 55%, var(--bg) 72%);
}

.eyebrow {
  margin: 0 0 0.75rem;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

h1 {
  margin: 0;
  font-size: clamp(2.25rem, 7vw, 4rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.lede {
  max-width: 36rem;
  margin: 1.5rem 0 0;
  color: var(--muted);
  font-size: 1.2rem;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

.button {
  display: inline-block;
  padding: 0.7rem 1.25rem;
  border-radius: 999px;
  font-weight: 700;
  text-decoration: none;
}

.button-primary {
  background: var(--amber);
  color: var(--bg);
}
.button-primary:hover { background: var(--amber-bright); }
.button-primary:active { background: var(--amber-deep); }

.button-secondary {
  border: 1px solid var(--blue-gray);
  color: var(--ink);
}
.button-secondary:hover { background: var(--blue-gray); }

/* ---------- games carousel ---------- */

/* Full screen, and the page continues underneath. svh rather than vh so a
   phone's collapsing address bar doesn't push the buttons off the bottom. */
.carousel {
  /* Named, because the seam's mirrored image has to be exactly this tall to
     line up with the slide it reflects. */
  --carousel-height: max(100svh, 32rem);
  position: relative;
  height: max(100vh, 32rem);
  height: var(--carousel-height);
  background: var(--black);
}

/* Horizontal scroll-snap: one slide per screen, swipeable, no script. */
.carousel-track {
  display: flex;
  height: 100%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.carousel-track::-webkit-scrollbar { display: none; }

.slide {
  position: relative;
  flex: 0 0 100%;
  overflow: hidden;
  scroll-snap-align: start;
  font-family: var(--game-font);
  color: var(--game-ink);
}

.slide-wallpaper {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Title at the top, buttons near the bottom, each on a scrim of the game's
   own background so it reads over any picture. */
.slide-content {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  height: 100%;
  padding: 7rem var(--gutter) max(4rem, 10svh);
  text-align: center;
  background: linear-gradient(to bottom,
    var(--game-scrim) 0%, transparent 35%, transparent 60%, var(--game-scrim) 100%);
}

.slide-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  width: min(36rem, 100%);
}

/* The seam: the bottom of the slide's wallpaper mirrored into the page,
   blurred, and fading out over 100px. The <img> is the full carousel height and
   flipped, so its top row is the wallpaper's bottom row — the same crop the
   slide shows. It overhangs left and right so the blur has pixels to sample
   at the edges instead of fading them out; on screens where the height sets
   the crop (most of them), that overhang doesn't change the alignment. The
   game's scrim goes over it too, as it does over the slide's bottom edge,
   so the reflection starts exactly as dark as the edge it mirrors. It sits
   *under* the section that follows (see #studio), which it overlaps. */
.carousel-seam {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 0;
  height: 100px;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
  mask-image: linear-gradient(to bottom, #000, transparent);
}

.carousel-seam img {
  position: absolute;
  top: 0;
  left: -16px;
  width: calc(100% + 32px);
  height: var(--carousel-height);
  object-fit: cover;
  transform: scaleY(-1);
  filter: blur(6px);
}

.carousel-seam::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--game-scrim);
}

/* ---------- per-game themes ---------- */

/* Blicky in the Mud, in its launcher's own look: the palette of
   blicky-in-the-mud/launcher, monospace, a wide-tracked title with a hard
   black shadow, and flat square keys with a foot. */
.theme-bitm {
  --game-bg: #10140f;
  --game-scrim: rgba(16, 20, 15, 0.85);
  --game-ink: #e8e2d4;
  --game-ink-dim: #9a9382;
  --game-rule: #2f3a2c;
  --game-play: #6fbf73;
  --game-play-foot: #2f5d3a;
  --game-gallery: #2c3729;
  --game-gallery-hover: #33402f;
  --game-gallery-border: #38452f;
  --game-gallery-foot: #161c15;
  --game-font: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

.theme-bitm .slide-title {
  margin: 0;
  padding-left: 0.18em; /* balance the trailing letter-spacing */
  color: var(--game-ink);
  font-size: clamp(2rem, 6vw, 4.5rem);
  line-height: 1.15;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-shadow: 0 3px 0 #000;
}

.theme-bitm .slide-button {
  display: block;
  padding: 1.1rem 1.5rem;
  border: 0;
  border-radius: 0;
  font: inherit;
  font-size: clamp(1rem, 2.5vw, 1.25rem);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
}

.theme-bitm .slide-button-gallery {
  color: var(--game-ink);
  background: var(--game-gallery);
  border: 1px solid var(--game-gallery-border);
  box-shadow: 0 6px 0 0 var(--game-gallery-foot);
}
.theme-bitm .slide-button-gallery:hover { background: var(--game-gallery-hover); }
.theme-bitm .slide-button-gallery:active {
  transform: translateY(2px);
  box-shadow: 0 4px 0 0 var(--game-gallery-foot);
}

.theme-bitm .slide-button-play {
  color: var(--game-bg);
  background: var(--game-play);
  border-bottom: 6px solid var(--game-play-foot);
}
.theme-bitm .slide-button-play:hover { filter: brightness(1.1); }
.theme-bitm .slide-button-play:active {
  transform: translateY(2px);
  border-bottom-width: 4px;
}

.theme-bitm .slide-button:focus-visible,
.theme-bitm .gallery-close:focus-visible {
  outline: 2px solid var(--game-ink);
  outline-offset: 4px;
  border-radius: 0;
}

/* ---------- gallery overlay ---------- */

.gallery {
  width: min(64rem, calc(100% - 2 * var(--gutter)));
  max-height: calc(100% - 4rem);
  padding: 0;
  border: 1px solid var(--game-gallery-border);
  background: var(--game-bg);
  color: var(--game-ink);
  font-family: var(--game-font);
}
.gallery::backdrop { background: rgba(0, 0, 0, 0.8); }

/* Zoomed in, the dialog is one fixed-height column: header and caption take
   what they need and the stage gets exactly the rest, so nothing scrolls and
   the size never changes from one screenshot to the next. Only while open —
   a `display` on a closed <dialog> would override the one that hides it. */
.gallery[open].gallery-viewing {
  display: flex;
  flex-direction: column;
  height: min(calc(100svh - 4rem), 52rem);
  overflow: hidden;
}
.gallery-viewing .gallery-head { flex: none; }
body:has(.gallery[open]) { overflow: hidden; }

.gallery-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--game-rule);
}

.gallery-head h2 {
  margin: 0;
  color: var(--game-ink);
  font-size: 1rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.gallery-close {
  padding: 0.25rem 0.75rem;
  border: 1px solid var(--game-gallery-border);
  background: var(--game-gallery);
  color: var(--game-ink);
  font: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}
.gallery-close:hover { background: var(--game-gallery-hover); }

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
  padding: 1.25rem;
}

/* One shape for every cell, whatever the screenshot's: the full picture is
   one click away in the viewer. */
.gallery-thumb {
  display: block;
  aspect-ratio: 16 / 10;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--game-gallery-border);
  background: var(--game-bg);
  cursor: zoom-in;
}
.gallery-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.2s;
}
.gallery-thumb:hover img { transform: scale(1.04); }

.gallery-viewer {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  margin: 0;
  padding: 1rem 1.25rem 1.25rem;
}
.gallery-viewer:focus { outline: none; }

/* Whatever height the viewer leaves it; each image is fitted inside. */
.gallery-stage {
  position: relative;
  flex: 1;
  min-height: 0;
}

.gallery-track {
  display: flex;
  height: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.gallery-track::-webkit-scrollbar { display: none; }

.gallery-slide {
  display: flex;
  flex: 0 0 100%;
  align-items: center;
  justify-content: center;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

.gallery-slide img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  user-select: none;
}

.gallery-step {
  position: absolute;
  top: 50%;
  width: 3rem;
  height: 3rem;
  padding: 0;
  transform: translateY(-50%);
  border: 1px solid var(--game-gallery-border);
  background: rgba(44, 55, 41, 0.85);
  color: var(--game-ink);
  font: inherit;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}
.gallery-step:hover { background: var(--game-gallery-hover); }
.gallery-step[data-step="-1"] { left: 0.5rem; }
.gallery-step[data-step="1"] { right: 0.5rem; }

.gallery-caption {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1rem;
  color: var(--game-ink-dim);
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.gallery-back {
  padding: 0.5rem 1rem;
  border: 1px solid var(--game-gallery-border);
  background: var(--game-gallery);
  color: var(--game-ink);
  font: inherit;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}
.gallery-back:hover { background: var(--game-gallery-hover); }

.theme-bitm .gallery-thumb:focus-visible,
.theme-bitm .gallery-step:focus-visible,
.theme-bitm .gallery-back:focus-visible {
  outline: 2px solid var(--game-ink);
  outline-offset: 3px;
  border-radius: 0;
}

@media (prefers-reduced-motion: reduce) {
  .gallery-thumb img { transition: none; }
}

.site-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding-top: 2rem;
  padding-bottom: 3rem;
  color: var(--muted);
  font-size: 0.9rem;
  border-top: 1px solid var(--line);
}
.site-footer p { margin: 0; }

.footer-links { display: flex; gap: 1.25rem; }
.footer-links a { color: var(--muted); }
.footer-links a:hover { color: var(--ink); }

/* ---------- legal pages ---------- */

.legal {
  max-width: 44rem;
  padding-top: 1rem;
  padding-bottom: 4rem;
}

.legal h1 {
  font-size: clamp(2rem, 6vw, 2.75rem);
  line-height: 1.1;
}

.legal h2 {
  margin: 2.25rem 0 0.5rem;
  font-size: 1.15rem;
}

.legal p,
.legal ul { margin: 0 0 0.75rem; }

.legal .under {
  margin-top: 0.5rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.legal address {
  margin: 0 0 0.75rem;
  font-style: normal;
  white-space: pre-line;
}

.legal .courtesy {
  margin-top: 2.25rem;
  color: var(--muted);
  font-size: 0.9rem;
  font-style: italic;
}

.legal .back {
  display: inline-block;
  margin-top: 2rem;
}

.languages {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

/* The flags are drawn rather than typed: emoji flags aren't flags on
   Windows, where the letters behind them show through instead. */
.languages button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 1.9rem;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 0.4rem;
  background: var(--surface);
  cursor: pointer;
}
.languages button:hover { border-color: var(--gray-700); }
.languages button[aria-pressed="false"] { opacity: 0.45; }
.languages button[aria-pressed="true"] { border-color: var(--blue-gray); background: var(--blue-gray); }

@media (max-width: 44rem) {
  .hero-with-logo { flex-direction: column; align-items: flex-start; gap: 1.5rem; }
  .hero-logo { width: 176px; height: 176px; padding: 1.25rem; }
  .site-header-overlay .brand span { display: none; }
  /* Always stacked on narrow screens, so a long caption can't change the
     stage's height from one slide to the next by wrapping the button. */
  .gallery-caption { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .slide-button:active { transform: none; }
}
