/* ---------------------------------------------------------------------------
   Montezuma's Revenge (CoCo 3) — landing page

   Every colour below is a real GIME palette entry from the game's own RGB
   palette set (includes/paletteData.asm), decoded from the 6-bit
   %R1G1B1R0G0B0 register format. No other colours are used.
   --------------------------------------------------------------------------- */

:root {
  --black:  #000000;  /* 0  — background */
  --orange: #FFAA00;  /* 52 — title-room brick */
  --red:    #AA0000;  /* 32 — mortar */
  --white:  #FFFFFF;  /* 63 */
  --grey:   #AAAAAA;  /* 56 */
  --cyan:   #55FFFF;  /* 31 — ladders and ropes */
  --yellow: #FFFF55;  /* 55 — Joe's hat, jewels */
  --pink:   #FFAAAA;  /* 60 — Joe's skin */
  --olive:  #555500;  /* 6  — mortar in the deeper rooms */

  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas,
          "DejaVu Sans Mono", "Courier New", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, sans-serif;

  /* The game's own tile.fullBrick, extracted by scripts/extract-page-art.py:
     8x8 holding two staggered 8x4 bricks. Drawn at 4x, so one brick spans
     --brick-tile across and half that down.

     --brick-tile is the page's unit of distance: Joe's patrol is paced in
     bricks per second against it (see the script in index.html), so his
     apparent speed does not depend on window width or zoom. A brick is as wide
     as the whole tile but only half as tall, so the vertical unit is the
     course, and mixing the two is what once made the band twice its height. */
  --brick: url("art/brick.png");
  --brick-tile: 32px;                            /* the 8x8 tile, drawn at 4x */
  --brick-course: calc(var(--brick-tile) / 2);   /* one course: an 8x4 brick */
  --band-h: calc(var(--brick-course) * 2);       /* the band is two courses */
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--black);
  color: var(--white);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.25vw, 1.125rem);
  line-height: 1.65;
  -webkit-text-size-adjust: 100%;
}

.wrap {
  max-width: 62rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* --- brick banding ------------------------------------------------------- */

.bricks.band {
  height: var(--band-h);
  background-image: var(--brick);
  background-size: var(--brick-tile) var(--brick-tile);
  background-repeat: repeat;
  image-rendering: pixelated;
}

/* --- extracted game art -------------------------------------------------- */

/* Every img.pix is real game artwork at an integer scale, so nearest-neighbour
   keeps the original pixel grid intact.

   max-width: none is load-bearing. These images carry exact width/height
   attributes and some deliberately overhang their container -- the Joe on the
   pole is 64px wide over a 32px strip. A stylesheet we do not control (a host
   reset, a user stylesheet) that sets `img { max-width: 100% }` without
   `height: auto` would clamp the width while the height attribute held, and
   squash the sprite horizontally. */
.pix {
  display: block;
  max-width: none;
  image-rendering: pixelated;
}

.hicon {
  display: inline-block;
  margin-right: 0.7rem;
  vertical-align: -0.1em;
}

/* A lineup standing on a brick floor: names above, feet on the bricks. */
.cast {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  align-items: stretch;          /* equal-height cells: names line up */
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.cast-item {
  display: grid;
  grid-template-rows: auto 1fr;  /* name, then figure pushed to the floor */
  align-items: end;
  justify-items: center;
  gap: 0.9rem;
}

.cast-name {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--yellow);
  text-align: center;
}

.bricks.floor {
  height: var(--brick-course);
  background-image: var(--brick);
  background-size: var(--brick-tile) var(--brick-tile);
  /* start mid-tile so the strip reads as a single course of bricks */
  background-position: 0 calc(var(--brick-course) * -1);
  image-rendering: pixelated;
}

/* Item glyphs, bottom-aligned so they sit on a common line. */
.glyphs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
  gap: 1.75rem 1rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
}

.glyphs li {
  display: grid;
  grid-template-rows: 1fr auto;  /* glyphs sit on a common line, names below */
  align-items: end;
  justify-items: center;
  gap: 0.8rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--grey);
  text-align: center;
}

/* Decorative sprites out in the gutter beside the text column. They are
   hidden rather than reflowed once the gutter is gone. */
.margin-art {
  position: absolute;
  top: clamp(4rem, 9vw, 7rem);
}

/* Gutter art alternates side down the page: spider left, snake right, skull
   left, then the ladder, pole and rope strips right, left, right. */
.art-spider { right: calc(50% + 32.5rem); }
.art-snake { left: calc(50% + 32.5rem); }
.art-skull { right: calc(50% + 32.5rem); }

.art-ladder,
.art-pole,
.art-rope {
  position: absolute;
  background-repeat: repeat-y;
  image-rendering: pixelated;
}

.art-ladder {
  left: calc(50% + 32.5rem);
  width: 64px;
  height: 256px;
  background-image: url("art/ladder.png");
  background-size: 64px 32px;
}

.art-ladder img { margin: 88px 0 0; }

.art-pole {
  right: calc(50% + 33.5rem);
  width: 32px;
  height: 288px;
  background-image: url("art/pole.png");
  background-size: 32px 32px;
}

.art-pole img { margin: 104px 0 0 -16px; }

.art-rope {
  left: calc(50% + 33.5rem);
  width: 32px;
  height: 272px;
  background-image: url("art/rope.png");
  background-size: 32px 32px;
}

.art-rope img { margin: 96px 0 0 -16px; }

/* Band walkers: a sprite that paces back and forth along a brick band.
   Two instances -- Joe walking above "The game", a skull rolling along the
   footer. Both work the same way: two stacked filmstrips, one per direction,
   cross-faded at the turn so each direction uses the game's own frames rather
   than one of them mirrored.

   Durations here are the no-script fallback. pace() in index.html recomputes
   them from the measured travel distance so speed is a fixed number of bricks
   per second whatever the window width or zoom. The facing swap must always be
   exactly twice the patrol -- one full round trip.

   These animations run unconditionally, by the author's choice: deliberately
   outside the prefers-reduced-motion gate that still covers smooth scrolling
   and the button hover. */
.band-stage {
  position: relative;
  padding-top: 88px;             /* clearance so a walker never overlaps text */
}

.walker {
  --inset: 20px;                 /* gap left at each end of the walk */
  --bricks-per-sec: 3.75;        /* pace() reads this; per-instance below */
  position: absolute;
  /* --band-h, not a literal: feet land on top of the band by construction, so
     the two cannot drift apart. */
  bottom: var(--band-h);
  left: max(var(--inset), calc(50% - 31rem));
  width: var(--w);
  height: var(--h);
}

.facing {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  image-rendering: pixelated;
}

/* facing-a travels right and is the one visible at t=0, because the patrol
   alternates and so starts left-to-right. facing-b travels left. */
.facing-b { opacity: 0; }

@keyframes patrol {
  from { left: var(--inset); }
  to { left: calc(100% - var(--w) - var(--inset)); }
}

@keyframes face-a {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

@keyframes face-b {
  0%, 50% { opacity: 0; }
  50.01%, 100% { opacity: 1; }
}

/* --- Joe: 3 frames of 20x20 at 4x -------------------------------------- */

.walker-joe { --w: 80px; --h: 80px; }

.walker-joe .facing { background-size: 240px 80px; }

.walker-joe .facing-a { background-image: url("art/joe-walk-right.png"); }
.walker-joe .facing-b { background-image: url("art/joe-walk-left.png"); }

@keyframes joe-step {
  from { background-position: 0 0; }
  to { background-position: -240px 0; }
}

.walker-joe { animation: patrol 15s linear infinite alternate; }

.walker-joe .facing-a {
  animation: joe-step 0.48s steps(3) infinite, face-a 30s linear infinite;
}

.walker-joe .facing-b {
  animation: joe-step 0.48s steps(3) infinite, face-b 30s linear infinite;
}

/* --- skull: the 8 rotation phases, 16x14 at 4x -------------------------- */

/* A rolling skull turns the way it travels, so facing-a steps the phases
   clockwise, and its roll rate is geometry rather than taste: the skull is 64px
   across, so one turn covers pi * 64 = 201px, and at 5.625 bricks/sec
   (180px/sec) that is 1.12s. Set it otherwise and the skull skids. The two
   numbers move together -- change the pace and the roll must follow. */
.walker-skull {
  --w: 64px;
  --h: 56px;
  --bricks-per-sec: 5.625;       /* 1.5x Joe's pace */
}

.walker-skull .facing { background-size: 512px 56px; }

.walker-skull .facing-a { background-image: url("art/skull-roll-right.png"); }
.walker-skull .facing-b { background-image: url("art/skull-roll-left.png"); }

@keyframes skull-step {
  from { background-position: 0 0; }
  to { background-position: -512px 0; }
}

.walker-skull { animation: patrol 10s linear infinite alternate; }

.walker-skull .facing-a {
  animation: skull-step 1.12s steps(8) infinite, face-a 20s linear infinite;
}

.walker-skull .facing-b {
  animation: skull-step 1.12s steps(8) infinite, face-b 20s linear infinite;
}

/* --- headings ------------------------------------------------------------ */

h1, h2, h3, .eyebrow, .btn, kbd, .term, th {
  font-family: var(--mono);
}

h1 {
  margin: 0.6rem 0 0.5rem;
  font-size: clamp(2.1rem, 8vw, 4.25rem);
  line-height: 1.02;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--orange);
  text-shadow: 4px 4px 0 var(--red);
}

h2 {
  margin: 0 0 1.4rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--red);
  font-size: clamp(1.35rem, 3.4vw, 1.9rem);
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--orange);
}

h3 {
  margin: 2.2rem 0 0.6rem;
  font-size: 1.05rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--yellow);
}

.eyebrow {
  margin: 0;
  font-size: 0.8rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cyan);
}

/* --- text --------------------------------------------------------------- */

p { max-width: 46rem; }

.tagline {
  margin: 0 0 1.25rem;
  font-size: clamp(1.1rem, 2.4vw, 1.4rem);
  color: var(--white);
}

.pitch { color: var(--grey); }

.caption,
.credits,
figcaption {
  font-size: 0.9rem;
  color: var(--grey);
}

.note {
  border-left: 4px solid var(--orange);
  padding-left: 1rem;
  color: var(--grey);
}

.nowrap { white-space: nowrap; }

a {
  color: var(--cyan);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

a:hover { color: var(--yellow); }

:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
}

/* --- layout ------------------------------------------------------------- */

.hero { padding-bottom: clamp(1rem, 3vw, 2rem); }

.hero .wrap { padding-top: clamp(2rem, 6vw, 4rem); }

main section {
  position: relative;            /* anchor for .margin-art */
  padding: clamp(2.5rem, 6vw, 4.5rem) 0 0;
  scroll-margin-top: 1.5rem;
}

main section:last-child { padding-bottom: clamp(2.5rem, 6vw, 4.5rem); }

/* --- buttons ------------------------------------------------------------ */

.cta {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: stretch;
  max-width: none;
  margin: 1.75rem 0 2.5rem;
}

.cta-inline { margin: 0 0 1rem; }

/* The hero pair sits under the screenshot and spans it: download at the left
   edge, "watch it play" flush with the screenshot's right edge. Both are inside
   the same .wrap as the image, so its content edges are the alignment. */
.hero .cta {
  justify-content: space-between;
  margin: 1.75rem 0 0.5rem;
}

.btn {
  display: block;
  padding: 0.85rem 1.4rem;
  border: 3px solid var(--orange);
  background: var(--black);
  box-shadow: 5px 5px 0 var(--red);
  color: var(--yellow);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

.btn:hover,
.btn:focus-visible {
  background: var(--yellow);
  border-color: var(--yellow);
  box-shadow: 7px 7px 0 var(--red);
  color: var(--black);
  transform: translate(-2px, -2px);
}

.btn-sub {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: none;
  color: var(--grey);
}

.btn:hover .btn-sub,
.btn:focus-visible .btn-sub { color: var(--red); }

.btn-ghost {
  align-self: flex-start;
  border-color: var(--cyan);
  color: var(--cyan);
  box-shadow: 5px 5px 0 var(--olive);
}

.btn-ghost:hover,
.btn-ghost:focus-visible {
  background: var(--cyan);
  border-color: var(--cyan);
  box-shadow: 7px 7px 0 var(--olive);
  color: var(--black);
}

/* --- screenshots -------------------------------------------------------- */

.shot { margin: 0; }

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 2px solid var(--red);
  background: var(--black);
  image-rendering: pixelated;
}

.hero-shot img { box-shadow: 10px 10px 0 var(--olive); }

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.75rem;
  margin-bottom: 1.25rem;
}

.gallery .shot img { cursor: zoom-in; }

.gallery .shot img:hover { border-color: var(--yellow); }

figcaption { margin-top: 0.6rem; }

/* --- video -------------------------------------------------------------- */

.player { margin-bottom: 1rem; }

/* The embed gets a fixed 16:9 frame in the page's own border, so it sits in the
   layout like the screenshots rather than like a third-party widget. */
.player iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 2px solid var(--red);
  background: var(--black);
}

/* --- lists -------------------------------------------------------------- */

.features,
.plain {
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
}

.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 0.55rem 2rem;
}

.features li,
.plain li {
  position: relative;
  padding-left: 1.5rem;
  max-width: 46rem;
}

.plain li { margin-bottom: 0.7rem; }

.features li::before,
.plain li::before {
  content: "\25AA";
  position: absolute;
  left: 0;
  color: var(--yellow);
}

.plain li::before { color: var(--orange); }

.plain strong { color: var(--white); }

/* --- controls table ----------------------------------------------------- */

.keys {
  width: 100%;
  max-width: 46rem;
  border-collapse: collapse;
  text-align: left;
}

.keys th {
  width: 1%;
  padding: 0.85rem 1.5rem 0.85rem 0;
  border-top: 1px solid var(--olive);
  vertical-align: top;
  white-space: nowrap;
  font-weight: normal;
  color: var(--yellow);
}

.keys td {
  padding: 0.85rem 0;
  border-top: 1px solid var(--olive);
  vertical-align: top;
  color: var(--grey);
}

kbd {
  display: inline-block;
  padding: 0.05em 0.4em;
  border: 2px solid var(--cyan);
  background: var(--black);
  color: var(--cyan);
  font-size: 0.85em;
  line-height: 1.4;
  white-space: nowrap;
}

.term {
  max-width: 46rem;
  margin: 1rem 0 1.5rem;
  padding: 1rem 1.2rem;
  border: 2px solid var(--cyan);
  background: var(--black);
  color: var(--cyan);
  overflow-x: auto;
}

.term code { font: inherit; }

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

/* .band-stage supplies the gap above via its padding, so the band needs no
   margin of its own -- a margin here would also inflate the stage. */
footer .wrap {
  padding-top: 2rem;
  padding-bottom: 3rem;
}

footer .credits { max-width: 48rem; }

footer strong { color: var(--pink); }

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

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.75rem, 3vw, 2.5rem);
  background: var(--black);
  cursor: zoom-out;
}

.lightbox[hidden] { display: none; }

.lightbox img {
  max-width: 100%;
  max-height: 100%;
  border: 2px solid var(--red);
  image-rendering: pixelated;
}

/* --- narrow screens ----------------------------------------------------- */

/* Below this there is no gutter left to decorate. */
@media (max-width: 84rem) {
  .margin-art { display: none; }
}

@media (max-width: 40rem) {
  .cast { gap: 1rem; }
  .hicon { margin-right: 0.5rem; }

  .keys th,
  .keys td {
    display: block;
    width: auto;
    padding: 0;
  }

  .keys th {
    border-top: 1px solid var(--olive);
    padding-top: 0.85rem;
  }

  .keys td {
    padding-bottom: 0.85rem;
    border-top: 0;
  }

  .btn { width: 100%; }

  h1 { text-shadow: 3px 3px 0 var(--red); }
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  .btn { transition: transform 0.08s steps(2), background-color 0.08s; }
}
