html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #000;
}

body {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  font-family: system-ui, sans-serif;
  color: #fff;
}

/* The Stage is the viewport; the World is the full-length canvas that
   scrolls inside it. Pointer-driven pan/zoom (SPEC.md §9) replaces this
   native scrollbar in a later ticket without changing this structure.
   flex: 1 (rather than a fixed 100vh) so the Stage still fills the rest of
   the viewport when the runtime-validation banner (SPEC.md §5, layer 3) is
   present above it. */
#stage {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow-x: auto;
  overflow-y: hidden;
}

#world {
  position: relative;
  height: 100%;
}

/* The Axis (SPEC.md §7): one solid black bar running through the middle of
   the page, carrying the year numerals and every Event's Tick inside
   itself. There is no pale strip and no gutter — once Blocks land (#28,
   #29) they butt directly against its top and bottom edges. */
.axis {
  /* height set inline from render/axis.ts's AXIS_HEIGHT — the one source of truth for the Axis's own geometry */
  position: absolute;
  left: 0;
  top: 50%;
  background: #000;
  transform: translateY(-50%);
}

.axis__year {
  position: absolute;
  top: 12px;
  height: 14px;
  line-height: 14px;
  transform: translateX(-50%);
  color: #fff;
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.axis__tick {
  position: absolute;
  width: 3px;
  height: 12px;
  transform: translateX(-50%);
}

.axis__tick--above {
  top: 0;
}

.axis__tick--below {
  bottom: 0;
}

.content-error-banner {
  margin: 0;
  padding: 0.75em 1em;
  background: #7a1b1b;
  color: #fff;
  font-weight: 700;
}
