/* CSS owns presentation — including the canvas.
 *
 * Every colour the renderer draws is read out of these custom properties at
 * runtime. render.js contains no hex codes at all, so the entire look of the game
 * lives in this one block. The game ships dark, and only dark — there is no light
 * theme and no toggle. (The shell may still send a dark signal; the game simply
 * ignores it, because it is already dark.) */

:root {
  color-scheme: dark;

  --c-sky: #16202c;
  --c-sky-fast: #38506b;
  --c-sky-back: #0e1620;
  --c-streak: #8fb4d9;

  --c-ground: #2b3327;
  --c-ground-edge: #47543c;

  --c-balloon: #e2603c;
  --c-balloon-shade: #96351f;
  --c-basket: #57391f;
  --c-flame: #ffcf6b;

  --c-pad: #47c79a;
  --c-pad-glow: #47c79a;

  --c-bird: #b9c3cd;
  --c-bird-perched: #ef7060;

  --c-predict: #9dc8f0;
  --c-predict-bad: #ef7060;

  /* The touchdown reticle. Colour is SEVERITY, not position: green = feather, amber =
   * hard but survivable, red (--c-predict-bad) = fatal. Whether you are on the pad is
   * shown by the bracket being solid or dashed. Conflating the two meant a 2.97 m/s
   * touchdown — a hair from death — was drawn the same green as a perfect one. */
  --c-touch-ok: #47c79a;
  --c-touch-hard: #e8a04a;

  --c-sock: #9aa3ad;
  --c-sock-cloth: #f0873a; /* the orange bands */
  --c-sock-band: #e6e0d2;  /* and the white ones */

  --c-ink: #e8ecf1;
  --c-ink-soft: #8b949e;

  --ui-bg: #10151b;
  --ui-panel: #1a222c;
  --ui-line: #2b3440;
  --ui-text: #e8ecf1;
  --ui-dim: #8b949e;
  --ui-accent: #47c79a;
  --ui-warn: #ef7060;

  --pad: 10px;
  --radius: 10px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--ui-bg);
  color: var(--ui-text);
  font: 500 15px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-text-size-adjust: 100%;
}

#game {
  height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  outline: none;
  padding-bottom: env(safe-area-inset-bottom);
}

/* ---------------------------------------------------------------- bar */

#bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pad);
  padding: var(--pad) 14px;
  border-bottom: 1px solid var(--ui-line);
  background: var(--ui-panel);
}

/* The title bar IS the level button. No extra chrome for a thing you press twice
 * a session — but it must still look pressable, so it gets a caret. */
#titles {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  gap: 1px;
  padding: 4px 22px 4px 6px;
  margin-left: -6px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  position: relative;
}
#titles::after {
  content: '';
  position: absolute;
  right: 7px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-right: 1.5px solid var(--ui-dim);
  border-bottom: 1.5px solid var(--ui-dim);
  transform: translateY(-70%) rotate(45deg);
}
#titles:active { background: var(--ui-bg); }
#level-name { font-weight: 600; letter-spacing: -0.01em; }
#level-par { font-size: 12px; color: var(--ui-dim); }

#readouts {
  display: flex;
  gap: 12px;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--ui-dim);
}
#readouts span { min-width: 3.4em; text-align: right; }

/* Speed. Small, quiet, and never where a thumb lands by accident. */
#speed {
  min-width: 40px;
  padding: 7px 8px;
  border: 1px solid var(--ui-line);
  border-radius: 8px;
  background: var(--ui-bg);
  color: var(--ui-dim);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
#speed[data-fast="true"] { color: var(--ui-accent); border-color: var(--ui-accent); }

#devbar {
  display: flex;
  gap: 6px;
  padding: 8px 12px 0;
}
#devbar[hidden] { display: none; }
#devbar button {
  flex: 1;
  padding: 8px;
  border: 1px dashed var(--ui-line);
  border-radius: 8px;
  background: transparent;
  color: var(--ui-dim);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
#devbar button[data-on="true"] { color: var(--ui-accent); border-color: var(--ui-accent); }
#readout-mass.warn { color: var(--ui-warn); font-weight: 700; }

/* Sink rate. Amber once you are coming down harder than a feather; red once you are
 * coming down harder than you can survive. */
#readout-vs.warn { color: var(--c-touch-hard); font-weight: 700; }
#readout-vs.danger { color: var(--ui-warn); font-weight: 800; }

/* ---------------------------------------------------------------- stage */

#stage-wrap { position: relative; overflow: hidden; }
#stage { display: block; width: 100%; height: 100%; touch-action: none; }

/* While the level is armed or paused, the stage invites a scouting drag. */
#stage[data-recon="true"] { cursor: grab; }
#stage[data-recon="true"]:active { cursor: grabbing; }

/* The big pre-flight Play button, centred over the launch point. It is deliberately
 * large and soft — the first thing you see on a level, and a clear "when you're ready". */
#play {
  position: absolute;
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  width: 84px;
  height: 84px;
  border: none;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ui-accent) 92%, transparent);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
  animation: play-pulse 2.4s ease-in-out infinite;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
#play[hidden] { display: none; }
#play svg { width: 40px; height: 40px; fill: currentColor; margin-left: 4px; }
#play:active { transform: translate(-50%, -50%) scale(0.94); }

@keyframes play-pulse {
  0%, 100% { box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28), 0 0 0 0 color-mix(in srgb, var(--ui-accent) 40%, transparent); }
  50% { box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28), 0 0 0 14px transparent; }
}

/* The in-flight pause toggle, tucked in a corner so it never competes with the tools. */
#pause {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 40px;
  height: 40px;
  border: 1px solid var(--ui-line);
  border-radius: 10px;
  background: color-mix(in srgb, var(--ui-bg) 82%, transparent);
  color: var(--ui-text);
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  z-index: 2;
}
#pause[hidden] { display: none; }
#pause svg { width: 20px; height: 20px; fill: currentColor; }
#pause .ico-play { display: none; }
#pause .ico-pause { display: block; }
/* When paused, the button offers Resume. */
#pause[data-paused="true"] { color: var(--ui-accent); border-color: var(--ui-accent); }
#pause[data-paused="true"] .ico-play { display: block; }
#pause[data-paused="true"] .ico-pause { display: none; }

@media (prefers-reduced-motion: reduce) {
  #play { animation: none; }
}


/* The heat bar is the real fuel gauge: gas is only worth anything as heat, and
 * heat is always leaking. Putting it flush against the sky keeps the player's
 * eye on the thing that is quietly killing them. */
#heat {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 4px;
  background: color-mix(in srgb, var(--ui-line) 60%, transparent);
}
#heat-fill {
  height: 100%;
  background: var(--c-flame);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 90ms linear;
}

/* ---------------------------------------------------------------- overlay */

#overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 6px;
  text-align: center;
  background: color-mix(in srgb, var(--ui-bg) 78%, transparent);
  backdrop-filter: blur(2px);
}
#overlay[hidden] { display: none; }

#verdict {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 0.06em;
}
#verdict[data-outcome="gold"] { color: #d9a520; }
#verdict[data-outcome="silver"] { color: #9aa3ad; }
#verdict[data-outcome="bronze"] { color: #b1723c; }
#verdict[data-outcome="fail"] { color: var(--ui-warn); }

#verdict-detail { font-size: 13px; color: var(--ui-dim); }

#overlay-actions { display: flex; gap: 8px; justify-content: center; margin-top: 10px; }
#overlay-actions button {
  padding: 10px 22px;
  border: 1px solid var(--ui-line);
  border-radius: var(--radius);
  background: var(--ui-panel);
  color: var(--ui-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
#next { background: var(--ui-accent); border-color: var(--ui-accent); color: #fff; }

/* ---------------------------------------------------------------- tools */

#tools {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--ui-line);
  background: var(--ui-panel);
}

#tools button {
  display: grid;
  grid-template-areas: "glyph count" "label count";
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0 8px;
  /* Thumb-sized. This is a slow game played one deliberate tap at a time; the
   * tap must never be the hard part. */
  min-height: 58px;
  padding: 8px 12px;
  border: 1px solid var(--ui-line);
  border-radius: var(--radius);
  background: var(--ui-bg);
  color: var(--ui-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

#tools button:active:not(:disabled) { transform: translateY(1px); background: var(--ui-panel); }
#tools button:disabled { opacity: 0.35; cursor: default; }

.glyph { grid-area: glyph; font-size: 15px; line-height: 1; color: var(--ui-dim); }
.label { grid-area: label; font-size: 12px; color: var(--ui-dim); }
.count {
  grid-area: count;
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

#tool-burn .glyph { color: var(--c-flame); }
#tool-vent .glyph { color: var(--c-predict); }
#tool-ballast .glyph { color: var(--ui-dim); }

/* Ballast is a one-way door. It should not look like the other two. */
#tool-ballast { border-style: dashed; }

@media (prefers-reduced-motion: reduce) {
  #heat-fill { transition: none; }
  #tools button:active:not(:disabled) { transform: none; }
}

/* ---------------------------------------------------------------- picker */

#picker {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  background: color-mix(in srgb, var(--ui-bg) 70%, transparent);
  backdrop-filter: blur(3px);
  z-index: 2;
}
#picker[hidden] { display: none; }

#picker-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  margin: 0;
  max-height: 70%;
  overflow-y: auto;
  /* A flex item defaults to min-height:auto, which refuses to shrink below its content.
   * With a short roster the list fitted and nobody noticed; once there were nine levels it
   * grew past its max-height instead of scrolling, shoving the Close button off the bottom
   * of the sheet and stranding the last levels out of reach. min-height:0 is what actually
   * lets overflow-y do its job. */
  min-height: 0;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Rows keep their full height and let the list scroll, rather than each one squashing a
 * little to make nine fit where four used to. */
#picker-list > li { flex: 0 0 auto; }

/* A sheet from the bottom, not a centred modal. On a phone the levels should land
 * under the thumb that opened them. */
.picker-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 54px;
  padding: 8px 14px;
  border: 1px solid var(--ui-line);
  border-radius: var(--radius);
  background: var(--ui-panel);
  color: var(--ui-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.picker-row:active { transform: translateY(1px); }
.picker-row[data-current] { border-color: var(--ui-accent); }

.picker-name { font-weight: 600; }
.picker-meta { font-size: 12px; color: var(--ui-dim); font-variant-numeric: tabular-nums; }

.picker-medal { font-size: 13px; width: 1em; color: transparent; }
.picker-medal[data-medal="gold"] { color: #d9a520; }
.picker-medal[data-medal="silver"] { color: #9aa3ad; }
.picker-medal[data-medal="bronze"] { color: #b1723c; }

/* Two buttons share the picker's footer now, so the margin moves to the row. */
#picker-actions {
  display: flex;
  gap: 8px;
  margin: 0 12px 14px;
}
#picker-actions > button { flex: 1; }
#picker-actions > button[hidden] { display: none; }

#picker-close,
#picker-log {
  margin: 0;
  padding: 12px;
  border: 1px solid var(--ui-line);
  border-radius: var(--radius);
  background: var(--ui-panel);
  color: var(--ui-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .picker-row:active { transform: none; }
}

/* ---------------------------------------------------------------- flight log
 *
 * The same bottom-sheet language as the level picker — this is the picker's sibling, not
 * a new kind of surface. It carries the min-height:0 fix from the outset: a nine-row list
 * inside a flex column will otherwise refuse to shrink and shove its own Close button off
 * the screen, which is exactly how the picker broke. */

#summary {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  background: color-mix(in srgb, var(--ui-bg) 82%, transparent);
  backdrop-filter: blur(3px);
  z-index: 3;
}
#summary[hidden] { display: none; }

#summary-head {
  padding: 16px 14px 4px;
  font-size: 17px;
  font-weight: 650;
  color: var(--ui-text);
  text-align: center;
}

#summary-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  margin: 0;
  max-height: 60%;
  overflow-y: auto;
  min-height: 0;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
#summary-list > li { flex: 0 0 auto; }

.summary-row {
  display: grid;
  grid-template-columns: 1.6em 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--ui-line);
  border-radius: var(--radius);
  background: var(--ui-panel);
  color: var(--ui-text);
}
/* A level you have not landed yet is present but plainly unfinished — it should read as
 * a gap in the log, not as a zero. */
.summary-row[data-landed="false"] { opacity: 0.5; }

.summary-n { color: var(--ui-dim); font-variant-numeric: tabular-nums; }
.summary-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.summary-score { color: var(--ui-dim); font-variant-numeric: tabular-nums; }
/* Over par is worth seeing at a glance; at par should not shout. */
.summary-score[data-over="true"] { color: var(--ui-warn); }

.summary-medal { font-size: 13px; line-height: 1; }
.summary-medal[data-medal="gold"] { color: var(--ui-accent); }
.summary-medal[data-medal="silver"] { color: var(--ui-text); }
.summary-medal[data-medal="bronze"] { color: var(--ui-dim); }

#summary-total {
  padding: 0 14px 10px;
  text-align: center;
  color: var(--ui-dim);
  font-variant-numeric: tabular-nums;
}

#summary-close {
  margin: 0 12px 14px;
  padding: 12px;
  border: 1px solid var(--ui-line);
  border-radius: var(--radius);
  background: var(--ui-panel);
  color: var(--ui-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
