/* The two players keep the colours of their gumdrop, whatever the theme. */
:root {
  --p0: #ff4f9d; --p0-light: #ffa6cf; --p0-dark: #c42a6d;
  --p1: #2d8dff; --p1-light: #9fd8ff; --p1-dark: #1a5cc4;
}

.app {
  max-width: 760px;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  padding: max(14px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* upright, the field sits in the middle and the controls stay at the bottom, under the thumbs */
.stage { margin: auto 0; }
.controls { margin-top: auto; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Top bar: back, both scores, new game. */
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.scores {
  flex: 1;
  max-width: 460px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  min-width: 0;
}
.score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 4px 6px;
  border-radius: 16px;
  transition: background 0.2s ease;
}
.score.active { background: var(--cream-2); box-shadow: inset 0 2px 4px rgba(120, 80, 40, 0.15); }
.score .name { font-weight: 700; font-size: 1.05rem; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#score-0 .name { color: var(--p0-dark); }
#score-1 .name { color: var(--p1-dark); }
.pts { display: flex; gap: 4px; flex-wrap: wrap; justify-content: center; }
.pts i { width: 14px; height: 14px; border-radius: 50%; background: var(--cream-2); box-shadow: inset 0 2px 3px rgba(120, 80, 40, 0.25); }
#score-0 .pts i.on { background: radial-gradient(circle at 35% 30%, var(--p0-light), var(--p0)); box-shadow: 0 2px 0 var(--p0-dark); }
#score-1 .pts i.on { background: radial-gradient(circle at 35% 30%, var(--p1-light), var(--p1)); box-shadow: 0 2px 0 var(--p1-dark); }
.vs { font-weight: 700; color: var(--muted); }

/* The field */
.stage {
  position: relative;
  border-radius: 26px;
  overflow: hidden;
  box-shadow: inset 0 0 0 4px #fff, 0 6px 0 var(--cream-dark), 0 22px 34px -16px rgba(90, 50, 150, 0.5);
}
.stage.shake { animation: shake 0.4s ease; }
#field { display: block; width: 100%; aspect-ratio: 600 / 420; touch-action: manipulation; }

.banner {
  position: absolute;
  left: 50%;
  top: 34%;
  padding: 8px 26px;
  border: 5px solid #fff;
  border-radius: 999px;
  font-size: clamp(1.6rem, 6vw, 2.6rem);
  font-weight: 700;
  white-space: nowrap;
  color: #fff;
  text-shadow: 0 3px 0 rgba(0, 0, 0, 0.18);
  background: var(--purple);
  box-shadow: 0 6px 0 rgba(58, 31, 74, 0.25);
  pointer-events: none;
  animation: banner 1.8s ease-out forwards;
}
.banner.hit { background: linear-gradient(90deg, var(--pink), var(--orange), #f5b800, var(--green), var(--blue), var(--purple)); }
.banner.near { background: var(--orange); }

/* Modal over the field for the secret dodge, hand-over and winner. */
.modal {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  padding: 12px;
  background: rgba(110, 63, 196, 0.55);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
}
.modal-card { width: min(440px, 100%); padding: 18px 20px 20px; text-align: center; }
.modal-title { margin: 0 0 6px; font-size: clamp(1.25rem, 4.5vw, 1.6rem); font-weight: 700; color: var(--who, var(--ink)); }
.modal-text { margin: 0 0 16px; color: var(--muted); font-weight: 500; line-height: 1.4; }
.modal-actions { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 10px; }
.modal-actions .btn { min-height: 52px; padding: 10px 8px; font-size: 1.1rem; line-height: 1.15; }
/* "kies stiekem": the field hides behind a curtain (two halves sliding in, 350 ms) and the question sits on it */
.modal.secret { background: none; }
.curtain { position: absolute; inset: 0; z-index: 9; overflow: hidden; pointer-events: none; }
.curtain i {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 52%;
  background:
    radial-gradient(circle at 50% 0, #ffd166 0 9px, transparent 10px) 0 calc(100% - 4px) / 28px 18px repeat-x,
    linear-gradient(180deg, rgba(0, 0, 0, 0.25), transparent 16%, transparent 84%, rgba(0, 0, 0, 0.2)),
    repeating-linear-gradient(90deg, var(--purple-dark) 0 6px, var(--purple) 16px 30px, var(--purple-dark) 40px 46px);
  transition: transform 0.35s cubic-bezier(0.5, 0, 0.3, 1);
}
.curtain .left { left: 0; transform: translateX(-102%); box-shadow: inset -8px 0 12px rgba(0, 0, 0, 0.3); }
.curtain .right { right: 0; transform: translateX(102%); box-shadow: inset 8px 0 12px rgba(0, 0, 0, 0.3); }
.curtain.closed i { transform: translateX(0); }
/* a scalloped valance across the top */
.curtain::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 1;
  height: 22px;
  background: radial-gradient(circle at 50% 0, var(--purple-dark) 0 15px, transparent 16px) 0 0 / 30px 22px repeat-x;
  transform: translateY(-100%);
  transition: transform 0.35s ease;
}
.curtain.closed::before { transform: none; }
/* the end card covers the whole screen: the field is too small for it on phones */
#end { position: fixed; z-index: 40; overflow-y: auto; }
.modal .end-card { width: min(380px, 100%); }
#end .over-text p { margin-top: 8px; }

/* Controls */
.controls {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  grid-template-areas: "turn turn turn" "angle power throw";
  align-items: center;
  gap: 8px 16px;
  padding: 12px 16px 16px;
}
.turn { grid-area: turn; margin: 0; text-align: center; font-weight: 600; font-size: 1.05rem; }
.turn b { color: var(--who, var(--ink)); }
.slider:nth-of-type(1) { grid-area: angle; }
.slider:nth-of-type(2) { grid-area: power; }
#throw { grid-area: throw; min-width: 120px; font-size: 1.35rem; }
#throw:disabled { cursor: default; }
.controls.idle .slider, .controls.idle #throw { opacity: 0.45; pointer-events: none; }

.slider { display: flex; flex-direction: column; gap: 6px; }
.slider-label { font-weight: 600; color: var(--muted); }
.slider-label b { color: var(--ink); font-variant-numeric: tabular-nums; }
.slider input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 18px;
  border-radius: 999px;
  background: var(--cream-2);
  box-shadow: inset 0 2px 4px rgba(120, 80, 40, 0.22);
  outline: none;
}
.slider input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 0;
  background: radial-gradient(circle at 38% 32%, var(--p0-light), var(--p0) 70%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 4px 0 var(--p0-dark);
  cursor: pointer;
}
.slider input::-moz-range-thumb {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 0;
  background: radial-gradient(circle at 38% 32%, var(--p0-light), var(--p0) 70%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 4px 0 var(--p0-dark);
  cursor: pointer;
}
.controls.p1 .slider input::-webkit-slider-thumb { background: radial-gradient(circle at 38% 32%, var(--p1-light), var(--p1) 70%); box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 4px 0 var(--p1-dark); }
.controls.p1 .slider input::-moz-range-thumb { background: radial-gradient(circle at 38% 32%, var(--p1-light), var(--p1) 70%); box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 4px 0 var(--p1-dark); }
.slider input:disabled::-webkit-slider-thumb { cursor: default; }
.slider input:disabled::-moz-range-thumb { cursor: default; }

/* Help */
/* Help, on the start screen */
.help { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--muted); font-size: 0.98rem; line-height: 1.5; text-align: left; }
.help summary { list-style: none; min-height: 44px; display: inline-flex; align-items: center; gap: 6px; padding: 8px 18px; border-radius: 999px; cursor: pointer; color: var(--ink); font-weight: 600; }
.help summary::-webkit-details-marker { display: none; }
.help ul { margin: 0; padding: 12px 18px 12px 34px; width: 100%; }
.help strong { color: var(--ink); }
kbd { font: inherit; font-size: 0.85em; padding: 0 7px; border-radius: 8px; background: #fff; box-shadow: 0 2px 0 var(--cream-dark); color: var(--ink); }

/* Start screen */
.start {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  overflow-y: auto;
  padding: 24px 16px;
  /* see-through: the world (world.js) with its moving spectators shows behind the start screen */
  background: transparent;
}
body.at-start .app { visibility: hidden; }
.start-card { width: min(360px, 100%); display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center; }
.start-card h1 { margin: 0; font-size: clamp(2.4rem, 10vw, 3.8rem); white-space: nowrap; }
/* The hero above the title: the two gumdrops throw a ball back and forth (2 × 1.3 s), squashing as they throw and catch */
.start-head { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.hero { display: block; width: clamp(240px, 70vw, 320px); height: auto; overflow: visible; }
.hero-shadow { fill: rgba(60, 30, 110, 0.16); }
.hero-blob .body { stroke-width: 2.5; }
.hero-blob.p0 .body { fill: var(--p0); stroke: var(--p0-dark); }
.hero-blob.p1 .body { fill: var(--p1); stroke: var(--p1-dark); }
.hero-blob .shine { fill: #fff; opacity: 0.55; }
.hero-blob .eye { fill: #3a1f4a; }
.hero-blob .glint { fill: #fff; }
.hero-blob .mouth { fill: none; stroke: #3a1f4a; stroke-width: 2.4; stroke-linecap: round; }
.hero-blob .cheek { fill: #ff7aa8; opacity: 0.55; }
.hero-blob > g { transform-box: fill-box; transform-origin: 50% 100%; animation: hero-squash 2.6s ease-in-out infinite; }
.hero-blob.p1 > g { animation-delay: -1.3s; }
.hero-ball { animation: hero-x 1.3s linear infinite alternate; }
.hero-ball-y { animation: hero-y 0.65s infinite alternate; }
.hero-ball circle { fill: #ffd21e; stroke: #c99a00; stroke-width: 2; }
.hero-ball .gloss { fill: #fff; opacity: 0.7; }
@keyframes hero-x { from { transform: translateX(0); } to { transform: translateX(112px); } }
@keyframes hero-y { from { transform: translateY(0); animation-timing-function: cubic-bezier(0.2, 0.6, 0.4, 1); } to { transform: translateY(-62px); } }
@keyframes hero-squash {
  0%, 100% { transform: scale(1.1, 0.88); }
  10%, 90% { transform: scale(1, 1); }
  50% { transform: scale(1, 1.03) translateY(-2px); }
}
@media (orientation: portrait) and (min-width: 600px) { .hero { width: min(460px, 60vw); } }
@media (max-height: 640px) and (orientation: portrait) { .hero { width: 190px; } }
.start-form { width: 100%; padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 10px; }
.start-form .label { margin: 0; }
/* the second row: Robo's level, or the two names side by side */
.names { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.names .player-field { min-width: 0; padding: 6px 8px; gap: 6px; }
.names .player-field .badge { width: 24px; height: 24px; }
.names .player-field input { width: 100%; font-size: 1.05rem; }
/* the points: in the gear sheet (or here, when the arcade has no sheets) */
.settings-body { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.settings-body .label { margin: 0; font-size: 1.05rem; }
.player-field { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-radius: 16px; background: var(--cream-2); box-shadow: inset 0 2px 4px rgba(120, 80, 40, 0.18); }
.player-field .badge { flex: none; width: 30px; height: 30px; border-radius: 50% 50% 40% 40%; }
.player-field.p0 .badge { background: radial-gradient(circle at 38% 30%, var(--p0-light), var(--p0)); }
.player-field.p1 .badge { background: radial-gradient(circle at 38% 30%, var(--p1-light), var(--p1)); }
.player-field input { flex: 1; min-width: 0; border: 0; background: none; font: inherit; font-size: 1.15rem; font-weight: 600; color: var(--ink); outline: none; }
.player-field input::placeholder { color: var(--muted); }
.targets { display: flex; justify-content: center; gap: 10px; }
.targets button {
  width: 60px;
  height: 50px;
  border: 0;
  border-radius: 16px;
  font: inherit;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--ink);
  background: #fff;
  box-shadow: 0 4px 0 var(--cream-dark);
  cursor: pointer;
}
.targets button.on { color: #fff; background: var(--purple); box-shadow: 0 4px 0 var(--purple-dark); }
.targets.wide button { width: auto; flex: 1; padding: 0 10px; font-size: 1.1rem; white-space: nowrap; }
.targets.small button { height: 44px; font-size: 0.95rem; }
.player-field input:disabled { color: var(--ink); opacity: 1; }
.start-actions { width: min(280px, 100%); display: flex; flex-direction: column; align-items: center; gap: 16px; }
.start-actions #start-btn { width: 100%; text-align: center; }
.start-actions a { text-decoration: none; }

/* the stickers earned in this match, again on the end card */
.new-stickers { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 10px; margin: 0; padding: 5px 10px; border-radius: 16px; background: #fff7cc; box-shadow: inset 0 0 0 3px var(--lemon); color: var(--ink); font-weight: 700; line-height: 1.2; animation: sticker-row 0.4s ease 0.3s backwards; }
.new-stickers > span { display: inline-flex; align-items: center; gap: 6px; }
.new-stickers .art { width: 34px; height: 34px; }
@keyframes sticker-row { from { transform: scale(0.85); opacity: 0; } }
/* a theme colour that is light (gold, teal) still gives a clear purple button */
.btn--purple { background: linear-gradient(180deg, color-mix(in srgb, var(--purple) 75%, #fff), var(--purple)); }

@keyframes banner {
  0% { transform: translate(-50%, 14px) scale(0.5) rotate(-6deg); opacity: 0; }
  14% { transform: translate(-50%, 0) scale(1.12) rotate(2deg); opacity: 1; }
  24% { transform: translate(-50%, 0) scale(1) rotate(0); }
  80% { opacity: 1; }
  100% { transform: translate(-50%, -24px) scale(1); opacity: 0; }
}
@keyframes shake {
  20% { transform: translate(-6px, 2px); } 40% { transform: translate(5px, -2px); }
  60% { transform: translate(-3px, 1px); } 80% { transform: translate(2px, 0); }
}

@keyframes banner-fade {
  0%, 100% { transform: translate(-50%, 0); opacity: 0; }
  12%, 80% { transform: translate(-50%, 0); opacity: 1; }
}

@media (max-width: 560px) {
  .controls { grid-template-columns: 1fr 1fr; grid-template-areas: "turn turn" "angle power" "throw throw"; }
  #throw { width: 100%; }
  /* blurring the moving field behind the modal is heavy on phones */
  .modal { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(110, 63, 196, 0.72); }
  .modal.secret { background: none; }
  .modal-card { padding: 14px 14px 16px; }
  .modal-text { margin-bottom: 12px; }
  .modal-actions { gap: 8px; }
  .modal-actions .btn { padding: 8px 6px; font-size: 1rem; }
}

/* phones: no "vs" between the scores, so both names fit (also "Robo" with his picture) */
@media (max-width: 440px) {
  .vs { display: none; }
  .scores { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 6px; padding: 6px 8px; }
  .score .name .art { width: 1em; height: 1em; }
}
@media (max-width: 360px) {
  .topbar { gap: 6px; }
  .scores { gap: 4px; padding: 6px 8px; }
  .score { padding: 4px; }
  .score .name { font-size: 0.92rem; }
  .vs { display: none; }
  .scores { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .modal-title { font-size: 1.15rem; }
  /* every dodge button on two lines: the arrow above its word */
  .modal-actions .btn .art { display: block; margin: 0 auto 2px; }
}

/* Landscape: the top bar falls apart into side columns. Back on the left; on the right the round
   buttons, the score and the controls with "Gooi!" at the bottom; the field gets the full height. */
@media (orientation: landscape) {
  .app {
    --side: 300px;
    --pad-y: 12px;
    max-width: none;
    height: 100vh;
    height: 100dvh;
    min-height: 0;
    padding: max(var(--pad-y), env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(var(--pad-y), env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) var(--side);
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas: "back stage actions" ". stage scores" ". stage controls";
    gap: 10px 14px;
  }
  .topbar { display: contents; }
  .topbar .back-link { grid-area: back; }
  .top-actions { grid-area: actions; justify-content: flex-end; }
  .scores { grid-area: scores; max-width: none; grid-template-columns: minmax(0, 1fr); gap: 2px; padding: 6px 10px; }
  .vs { display: none; }
  .score { flex-direction: row; justify-content: space-between; gap: 10px; padding: 4px 8px; }
  .stage {
    grid-area: stage;
    width: min(100%, calc((100vh - 2 * var(--pad-y)) * 600 / 420));
    width: min(100%, calc((100dvh - 2 * var(--pad-y)) * 600 / 420));
    margin: 0;
    align-self: center;
    justify-self: center;
  }
  .controls {
    grid-area: controls;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    padding: 12px 14px 14px;
    min-height: 0;
  }
  /* the turn on top; the sliders and "Gooi!" together at the bottom, under the thumb */
  .slider:first-of-type { margin-top: auto; }
  #throw { width: 100%; min-width: 0; margin-top: 4px; padding-top: 16px; padding-bottom: 16px; font-size: 1.5rem; }
  .modal-card { padding: 14px 16px 16px; }
  .modal-text { margin-bottom: 12px; line-height: 1.3; }

  /* the start screen in two columns: the choices left, the big button right */
  .start-card {
    width: min(760px, 100%);
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    grid-template-areas: "logo actions" "form actions";
    gap: 14px 28px;
    align-items: center;
  }
  /* the hero sits left of the title */
  .start-head { grid-area: logo; flex-direction: row; gap: 14px; }
  .start-card h1 { font-size: clamp(2rem, 9vh, 3.6rem); }
  .hero { width: clamp(140px, 32vh, 280px); }
  .start-form { grid-area: form; }
  .start-actions { grid-area: actions; width: 100%; gap: 12px; }
  .start-actions #start-btn { padding-top: 22px; padding-bottom: 22px; font-size: 1.5rem; }
  .start-card .help, .start-card .start-utils, .start-card > .settings-body { grid-column: 1 / -1; }
}
/* phones on their side: smaller buttons and a narrower side column */
@media (orientation: landscape) and (max-height: 520px) {
  .app { --side: 250px; --pad-y: 8px; gap: 8px 10px; }
  .topbar .icon-btn, .topbar .back-link { width: 44px; height: 44px; font-size: 1.2rem; }
  .top-actions { gap: 6px; }
  .scores { padding: 4px 8px; }
  .score { padding: 2px 6px; }
  .score .name { font-size: 1rem; }
  .pts i { width: 12px; height: 12px; }
  .controls { gap: 6px; padding: 8px 12px 10px; }
  .turn { font-size: 0.95rem; line-height: 1.2; }
  .slider { gap: 2px; }
  #throw { padding-top: 10px; padding-bottom: 10px; font-size: 1.3rem; }
  .modal { padding: 8px; }
  .modal-card { padding: 10px 12px 12px; }
  .modal-title { font-size: 1.15rem; margin-bottom: 2px; }
  .modal-text { margin-bottom: 8px; font-size: 0.95rem; }
  .modal-actions { gap: 8px; }
  .modal-actions .btn { min-height: 46px; padding: 6px; font-size: 1rem; }
  .banner { font-size: 1.6rem; }
  .start { padding: 10px 16px; }
  .start-card { gap: 10px 24px; }
  .start-form { padding: 10px 12px 12px; gap: 8px; }
  .targets button { height: 46px; }
  .start-actions #start-btn { padding-top: 18px; padding-bottom: 18px; }
}
/* the end card in two columns where the screen is low, so both buttons are on screen */
@media (orientation: landscape) and (max-height: 560px) {
  .modal .end-card {
    width: min(600px, 100%);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    grid-template-areas: "icon text" "title text" "stars text" "stickers actions";
    align-items: center;
    gap: 8px 20px;
  }
  .end-card .over-icon { grid-area: icon; }
  .end-card .over-title { grid-area: title; }
  .end-card .over-stars { grid-area: stars; }
  .end-card .over-text { grid-area: text; }
  .end-card .new-stickers { grid-area: stickers; }
  .end-card .over-actions { grid-area: actions; margin-top: 0; }
}

/* Tablets: the field as wide as the screen (upright) or as high (on its side), and controls to match. */
@media (orientation: portrait) and (min-width: 561px) {
  .app { max-width: none; gap: 18px; }
  .controls { padding: 16px 22px 20px; gap: 12px 24px; }
  #throw { min-width: 200px; padding-top: 20px; padding-bottom: 20px; font-size: 1.7rem; }
}
@media (min-width: 561px) and (min-height: 600px) {
  .turn { font-size: 1.3rem; }
  .slider-label { font-size: 1.2rem; }
  .slider input { height: 22px; }
  .slider input::-webkit-slider-thumb { width: 40px; height: 40px; }
  .slider input::-moz-range-thumb { width: 40px; height: 40px; }
  .score .name { font-size: 1.25rem; }
  .pts i { width: 18px; height: 18px; }
}
@media (orientation: landscape) and (min-height: 600px) {
  .controls { gap: 22px; padding: 18px 18px 18px; }
  #throw { padding-top: 22px; padding-bottom: 22px; font-size: 1.8rem; }
}

/* the spectators on the stand (world.js): they bob along, and jump up when a ball hits */
.world-fx { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; container-type: size; }
.world-fx-stage { position: absolute; left: 50%; bottom: 0; width: max(100cqw, 100cqh * 1200 / 844); aspect-ratio: 1200 / 844; transform: translateX(-50%); }
.world-fx span { position: absolute; width: 7.67%; line-height: 0; transform-origin: 50% 100%; animation: fan-bob 2.6s ease-in-out calc(var(--g) * -0.37s) infinite; }
.world-fx svg { display: block; width: 100%; height: auto; overflow: visible; }
.world-fx.cheer span { animation: fan-cheer 0.38s ease-out calc(var(--g) * 0.04s) 4; }
@keyframes fan-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5%); } }
@keyframes fan-cheer { 0%, 100% { transform: translateY(0) scale(1, 1); } 15% { transform: translateY(0) scale(1.06, 0.9); } 55% { transform: translateY(-45%) scale(0.96, 1.06); } }

@media (prefers-reduced-motion: reduce) {
  .world-fx span, .hero-blob > g, .hero-ball, .hero-ball-y { animation: none !important; }
  .curtain i, .curtain::before { transition: none; }
  .stage.shake { animation: none; }
  .banner { animation-name: banner-fade; }
  .score { transition: none; }
  .new-stickers { animation: none; }
}

/* ---- Desktop: a big screen (the same test as html.desktop in assets/arcade.js) ----
   The field in the middle as big as the window allows; on the left the back button, the score of both players and,
   with a mouse (html.mouse), the keys; on the right the round buttons and the throw controls with big sliders and
   "Gooi!". On the field the mouse aims like a slingshot (game.js); a finger uses the sliders, so a big tablet on its
   side gets the same layout without the keys and the mouse hint. Sizes scale with --ui (assets/style.css). */
.key-card, .mouse-hint { display: none; }
@media (hover: hover) and (pointer: fine) {
  .slider input:not(:disabled) { cursor: pointer; }
  .slider input:not(:disabled):hover::-webkit-slider-thumb { filter: brightness(1.08); }
  .stage.can-aim #field { cursor: grab; }
  .stage.aiming #field { cursor: grabbing; }
}
@media (min-width: 1100px) and (min-height: 650px) {
  html.mouse .help .keys-line { display: none; }
  /* the pill's buttons as assets/style.css means them on desktop (its 44px base rule comes later in that file and wins) */
  :is(#start, body) .app .topbar .top-actions > .icon-btn { width: calc(52px * var(--ui)); height: calc(52px * var(--ui)); font-size: calc(1.4rem * var(--ui)); }
  .app {
    /* the right column holds the pill of four round buttons: never narrower than that */
    --side-l: clamp(160px, 11.5vw, 300px);
    --side-r: clamp(max(240px, 212px * var(--ui)), 17vw, 420px);
    --pad-y: calc(14px * var(--ui));
    grid-template-columns: var(--side-l) minmax(0, 1fr) var(--side-r);
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas: "back stage actions" "scores stage controls" "keys stage controls";
    gap: calc(16px * var(--ui)) calc(14px * var(--ui));
    padding: var(--pad-y) calc(14px * var(--ui));
  }
  :is(#start, body) .app .topbar .top-actions { grid-area: actions; justify-self: end; }
  .stage { width: min(100%, calc((100dvh - 2 * var(--pad-y)) * 600 / 420)); border-radius: calc(26px * var(--ui)); }
  .banner { font-size: calc(2.6rem * var(--ui)); }

  /* both players, one under the other, with big names and points */
  .scores { grid-area: scores; align-self: start; gap: calc(8px * var(--ui)); padding: calc(10px * var(--ui)); }
  .score { flex-direction: column; align-items: flex-start; gap: calc(8px * var(--ui)); padding: calc(10px * var(--ui)) calc(12px * var(--ui)); border-radius: calc(18px * var(--ui)); }
  .score .name { font-size: calc(22px * var(--ui)); }
  .pts { justify-content: flex-start; gap: calc(6px * var(--ui)); }
  .pts i { width: calc(22px * var(--ui)); height: calc(22px * var(--ui)); }
  #score-0.active { box-shadow: inset 0 0 0 3px var(--p0), inset 0 2px 4px rgba(120, 80, 40, 0.15); }
  #score-1.active { box-shadow: inset 0 0 0 3px var(--p1), inset 0 2px 4px rgba(120, 80, 40, 0.15); }

  /* the throw controls: whose turn, two big sliders and "Gooi!", together at the top of the column */
  .controls { grid-area: controls; align-self: start; gap: calc(18px * var(--ui)); padding: calc(18px * var(--ui)); }
  .slider:first-of-type { margin-top: 0; }
  .turn { font-size: calc(22px * var(--ui)); line-height: 1.25; text-align: left; }
  .slider { gap: calc(10px * var(--ui)); }
  .slider-label { font-size: calc(21px * var(--ui)); }
  .slider input { height: calc(26px * var(--ui)); }
  .slider input::-webkit-slider-thumb { width: calc(50px * var(--ui)); height: calc(50px * var(--ui)); }
  .slider input::-moz-range-thumb { width: calc(50px * var(--ui)); height: calc(50px * var(--ui)); }
  #throw { min-height: calc(76px * var(--ui)); padding-top: 0; padding-bottom: 0; font-size: calc(2rem * var(--ui)); border-radius: calc(24px * var(--ui)); }

  /* the keys and the mouse, under the scores */
  .key-card {
    grid-area: keys;
    align-self: start;
    display: flex;
    flex-direction: column;
    gap: calc(10px * var(--ui));
    padding: calc(12px * var(--ui)) calc(14px * var(--ui)) calc(14px * var(--ui));
    font-size: calc(18px * var(--ui));
    color: var(--muted);
    font-weight: 600;
    line-height: 1.3;
  }
  .key-title { margin: 0; color: var(--ink); font-weight: 700; font-size: calc(19px * var(--ui)); }
  .key-card ul { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: calc(9px * var(--ui)) calc(12px * var(--ui)); }
  .key-card li { display: contents; }
  .key-card .keys { display: inline-flex; gap: calc(4px * var(--ui)); }
  .key-card kbd { display: inline-grid; place-items: center; min-width: 1.9em; height: 1.75em; padding: 0 0.4em; font-size: 0.95em; font-weight: 700; }
  .mouse-hint { display: block; margin: 0; padding-top: calc(12px * var(--ui)); border-top: 2px dashed var(--cream-2); color: var(--muted); font-size: calc(18px * var(--ui)); font-weight: 600; line-height: 1.3; }
  .mouse-hint .art { width: 1.2em; height: 1.2em; vertical-align: -0.25em; }
  .controls.idle .mouse-hint { opacity: 0.45; }
  /* a touch screen has no keys, and a finger aims with the sliders */
  html:not(.mouse) :is(.key-card, .mouse-hint) { display: none; }

  /* the secret choice on the curtain, and the hand-over: a big card with big buttons */
  .modal { padding: calc(24px * var(--ui)); }
  .modal-card { width: min(100%, calc(580px * var(--ui))); padding: calc(26px * var(--ui)) calc(28px * var(--ui)) calc(28px * var(--ui)); }
  .modal-title { margin-bottom: calc(10px * var(--ui)); font-size: calc(2rem * var(--ui)); }
  .modal-text { margin-bottom: calc(22px * var(--ui)); font-size: calc(20px * var(--ui)); }
  .modal-actions { gap: calc(14px * var(--ui)); }
  .modal-actions .btn { min-height: calc(76px * var(--ui)); font-size: calc(1.45rem * var(--ui)); border-radius: calc(22px * var(--ui)); }

  /* the end card over the whole screen: wide, in two columns */
  .modal .end-card {
    width: min(100%, calc(720px * var(--ui)));
    max-height: calc(100dvh - 48px);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    grid-template-areas: "icon text" "title text" "stars text" "stickers actions";
    align-items: center;
    gap: calc(10px * var(--ui)) calc(28px * var(--ui));
    padding: calc(24px * var(--ui)) calc(28px * var(--ui));
  }
  .end-card .over-icon { grid-area: icon; }
  .end-card .over-icon .art { width: calc(84px * var(--ui)); height: calc(84px * var(--ui)); }
  .end-card .over-title { grid-area: title; font-size: calc(1.9rem * var(--ui)); }
  .end-card .over-stars { grid-area: stars; }
  .end-card .over-stars span { width: calc(46px * var(--ui)); height: calc(46px * var(--ui)); }
  .end-card .over-stars span:nth-child(2) { width: calc(58px * var(--ui)); height: calc(58px * var(--ui)); margin-top: calc(-8px * var(--ui)); }
  .end-card .over-text { grid-area: text; font-size: calc(19px * var(--ui)); }
  .end-card .new-stickers { grid-area: stickers; font-size: calc(18px * var(--ui)); }
  .end-card .new-stickers .art { width: calc(40px * var(--ui)); height: calc(40px * var(--ui)); }
  .end-card .over-actions { grid-area: actions; margin-top: 0; padding: 0; position: static; background: none; gap: calc(14px * var(--ui)); }
  .end-card .over-actions .btn { min-height: calc(60px * var(--ui)); font-size: calc(1.25rem * var(--ui)); border-radius: calc(20px * var(--ui)); }

  /* the start screen: two columns at any width, scaled up */
  .start { padding: calc(24px * var(--ui)) 24px; }
  .start-card { width: min(94vw, calc(900px * var(--ui))); grid-template-areas: "logo logo" "form actions"; gap: calc(18px * var(--ui)) calc(44px * var(--ui)); justify-items: center; }
  .start-head { gap: calc(24px * var(--ui)); }
  .start-card h1 { font-size: calc(4.4rem * var(--ui)); }
  .hero { width: calc(300px * var(--ui)); }
  .start-form { padding: calc(14px * var(--ui)) calc(18px * var(--ui)) calc(18px * var(--ui)); gap: calc(12px * var(--ui)); }
  .start-form .label, .settings-body .label { font-size: calc(19px * var(--ui)); }
  .targets { gap: calc(12px * var(--ui)); }
  .targets button { width: calc(72px * var(--ui)); height: calc(64px * var(--ui)); font-size: calc(1.5rem * var(--ui)); border-radius: calc(18px * var(--ui)); }
  .targets.wide button { width: auto; font-size: calc(21px * var(--ui)); }
  .targets.small button { height: calc(56px * var(--ui)); font-size: calc(18px * var(--ui)); }
  .names { gap: calc(10px * var(--ui)); }
  .names .player-field { padding: calc(8px * var(--ui)) calc(12px * var(--ui)); }
  .names .player-field .badge { width: calc(30px * var(--ui)); height: calc(30px * var(--ui)); }
  .names .player-field input { font-size: calc(19px * var(--ui)); }
  .start-actions { gap: calc(12px * var(--ui)); }
  .start-actions #start-btn { padding: calc(26px * var(--ui)) 20px; font-size: calc(1.9rem * var(--ui)); border-radius: calc(24px * var(--ui)); }
}
