:root {
  --wood: #b76828;
  --wood-dark: #6e3a12;
  --paper: #fffaf0;
  --ink: #3c260e;
  --green: #74cf35;
  --green-dark: #357a0d;
  --orange: #ffad2b;
  --orange-dark: #a95b00;
  --blue: #2fb3f5;
  --blue-dark: #0a5f9e;
  --highlight: #ffe7a8;
  --wood-grain: repeating-linear-gradient(3deg, #e39b4d00 0 38px, #6f340b14 40px 46px, #f4af650f 48px 84px);
  --wood-face: linear-gradient(100deg, #c97b32, #eba857 24%, #d58a3b 73%, #bd6926);
  --wood-edge: #71380f;
  --wood-shadow: inset 0 3px 0 #ffda8b, inset 0 -5px 0 #a6531e, 0 5px 0 #59350d55, 0 10px 20px #163c3940;
  --radius: 22px;
  --gap: clamp(8px, 2vmin, 18px);
  --header: clamp(60px, 13vh, 130px);
  --control: clamp(52px, 8vmin, 72px);
  --font: "Fredoka", "Trebuchet MS", system-ui, sans-serif;
  color-scheme: light;
}

* {
  box-sizing: border-box;
}

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

body {
  height: 100dvh;
  overflow: hidden;
  display: grid;
  grid-template-rows: var(--header) minmax(0, 1fr);
  grid-template-columns: minmax(0, 1fr);
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  font-family: var(--font);
  font-weight: 600;
  color: var(--ink);
  background: #52bdde url("../assets/ui/background.webp") center / cover no-repeat;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

[hidden] {
  display: none !important;
}

main {
  display: grid;
  min-height: 0;
}

.screen {
  min-height: 0;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  touch-action: manipulation;
}

img {
  -webkit-user-drag: none;
}

.icon {
  width: 1.3em;
  height: 1.3em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- buttons ---------- */

/* Candy buttons in the style of the original art: glossy gradient, thick dark outline,
   two shine spots on top, white text and icons outlined in dark. */
.btn {
  --c1: #a6ee3f;
  --c2: #45b51a;
  --edge: #2b1a0f;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  min-width: var(--control);
  height: var(--control);
  padding: 0 1.1em;
  border: clamp(3px, 0.45vmin, 4px) solid var(--edge);
  border-radius: 999px;
  background: linear-gradient(var(--c1), var(--c2));
  color: #fff;
  font-size: clamp(20px, 3vmin, 28px);
  font-weight: 700;
  -webkit-text-stroke: 0.12em var(--edge);
  paint-order: stroke fill;
  text-shadow: 0 0.08em 0 var(--edge);
  box-shadow:
    inset 0 -0.3em 0 rgb(0 0 0 / 0.14),
    inset 0 0.22em 0 rgb(255 255 255 / 0.35),
    0 0.2em 0 var(--edge);
  transition: transform 0.15s cubic-bezier(0.3, 1.6, 0.5, 1);
}

/* shine spots */
.btn::before,
.btn::after {
  content: "";
  position: absolute;
  top: 0.32em;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.8);
  pointer-events: none;
}

.btn::before {
  left: 0.5em;
  width: 0.55em;
  height: 0.26em;
  rotate: -35deg;
}

.btn::after {
  right: 0.5em;
  width: 0.3em;
  height: 0.22em;
  rotate: 35deg;
}

.btn .icon {
  stroke-width: 3;
  filter: drop-shadow(1.5px 0 0 var(--edge)) drop-shadow(-1.5px 0 0 var(--edge)) drop-shadow(0 1.5px 0 var(--edge))
    drop-shadow(0 -1.5px 0 var(--edge));
}

/* full-color pictures inside a button (assets/ui/buttons) */
.btn .btn-art {
  width: 1.55em;
  height: 1.55em;
  flex: none;
  filter: drop-shadow(0 2px 0 rgb(0 0 0 / 0.2));
}

/* round candy button, e.g. a new name */
.btn--square.name-btn {
  border-radius: 50%;
}

/* full-color icons carry their own outline */
.btn .icon--art {
  width: 1.5em;
  height: 1.5em;
  filter: none;
}

/* a squish when pressed */
.btn:active:not(:disabled) {
  transform: scale(0.92) translateY(2px);
}

.btn:disabled {
  filter: grayscale(0.8) opacity(0.6);
  cursor: default;
}

.btn:focus-visible,
.sprite-btn:focus-visible {
  outline: 4px solid #fff;
  outline-offset: 3px;
}

/* rounded square, like the original icon buttons */
.btn--square {
  width: var(--control);
  padding: 0;
  border-radius: 32%;
}

.btn--pill {
  height: calc(var(--control) * 1.25);
  padding: 0 1.2em;
  font-size: clamp(24px, 3.6vmin, 34px);
}

/* a smaller pill for secondary actions with a label */
.btn--pill.btn--small {
  height: var(--control);
  padding: 0 0.9em;
  font-size: clamp(17px, 2.5vmin, 23px);
}

.btn--yellow {
  --c1: #ffe75a;
  --c2: #ffa80c;
}

.btn--orange {
  --c1: #ffbf4d;
  --c2: #ff6a0a;
}

.btn--blue {
  --c1: #62d7ff;
  --c2: #1670f2;
}

.btn--pink {
  --c1: #ff9fb6;
  --c2: #f0507a;
}

/* Tool states: the chosen tool lifts and glows. */
.btn[aria-pressed="false"],
.sprite-btn[aria-pressed="false"] {
  filter: saturate(0.75);
}

.btn[aria-pressed="true"],
.sprite-btn[aria-pressed="true"] {
  transform: scale(1.1);
}

.btn--square[aria-pressed="true"] {
  box-shadow:
    inset 0 -0.3em 0 rgb(0 0 0 / 0.14),
    inset 0 0.22em 0 rgb(255 255 255 / 0.35),
    0 0.2em 0 var(--edge),
    0 0 0 4px #fff6a8;
}

/* Buttons that are a picture from the original art (assets/ui/buttons). */
.sprite-btn {
  --s: var(--control);
  position: relative;
  width: var(--s);
  height: var(--s);
  padding: 0;
  border: 0;
  background: none;
  transition: transform 0.15s cubic-bezier(0.3, 1.6, 0.5, 1);
}

.sprite-btn img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 3px 0 rgb(0 0 0 / 0.22));
}

.sprite-btn:active {
  transform: scale(0.9);
}

.sprite-btn[aria-pressed="true"] img {
  filter: drop-shadow(0 0 0 #fff) drop-shadow(0 0 5px #fff59d) drop-shadow(0 0 3px #fff59d);
}

.sprite-btn.corner {
  --s: clamp(64px, 11vmin, 104px);
}

.panel {
  background: var(--paper);
  border: 5px solid var(--wood);
  border-radius: var(--radius);
  box-shadow: 0 6px 0 var(--wood-dark);
}

/* wooden holder for steps and tools */
/* Wooden tiles, as in the original: grain over a warm gradient, a dark edge, a light
   inner rim and a soft shadow. */
.rail,
.wood {
  position: relative;
  background: var(--wood-grain), var(--wood-face);
  border: 4px solid var(--wood-edge);
  border-radius: 30px;
  box-shadow: var(--wood-shadow);
}

.rail::after,
.wood::after {
  content: "";
  position: absolute;
  inset: 4px;
  border: 2px solid #ffca7380;
  border-radius: inherit;
  pointer-events: none;
}

/* ---------- header and logo ---------- */

.topbar {
  position: relative;
  z-index: 5;
  display: grid;
  --corner: clamp(64px, 11vmin, 104px);
  grid-template-columns: var(--corner) minmax(0, 1fr) var(--corner);
  align-items: center;
  gap: var(--gap);
  padding: 6px var(--gap) 0;
}

.logo-slot {
  height: 100%;
  min-width: 0;
  display: grid;
  place-items: center;
}

.logo {
  height: calc(var(--header) - 10px);
  max-width: 100%;
  object-fit: contain;
  transform-origin: center;
  cursor: pointer;
}

.logo.settling {
  transition: transform 0.8s cubic-bezier(0.34, 1.35, 0.5, 1);
}

body[data-screen="landing"] .topbar .sprite-btn,
body[data-screen="home"] #homeBtn {
  visibility: hidden;
}

/* ---------- landing ---------- */

#landing {
  position: relative;
  cursor: pointer;
}

.tap-hint {
  position: absolute;
  left: 50%;
  bottom: 16%;
  translate: -50% 0;
  height: calc(var(--control) * 1.5);
  padding: 0 1.4em;
  font-size: clamp(28px, 5vmin, 46px);
  white-space: nowrap;
  animation: bob 1.4s ease-in-out infinite;
}

.title {
  margin: 0 0 var(--gap);
  text-align: center;
  font-size: clamp(26px, 5vmin, 46px);
  font-weight: 700;
  line-height: 1.1;
  color: #fff;
  text-shadow:
    0 3px 0 var(--wood-dark),
    0 0 10px rgb(0 0 0 / 0.3);
}

/* ---------- home ---------- */

#home {
  overflow-y: auto;
  padding: var(--gap);
}

.tiles {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap);
  max-width: 1100px;
  margin: 0 auto;
}

/* Tablet: a 4x4 grid sized to fit the screen's height. */
@media (orientation: landscape) and (min-width: 640px) {
  #home {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    overflow: hidden;
  }

  .tiles {
    container-type: size;
    display: grid;
    grid-template-columns: repeat(4, auto);
    align-content: center;
    width: 100%;
    max-width: none;
  }

  .tiles .tile {
    /* a tile is about its width plus 28px tall (padding, border and name) */
    width: clamp(90px, (100cqh - 3 * var(--gap)) / 4 - 32px, 170px);
  }
}

.tile {
  width: clamp(100px, 16vmin, 150px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 8px 6px;
  background: var(--paper);
  border: 4px solid var(--wood);
  border-radius: 20px;
  box-shadow: 0 5px 0 var(--wood-dark);
  transition:
    transform 0.08s,
    box-shadow 0.08s;
}

.tile:active {
  transform: translateY(3px);
  box-shadow: 0 2px 0 var(--wood-dark);
}

.tile img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
}

.tile {
  position: relative;
}

/* Best grade for this animal */
.tile .best {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 40px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 3px solid var(--orange-dark);
  border-radius: 50%;
  background: #ffcf33;
  color: #fff;
  font-size: 17px;
  text-shadow: 0 2px 0 var(--orange-dark);
  rotate: 10deg;
}

/* This animal has a saved game to continue. */
.tile .resume {
  position: absolute;
  top: -10px;
  left: -10px;
  width: 38px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 3px solid var(--green-dark);
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-size: 15px;
}

.tile span {
  font-size: clamp(15px, 2.3vmin, 21px);
  color: var(--wood-dark);
}

/* Animals still to come */
.tile--soon {
  cursor: default;
  background: rgb(255 250 240 / 0.6);
  border-style: dashed;
  box-shadow: none;
}

.tile--soon .soon-pic {
  width: 100%;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  font-size: clamp(34px, 7vmin, 60px);
  font-weight: 700;
  color: #fff;
  -webkit-text-stroke: 0.08em #c9a27a;
  paint-order: stroke fill;
}

.tile--soon.shake {
  animation: shake 0.4s;
}

/* ---------- spin ---------- */

#spin {
  --rail: clamp(150px, 22vw, 300px);
  display: grid;
  min-height: 0;
  gap: var(--gap);
  padding: 4px var(--gap) calc(var(--gap) + 5px);
  grid-template:
    "steps" auto
    "wheel" minmax(0, 1fr)
    "side" auto
    / minmax(0, 1fr);
}

/* Wooden holder with the animal's name and one dot per part. */
.steps-box {
  grid-area: steps;
  justify-self: center;
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(4px, 1vmin, 8px);
  padding: clamp(6px, 1.2vmin, 10px) clamp(10px, 2vmin, 16px) clamp(10px, 1.8vmin, 16px);
  border-radius: 30px;
}

.steps-name {
  margin: 0;
  font-size: clamp(17px, 3vmin, 26px);
  font-weight: 700;
  line-height: 1.1;
  color: #fff;
  -webkit-text-stroke: 0.14em var(--wood-dark);
  paint-order: stroke fill;
}

.steps {
  display: flex;
  align-items: center;
  gap: clamp(6px, 1.4vmin, 12px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  width: clamp(52px, 9.5vmin, 88px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 3px solid var(--wood-dark);
  border-radius: 50%;
  background: var(--paper);
  color: var(--wood);
  font-size: clamp(18px, 3vmin, 28px);
  transition: transform 0.2s;
}

.step img {
  width: 78%;
  height: 78%;
  object-fit: contain;
}

.step.done {
  border-color: var(--green-dark);
  background: #eaffd8;
}

.step.current {
  transform: scale(1.12);
  border-color: var(--orange-dark);
  background: var(--highlight);
  box-shadow: 0 0 0 3px #fff;
}

.wheel-area {
  grid-area: wheel;
  container-type: size;
  display: grid;
  place-items: center;
  min-height: 0;
}

.wheel-box {
  position: relative;
  width: min(100cqw, 100cqh);
  aspect-ratio: 1;
  touch-action: none;
  cursor: grab;
}

.wheel-box::before {
  content: "";
  position: absolute;
  inset: 0;
  border: clamp(3px, 0.8cqmin, 5px) solid #713407;
  border-radius: 50%;
  background: var(--wood-grain), linear-gradient(110deg, #ffcf79, #af5b21 35%, #d78b3c 60%, #f5b669);
  box-shadow:
    inset 0 4px 0 #ffde92,
    inset 0 -7px 0 #9c4818,
    0 7px 0 #73471966,
    0 12px 25px #23523655;
}

.wheel-box:active {
  cursor: grabbing;
}

.wheel-box:focus-visible {
  outline: 4px solid #fff;
  outline-offset: 4px;
  border-radius: 50%;
}

#wheel {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  will-change: transform;
}

.hub {
  position: absolute;
  inset: 29%;
  overflow: hidden;
  border: clamp(4px, 0.9cqmin, 8px) solid var(--wood);
  border-radius: 50%;
  background: var(--paper);
  box-shadow:
    0 0 0 4px #ffd977,
    0 6px 16px rgb(0 0 0 / 0.3);
}

.hub.pop {
  animation: pop 0.35s ease-out;
}

#hub {
  display: block;
  width: 100%;
  height: 100%;
}

.hub-marker {
  position: absolute;
  width: 16%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border: 3px dashed var(--orange-dark);
  border-radius: 50%;
  animation: pulse 1.2s ease-in-out infinite;
  pointer-events: none;
}

.pointer {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: -3%;
  width: 12%;
  translate: -50% 0;
  filter: drop-shadow(0 3px 2px rgb(0 0 0 / 0.3));
  pointer-events: none;
}

.fly {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}

/* A hand sweeps clockwise along the white ring at the wheel's edge to show the swipe.
   The layer turns around the wheel's center; the fingertip sits on the ring. */
.swipe-hand {
  position: absolute;
  z-index: 2;
  inset: 0;
  pointer-events: none;
  animation: sweep 2.4s ease-in-out infinite;
}

.swipe-hand > span {
  position: absolute;
  left: 50%;
  top: 95%; /* the white ring where the slices end (RIM in spin.js) */
  translate: -40% -12%; /* fingertip of the hand icon */
  font-size: 13cqmin;
  line-height: 0;
}

.hand {
  width: 1em;
  height: 1em;
  fill: #fff;
  stroke: var(--wood-dark);
  stroke-width: 1.4;
  filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.35));
}

.spin-side {
  grid-area: side;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: calc(var(--gap) * 1.5);
  min-height: calc(var(--control) * 1.25 + 5px);
}

/* Before the first spin: a big button for players who tap instead of swipe. */
.spin-now {
  animation: nudge 2.4s 1.2s ease-in-out infinite;
}

/* Phones: no prompt; the buttons stack, Draw It! at the bottom, in a row of fixed height so
   the wheel stays put while they come and go. */
@media (max-width: 700px) and (orientation: portrait) {
  #spin .bubble {
    display: none;
  }

  .spin-side {
    flex-direction: column;
    justify-content: flex-end;
    gap: 12px;
    height: calc(var(--control) * 2.25 + 22px);
  }
}

.bubble {
  position: relative;
  max-width: 100%;
  margin: 0;
  padding: 0.5em 0.9em;
  background: #fff;
  border: 4px solid var(--wood);
  border-radius: 22px;
  box-shadow: 0 5px 0 var(--wood-dark);
  font-size: clamp(19px, 3.2vmin, 28px);
  line-height: 1.2;
  text-align: center;
  color: var(--wood-dark);
  animation: nudge 2.4s ease-in-out infinite;
}

.bubble b {
  color: var(--orange-dark);
}

/* tail pointing at the wheel */
.bubble::before {
  content: "";
  position: absolute;
  top: -12px;
  left: calc(50% - 10px);
  width: 20px;
  height: 20px;
  background: #fff;
  border: 4px solid var(--wood);
  border-right: 0;
  border-bottom: 0;
  rotate: 45deg;
}

.respin {
  position: relative;
}

.respin .badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border: 2px solid var(--orange-dark);
  border-radius: 13px;
  background: #fff;
  color: var(--orange-dark);
  font-size: 15px;
  text-shadow: none;
}

@media (orientation: landscape) and (min-width: 640px) {
  /* equal side columns keep the wheel in the middle of the screen */
  #spin {
    grid-template: "steps wheel side" minmax(0, 1fr) / var(--rail) minmax(0, 1fr) var(--rail);
  }

  .steps {
    flex-direction: column;
  }

  .spin-side {
    flex-direction: column;
  }

  .bubble::before {
    top: calc(50% - 10px);
    left: -12px;
    rotate: -45deg;
  }
}

/* ---------- draw ---------- */

/* Phone and portrait: example on top, board, then tools and done. */
#draw {
  --rail: clamp(150px, 22vw, 300px);
  display: grid;
  min-height: 0;
  gap: var(--gap);
  padding: 4px var(--gap) calc(var(--gap) + 5px);
  grid-template:
    "example example" auto
    "board board" minmax(0, 1fr)
    "tools done" auto
    / minmax(0, 1fr) auto;
}

#draw[data-level="easy"] .example-wrap {
  display: none;
}

.example-wrap {
  grid-area: example;
  justify-self: center;
  align-self: center;
}

.example {
  display: block;
  width: clamp(96px, 19vh, 220px);
  aspect-ratio: 1;
}

.tools {
  grid-area: tools;
  justify-self: center;
  align-self: center;
  display: flex;
  align-items: flex-start;
  gap: clamp(6px, 1.4vmin, 12px);
  padding: clamp(6px, 1.2vmin, 10px) clamp(8px, 1.6vmin, 14px);
  border-radius: 28px;
}

.tool {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px; /* room for the chosen tool to grow and its size dot */
}

.tool-label {
  font-size: clamp(12px, 1.7vmin, 15px);
  line-height: 1;
  color: #fff;
  -webkit-text-stroke: 0.2em var(--wood-dark);
  paint-order: stroke fill;
}

#drawBtn,
.draw-done {
  white-space: nowrap;
}

.draw-done {
  grid-area: done;
  justify-self: center;
  align-self: center;
}

.draw-done.shake {
  animation: shake 0.4s;
}

/* Portrait: the board sits where the color and result boards are. Under it the tools and the
   example share the row, evenly spaced, like the color tools and palette; Done is at the bottom. */
@media (orientation: portrait) {
  #draw {
    --tool: var(--control);
    column-gap: 0;
    grid-template:
      "board board board board board" auto
      ". tools . example ." minmax(0, 1fr)
      "done done done done done" auto
      / minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr);
  }

  #draw[data-level="easy"] {
    grid-template-areas:
      "board board board board board"
      ". tools tools tools ."
      "done done done done done";
  }

  #draw .tools {
    --control: var(--tool);
    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: 10px 14px;
    padding: 12px 14px;
  }

  #draw[data-level="easy"] .tools {
    grid-template-columns: repeat(4, auto);
  }

  /* as tall as the two rows of tools beside it */
  .example {
    width: calc(2 * var(--tool) + 86px);
  }

  .example-wrap {
    position: relative;
  }

  .example-wrap::before {
    position: absolute;
    z-index: 1;
    top: 0;
    left: 50%;
    translate: -50% -55%;
    padding: 3px 12px;
    border: 3px solid var(--wood-edge);
    border-radius: 999px;
    background: var(--wood-grain), var(--wood-face);
    box-shadow: 0 3px 0 #59350d55;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    color: #fff;
    -webkit-text-stroke: 0.18em var(--wood-dark);
    paint-order: stroke fill;
  }

  #draw[data-level="medium"] .example-wrap::before {
    content: "Copy this!";
  }

  #draw[data-level="hard"] .example-wrap::before {
    content: "Draw this!";
  }
}

/* Phones: small tool tiles; Done keeps the full size of the result screen's Save. */
@media (max-width: 520px) and (orientation: portrait) {
  #draw {
    --tool: clamp(40px, 11vw, 56px);
  }

  #color .tools {
    --control: clamp(40px, 11vw, 56px);
    gap: 6px;
    padding: 12px 14px;
  }
}

/* Size of the active pencil, eraser or brush, shown on its button. */
.size-dot {
  position: absolute;
  right: 0;
  bottom: 0;
  width: calc(var(--dot, 8px) + 4px);
  aspect-ratio: 1;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--ink, #2a2118);
  box-shadow: 0 0 0 2px var(--wood-dark);
}

#eraserBtn .size-dot {
  background: #fff;
}

.sizes {
  position: absolute;
  z-index: 6;
  bottom: calc(100% + 14px);
  left: 50%;
  translate: -50% 0;
  display: flex;
  gap: 8px;
  padding: 8px;
}

.size {
  width: 48px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: 0;
  border: 3px solid var(--wood-dark);
  border-radius: 50%;
  background: var(--paper);
}

.size[aria-pressed="true"] {
  background: var(--highlight);
  border-color: var(--orange-dark);
}

.size span {
  width: var(--dot);
  aspect-ratio: 1;
  border-radius: 50%;
  background: #2a2118;
}

@media (orientation: landscape) and (min-width: 640px) {
  /* Equal side columns keep the board in the middle of the screen. */
  #draw {
    grid-template:
      "tools board ." minmax(0, 1fr)
      "tools board example" auto
      "tools board done" auto
      "tools board ." minmax(0, 1fr)
      / var(--rail) minmax(0, 1fr) var(--rail);
  }

  .tools {
    flex-direction: column;
    align-items: center;
  }

  .example {
    width: min(calc(var(--rail) - 16px), 34vh);
  }

  .sizes {
    flex-direction: column;
    bottom: auto;
    top: 50%;
    left: calc(100% + 14px);
    translate: 0 -50%;
  }
}

/* ---------- boards (draw, color, result) ---------- */

.board-area {
  grid-area: board;
  position: relative;
  container-type: size;
  display: grid;
  place-items: center;
  min-height: 0;
}

/* A wooden title tile above a wooden frame holding the square board. */
.board-stack {
  --title: clamp(46px, 7vmin, 66px);
  --pad: clamp(6px, 1.1vmin, 10px);
  --between: clamp(8px, 1.4vmin, 14px);
  display: flex;
  flex-direction: column;
  gap: var(--between);
}

.title-tile {
  contain: inline-size; /* takes the board's width; a long title shortens instead of widening */
  height: var(--title);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 14px;
  border-radius: 22px;
}

/* room for the back button, kept on both sides so the title stays centered */
.title-tile:has(.title-back) {
  padding: 0 calc(var(--title) + 10px);
}

.frame {
  padding: var(--pad);
  border-radius: 26px;
}

.frame-title {
  position: relative;
  z-index: 1;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-size: clamp(16px, 3.3vmin, 30px);
  font-weight: 700;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: #fff;
  -webkit-text-stroke: 0.14em var(--wood-dark);
  paint-order: stroke fill;
  text-shadow: 0 0.08em 0 var(--wood-dark);
}

.title-back {
  --s: calc(var(--title) - 18px);
  position: absolute;
  z-index: 1;
  left: 12px;
}

.frame-star {
  position: relative;
  z-index: 1;
  height: calc(var(--title) * 0.66);
  flex: none;
  filter: drop-shadow(0 2px 0 rgb(0 0 0 / 0.25));
  animation: twinkle 2.4s ease-in-out infinite;
}

.frame-star:last-child {
  animation-delay: 1.2s;
}

/* The square board fills what is left under the title tile. */
.board {
  position: relative;
  z-index: 1;
  display: block;
  width: min(
    100cqw - 2 * var(--pad, 0px) - 12px,
    100cqh - var(--title, 0px) - var(--between, 0px) - 2 * var(--pad, 0px) - 30px
  );
  aspect-ratio: 1;
  border-radius: 16px;
  background: var(--paper);
  box-shadow:
    0 0 0 3px #96501b,
    inset 0 3px 9px #b6701e25;
  touch-action: none;
}

/* Stars after each part, over the board */
.stars {
  position: absolute;
  z-index: 4;
  inset: var(--pad);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 2%;
  border-radius: 16px;
  background: rgb(255 250 240 / 0.6);
}

.stars img {
  width: 24%;
  animation: pop-in 0.45s backwards;
}

.stars img:not(.on) {
  filter: grayscale(1) brightness(1.35) opacity(0.55);
}

.stars img:nth-child(2) {
  width: 30%;
  translate: 0 -14%;
  animation-delay: 0.15s;
}

.stars img:nth-child(3) {
  animation-delay: 0.3s;
}

/* ---------- color ---------- */

/* Phone and portrait: board, colors, then tools and done. */
#color {
  --rail: clamp(150px, 22vw, 300px);
  display: grid;
  min-height: 0;
  gap: var(--gap);
  padding: 0 var(--gap) calc(var(--gap) + 5px);
  /* portrait: board on top, the tools beside the colors centered in the space below it,
     Done centered at the bottom */
  column-gap: 0;
  grid-template:
    "board board board board board" auto
    ". tools . palette ." minmax(0, 1fr)
    "done done done done done" auto
    / minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr);
}

#color .tools {
  flex-direction: column;
  align-items: center;
}

/* Portrait: color and result boards get the same size and place, worked out from the width
   and from the room the controls below them need (--below), so the space under the board
   can be shared out evenly. */
@media (orientation: portrait) {
  #draw,
  #color,
  #result {
    --below: clamp(300px, 38vh, 440px);
  }

  #draw {
    padding-top: 0;
  }

  #draw .board-area,
  #color .board-area,
  #result .board-area {
    container-type: inline-size;
    place-items: start center;
  }

  #draw .board,
  #color .board,
  #result .board {
    width: min(
      100cqw - 2 * var(--pad) - 12px,
      100dvh - var(--header) - var(--title) - var(--between) - 2 * var(--pad) - 30px - var(--below)
    );
  }
}

.palette {
  grid-area: palette;
  justify-self: center;
  align-self: center;
  display: grid;
  grid-template-columns: repeat(5, auto);
  gap: clamp(5px, 1.2vmin, 10px);
  padding: clamp(12px, 1.6vmin, 16px);
  border-radius: 28px;
}

.swatch {
  width: clamp(36px, 6.5vmin, 54px);
  aspect-ratio: 1;
  padding: 0;
  border: 3px solid #fff;
  border-radius: 50%;
  background: var(--c);
  box-shadow: 0 3px 0 rgb(0 0 0 / 0.25);
  transition: transform 0.12s;
}

.swatch[aria-pressed="true"] {
  transform: scale(1.15);
  border-color: var(--highlight);
  box-shadow:
    0 0 0 3px var(--orange-dark),
    0 3px 0 rgb(0 0 0 / 0.25);
}

/* The fill and brush buttons show the chosen color. */
#fillBtn .size-dot {
  width: 16px;
}

#fillBtn .size-dot,
#brushBtn .size-dot {
  background: var(--ink);
  border-color: var(--wood-dark);
}

@media (orientation: landscape) and (min-width: 640px) {
  #color {
    column-gap: var(--gap);
    grid-template:
      "tools board ." minmax(0, 1fr)
      "tools board palette" auto
      "tools board done" auto
      "tools board ." minmax(0, 1fr)
      / var(--rail) minmax(0, 1fr) var(--rail);
  }

  .palette {
    grid-template-columns: repeat(3, auto);
  }
}

/* ---------- result ---------- */

/* Phone and portrait: board, grade, name, then Color more and Play again side by side with
   Save under them. The two side holders step aside so their pieces share one grid. */
#result {
  display: grid;
  min-height: 0;
  gap: calc(var(--gap) * 1.2) calc(var(--gap) * 1.6);
  padding: 0 var(--gap) calc(var(--gap) + 5px);
  grid-template:
    "board board" auto
    ". ." minmax(0, 1fr)
    "verdict verdict" auto
    "name name" auto
    ". ." minmax(0, 1fr)
    "color again" auto
    "save save" auto
    / minmax(0, 1fr) minmax(0, 1fr);
}

.result-left,
.result-side {
  display: contents;
}

.result-parts {
  display: none;
}

.verdict {
  grid-area: verdict;
  justify-self: center;
}

.name-tag {
  grid-area: name;
  justify-self: center;
  margin-top: calc(var(--gap) * 0.8);
}

@media (orientation: portrait) {
  .grade {
    --size: clamp(70px, 13vmin, 80px);
  }
}

#backToColor {
  grid-area: color;
  justify-self: end;
}

#playAgain {
  grid-area: again;
  justify-self: start;
}

#saveBtn {
  grid-area: save;
  justify-self: center;
}

.verdict {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--gap);
}

/* Bubbly grade badge: a candy coin with shine spots that keeps gently wobbling. */
.grade,
.badge-fly {
  --size: clamp(70px, 13vmin, 120px);
  position: relative;
  flex: none;
  width: var(--size);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: calc(var(--size) * 0.06) solid #2b1a0f;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, #fff27a, #ffd21f 45%, #ff9d0a);
  box-shadow:
    inset 0 calc(var(--size) * -0.07) 0 rgb(170 80 0 / 0.35),
    inset 0 calc(var(--size) * 0.05) 0 rgb(255 255 255 / 0.55),
    0 calc(var(--size) * 0.05) 0 #2b1a0f;
  color: #fff;
  font-size: calc(var(--size) * 0.44);
  font-weight: 700;
  line-height: 1;
  -webkit-text-stroke: calc(var(--size) * 0.05) #2b1a0f;
  paint-order: stroke fill;
}

.grade::before,
.grade::after,
.badge-fly::before {
  content: "";
  position: absolute;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.85);
}

.grade::before,
.badge-fly::before {
  top: 14%;
  left: 18%;
  width: 22%;
  height: 11%;
  rotate: -40deg;
}

.grade::after {
  top: 12%;
  right: 22%;
  width: 9%;
  height: 9%;
}

.grade {
  animation:
    badge-in 0.7s 0.2s cubic-bezier(0.3, 1.7, 0.5, 1) backwards,
    wobble 2.6s 1s ease-in-out infinite;
}

/* small badges that fly out at the player and off the screen */
.badge-fly {
  --size: clamp(44px, 8vmin, 70px);
  position: fixed;
  z-index: 60;
  pointer-events: none;
}

.praise {
  margin: 0;
}

.name-tag {
  width: min(100%, 360px);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 5px 5px 14px;
  border-radius: 999px;
}

.name-tag input {
  flex: 1;
  width: 0;
  min-width: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: clamp(20px, 3.2vmin, 28px);
  line-height: 1.2;
  text-align: center;
  color: var(--wood-dark);
  user-select: text;
}

.name-tag .btn {
  --control: 46px;
  flex: none;
  font-size: 20px;
}

/* Each part with the stars it earned */
.rail-title {
  position: relative;
  z-index: 1;
  margin: 0 0 8px;
  text-align: center;
  font-size: clamp(17px, 2.6vmin, 24px);
  font-weight: 700;
  line-height: 1.1;
  color: #fff;
  -webkit-text-stroke: 0.14em var(--wood-dark);
  paint-order: stroke fill;
}

.part-scores {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.part-scores li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 4px;
  border-radius: 999px;
  background: rgb(255 250 240 / 0.9);
  box-shadow: inset 0 -3px 0 #e3c89f;
}

.part-pic {
  width: clamp(36px, 5.5vmin, 50px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 3px solid var(--wood);
  border-radius: 50%;
  background: #fff;
}

.part-pic img {
  width: 78%;
  height: 78%;
  object-fit: contain;
}

.part-name {
  overflow: hidden;
  font-size: clamp(14px, 2vmin, 18px);
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--wood-dark);
}

.part-stars {
  display: flex;
}

.part-stars img {
  width: clamp(16px, 2.4vmin, 22px);
}

.part-stars img:not(.on) {
  filter: grayscale(1) brightness(1.35) opacity(0.5);
}

/* Tablet: the board in the middle as on the draw and color screens; the parts and Color more
   on the left, the grade, name, Save and Play again on the right. */
@media (orientation: landscape) and (min-width: 640px) {
  /* The same columns as the color screen, so the board matches it. Each side then moves
     toward the board by half the empty room beside the frame, to sit centered between the
     screen edge and the frame. The board's size is worked out as in .board. */
  #result {
    --rail: clamp(150px, 22vw, 300px);
    --title: clamp(46px, 7vmin, 66px);
    --between: clamp(8px, 1.4vmin, 14px);
    --pad: clamp(6px, 1.1vmin, 10px);
    --area: calc(100cqw - 2 * var(--rail) - 2 * var(--gap));
    --frame: calc(
      min(var(--area) - 2 * var(--pad) - 12px, 100cqh - var(--title) - var(--between) - 2 * var(--pad) - 30px) +
        2 * var(--pad) + 8px
    );
    --shift: calc((var(--area) - var(--frame)) / 4);
    container-type: size;
    gap: var(--gap);
    grid-template: "left board side" minmax(0, 1fr) / var(--rail) minmax(0, 1fr) var(--rail);
  }

  .result-left {
    translate: var(--shift) 0;
  }

  .result-side {
    translate: calc(-1 * var(--shift)) 0;
  }

  .result-left,
  .result-side {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    justify-self: center;
    gap: calc(var(--gap) * 1.6);
    width: min(100%, var(--rail));
    min-width: 0;
  }

  .result-left {
    grid-area: left;
  }

  .result-side {
    grid-area: side;
  }

  .result-parts {
    display: block;
    width: 100%;
    padding: 12px;
    border-radius: 26px;
  }

  .verdict {
    flex-direction: column;
    text-align: center;
  }

  .name-tag {
    width: 100%;
  }
}

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

.levels {
  display: flex;
  gap: 14px;
}

.level {
  display: grid;
  justify-items: center;
  gap: 6px;
  width: clamp(88px, 22vmin, 130px);
  padding: 12px 8px 10px;
  border: 4px solid var(--wood);
  border-radius: 20px;
  background: var(--paper);
  box-shadow: 0 5px 0 var(--wood-dark);
  font-size: clamp(17px, 2.6vmin, 22px);
  color: var(--wood-dark);
}

.level[aria-pressed="true"] {
  border-color: var(--orange-dark);
  background: var(--highlight);
}

.level-pic {
  font-size: clamp(40px, 8vmin, 60px);
  color: var(--blue-dark);
}

/* ---------- dialogs ---------- */

.dialog {
  overflow: visible;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
}

.dialog::backdrop {
  background: rgb(30 20 5 / 0.45);
}

.dialog .panel {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 18px;
  min-width: min(88vw, 340px);
  padding: 28px 24px 24px;
}

.dialog .close {
  position: absolute;
  top: -18px;
  right: -18px;
}

#helpDialog .panel {
  width: min(92vw, 480px);
  gap: 20px;
  padding: 26px 22px 24px;
}

.help-title {
  color: var(--wood-dark);
}

/* Spin, draw, color: a picture and a few words each */
.how {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
  line-height: 1.15;
}

.how li {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 4px;
}

.how-pic {
  width: clamp(56px, 16vw, 72px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  margin-bottom: 4px;
  border: 4px solid var(--wood);
  border-radius: 50%;
  background: var(--highlight);
  font-size: clamp(28px, 8vw, 36px);
  color: var(--wood-dark);
}

.how b {
  font-size: 22px;
  color: var(--orange-dark);
}

.how li > span:last-child {
  font-size: 15px;
  font-weight: 500;
  color: var(--wood-dark);
}

/* Sounds, music and reset: three buttons of one size, each with a label */
.settings {
  --control: 64px;
  gap: 22px;
}

.setting {
  display: grid;
  justify-items: center;
  gap: 8px;
}

.settings [aria-pressed="true"]:not(:active) {
  transform: none;
}

#musicBtn {
  font-size: 30px;
  border-width: 4px;
}

.reset-hint {
  max-width: 300px;
  margin: -6px 0 0;
  text-align: center;
  font-size: 16px;
  color: #c0392b;
}

/* Music off: grey candy */
.settings .btn[aria-pressed="false"] {
  --c1: #dfe6ec;
  --c2: #97a4b0;
}

/* Reset asks before clearing: it wiggles and shows a check mark. */
#resetBtn.asking {
  animation: shake 0.5s infinite;
}

#resetBtn.asking::after {
  content: "✓";
  position: absolute;
  top: -8px;
  right: -8px;
  width: 28px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 3px solid var(--green-dark);
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-size: 16px;
}

.confetti {
  position: fixed;
  inset: 0;
  z-index: 50;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

#continueBtn {
  width: 100%;
}

.dialog h2 {
  margin: 0;
  font-size: 28px;
}

.row {
  display: flex;
  gap: 16px;
}

/* ---------- motion ---------- */

@keyframes bob {
  50% {
    transform: translateY(-10px) scale(1.06);
  }
}

@keyframes pulse {
  50% {
    transform: scale(1.25);
    opacity: 0.6;
  }
}

@keyframes badge-in {
  from {
    transform: scale(0) rotate(-200deg);
  }
}

@keyframes wobble {
  0%,
  100% {
    transform: rotate(8deg) scale(1);
  }
  50% {
    transform: rotate(-6deg) scale(1.06);
  }
}

@keyframes twinkle {
  50% {
    transform: rotate(14deg) scale(1.12);
  }
}

@keyframes pop-in {
  from {
    transform: scale(0);
    opacity: 0;
  }
  70% {
    transform: scale(1.15);
  }
}

@keyframes shake {
  25% {
    transform: translateX(-8px) rotate(-4deg);
  }
  75% {
    transform: translateX(8px) rotate(4deg);
  }
}

@keyframes pop {
  40% {
    transform: scale(1.08);
  }
}

@keyframes sweep {
  0% {
    rotate: -70deg;
    opacity: 0;
  }
  15% {
    opacity: 1;
  }
  65% {
    rotate: 70deg;
    opacity: 1;
  }
  80%,
  100% {
    rotate: 70deg;
    opacity: 0;
  }
}

@keyframes nudge {
  0%,
  100% {
    transform: none;
  }
  10% {
    transform: rotate(-2deg) scale(1.04);
  }
  20% {
    transform: rotate(2deg) scale(1.04);
  }
  30% {
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}
