: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;
}

/* The game fits the screen; the page itself never scrolls. */
html {
  overflow: hidden;
}

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;
  justify-self: center;
  width: min(100%, 1400px);
  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 tiles, as in the original: grain over a warm gradient, a dark edge, a light
   inner rim and a soft shadow. */
.wood {
  position: relative;
  background: var(--wood-grain), var(--wood-face);
  border: 4px solid var(--wood-edge);
  border-radius: 30px;
  box-shadow: var(--wood-shadow);
}

.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 ---------- */

/* A grid sized to fit the screen: 3x5 on the phone, 4x4 on the tablet. */
#home {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  overflow: hidden;
  padding: var(--gap);
  --cols: 3;
  --rows: 5;
}

/* Sizes measured from a container are written as var(--cqw, 1cqw) and so on: browsers without
   container queries (before 2022) get --cqw, --cqh and --cqmin from main.js instead. */
.tiles {
  container-type: size;
  display: grid;
  grid-template-columns: repeat(var(--cols), auto);
  align-content: center;
  justify-content: center;
  gap: var(--gap);
}

.tiles .tile {
  /* a tile is about its width plus 32px tall (padding, border and name) */
  width: clamp(
    80px,
    min((100 * var(--cqw, 1cqw) - (var(--cols) - 1) * var(--gap)) / var(--cols), (100 * var(--cqh, 1cqh) - (var(--rows) - 1) * var(--gap)) / var(--rows) - 32px),
    170px
  );
}

/* the phone shows 15 tiles (spare "Soon" tiles hide) */
.tiles > .tile--soon:nth-child(n + 16) {
  display: none;
}

@media (orientation: landscape) and (min-width: 640px) {
  #home {
    --cols: 4;
    --rows: 4;
  }

  .tiles > .tile--soon:nth-child(n + 16) {
    display: flex;
  }
}

.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;
}

/* ---------- game screens: shared layout ---------- */

/* Two layouts: phone (portrait, the default) and tablet (landscape, further down).
   Phone: a wooden tile at the top (steps, tools or name), the board, then the controls.
   Tablet: a rail on each side with the wheel or board in the middle. */
#spin,
#draw,
#color,
#result {
  --step: clamp(52px, 9.5vmin, 88px); /* a step dot on the spin screen */
  --top-h: calc(var(--step) + 44px); /* height of the top tile */
  --top-w: min(100%, calc(var(--step) * 6.4)); /* its width */
  --pad: clamp(6px, 1.1vmin, 10px); /* frame around the board */
  --rail: clamp(150px, 22vw, 300px); /* tablet side columns */
  container-type: size;
  display: grid;
  min-height: 0;
  gap: var(--gap);
  padding: 4px var(--gap) calc(var(--gap) + 5px);
}

/* Phone: the board's size comes from the screen: the full width, or the height left after
   the top tile and what the screen puts under the board (--below, gaps included). */
#draw,
#color,
#result {
  --board: min(
    100 * var(--cqw, 1cqw) - 2 * var(--pad) - 16px,
    100 * var(--cqh, 1cqh) - var(--top-h) - var(--below) - 2 * var(--pad) - 8px
  );
}

.top-tile {
  justify-self: center;
  width: var(--top-w);
  height: var(--top-h);
  border-radius: 30px;
}

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

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

.board {
  position: relative;
  z-index: 1;
  display: block;
  width: var(--board);
  aspect-ratio: 1;
  border-radius: 16px;
  background: var(--paper);
  box-shadow:
    0 0 0 3px #96501b,
    inset 0 3px 9px #b6701e25;
  touch-action: none;
}

/* Phone: the title shows for a moment over the top of the board as an instruction. */
.title-tile {
  position: absolute;
  z-index: 5;
  top: 12%;
  left: 12px;
  right: 12px;
  width: fit-content;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0 auto;
  padding: 12px 22px;
  border-radius: 22px;
  font-size: clamp(18px, 3.3vmin, 30px);
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  color: #fff;
  -webkit-text-stroke: 0.14em var(--wood-dark);
  paint-order: stroke fill;
  text-shadow: 0 0.08em 0 var(--wood-dark);
  pointer-events: none;
  animation: instruction 2.4s 0.2s both;
}

/* the player's first touch on the board sends the instruction away */
.title-tile.gone {
  animation: instruction-out 0.25s both;
}

.title-tile > * {
  position: relative;
  z-index: 1;
}

.frame-star {
  height: 1.4em;
  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;
}

.done-btn {
  grid-area: done;
  justify-self: center;
  white-space: nowrap;
}

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

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

.tools {
  grid-area: tools;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  gap: clamp(6px, 1.4vmin, 12px);
  padding: 8px 12px;
  border-radius: 28px;
}

/* In the top tile the tools fill its height: button, gap, label. It sits above the board, so the
   sizes that open under it stay on top. */
.tools.top-tile {
  --control: calc(var(--top-h) - 50px);
  position: relative;
  z-index: 7;
}

.tool {
  position: relative;
  z-index: 1;
  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;
}

/* 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 for the chosen tool: under the top tile on the phone. */
.sizes {
  position: absolute;
  z-index: 6;
  top: calc(100% + 14px);
  left: 50%;
  translate: -50% 0;
  display: flex;
  gap: 8px;
  padding: 8px;
}

.size {
  position: relative;
  z-index: 1;
  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;
}

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

#spin {
  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;
  min-width: var(--top-w);
  width: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 0 12px 8px;
}

.steps-name {
  position: relative;
  z-index: 1;
  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 {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: clamp(6px, 1.4vmin, 12px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  width: calc(var(--step) * 0.9); /* a little smaller than the room for it: space under the dots */
  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 {
  border-color: var(--orange-dark);
  background: var(--highlight);
  box-shadow: inset 0 0 0 3px #fff;
}

/* After a spin lands, a cheer pops up over the lower wheel, clear of the hub. */
#spinTitle {
  top: 78%;
  translate: 0 -50%;
}

/* The wheel keeps a little room above it for the pointer. */
.wheel-area {
  grid-area: wheel;
  position: relative;
  container-type: size;
  display: grid;
  place-items: center;
  min-height: 0;
  padding-top: clamp(14px, 3vmin, 28px);
}

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

.wheel-box::before {
  content: "";
  position: absolute;
  inset: 0;
  border: clamp(3px, 0.8 * var(--cqmin, 1cqmin), 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.9 * var(--cqmin, 1cqmin), 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;
}

/* Easy: a star pops up at the pencil while tracing right on the line (draw.js) */
.sparkle {
  position: fixed;
  z-index: 15;
  width: 34px;
  pointer-events: none;
  filter: drop-shadow(0 2px 0 rgb(0 0 0 / 0.25));
}

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

/* 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: calc(13 * var(--cqmin, 1cqmin));
  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));
}

/* The buttons stack at the bottom, Draw It! last, in a row of fixed height so the wheel stays
   put while they come and go. */
.spin-side {
  grid-area: side;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  height: calc(var(--control) * 2.25 + 22px);
}

#drawBtn {
  white-space: nowrap;
}

/* 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;
}

.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;
}

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

#draw {
  --below: calc(var(--control) * 1.25 + 3 * var(--gap) + 10px);
  grid-template:
    "tools" auto
    "board" auto
    "." minmax(0, 1fr)
    "done" auto
    / minmax(0, 1fr);
}

/* Medium and hard: the example floats over everything; the player can drag it anywhere. */
.example-wrap {
  grid-area: example;
  position: fixed;
  z-index: 20;
  right: 12px;
  bottom: calc(var(--control) * 1.25 + 3 * var(--gap) + 10px);
  touch-action: none;
  cursor: grab;
}

.example-wrap.dragging {
  cursor: grabbing;
}

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

.example {
  display: block;
  width: calc(clamp(110px, 32vw, 220px) * var(--zoom, 1)); /* pinch to make it bigger (draw.js) */
  aspect-ratio: 1;
  box-shadow:
    0 6px 0 var(--wood-dark),
    0 10px 24px rgb(0 0 0 / 0.3);
}

/* a label on the example says what to do with it */
.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!";
}

/* 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 ---------- */

#color {
  /* 8 colors a row, as wide as the screen allows */
  --swatch: min(clamp(36px, 6.5vmin, 54px), (100 * var(--cqw, 1cqw) - 74px) / 8);
  --below: calc(var(--control) * 1.25 + 2 * var(--swatch) + 46px + 5 * var(--gap) + 10px);
  grid-template:
    "tools" auto
    "board" auto
    "." minmax(0, 1fr)
    "palette" auto
    "." minmax(0, 1fr)
    "done" auto
    / minmax(0, 1fr);
}

.palette {
  grid-area: palette;
  justify-self: center;
  display: grid;
  grid-template-columns: repeat(8, auto);
  gap: 6px;
  padding: 12px;
  border-radius: 28px;
}

.swatch {
  position: relative;
  z-index: 1;
  width: var(--swatch);
  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);
}

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

#result {
  --below: calc(var(--control) * 1.25 + clamp(70px, 13vmin, 80px) + 5 * var(--gap) + 10px);
  grid-template:
    "name" auto
    "board" auto
    "." minmax(0, 1fr)
    "verdict" auto
    "." minmax(0, 1fr)
    "actions" auto
    / minmax(0, 1fr);
}

/* the name plate at the top */
.name-tag {
  grid-area: name;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px 0 18px;
}

.name-tag input {
  position: relative;
  z-index: 1;
  flex: 1;
  width: 0;
  min-width: 0;
  padding: 0.18em 0; /* room for the stroke on tall letters */
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: clamp(28px, 5vmin, 40px);
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  color: #fff;
  -webkit-text-stroke: 0.14em var(--wood-dark);
  paint-order: stroke fill;
  user-select: text;
}

.name-tag .btn {
  --control: 50px;
  z-index: 1;
  flex: none;
  font-size: 22px;
}

.result-parts {
  display: none;
}

/* Grade and praise. The grade first shows in the middle of the screen, then settles here and
   the praise appears (result.js). */
.verdict {
  grid-area: verdict;
  position: relative;
  z-index: 10;
  justify-self: center;
  display: flex;
  align-items: center;
  gap: var(--gap);
}

.praise {
  margin: 0;
  opacity: 0;
  transition: opacity 0.4s;
}

.verdict.settled .praise {
  opacity: 1;
}

/* Bubbly grade badge: a candy coin with shine spots that keeps gently wobbling. */
.grade,
.badge-fly {
  --size: clamp(70px, 13vmin, 80px);
  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;
}

/* Phone: Save in the middle, round Color more and Play again of the same height beside it. */
.result-actions {
  grid-area: actions;
  justify-self: center;
  display: flex;
  align-items: center;
  gap: calc(var(--gap) * 1.6);
}

#backToColor,
#playAgain {
  width: calc(var(--control) * 1.25);
  height: calc(var(--control) * 1.25);
  padding: 0;
  border-radius: 50%;
  font-size: clamp(24px, 3.6vmin, 34px);
}

#backToColor .btn-label,
#playAgain .btn-label {
  display: none;
}

#backToColor::before,
#playAgain::before {
  left: 0.45em;
}

#backToColor::after,
#playAgain::after {
  display: none;
}

/* Each part with the stars it earned (tablet) */
.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 ---------- */

@media (orientation: landscape) and (min-width: 640px) {
  /* The wheel or board stays in the middle between two equal side columns. */
  #spin,
  #draw,
  #color,
  #result {
    --title: clamp(46px, 7vmin, 66px);
    --between: clamp(8px, 1.4vmin, 14px);
  }

  .top-tile {
    width: auto;
    height: auto;
  }

  /* spin */
  #spin {
    grid-template: "steps wheel side" minmax(0, 1fr) / var(--rail) minmax(0, 1fr) var(--rail);
  }

  .steps-box {
    align-self: center;
    min-width: 0;
    gap: clamp(4px, 1vmin, 8px);
    padding: clamp(6px, 1.2vmin, 10px) clamp(10px, 2vmin, 16px) clamp(10px, 1.8vmin, 16px);
  }

  .steps {
    flex-direction: column;
  }

  .wheel-area {
    padding-top: 0;
  }

  .wheel-box {
    width: min(100 * var(--cqw, 1cqw), 100 * var(--cqh, 1cqh));
  }

  .spin-side {
    justify-content: center;
    height: auto;
  }

  /* boards: the title tile sits above the frame, as wide as it */
  .board-area {
    container-type: size;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--between);
  }

  .board {
    width: min(
      100 * var(--cqw, 1cqw) - 2 * var(--pad) - 12px,
      100 * var(--cqh, 1cqh) - var(--title) - var(--between) - 2 * var(--pad) - 30px
    );
  }

  .board-area > .title-tile {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    margin: 0;
    contain: inline-size;
    width: min(100 * var(--cqw, 1cqw) - 4px, 100 * var(--cqh, 1cqh) - var(--title) - var(--between) - 22px); /* the frame's width */
    height: var(--title);
    padding: 0 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    animation: none;
  }

  .tools {
    flex-direction: column;
    align-self: center;
    justify-self: center;
    padding: clamp(6px, 1.2vmin, 10px) clamp(8px, 1.6vmin, 14px);
  }

  .tools.top-tile {
    --control: clamp(52px, 8vmin, 72px);
  }

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

  .done-btn {
    align-self: center;
  }

  /* draw */
  #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);
  }

  .example-wrap {
    position: relative;
    right: auto;
    bottom: auto;
    justify-self: center;
    cursor: default;
  }

  .example {
    width: min(calc(var(--rail) - 16px), 34vh);
    box-shadow: 0 6px 0 var(--wood-dark);
  }

  /* color */
  #color {
    --swatch: clamp(36px, 5.2vmin, 50px);
    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(4, auto);
  }

  /* result: the parts and Color more on the left; the grade, name, Save and Play again on the
     right. Each side moves toward the board by half the empty room beside the frame, so it sits
     centered between the screen edge and the frame. */
  #result {
    --area: calc(100 * var(--cqw, 1cqw) - 2 * var(--rail) - 2 * var(--gap));
    --frame: calc(
      min(var(--area) - 2 * var(--pad) - 12px, 100 * var(--cqh, 1cqh) - var(--title) - var(--between) - 2 * var(--pad) - 30px) +
        2 * var(--pad) + 8px
    );
    --shift: calc((var(--area) - var(--frame)) / 4);
    row-gap: calc(var(--gap) * 1.6);
    grid-template:
      ". board ." minmax(0, 1fr)
      "parts board verdict" auto
      "parts board name" auto
      "color board save" auto
      ". board again" auto
      ". board ." minmax(0, 1fr)
      / var(--rail) minmax(0, 1fr) var(--rail);
  }

  .result-parts,
  .verdict,
  .name-tag {
    align-self: center;
  }

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

  .result-actions {
    display: contents;
  }

  .result-parts,
  #backToColor {
    translate: var(--shift) 0;
  }

  .verdict,
  .name-tag,
  #saveBtn,
  #playAgain {
    translate: calc(-1 * var(--shift)) 0;
  }

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

  .grade {
    --size: clamp(70px, 13vmin, 120px);
  }

  .name-tag {
    width: 100%;
    padding: 6px 6px 6px 16px;
    border-radius: 999px;
  }

  .name-tag input {
    font-size: clamp(26px, 4vmin, 36px);
  }

  .name-tag .btn {
    --control: 46px;
  }

  #backToColor {
    grid-area: color;
  }

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

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

  #backToColor,
  #playAgain {
    justify-self: center;
    width: auto;
    height: var(--control);
    padding: 0 0.9em;
    border-radius: 999px;
    font-size: clamp(17px, 2.5vmin, 23px);
  }

  #backToColor .btn-label,
  #playAgain .btn-label {
    display: inline;
  }

  #backToColor::before,
  #playAgain::before {
    left: 0.5em;
  }

  #backToColor::after,
  #playAgain::after {
    display: block;
  }
}

/* ---------- 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 ---------- */

/* A dialog never grows past the screen: on a short screen (a phone on its side) it scrolls inside
   itself. The padding leaves room for the close button that sticks out of the panel. */
.dialog {
  max-width: calc(100vw - 8px);
  max-height: calc(100dvh - 8px);
  overflow: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  padding: 20px;
  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(100vw - 48px, 340px);
  padding: 28px 24px 24px;
}

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

#helpDialog .panel {
  width: min(100vw - 48px, 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, full screen, smooth lines and reset: buttons of one size, each with a label */
.settings {
  --control: 64px;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px 22px;
}

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

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

#musicBtn,
#fullBtn,
#smoothBtn {
  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%;
}

/* Short screens: a more compact help */
@media (max-height: 520px) {
  #helpDialog .panel {
    gap: 12px;
    padding: 18px 18px 16px;
  }

  .how-pic {
    width: 48px;
    font-size: 24px;
  }

  .settings {
    --control: 54px;
  }
}

.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);
  }
}

/* an instruction pops up over the board, stays a moment and goes */
@keyframes instruction {
  0% {
    opacity: 0;
    scale: 0.6;
  }
  10%,
  80% {
    opacity: 1;
    scale: 1;
  }
  100% {
    opacity: 0;
    scale: 0.9;
    visibility: hidden;
  }
}

@keyframes instruction-out {
  to {
    opacity: 0;
    scale: 0.9;
    visibility: hidden;
  }
}

@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;
  }
}
