/* BugBotLab, the game prototype. Phone first, one dark theme on purpose: this is a game, not a document. */

/* Light is the default. Dark arrives either from the phone's own setting or from the toggle, which stamps
   data-theme on <html>. Every colour is a token so both themes stay in step. */
:root {
  --green: #adc276;
  --green-hi: #4f6327;
  --deep: #46562c;
  --on-accent: #14170f;
  --bg: #efece2;
  --panel: #ffffff;
  --panel-2: #f2efe4;
  --line: #ddd8c8;
  --text: #23291d;
  --mute: #6b7364;
  --amber: #a8730a;
  --bad: #b03d26;
  --bad-bg: rgba(176, 61, 38, .1);
  --bad-text: #8e3320;
  --pick: #eff4e1;
  --kb-bg: #ddd8c9;
  --kb-key: #f7f4ea;
  --kb-key-hi: #e7e2d2;
  --kb-edge: rgba(0, 0, 0, .16);
  --kb-border: #c7c1ad;
  --api-bg: #e3ebcf;
  --api-fg: #3e5020;
  --scrim: rgba(255, 255, 255, .30);
  --hero-grad: linear-gradient(to bottom, rgba(255, 255, 255, .3) 0%, rgba(191, 215, 181, 1) 100%);
}

:root:not([data-theme="light"]) { color-scheme: light dark; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --green-hi: #c2d68c;
    --bg: #14170f;
    --panel: #1c2118;
    --panel-2: #262d20;
    --line: #333c2a;
    --text: #e8efdd;
    --mute: #98a48a;
    --amber: #ffc93c;
    --bad: #d2604b;
    --bad-bg: rgba(210, 96, 75, .14);
    --bad-text: #f0a596;
    --pick: #232c1a;
    --kb-bg: #1c2118;
    --kb-key: #2e3626;
    --kb-key-hi: #3c4632;
    --kb-edge: rgba(0, 0, 0, .38);
    --kb-border: #3d4733;
    --api-bg: #46562c;
    --api-fg: #c2d68c;
    --scrim: rgba(20, 23, 15, .32);
  --hero-grad: linear-gradient(to bottom, #171c13 0%, #2b3a22 100%);
    --hero-grad: linear-gradient(to bottom, #171c13 0%, #2b3a22 100%);
  }
}

:root[data-theme="dark"] {
  --green-hi: #c2d68c;
  --bg: #14170f;
  --panel: #1c2118;
  --panel-2: #262d20;
  --line: #333c2a;
  --text: #e8efdd;
  --mute: #98a48a;
  --amber: #ffc93c;
  --bad: #d2604b;
  --bad-bg: rgba(210, 96, 75, .14);
  --bad-text: #f0a596;
  --pick: #232c1a;
  --kb-bg: #1c2118;
  --kb-key: #2e3626;
  --kb-key-hi: #3c4632;
  --kb-edge: rgba(0, 0, 0, .38);
  --kb-border: #3d4733;
  --api-bg: #46562c;
  --api-fg: #c2d68c;
  --scrim: rgba(20, 23, 15, .32);
}

/* the light and dark switch, one button, always in the same corner */
.theme-btn {
  position: fixed; z-index: 40;
  top: calc(6px + env(safe-area-inset-top, 0px)); right: 10px;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--panel); color: var(--mute);
  font-size: 15px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  font-family: 'Nunito', system-ui, -apple-system, sans-serif;
  /* the site's hero gradient is the app's background, on every screen */
  background: var(--hero-grad) fixed;
  color: var(--text);
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  -webkit-font-smoothing: antialiased;
}

[hidden] { display: none !important; }

.screen {
  height: 100%;
  display: flex;
  flex-direction: column;
  animation: fade .22s ease both;
}
@keyframes fade { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .screen { animation: none; } }

.pad { padding: 20px 20px 0; }
.grow { flex: 1; min-height: 0; }
.center { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }

/* ---------- buttons ---------- */

.btn {
  width: 100%;
  min-height: 54px;
  border: 0;
  border-radius: 14px;
  font: 900 16.5px 'Nunito', sans-serif;
  letter-spacing: .01em;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn.primary { background: var(--green); color: var(--on-accent); box-shadow: 0 4px 0 var(--deep); }
.btn.primary:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--deep); }
.btn.primary.busy { background: var(--panel-2); color: var(--mute); box-shadow: none; }
.btn.primary.stop { background: var(--bad); color: #fff; box-shadow: 0 4px 0 #7d2a19; }
.btn.outline { background: transparent; color: var(--text); border: 2px solid var(--line); }
.btn.ghost { background: transparent; color: var(--mute); font-weight: 700; min-height: 46px; }
.foot { padding: 14px 20px calc(16px + env(safe-area-inset-bottom, 0px)); display: grid; gap: 8px; flex: none; }
.foot.flat { padding-top: 10px; }

/* ---------- landing ---------- */

.brand { width: 144px; height: auto; display: block; flex: none; }
.hero { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 4px; }
.hero h1 { font: 900 30px/1.18 'Nunito'; text-wrap: balance; margin-top: 2px; }
.hero p { font: 600 15px 'Nunito'; color: var(--mute); margin-top: 10px; }
/* standing still is the resting state, with the camera blinking. Now and then it jumps. */
@keyframes hop {
  0%, 88.75% { transform: translateY(0) rotate(0); }
  94% { transform: translateY(-18px) rotate(-3deg); }
  97.75% { transform: translateY(0) rotate(2deg); }
  100% { transform: translateY(0) rotate(0); }
}

/* the same sticker as the journey marker, standing still and hopping now and then */
/* .jbot is defined further down, so these need the extra class to win */
.jbot.bot-hero {
  position: static; top: auto; margin: 0; width: 232px; height: 219px;
  /* The jump sits at the end of the cycle, so a negative delay of that much starts the page on it:
     it jumps as the screen appears, blinks a second later, then settles into its own rhythm. */
  animation: hop 8.8s ease-in-out infinite -7.81s;
}
.jbot.bot-hero .jcam { animation-delay: -2.02s; }
/* its legs splay at the top of the jump and tuck as it lands, the way the 3D robot's do */
.jbot.bot-hero .jleg-bl, .jbot.bot-hero .jleg-fl { animation: heroSplayL 8.8s ease-in-out infinite -7.81s; }
.jbot.bot-hero .jleg-br, .jbot.bot-hero .jleg-fr { animation: heroSplayR 8.8s ease-in-out infinite -7.81s; }
@keyframes heroSplayL { 0%, 88.75%, 100% { rotate: 0deg; } 94% { rotate: 18deg; } 97.75% { rotate: -6deg; } }
@keyframes heroSplayR { 0%, 88.75%, 100% { rotate: 0deg; } 94% { rotate: -18deg; } 97.75% { rotate: 6deg; } }
.jbot.bot-hero.small { width: 104px; height: 98px; margin-bottom: 22px; }

/* ---------- questions ---------- */

.qbar { display: flex; align-items: center; gap: 12px; padding: 12px 16px; flex: none; }
.chev { width: 34px; height: 34px; border: 0; background: transparent; color: var(--mute); font-size: 30px; line-height: 1; cursor: pointer; }
.track { flex: 1; height: 10px; border-radius: 99px; background: var(--panel-2); overflow: hidden; }
.track span { display: block; height: 100%; background: var(--green); border-radius: 99px; transition: width .3s ease; }
.step { font: 800 12px 'Nunito'; color: var(--mute); }

h2 { font: 900 25px/1.2 'Nunito'; text-wrap: balance; }
.sub { font: 600 14.5px/1.5 'Nunito'; color: var(--mute); margin-top: 8px; }

.options { display: grid; gap: 10px; margin-top: 24px; }
.opt {
  display: flex; align-items: center; gap: 13px;
  padding: 14px 15px; border-radius: 15px;
  background: var(--panel); border: 2px solid var(--line);
  text-align: left; cursor: pointer; color: var(--text);
}
.opt-ic { font-size: 24px; flex: none; width: 30px; text-align: center; }
.opt-tx { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.opt-tx b { font: 800 15.5px 'Nunito'; }
.opt-tx i { font: 600 12.5px 'Nunito'; font-style: normal; color: var(--mute); }
.dot { width: 21px; height: 21px; border-radius: 50%; border: 2px solid var(--line); flex: none; }
.opt.chosen { border-color: var(--green); background: var(--pick); }
.opt.chosen .dot { background: var(--green); border-color: var(--green); box-shadow: inset 0 0 0 4px var(--panel); }

/* ---------- level ---------- */

/* drag this to trade robot view for code. Keep this block above the coaching styles: it has been
   lost twice to edits that rewrote the run of rules between the coaching and .ask. */
.split {
  flex: none; height: 18px; display: flex; align-items: center; justify-content: center;
  cursor: row-resize; touch-action: none;
}
.split span {
  width: 46px; height: 4px; border-radius: 99px; background: var(--line);
  transition: background .15s, width .15s;
}
.split:active span, .split.dragging span { background: var(--green); width: 64px; }

.lbar { display: flex; align-items: center; gap: 9px; padding: 6px 48px 6px 12px; flex: none; }

/* The bar belongs to the world below it, not to the interface, for the same reason the 3D view does.
   In the lab that is a pale steel panel, seamed like the floor. It looks the same in either
   interface theme. */
.lbar {
  position: relative;
  background:
    var(--lab-collage, none) center bottom / auto 118% repeat-x,
    repeating-linear-gradient(90deg, transparent 0 63px, rgba(80, 100, 110, .10) 63px 64px),
    linear-gradient(180deg, #f7f9fa 0%, #e8edef 58%, #dae1e4 100%);
  border-bottom: 1px solid #c2cccf;
}
.lbar .chev { color: #5a666c; }
.lbar .pill { color: #4a555b; }
.lbar .pill.xp { color: #9a6a12; }
.lbar .jtrack { background: #9fadb3; box-shadow: 0 0 0 1px rgba(255, 255, 255, .55); }
.lbar .jnode { background: #f2f6f7; border-color: #8e9ca2; }
.lbar .jnode.done { background: var(--green); border-color: var(--green); }
/* the chapter as a journey: checkpoints along a track, with the robot working its way through them */
/* the track sits low in the box so the robot standing on it has room above, inside the bar */
.journey { position: relative; flex: 1; height: 34px; }
.jtrack {
  position: absolute; left: 7px; right: 7px; top: 75%; height: 5px; margin-top: -2px;
  border-radius: 99px; background: var(--panel-2); overflow: hidden;
}
.jfill { display: block; height: 100%; width: 0; border-radius: 99px; background: var(--green); transition: width .7s ease .15s; }
.jnodes { position: absolute; left: 0; right: 0; top: 75%; height: 0;
          display: flex; align-items: center; justify-content: space-between; }
.jnode {
  width: 12px; height: 12px; border-radius: 50%; flex: none;
  background: var(--panel-2); border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font: 900 8px 'Nunito'; color: var(--on-accent);
}
.jnode.done { background: var(--green); border-color: var(--green); }
.jnode.under { opacity: 0; }     /* hidden under the robot, back when it moves on */
.jnode.last { width: 14px; height: 14px; border-radius: 4px; }
/* The journey marker: the robot as a sticker. Heavy black outline, yellow case, white dome on a dark
   collar, the camera pod with its lens, dark legs with a yellow band. The outline is black, which would
   vanish against the dark bar, so the whole thing carries a white rim, the way a die-cut sticker does. */
.jbot {
  position: absolute; top: -1px; width: 37px; height: 35px; margin-left: -18.5px;
  overflow: visible;
  filter: drop-shadow(0 0 1.1px #fff) drop-shadow(0 0 1.1px #fff) drop-shadow(0 1px 1px rgba(0, 0, 0, .5));
  transition: left .75s cubic-bezier(.25, 1.1, .4, 1);
  animation: jbob 2.4s ease-in-out infinite;
}
.jbot > *, .jbot .jleg > *, .jbot .jcam > * { stroke: #121212; stroke-width: 1.5; stroke-linejoin: round; }
.jbot .jcase { fill: #ffd21f; }
.jbot .jlimb { fill: #33363a; }
.jbot .jband { fill: #ffd21f; stroke-width: 1.2; }
.jbot .jpod { fill: #33363a; }
.jbot .jlensring { fill: #e8eaec; }
.jbot .jlens { fill: #16181a; stroke-width: 1.1; }
.jbot .jcollar { fill: #33363a; }
.jbot .jdome { fill: #fbfdfe; }
.jbot .jgloss { fill: rgba(255, 255, 255, .85); stroke: none; }
.jbot .jdomegloss { fill: #ffffff; stroke: none; }
.jbot .jspark { fill: #ffffff; stroke: none; }
/* the camera blinks: the lens shuts for a moment, as an eye does */
.jbot .jcam { transform-box: fill-box; transform-origin: 50% 50%;
              animation: camBlink 3.2s ease-in-out infinite; }
@keyframes camBlink { 0%, 93%, 100% { scale: 1 1; } 96% { scale: 1 0.06; } }
.jbot .jleg .jgloss { fill: rgba(255, 255, 255, .45); }

/* it bobs where it stands, and its legs swing while it walks to the next checkpoint */
.jbot.walking { animation-duration: .42s; }
.jbot.walking .jleg-fl, .jbot.walking .jleg-br { animation: jstep .42s ease-in-out infinite; }
.jbot.walking .jleg-fr, .jbot.walking .jleg-bl { animation: jstep .42s ease-in-out infinite reverse; }
.jbot .jleg { transform-box: fill-box; transform-origin: 50% 4%; }

@keyframes jbob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -1.3px; } }
@keyframes jstep { 0%, 100% { rotate: -7deg; } 50% { rotate: 7deg; } }
@media (prefers-reduced-motion: reduce) {
  .jbot, .jbot .jleg { animation: none; transition: none; }
}
}
}
}
.pill { font: 800 12.5px 'Nunito'; color: var(--mute); white-space: nowrap; }
.pill.xp { color: var(--amber); }

.stage { position: relative; flex: 1 1 auto; min-height: 120px; overflow: hidden; }
/* Every 3D view is two stacked canvases: the flat lab behind, the WebGL scene in front. They layer
   wherever the view is used, the level stage and the replay panel alike. */
.stage canvas, .podium-wrap canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  pointer-events: none;                                /* never let the view eat the divider's events */
}
/* the flat lab behind the 3D: scaled a touch so the blur has no visible edge */
.stage-bg { z-index: 0; filter: blur(2.5px) saturate(1.02); transform: scale(1.06);
            object-fit: fill; }                      /* the canvas is the box's own size */
#view, #podium-view { z-index: 1; background: transparent; }
/* the engine's own sound button, in the corner of the view */
.mute {
  position: absolute; right: 10px; top: 10px; z-index: 2;
  width: 32px; height: 32px; padding: 0; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid rgba(0, 0, 0, .12);
  background: rgba(255, 255, 255, .78);
  backdrop-filter: blur(4px);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .12);
  color: #2a3327;
  cursor: pointer;
}
.mute[aria-pressed="false"] { background: rgba(255, 255, 255, .55); color: #6b7364; }

/* Stuck?: the task's own nudge, shown in the coaching bubble that is already on the mat */
.stuck {
  position: absolute; right: 48px; top: 10px; z-index: 2;
  height: 30px; padding: 0 11px; border-radius: 99px;
  border: 1px solid rgba(0, 0, 0, .12);
  background: rgba(255, 255, 255, .78);
  backdrop-filter: blur(4px);
  color: #2a3327; font: 900 11.5px 'Nunito'; cursor: pointer;
}

.chapter {
  z-index: 2;                                          /* the canvas is z-index 1 */
  position: absolute; left: 12px; top: 10px;
  font: 800 10.5px 'Nunito'; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255, 255, 255, .6); background: rgba(0, 0, 0, .35);
  padding: 4px 9px; border-radius: 99px;
}
.ask { padding: 5px 16px 5px; flex: none; }
.ask h3 { font: 900 17.5px 'Nunito'; }
.ask p { font: 600 13px/1.4 'Nunito'; color: var(--mute); margin-top: 2px; }

/* The run's own output, in the bottom left of the mat. It is over the 3D view, which is always the
   lab whatever the interface is set to, so it is styled for that: a dark scrim with light text. */
.feedback { position: absolute; left: 10px; bottom: 10px; z-index: 3; max-width: 62%; }
.feedback:empty { display: none; }
.feedback.bad, .feedback.out {
  max-height: 46%; overflow-y: auto;
  padding: 8px 11px;
  border-radius: 4px 11px 11px 4px;
  font: 700 12.5px/1.4 'Nunito';
  background: rgba(16, 19, 12, .62);
  backdrop-filter: blur(9px) saturate(1.15);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
  color: #fff;
}
.feedback.bad { border-left: 3px solid var(--bad); animation: shake .3s ease; }
.feedback.out { border-left: 3px solid rgba(255, 255, 255, .5); }
/* what the program printed, above the verdict rather than in a console of its own */
.feedback .says { display: block; white-space: pre-line;   /* one print() to a line */
                  font: 500 12px/1.45 'Roboto Mono', monospace; color: #fff; }
.feedback .verdict { display: block; margin-top: 5px; color: rgba(255, 255, 255, .9); }
.feedback.bad .verdict, .feedback.bad:not(:has(.says)) { color: #ffb9ab; }
@keyframes shake { 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }

.edwrap {
  flex: none; height: var(--ed-h, 148px); margin: 0 12px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden;
}
#ed { height: 100%; }

/* The completion list. It hangs off the body rather than the editor, so it floats over the run bar and
   the keyboard instead of being clipped inside a scrolling box, and it is sized to be tapped with a
   thumb. On a pale interface a faint panel on a pale editor disappears, so it carries its own edge. */
.cm-tooltip.cm-tooltip-autocomplete {
  z-index: 70;
  border: 2px solid var(--green); border-radius: 14px; overflow: hidden;
  background: var(--panel);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .34), 0 0 0 4px var(--scrim);
}
.cm-tooltip-autocomplete > ul {
  max-height: 208px; min-width: 250px;
  font-family: 'Roboto Mono', monospace;
}
.cm-tooltip-autocomplete > ul > li {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 14px; font-size: 15px; line-height: 1.25; color: var(--text);
  border-bottom: 1px solid var(--line);
}
.cm-tooltip-autocomplete > ul > li:last-child { border-bottom: 0; }
.cm-tooltip-autocomplete > ul > li[aria-selected] { background: var(--green); color: var(--on-accent); }
.cm-completionLabel { font-weight: 500; }
.cm-completionDetail {
  font-style: normal; font-size: 12.5px; margin-left: 0; color: var(--mute);
}
.cm-tooltip-autocomplete > ul > li[aria-selected] .cm-completionDetail { color: var(--on-accent); opacity: .8; }

.runbar { padding: 8px 12px 5px; flex: none; display: flex; gap: 8px; }
.runbar .btn { min-height: 50px; flex: 1; }
/* the keyboard is shown and hidden on purpose, never on its own */
.kb-toggle {
  flex: none; width: 52px; min-height: 50px; border-radius: 14px;
  border: 2px solid var(--line); background: var(--panel); color: var(--mute);
  font-size: 21px; line-height: 1; cursor: pointer;
}
.kb-toggle[aria-pressed="true"] { background: var(--pick); border-color: var(--green); color: var(--text); }
.kb-toggle:disabled { opacity: .4; cursor: default; }
#replay { font-size: 15px; }

/* ---------- the keyboard ---------- */

.kb {
  flex: none;
  transition: max-height .22s ease, padding .22s ease, opacity .16s ease;
  max-height: 60vh;
  background: var(--kb-bg);
  border-top: 1px solid var(--line);
  padding: 6px 5px calc(3px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 5px;
}
body[data-kb="down"] .kb { max-height: 0; padding-top: 0; padding-bottom: 0; opacity: 0; overflow: hidden; }
.kb-row { display: flex; gap: 4px; justify-content: center; }
.kb-key {
  flex: 1; min-width: 0; height: 40px;
  border: 1px solid var(--kb-border); border-radius: 8px;
  background: var(--kb-key); color: var(--text);
  font: 500 16px 'Roboto Mono', monospace;
  box-shadow: 0 1.5px 0 var(--kb-edge);
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kb-key.api { background: var(--api-bg); color: var(--api-fg); font-size: 13px; font-weight: 700; }
.kb-key.dim { background: var(--panel-2); color: var(--mute); font-size: 14px; }
.kb-key.wide { flex: 1.4; }
.kb-key.space { flex: 2.6; font-size: 11px; font-family: 'Nunito', sans-serif; font-weight: 800; }
.kb-key.on { background: var(--green); color: var(--on-accent); }
.kb-key.hit { background: var(--kb-key-hi); transform: translateY(2px); box-shadow: none; }
/* ---------- the reward ---------- */

.win { position: relative; }
.win-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 16px 4px; }
.win-top { text-align: center; }
#win-title { text-transform: uppercase; letter-spacing: .02em; }

.tick {
  width: 58px; height: 58px; border-radius: 50%; margin: 0 auto 12px;
  background: var(--green); color: var(--on-accent);
  font: 900 30px 'Nunito'; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 9px rgba(173, 194, 118, .16);
  animation: pop .45s cubic-bezier(.2, 1.5, .4, 1) both;
}
@keyframes pop { from { transform: scale(.4); opacity: 0; } }
.why { font: 600 14px/1.5 'Nunito'; color: var(--mute); margin-top: 8px; }
.why b { color: var(--green-hi); font-family: 'Roboto Mono', monospace; font-weight: 700; font-size: 13px; }
.chips { display: flex; gap: 7px; justify-content: center; margin-top: 13px; }
.chip { background: var(--panel); border: 1px solid var(--line); border-radius: 99px; padding: 6px 12px; font: 700 12px 'Nunito'; color: var(--mute); }
.chip b { color: var(--text); font-weight: 900; }
#win-best.is-best { color: var(--amber); }
.xp-pop {
  font: 900 34px 'Nunito'; color: var(--amber); margin-top: 16px;
  animation: pop .5s .15s cubic-bezier(.2, 1.5, .4, 1) both;
}
.xp-track { height: 11px; border-radius: 99px; background: var(--panel-2); margin: 10px 0 6px; overflow: hidden; }
.xp-track span { display: block; height: 100%; background: linear-gradient(90deg, var(--green), #ffc93c); border-radius: 99px; transition: width 1s cubic-bezier(.2, .8, .3, 1); }
.xp-total { font: 700 12px 'Nunito'; color: var(--mute); }
.xp-total span { color: var(--text); font-weight: 900; }

.card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 13px 14px; margin-top: 14px; }
.card h4 { font: 900 12px 'Nunito'; letter-spacing: .08em; text-transform: uppercase; color: var(--mute); margin-bottom: 9px; }

.podium { display: grid; gap: 5px; }
.pod {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--panel-2); border: 1px solid transparent; border-radius: 11px;
  padding: 9px 11px; cursor: pointer; color: var(--text);
}
.pod.playing { border-color: var(--green); }
.pod-rk { font-size: 16px; }
.pod-nm { flex: 1; text-align: left; font: 800 14px 'Nunito'; }
.pod-tm { font: 700 13px 'Roboto Mono', monospace; color: var(--green-hi); }
.pod-go { font: 800 10.5px 'Nunito'; color: var(--mute); }
.podium-wrap { position: relative; height: 148px; margin-top: 9px; border-radius: 11px;
               overflow: hidden; background: var(--panel-2); }
.podium-cap { display: block; font: 700 11px 'Nunito'; color: var(--mute); text-align: center; padding-top: 6px; }

.hist { display: flex; align-items: flex-end; gap: 4px; height: 76px; }
.bar { flex: 1; background: var(--panel-2); border-radius: 4px 4px 0 0; position: relative; }
.bar.mine { background: var(--green); }
.bar em {
  position: absolute; top: -16px; left: 50%; transform: translateX(-50%);
  font: 900 9.5px 'Nunito'; font-style: normal; color: var(--green-hi);
}
.hist-axis { display: flex; gap: 4px; margin-top: 5px; }
.hist-axis span { flex: 1; text-align: center; font: 500 9px 'Roboto Mono', monospace; color: var(--mute); }

.confetti { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 5; }
.confetti i { position: absolute; top: -18px; width: 8px; height: 13px; border-radius: 2px; animation: fall linear both; }
@keyframes fall { to { transform: translateY(105vh) rotate(540deg); opacity: .2; } }

/* ---------- the league ---------- */

.lhead { background: var(--panel); padding: 20px 20px 17px; text-align: center; flex: none; }
.medal {
  width: 56px; height: 56px; border-radius: 50%; background: #cd8c52; margin: 0 auto 10px;
  display: flex; align-items: center; justify-content: center; font-size: 26px;
  box-shadow: 0 0 0 8px rgba(205, 140, 82, .2);
  animation: pop .5s cubic-bezier(.2, 1.5, .4, 1) both;
}
.lhead h2 { font-size: 21px; }
.lhead p { font: 700 11.5px 'Nunito'; color: var(--mute); margin-top: 4px; }
.league-rows { flex: 1; min-height: 0; overflow-y: auto; padding: 6px 0; }
.lrow { display: flex; align-items: center; gap: 11px; padding: 10px 20px; }
.lrk { width: 20px; text-align: center; font: 900 14px 'Nunito'; color: var(--mute); }
.lav { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font: 900 13px 'Nunito'; color: #fff; }
.lnm { flex: 1; font: 700 14.5px 'Nunito'; }
.lxp { font: 700 13px 'Roboto Mono', monospace; color: var(--mute); }
.lrow.me { background: var(--pick); border-top: 2px solid var(--green); border-bottom: 2px solid var(--green); }
.lrow.me .lrk, .lrow.me .lnm { font-weight: 900; color: var(--text); }
.lrow.me .lxp { color: var(--green-hi); }
.promo { border-top: 2px dashed var(--line); margin: 5px 20px; padding-top: 5px; }
.promo span { display: block; text-align: center; font: 900 9.5px 'Nunito'; letter-spacing: .07em; text-transform: uppercase; color: var(--green); }
.league-note { padding: 8px 20px 0; font: 700 12.5px/1.45 'Nunito'; color: var(--mute); text-align: center; flex: none; }

/* ---------- the wall ---------- */

.su-stats { display: flex; gap: 10px; margin-top: 22px; }
.su-stats div { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 12px 18px; display: flex; flex-direction: column; gap: 2px; }
.su-stats b { font: 900 21px 'Nunito'; color: var(--amber); }
.su-stats span { font: 700 10.5px 'Nunito'; color: var(--mute); }

/* ---------- taller screens get a taller editor ---------- */

@media (min-height: 820px) {
  .edwrap { height: var(--ed-h, 172px); }
  .kb-key { height: 44px; }
}
@media (max-height: 680px) {
  .edwrap { height: var(--ed-h, 122px); }
  .kb-key { height: 37px; }
  .ask h3 { font-size: 16px; }
  .ask p { display: none; }
}


/* ---------- the Stuck? card ---------- */

.help {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: calc(14px + env(safe-area-inset-top, 0px)) 12px calc(14px + env(safe-area-inset-bottom, 0px));
  background: rgba(8, 10, 7, .55);
  backdrop-filter: blur(3px);
  animation: fade .2s ease both;
}
.help-card {
  width: 100%; max-width: 520px; height: 100%;
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 18px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
  overflow: hidden;
}
.help-head {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 14px 12px 12px 18px; border-bottom: 1px solid var(--line);
}
.help-head h2 { flex: 1; font: 900 19px 'Nunito'; }
.help-x {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font: 400 21px/1 'Nunito'; cursor: pointer;
}
.help-body { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 18px 20px; }

.help-sec { padding: 16px 0; border-bottom: 1px solid var(--line); }
.help-sec:last-child { border-bottom: 0; }
.help-sec h3 { font: 900 15px 'Nunito'; margin-bottom: 10px; }
.help-sec p { font: 600 13.5px/1.55 'Nunito'; color: var(--mute); }
.help-sec p b { color: var(--text); }
.help-sec code {
  font: 500 12.5px 'Roboto Mono', monospace; color: var(--green-hi);
  background: var(--panel-2); padding: 1px 5px; border-radius: 5px;
}
.help-more {
  display: inline-block; margin-top: 12px; padding: 8px 14px;
  border-radius: 10px; background: var(--pick); border: 1px solid var(--green);
  font: 900 12.5px 'Nunito'; color: var(--text); text-decoration: none;
}

/* the diagrams: the robot sticker on a strip of floor, with what the words are describing drawn on it */
.dia {
  position: relative; height: 104px; margin-bottom: 12px;
  border-radius: 12px; background: var(--panel-2); overflow: hidden;
  color: var(--green-hi);
}
.dia-floor { position: absolute; left: 0; right: 0; bottom: 22px; height: 2px; background: var(--line); }
.dia .jbot { position: absolute; left: 16px; bottom: 12px; width: 52px; height: 49px; margin: 0; top: auto;
             right: auto; animation: none; }
/* past the goal: the goal sits in the middle and the robot has ended up beyond it */
.dia .dia-bot--past { left: auto; right: 16px; }
.dia .dia-bot--mid { left: 50%; margin-left: -26px; }
.dia .dia-bot--small { left: 22px; bottom: 10px; width: 40px; height: 38px; }
.dia-goal {
  position: absolute; right: 18px; bottom: 24px; width: 40px; height: 22px;
  border: 2px solid var(--green); border-radius: 6px; background: rgba(63, 154, 69, .18);
}
.dia-goal--mid { right: auto; left: 50%; margin-left: -20px; }
/* the goal sits on the end of the dashed route, so the two line up */
.dia-goal--far { right: auto; left: 82.5%; margin-left: -17px; bottom: auto; top: 10px; width: 34px; height: 18px; }
.dia-arrow {
  position: absolute; left: 74px; right: 62px; bottom: 50px; height: 2px;
  background: repeating-linear-gradient(90deg, currentColor 0 6px, transparent 6px 11px);
}
.dia-arrow--long { left: 74px; right: 74px; }
.dia-label {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 50px;
  font: 800 11px 'Roboto Mono', monospace; color: var(--green-hi);
}
.dia-label--bad { color: var(--bad); }
.dia-label--turn { bottom: 68px; }
.dia-turn {
  position: absolute; left: 50%; bottom: 40px; width: 46px; height: 46px; margin-left: -23px;
  border: 2px dashed currentColor; border-radius: 50%;
  border-right-color: transparent; border-bottom-color: transparent;
}
.dia-wall { position: absolute; left: 34%; right: 26%; top: 44px; height: 8px;
            border-radius: 3px; background: var(--wall, #56646b); }
.dia-path { position: absolute; inset: 0; width: 100%; height: 100%; }

body.modal { overflow: hidden; }


/* the line the robot is on, while it runs */
.cm-runline {
  background: linear-gradient(90deg, var(--pick) 0%, transparent 92%);
  box-shadow: inset 3px 0 0 var(--green);
}


/* The charge cell in the bar: a battery that fills as the days add up, in place of a streak flame. */
.pill.charge { display: inline-flex; align-items: center; gap: 6px; }
.batt {
  position: relative; display: inline-flex; align-items: center; gap: 1.5px;
  padding: 2px; height: 15px; box-sizing: border-box;
  border: 1.5px solid currentColor; border-radius: 3.5px; opacity: .85;
}
.batt::after {                                         /* the terminal on the end */
  content: ""; position: absolute; left: 100%; top: 50%; transform: translateY(-50%);
  width: 2px; height: 6px; border-radius: 0 1.5px 1.5px 0; background: currentColor;
}
.batt .cell { width: 3.5px; height: 100%; border-radius: 1px; background: transparent; }
.batt .cell.on { background: var(--green-hi); }
.lbar .batt .cell.on { background: #3f7a2a; }


/* who is signed in, and what just happened when they tried */
.su-who { font: 800 13px 'Nunito'; color: var(--text); text-align: center; margin-bottom: 2px; }
.su-note { font: 600 12.5px/1.4 'Nunito'; color: var(--mute); text-align: center; min-height: 1.2em; }
.su-note:empty { min-height: 0; }
