/* --------------------------------------------------------------------------
   Featured hero / carousel
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: max(38rem, 100svh);
  margin-top: -68px; /* slide under the transparent sticky header */
  overflow: hidden;
}

/* the abyss — layered gradient, slow hue drift */
.hero-ocean {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--ocean-bg);
  animation: bg-shift 14s ease-in-out infinite alternate;
}
@keyframes bg-shift {
  0% {
    filter: hue-rotate(0deg) brightness(1);
  }
  100% {
    filter: hue-rotate(14deg) brightness(1.08);
  }
}
.hero-ocean::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ocean-veil);
}

/* rising bubbles */
.depth-particles {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}
.depth-p {
  position: absolute;
  border-radius: 50%;
  background: var(--bubble);
  opacity: 0;
  animation: rise 10s linear infinite;
}
@keyframes rise {
  0% {
    opacity: 0;
    transform: translateY(100vh) scale(0.5);
  }
  15% {
    opacity: 0.6;
  }
  85% {
    opacity: 0.2;
  }
  100% {
    opacity: 0;
    transform: translateY(-10vh) scale(1);
  }
}

.slide {
  display: none;
  flex-direction: column;
  justify-content: flex-end;
  min-height: inherit;
  z-index: 2;
  padding-top: 7.5rem;
}
.slide.active {
  display: flex; /* without JS the first slide simply is the hero */
}
html.js .slide {
  display: flex;
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.9s ease, visibility 0.9s;
}
html.js .slide.active {
  position: relative;
  inset: auto;
  opacity: 1;
  visibility: visible;
}

.slide-copy {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem 3rem;
  align-items: end;
  padding-bottom: 1rem;
}
.slide-info {
  max-width: 40rem;
}

.featured-label {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.1rem;
}
.featured-label .pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pink);
  animation: blink 1.8s infinite;
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.2; }
}

.slide-copy h2 {
  font-size: clamp(2.4rem, 5.5vw, 4.3rem);
  font-weight: 900;
  margin-bottom: 0.35em;
}
.genre-row {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 1.1rem;
}
.slide-line {
  font-size: 1.08rem;
  line-height: 1.7;
  color: var(--ink);
  max-width: 33rem;
  margin: 0 0 1.6rem;
}
.slide-copy .platform-row {
  margin-block: 0 0.5rem;
}

.slide-aside {
  text-align: right;
  padding-bottom: 0.6rem;
}
.aside-num {
  font-family: var(--font-display);
  font-size: 3rem;
  font-weight: 900;
  color: var(--bright);
  line-height: 1;
}
.aside-label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.4rem;
}

.hero .board-art {
  position: relative;
  z-index: 2;
  width: 100%;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 96%);
  mask-image: linear-gradient(180deg, #000 55%, transparent 96%);
  opacity: 0.85;
}

/* the hero's living demo — a round of WordCrew playing itself.
   The full six-row board stays on screen the whole time, empty rows included,
   so the hero reads as the actual game instead of rows that appear and vanish. */
.demo-wrap {
  display: grid;
  gap: 0.7rem;
  justify-items: center;
  padding-bottom: 0.6rem;
  --demo-tile: 42px;
  --demo-gap: 6px;
}
.demo-board {
  display: grid;
  gap: var(--demo-gap);
}
.demo-row {
  display: grid;
  grid-template-columns: repeat(5, var(--demo-tile));
  gap: var(--demo-gap);
}
.demo-tile {
  width: var(--demo-tile);
  height: var(--demo-tile);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(var(--demo-tile) * 0.46);
  line-height: 1;
  text-transform: uppercase;
  color: var(--bright);
  background: color-mix(in srgb, var(--paper) 72%, transparent);
  border: 1px solid var(--bdr2);
  border-radius: 5px;
  transition: transform 180ms ease, background-color 260ms ease,
    border-color 260ms ease, color 200ms ease, box-shadow 200ms ease;
}
.demo-tile.filled {
  animation: demopop 160ms ease;
}
/* the tile waiting for the next letter — same idiom as the game's own cursor */
.demo-tile.is-cursor {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.demo-tile.t-c { background: var(--tile-c); border-color: var(--tile-c); color: var(--tile-c-fg); }
.demo-tile.t-p { background: var(--tile-p); border-color: var(--tile-p); color: var(--tile-p-fg); }
.demo-tile.t-a { background: var(--tile-a); border-color: var(--tile-a); color: var(--tile-a-fg); }
.demo-tile.reveal {
  animation: demoflip 420ms ease both;
}
@keyframes demopop {
  50% { transform: scale(1.12); }
}
@keyframes demoflip {
  0% { transform: rotateX(0); }
  49% { transform: rotateX(90deg); }
  51% { transform: rotateX(90deg); }
  100% { transform: rotateX(0); }
}
.demo-cap {
  color: var(--muted);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
}

.carousel .dots {
  position: absolute;
  left: 50%;
  bottom: 1.1rem;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  gap: 0.55rem;
}
.dot {
  appearance: none;
  width: 9px;
  height: 9px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: transparent;
  cursor: pointer;
  transition: width 200ms ease, background-color 200ms ease;
}
.dot[aria-current="true"] {
  width: 26px;
  background: var(--accent);
  border-color: var(--accent);
}

/* staged entrance on the active slide */
html.js .slide.active .featured-label,
html.js .slide.active h2,
html.js .slide.active .genre-row,
html.js .slide.active .slide-line,
html.js .slide.active .platform-row,
html.js .slide.active .slide-aside {
  animation: slideUp 0.7s ease both;
}
html.js .slide.active h2 { animation-delay: 0.12s; }
html.js .slide.active .genre-row { animation-delay: 0.22s; }
html.js .slide.active .slide-line { animation-delay: 0.32s; }
html.js .slide.active .platform-row { animation-delay: 0.42s; }
html.js .slide.active .slide-aside { animation-delay: 0.52s; }
@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ---------------- the hero on a narrow screen ----------------
   `.hero` pulls itself up by a flat -68px to slide under the transparent
   sticky header. That number is the header's height with the nav on ONE row,
   which is true above 678px and false below it: the header stands at 118px
   and then 154px, while the pull stays 68px. So the overlap is 68px whatever
   the header does, and the rest of it sits on the page background with the
   join running straight THROUGH the nav — the second row of links printed
   onto the hero gradient, which is what reads as broken.

   Matching the number to each breakpoint would work until somebody adds a
   sixth link. So below the width where the header stops being one row, the
   hero simply does not reach up at all: the header is an ordinary band above
   it and there is no overlap to get wrong.

   That also frees `.slide`'s 7.5rem of padding-top, which existed ONLY to
   push the copy clear of the overlapping header — 120px of a phone screen
   spent on a collision that no longer happens. And min-height goes with it:
   `max(38rem, 100svh)` is a floor of 608px on a 568px screen, so the hero was
   taller than the phone by construction and the copy sat in dead space. */
@media (max-width: 49rem) {
  .hero {
    margin-top: 0;
    min-height: 0;
  }
  .slide {
    padding-top: 2rem;
    padding-bottom: 2.5rem;
    justify-content: flex-start;
  }
  .slide-copy {
    grid-template-columns: 1fr;
    gap: 1.5rem;
    padding-bottom: 0;
  }
  .slide-aside { text-align: left; padding-bottom: 0; }
}
