:root {
  --bg-top: #1d2e31;
  --bg-bottom: #253538;
  --panel: rgba(34, 47, 50, 0.96);
  --dock: rgba(40, 55, 58, 0.95);
  --border: rgba(120, 175, 165, 0.28);
  --ink: #d8eae8;
  --muted: #7eaaa6;
  /* The fill behind a selected card. Darkened from #1a8a7a, which put its near-white
     label at 4.13:1 — under the 4.5:1 AA needs for text this size. #177a6c reads 5.07:1
     and is close enough that nothing else in the palette had to move. */
  --teal-900: #177a6c;
  --teal-700: #22a090;
  --focus: #4db8ff;
  --focus-glow: #ffd166;
  --shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
  --radius-xl: 24px;
  --radius-lg: 18px;
  --radius-md: 14px;
  --radius-sm: 10px;
}

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

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(ellipse at 30% 0%, rgba(180, 140, 40, 0.14), transparent 40%),
    radial-gradient(ellipse at 80% 100%, rgba(10, 60, 70, 0.35), transparent 45%),
    linear-gradient(180deg, var(--bg-top) 0%, var(--bg-bottom) 100%);
  color: var(--ink);
  font-family: Roboto, Arial, sans-serif;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

button, input { font: inherit; }
button { cursor: pointer; }

button:focus-visible,
input:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--focus-glow);
}

#sim-app {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 10px;
}

#stage-panel {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 10px;
  padding: 10px;
  border-radius: var(--radius-xl);
  border: 1px solid var(--border);
  background: var(--panel);
  box-shadow: var(--shadow);
  overflow: hidden;
}

#canvas-frame {
  position: relative;
  min-height: 0;
  overflow: hidden;
  border-radius: 20px;
  background:
    radial-gradient(ellipse at 50% 2%, rgba(255, 226, 160, 0.30), transparent 42%),
    radial-gradient(ellipse at 50% 100%, rgba(70, 108, 116, 0.42), transparent 52%),
    linear-gradient(180deg, #47606a 0%, #33474f 52%, #22333a 100%);
  box-shadow: inset 0 0 0 1px rgba(150, 195, 190, 0.20);
}

#sim-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
}

/* The canvas is the sim's main control surface — tabindex=0, role=application, and the
   depth, trees and channel keys all live on it — so it has to show when it holds focus.
   Drawn inside the frame, in the light blue that reads against a dark 3D scene, with a
   soft inner glow so the ring survives wherever the diorama happens to be pale. */
#sim-canvas:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: -3px;
  box-shadow: inset 0 0 0 7px rgba(77, 184, 255, 0.30);
}

/* ── Year track ──────────────────────────────────────────────────────────── */

#year-track {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 14px;
  pointer-events: none;
}

/* What the last year did to the table. Sits just above the year track, same pill style as
   the scene badges, and stays until the next run so nobody has to catch it. */
.table-note {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 84px;
  width: fit-content;
  max-width: calc(100% - 36px);
  margin: 0 auto;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(12, 22, 24, 0.86);
  border: 1px solid rgba(130, 180, 170, 0.34);
  color: #eaf6f3;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  text-align: center;
  pointer-events: none;
}

.table-note[hidden] { display: none; }

@media (max-width: 390px) {
  .table-note { border-radius: 14px; font-size: 13px; }
}

#year-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 6px;
}

#year-head strong {
  font-size: 18px;
  font-weight: 700;
  color: #ffffff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

#year-head span {
  font-size: 14px;
  font-weight: 500;
  color: #dfeeea;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

#year-bar {
  position: relative;
  height: 22px;
  border-radius: 11px;
  background: rgba(12, 22, 24, 0.55);
  border: 1px solid rgba(190, 225, 218, 0.34);
  overflow: hidden;
}

#year-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: linear-gradient(90deg, rgba(34, 160, 144, 0.85), rgba(120, 200, 120, 0.85));
  transition: width 0.1s linear;
}

#year-marker {
  position: absolute;
  top: -3px;
  bottom: -3px;
  left: 0%;
  width: 3px;
  border-radius: 2px;
  background: #ffd166;
  box-shadow: 0 0 6px rgba(255, 209, 102, 0.9);
  transition: left 0.1s linear;
}

.year-band {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid rgba(190, 225, 218, 0.26);
}

.year-band:last-child { border-right: none; }

.year-band span {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: #eaf6f3;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
  white-space: nowrap;
  overflow: hidden;
  padding: 0 4px;
}

/* Narrow screens keep the season names: each band is still about 88px wide at 390px, so
   the words fit once they drop the capitals and the letter-spacing. */
@media (max-width: 640px) {
  .year-band span {
    font-size: 12px;
    letter-spacing: 0;
    text-transform: none;
  }
}

/* Labels that sit on the diorama and name the control underneath them. Sentence case, not
   uppercase: these are words a third grader reads and says out loud, and the two badges
   have to match each other. */
.interaction-hint {
  position: absolute;
  transform: translate(-50%, -100%);
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(12, 22, 24, 0.78);
  border: 1px solid rgba(130, 180, 170, 0.26);
  color: #cfe8e2;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.2px;
  pointer-events: none;
  transition: opacity 0.4s ease;
}

.interaction-hint.hidden { opacity: 0; }

/* While a year is running the setup labels stay on the diorama, but as a plain readout of
   what this pool is ("Depth: Deep"): no pill outline, no dots, no pointer, no hover. A
   greyed or dimmed control still invites a press; a bare label does not, and the student
   can still see which pool is running. */
.interaction-hint.locked {
  pointer-events: none;
  cursor: default;
  background: rgba(12, 22, 24, 0.5);
  border-color: transparent;
  color: #eaf6f3;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

.interaction-hint.locked .badge-dots { display: none; }

/* Anchored to a place in the 3D scene rather than a corner of the frame; JS sets
   left/top from the projected world point each frame. */
.scene-badge {
  top: 0;
  left: 0;
  right: auto;
  transform: translate(-50%, -50%);
  border-color: rgba(160, 216, 232, 0.45);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

/* The depth badge is a real control, not a caption: it is a second grab handle for the
   knob it sits beside, so it takes pointer events and drags vertically. It is a much
   bigger target than the knob, which matters for the age band. */
.depth-badge {
  pointer-events: auto;
  gap: 4px;
  padding: 4px 8px;
  cursor: ns-resize;
  touch-action: none;
  user-select: none;
}

/* The channel badge presses too, so all three scene labels are handles rather than one
   caption among two controls — and a label that takes hover is the only way it can carry a
   tooltip like the other two. The groove underneath still works; this is a second target. */
.channel-badge {
  pointer-events: auto;
  cursor: pointer;
  user-select: none;
}

/* The trees badge is a tap target: one press moves to the next of the three states. */
.trees-badge {
  pointer-events: auto;
  gap: 7px;
  padding: 4px 8px;
  cursor: pointer;
  user-select: none;
}

/* Carousel dots: how many states there are, and which one you are on. */
.badge-dots {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-left: 2px;
  border-left: 1px solid rgba(160, 216, 232, 0.28);
  margin-left: 1px;
}

.badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid rgba(190, 230, 240, 0.6);
  background: transparent;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.badge-dot:first-child { margin-left: 3px; }
.badge-dot.on { background: #eafaff; border-color: #eafaff; }

.depth-badge .hint-label strong,
.trees-badge .hint-label strong {
  color: #eafaff;
  font-weight: 700;
}

.scene-badge.hot {
  background: rgba(30, 74, 84, 0.92);
  border-color: #9fd8e8;
  color: #eafaff;
}

/* ── Control tooltip ─────────────────────────────────────────────────────── */

#tip {
  position: fixed;
  z-index: 60;
  max-width: 290px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: #08181a;
  border: 1px solid rgba(150, 200, 192, 0.4);
  color: #eaf7f4;
  font-size: 13.5px;
  line-height: 1.45;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.55);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}

#tip.show {
  opacity: 1;
  transform: translateY(0);
}

/* ── Controls dock ───────────────────────────────────────────────────────── */

#controls-dock {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-lg);
  background: var(--dock);
  border: 1px solid var(--border);
}

.control-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 8px 12px 10px;
  border-radius: var(--radius-md);
  background: rgba(12, 20, 22, 0.55);
  border: 1px solid rgba(90, 140, 130, 0.16);
}

.card-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--muted);
}

.seg-btns {
  display: flex;
  gap: 5px;
}

.seg-btn {
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(110, 160, 150, 0.26);
  background: rgba(30, 44, 46, 0.9);
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.seg-btn:hover { background: rgba(42, 62, 64, 0.95); }

.seg-btn.active {
  background: var(--teal-900);
  border-color: var(--teal-700);
  color: #f2fffc;
}

/* ── Species toggles ─────────────────────────────────────────────────────── */

.species-card { flex: 1 1 320px; }

.species-btns {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.species-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px 5px 6px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(110, 160, 150, 0.26);
  background: rgba(30, 44, 46, 0.9);
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.species-btn canvas {
  display: block;
  width: 38px;
  height: 28px;
  border-radius: 5px;
  /* A pool-water ground behind the animal, since these are all aquatic forms. */
  background: rgba(74, 144, 168, 0.42);
}

.species-btn:hover:not(:disabled) { background: rgba(42, 62, 64, 0.95); }

/* Dimmed while a year runs, not hidden: these cards double as the key for what is in the
   pool, and that is exactly what a student wants to read WHILE watching the year. */
.species-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.species-btn.active {
  background: var(--teal-900);
  border-color: var(--teal-700);
  color: #f2fffc;
}

/* ── Arrivals legend ─────────────────────────────────────────────────────── */
/* Reads as a key, not a control: no fill, no pressed state, dimmed when the animal is
   not in the pool. Dimming rather than hiding so a student can see these exist and learn
   what brings them. */

/* Stacked on purpose: the toggles wrap unpredictably, and a vertical divider between
   them and the arrivals ended up orphaned at the right edge whenever they did. */
.species-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.arrival-split {
  height: 1px;
  margin: 2px 0 0;
  background: rgba(140, 190, 180, 0.26);
}

.arrival-block {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.arrival-heading {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--muted);
}

.arrival-items {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* Dimming the whole row to 0.38 put this text at 1.99:1, which is unreadable and well
   under AA — and it is a key, so it has to be read in exactly the state that says the
   animal is absent. The absent/present difference is carried by the ICON instead, which
   no contrast rule applies to, while the words stay at full opacity. */
.arrival-item {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 2px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: color 0.2s ease;
}

.arrival-item.here { color: #e6f5f1; }

.arrival-item.here canvas {
  opacity: 1;
  filter: none;
}

.arrival-item canvas {
  display: block;
  width: 38px;
  height: 28px;
  border-radius: 5px;
  background: rgba(74, 144, 168, 0.42);
  opacity: 0.42;
  filter: saturate(0.3);
  transition: opacity 0.2s ease, filter 0.2s ease;
}

.arrival-item.here canvas {
  opacity: 1;
  filter: none;
}

.arrival-item .arrival-note {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--muted);
}

/* ── Info dialog ─────────────────────────────────────────────────────────── */

/* Verbatim copy of the boilerplate block, not a per-sim restyle (machine-verifiable
   COLOR-2 / TYPO-4). The dialog is Tuva Sims chrome, not the sim's: the shared toolbar
   injects #info-dialog-scoped rules after this stylesheet and wins on specificity, so a
   per-sim recolor here is dead weight that only drifts. This sim used to carry a green
   header, its own tab pills and its own dialog typography. */
#info-dialog {
  border: none;
  border-radius: 12px;
  padding: 0;
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 80px);
  overflow: hidden;
  margin: auto;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.22);
  background: #ffffff;
  /* The dialog is white, but the page theme is dark and sets --ink / --muted pale. Reset
     them here to the boilerplate's values so the dialog text reads dark on white. */
  --ink: #2C3E3E;
  --muted: #5A6E6E;
}

#info-dialog::backdrop {
  background: rgba(30, 16, 48, 0.55);
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  background: #5c4738;
  color: #ffffff;
}

.dialog-header h2 {
  font-size: 16px;
  font-weight: 600;
}

#dialog-close-btn {
  background: transparent;
  border: none;
  color: #ffffff;
  font-size: 18px;
  cursor: pointer;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

#dialog-close-btn:hover {
  background: rgba(255, 255, 255, 0.15);
}

#dialog-close-btn:focus-visible {
  outline: 3px solid var(--focus-glow);
  outline-offset: 2px;
}

.dialog-tabs {
  display: flex;
  border-bottom: 2px solid #E5EAE9;
  background: #F8FBFB;
}

.tab-btn {
  flex: 1;
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  padding: 10px 0;
  font-family: Roboto, Arial, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.tab-btn:hover {
  color: #5c4738;
}

.tab-btn.active,
.tab-btn[aria-selected="true"] {
  color: #5c4738;
  border-bottom-color: #5c4738;
}

.tab-btn:focus-visible {
  outline: 3px solid var(--focus-glow);
  outline-offset: -3px;
}

.dialog-body {
  padding: 16px 20px;
  overflow-y: auto;
  max-height: calc(100vh - 240px);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.55;
}

.dialog-body h3 {
  font-size: 14px;
  font-weight: 600;
  color: #5c4738;
  margin-top: 14px;
  margin-bottom: 6px;
}

.dialog-body h3:first-child {
  margin-top: 0;
}

.dialog-body p {
  margin-bottom: 8px;
}

.dialog-body ul,
.dialog-body ol {
  padding-left: 20px;
  margin-bottom: 8px;
}

.dialog-body li {
  margin-bottom: 4px;
}

#info-dialog summary {
  cursor: pointer;
  font-weight: 600;
  color: #5c4738;
  margin-top: 12px;
}

.standard-tag {
  display: inline-block;
  padding: 1px 7px;
  margin-right: 5px;
  border-radius: 5px;
  background: #e7f1f0;
  color: #004445;
  font-weight: 600;
  font-size: 13px;
}

@media (max-width: 720px) {
  #controls-dock { gap: 7px; padding: 8px; }
  .control-card { padding: 6px 9px 8px; }
  .seg-btn { padding: 6px 9px; font-size: 12px; }
  .species-btn { font-size: 14px; }
}
/* Shown only when WebGL cannot start: the scene is empty, and this says why. */
#no-gl { position: absolute; z-index: 5; top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: min(380px, calc(100% - 24px)); padding: 12px 16px; line-height: 1.45; background: var(--panel); color: var(--ink); border: 1px solid var(--border); border-radius: 10px; text-align: center; pointer-events: none; }
