/* ==========================================================================
   Asset sheet page only.

   Deliberately plain: no atmosphere, no frames, no panels. Every specimen is
   the real element from world.css or console.css, sitting on a neutral
   ground at the size it reaches on the grid. Nothing here restyles a tile,
   the robot or a button — if a specimen looks wrong here, it looks wrong in
   the game.
   ========================================================================== */

.sheet-page {
  background: var(--sheet-bg);
  color: var(--sheet-ink);
}

/* Jump links glide rather than snap. Scroll behaviour has to be set on the
   scrolling element itself, which is the root, not the body. */
@media (prefers-reduced-motion: no-preference) {
  html:has(.sheet-page) { scroll-behavior: smooth; }
}

/* The sheet fills the window: the more room there is, the more specimens sit
   side by side. */
.sheet-shell {
  display: grid;
  grid-template-columns: minmax(9rem, 12rem) minmax(0, 1fr);
  gap: clamp(var(--gap-4), 3vw, 3rem);
  width: 100%;
  padding: clamp(var(--gap-4), 3vw, var(--gap-6));
}

.sheet-main { min-width: 0; }

/* --- Sidebar -------------------------------------------------------------
   The grid item stretches the full height of the page, which is what gives
   the inner block something to stick against.
   ------------------------------------------------------------------------ */

.sidebar__inner {
  position: sticky;
  top: clamp(var(--gap-4), 3vw, var(--gap-6));
  display: grid;
  align-content: start;
  gap: var(--gap-2);
}

.sidebar__title {
  font-family: var(--font-pixel);
  font-size: clamp(1.4rem, 1.1rem + 1.2vw, 1.9rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: .04em;
}

.sidebar__back {
  font-family: var(--font-pixel);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--sheet-soft);
  transition: color 120ms var(--ease-out);
}

.sidebar__back:hover { color: var(--sheet-ink); }

.sidenav {
  display: grid;
  gap: 1px;
  margin-top: var(--gap-3);
  padding-top: var(--gap-3);
  border-top: 1px solid var(--sheet-rule);
}

.sidenav__link {
  padding: var(--gap-2) var(--gap-2);
  border-radius: var(--radius-sm);
  font-family: var(--font-pixel);
  font-size: .7rem;
  letter-spacing: .08em;
  text-decoration: none;
  color: var(--sheet-soft);
  transition: color 120ms var(--ease-out), background 120ms var(--ease-out);
}

.sidenav__link:hover {
  color: var(--sheet-ink);
  background: var(--sheet-tint);
}

.sidenav__link[aria-current] {
  color: var(--sheet-ink);
  background: var(--sheet-tint);
  box-shadow: inset 2px 0 0 var(--sheet-ink);
}

@media (max-width: 760px) {
  .sheet-shell { grid-template-columns: minmax(0, 1fr); }

  .sidebar__inner {
    position: static;
    gap: var(--gap-1);
  }

  .sidenav {
    grid-auto-flow: column;
    justify-content: start;
    gap: var(--gap-1);
    overflow-x: auto;
    scrollbar-width: thin;
  }

  .sidenav__link { white-space: nowrap; }
}

/* --- Sections ------------------------------------------------------------ */

.group {
  /* So a jump link does not land the heading flush against the top. */
  scroll-margin-top: var(--gap-5);
}

.group + .group { margin-top: clamp(var(--gap-6), 5vw, 3.5rem); }

.group__name {
  font-family: var(--font-pixel);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--sheet-soft);
}

/* --- Specimens -----------------------------------------------------------
   One cell is one tile at grid scale. Wider specimens only raise --cols and
   --rows; the same custom properties drive both the box and the grid of
   tiles inside it, exactly as the plot does.
   ------------------------------------------------------------------------ */

.specimens {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(var(--gap-4), 3vw, var(--gap-6));
  margin-top: var(--gap-4);
}

.specimen {
  display: grid;
  justify-items: center;
  gap: var(--gap-2);
}

.specimen__cell {
  --cols: 1;
  --rows: 1;
  position: relative;
  width: calc(var(--tile-size) * var(--cols));
  height: calc(var(--tile-size) * var(--rows));
}

/* --- Robot grid ----------------------------------------------------------
   A livery per row, a heading per column. Four tiles plus a label fits a
   phone without any rearranging.
   ------------------------------------------------------------------------ */

.botgrid {
  display: grid;
  grid-template-columns: 3.6rem repeat(7, var(--tile-size));
  justify-content: start;
  align-items: center;
  /* The row gap carries the sleep bubble, which stands above its tile. */
  gap: var(--gap-4) clamp(var(--gap-3), 3vw, var(--gap-5));
  margin-top: var(--gap-4);
}

.botgrid__view {
  font-family: var(--font-pixel);
  font-size: .64rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: center;
  color: var(--sheet-soft);
}

/* Row label, shared by the robot grid and the ground grid. */
.rowname {
  font-family: var(--font-pixel);
  font-size: .78rem;
  color: var(--sheet-ink);
}

/* --- Animations ----------------------------------------------------------
   At grid scale, like everything else on the sheet. Only the three exits are
   here: they animate the robot's body, so they play identically on every
   livery and one is enough. The one animation that DOES differ per livery is
   the sleep, which lives in the robot grid above for that reason.
   ------------------------------------------------------------------------ */

.animset {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(var(--gap-5), 4vw, var(--gap-6));
  margin-top: var(--gap-4);
}

.animspec {
  display: grid;
  justify-items: center;
  gap: var(--gap-3);
}

.animspec__stage {
  --cols: 1;
  --rows: 1;
  position: relative;
  width: var(--tile-size);
  height: var(--tile-size);
}

.animspec__caption {
  display: grid;
  justify-items: center;
  gap: 2px;
  text-align: center;
}

.animspec__name {
  font-family: var(--font-pixel);
  font-size: .76rem;
  color: var(--sheet-ink);
}

.animspec__note {
  max-width: 16ch;
  font-size: .72rem;
  line-height: 1.35;
  color: var(--sheet-soft);
}

/* --- Terrain -------------------------------------------------------------
   The terrains run across the page, a column each, carrying everything that
   belongs on them: a patch, the two shades it draws from, the blocker it is
   walled with, the hazards it can carry, and the two markers. Reading across
   a row compares the same piece on every terrain.
   ------------------------------------------------------------------------ */

.terraingrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, max-content));
  justify-content: start;
  align-items: start;
  gap: clamp(var(--gap-5), 3vw, var(--gap-6));
  margin-top: var(--gap-4);
}

.terrain {
  display: grid;
  justify-items: start;
  gap: var(--gap-3);
}

.terrain__kit {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--gap-3);
  max-width: calc(var(--tile-size) * 3);
}

.specimen__name {
  font-family: var(--font-pixel);
  font-size: .76rem;
  color: var(--sheet-ink);
}

/* --- Controls ------------------------------------------------------------ */

.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(var(--gap-4), 4vw, var(--gap-6));
  margin-top: var(--gap-4);
}

.controls__set {
  display: grid;
  justify-items: start;
  gap: var(--gap-3);
}

.controls__name {
  font-family: var(--font-pixel);
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--sheet-soft);
}

.controls__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-2);
}

/* --- When the sheet breaks -----------------------------------------------
   The sections are all built by script, so one thrown error leaves the page
   showing its headings and nothing else. This puts the reason on the page
   rather than leaving it to look like a styling bug.
   ------------------------------------------------------------------------ */

.sheet-error {
  position: sticky;
  top: 0;
  z-index: 10;
  display: grid;
  gap: var(--gap-3);
  padding: var(--gap-4);
  font-family: var(--font-body);
  font-size: .82rem;
  color: var(--lit-white);
  background: var(--berry-deep);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
}

.sheet-error__item + .sheet-error__item {
  padding-top: var(--gap-3);
  border-top: 1px solid rgba(255, 255, 255, .25);
}

.sheet-error__where {
  margin: var(--gap-2) 0 0;
  overflow-x: auto;
  font-family: ui-monospace, 'Cascadia Mono', monospace;
  font-size: .72rem;
  line-height: 1.5;
  white-space: pre;
  opacity: .85;
}

/* --- Items ---------------------------------------------------------------
   Things the plot gives the robot, rather than ground it walks on. Shown with
   what they do, because unlike a terrain an item's rule is not visible from
   looking at it.
   ------------------------------------------------------------------------ */

.itemset {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--gap-5);
}

.itemspec {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--gap-4);
  margin: 0;
}

.itemspec__caption { display: grid; gap: 3px; }

.itemspec__name {
  font-family: var(--font-pixel);
  font-size: .8rem;
  letter-spacing: .06em;
  color: var(--sheet-ink);
}

.itemspec__note {
  font-size: .78rem;
  line-height: 1.45;
  color: var(--sheet-soft);
}
