/* The world map (docs/math-racing/v5-worlds.md §9; src/run/screens/map-ui.js, map-layout.js): the hub between races, a race
   track in the grass. Upright: a chip band on top, the track, a bar with the world's name and Go.
   On its side (5/4, as the rest of the game): the track on the left, one panel on the right.
   The bands here are the numbers in map-layout.js CHROME (the node test lays the track out with them).
   The track scrolls up and down when it is taller than the stage. Everything that moves animates transform or opacity. */
.map{
  --map-grass:#9fd67c; --map-lite:rgba(255,255,255,.22); --map-deep:rgba(46,110,40,.16);
  --map-rim:#ffffff; --map-rim-edge:#4f8a3f; --map-cream:#fff6e4;
  /* the road: open (colour) and not yet open (soft grey) */
  --rd-as:#5a6070; --rd-kw:#ffffff; --rd-kc:#ff8a3d; --rd-cl:rgba(255,255,255,.85); --rd-sh:rgba(28,64,22,.2);
  --rd-off-as:#c3cbbd; --rd-off-kw:#eef2ea; --rd-off-kc:#d8ded3;
  /* scenery */
  --sc-sh:rgba(28,64,22,.18); --sc-tr:#8a5a35;
  --sc-t0a:#4fa64a; --sc-t0b:#74c766; --sc-t1a:#3d8f55; --sc-t1b:#5cb071; --sc-t2a:#7cb944; --sc-t2b:#9ad25f;
  --sc-pa:#3b8a56; --sc-pb:#2c6e44; --sc-b0:#5db55a; --sc-b1:#4aa060; --sc-hl:rgba(255,255,255,.2);
  --sc-f0:#ffd23f; --sc-f1:#ff9fcf; --sc-f2:#ffffff; --sc-fc:#f39c34; --sc-ro:#b9beb2; --sc-rh:#e2e5dc;
  --map-side:clamp(172px, 22vw, 240px);
  position:fixed; inset:0; z-index:40; box-sizing:border-box; overflow:hidden;
  display:grid; grid-template:"back" 50px "stage" minmax(0, 1fr) "bar" 92px / minmax(0, 1fr);
  padding:env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
  background:radial-gradient(120% 60% at 30% 0%, var(--map-lite), transparent 70%), var(--map-grass);
  color:var(--ink); touch-action:manipulation;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .map{
    --map-grass:#2d5238; --map-lite:rgba(150,190,255,.08); --map-deep:rgba(0,0,0,.18);
    --map-rim:#31436e; --map-rim-edge:#0b1a12; --map-cream:#2a3350;
    --rd-as:#262b38; --rd-kw:#dfe6f5; --rd-kc:#f08a46; --rd-cl:rgba(230,236,255,.7); --rd-sh:rgba(0,0,0,.3);
    --rd-off-as:#3c4c44; --rd-off-kw:#4f6158; --rd-off-kc:#46564f;
    --sc-sh:rgba(0,0,0,.22); --sc-tr:#5a4030;
    --sc-t0a:#2f6d3a; --sc-t0b:#3f854a; --sc-t1a:#285e3d; --sc-t1b:#36764c; --sc-t2a:#4a7330; --sc-t2b:#5c8a3c;
    --sc-pa:#2a6640; --sc-pb:#1f4f31; --sc-b0:#367a3f; --sc-b1:#2d6b44; --sc-hl:rgba(200,220,255,.1);
    --sc-f0:#c9a84a; --sc-f1:#c78aa8; --sc-f2:#c9d2e0; --sc-fc:#b5823f; --sc-ro:#5d6670; --sc-rh:#7a838c }
}
:root[data-theme="dark"] .map{
  --map-grass:#2d5238; --map-lite:rgba(150,190,255,.08); --map-deep:rgba(0,0,0,.18);
  --map-rim:#31436e; --map-rim-edge:#0b1a12; --map-cream:#2a3350;
  --rd-as:#262b38; --rd-kw:#dfe6f5; --rd-kc:#f08a46; --rd-cl:rgba(230,236,255,.7); --rd-sh:rgba(0,0,0,.3);
  --rd-off-as:#3c4c44; --rd-off-kw:#4f6158; --rd-off-kc:#46564f;
  --sc-sh:rgba(0,0,0,.22); --sc-tr:#5a4030;
  --sc-t0a:#2f6d3a; --sc-t0b:#3f854a; --sc-t1a:#285e3d; --sc-t1b:#36764c; --sc-t2a:#4a7330; --sc-t2b:#5c8a3c;
  --sc-pa:#2a6640; --sc-pb:#1f4f31; --sc-b0:#367a3f; --sc-b1:#2d6b44; --sc-hl:rgba(200,220,255,.1);
  --sc-f0:#c9a84a; --sc-f1:#c78aa8; --sc-f2:#c9d2e0; --sc-fc:#b5823f; --sc-ro:#5d6670; --sc-rh:#7a838c }
@media (min-aspect-ratio: 5/4){
  .map{grid-template:"stage back" 50px "stage bar" minmax(0, 1fr) / minmax(0, 1fr) var(--map-side)}
}

/* The chip back to the start card (grade, topic, difficulty) */
.map-back{grid-area:back; align-self:center; justify-self:start; margin-left:12px; max-width:calc(100% - 24px); min-height:44px; box-sizing:border-box; z-index:1;
  display:flex; align-items:center; gap:6px; padding:6px 14px 6px 10px; font:600 14px/1 var(--font-display); color:var(--ink); box-shadow:0 2px 0 var(--tile-edge)}
.map-back span:last-child{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.map-back span:first-child{font-size:20px; line-height:.8; margin-top:-2px}

/* The bar: the selected world's name and the one big button */
.map-bar{grid-area:bar; display:flex; align-items:center; gap:12px; margin:0 12px 12px; padding:0 12px 0 18px; border-radius:22px; z-index:1;
  background:var(--tile); border:1px solid var(--panel-line); box-shadow:0 5px 0 var(--tile-edge)}
.map-name{flex:1 1 auto; min-width:0; font:700 24px/1.05 var(--font-display); text-wrap:balance}
.map-go{flex:none; min-width:112px; padding:14px 26px; font-size:26px; font-weight:700; border-radius:18px}
@media (min-aspect-ratio: 5/4){
  .map-back{justify-self:stretch; margin:0 12px 0 0; max-width:none}
  .map-bar{flex-direction:column; justify-content:flex-end; align-items:stretch; gap:12px; margin:6px 12px 12px 0; padding:14px 12px 16px; text-align:center}
  .map-name{flex:1 1 auto; display:grid; place-items:center; font-size:26px}
  .map-go{min-width:0; padding:16px 10px}
}
/* (2026-11-12, coordinator: the landscape side panel was a tall, mostly empty column.) Now one group: the selected
   world's painting with its name under it, your racer (bigger) with the record cup beside it, and Go at the bottom.
   The painting (--map-pic, set by map-ui.js) shrinks first on short screens. Nothing new to read or tap. */
@media (min-aspect-ratio: 5/4){
  .map-bar{display:grid; grid-template-columns:1fr auto auto 1fr; grid-template-rows:minmax(0, max-content) auto auto;
    grid-template-areas:"name name name name" ". racer rec ." "go go go go"; align-content:center; column-gap:10px; row-gap:12px}
  .map-bar .map-name{grid-area:name; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; min-height:0}
  .map-bar .map-name::before{content:''; flex:0 1 clamp(120px, 26vh, 210px); min-height:0; aspect-ratio:1; max-width:100%; border-radius:50%;
    background:var(--map-pic, none) center / cover, var(--map-cream); box-shadow:0 0 0 4px var(--map-rim), 0 4px 0 4px var(--map-rim-edge)}
  .map-bar .map-racer{grid-area:racer; width:64px; height:64px; align-self:center}
  .map-bar .map-rec{grid-area:rec; align-self:center}
  .map-bar .map-go{grid-area:go}
  /* only as tall as what it holds, right under the back chip (it may still shrink on short screens: the painting gives way) */
  .map-bar{align-self:start; max-height:calc(100% - 18px); box-sizing:border-box}
}
@media (min-aspect-ratio: 5/4) and (max-height:430px){ .map-bar .map-racer{width:52px; height:52px} .map-name{font-size:22px} .map-bar{row-gap:10px} }
@media (max-width:359px){ .map-name{font-size:20px} .map-go{min-width:96px; padding:14px 18px} }

/* The stage scrolls up and down (no bar; its edges fade under the chip and the bar) */
.map-stage{grid-area:stage; position:relative; min-width:0; min-height:0; --r:32px;
  overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; scrollbar-width:none;
  -webkit-mask-image:linear-gradient(transparent, #000 14px, #000 calc(100% - 14px), transparent); mask-image:linear-gradient(transparent, #000 14px, #000 calc(100% - 14px), transparent)}
.map-stage::-webkit-scrollbar{display:none}
.map-track{position:relative; width:100%; min-height:100%;
  background:
    radial-gradient(28% 9% at 18% 12%, var(--map-lite), transparent 70%),
    radial-gradient(30% 8% at 82% 30%, var(--map-deep), transparent 70%),
    radial-gradient(26% 10% at 30% 52%, var(--map-deep), transparent 70%),
    radial-gradient(32% 9% at 76% 70%, var(--map-lite), transparent 70%),
    radial-gradient(28% 8% at 22% 90%, var(--map-lite), transparent 70%)}
.map-road{position:absolute; left:0; top:0; display:block; pointer-events:none; overflow:visible}
.map-road path[class^="rd-"]{fill:none; stroke-linecap:round; stroke-linejoin:round}
.rd-on .rd-sh,.rd-off .rd-sh{stroke:var(--rd-sh)}
.rd-on .rd-kw{stroke:var(--rd-kw)} .rd-on .rd-kc{stroke:var(--rd-kc); stroke-linecap:butt} .rd-on .rd-as{stroke:var(--rd-as)} .rd-on .rd-cl{stroke:var(--rd-cl); stroke-linecap:butt}
.rd-off .rd-kw{stroke:var(--rd-off-kw)} .rd-off .rd-kc{stroke:var(--rd-off-kc); stroke-linecap:butt} .rd-off .rd-as{stroke:var(--rd-off-as)} .rd-off .rd-cl{stroke:var(--rd-off-kw); stroke-linecap:butt; opacity:.6}
.rd-off .rd-sh{opacity:.5}
.rd-new{opacity:0; transition:opacity .6s ease-out}
.rd-new.in{opacity:1}
.sc-sh{fill:var(--sc-sh)} .sc-tr{fill:var(--sc-tr)}
.sc-t0a{fill:var(--sc-t0a)} .sc-t0b{fill:var(--sc-t0b)} .sc-t1a{fill:var(--sc-t1a)} .sc-t1b{fill:var(--sc-t1b)} .sc-t2a{fill:var(--sc-t2a)} .sc-t2b{fill:var(--sc-t2b)}
.sc-pa{fill:var(--sc-pa)} .sc-pb{fill:var(--sc-pb)} .sc-b0{fill:var(--sc-b0)} .sc-b1{fill:var(--sc-b1)} .sc-hl{fill:var(--sc-hl)}
.sc-f0{fill:var(--sc-f0)} .sc-f1{fill:var(--sc-f1)} .sc-f2{fill:var(--sc-f2)} .sc-fc{fill:var(--sc-fc)} .sc-ro{fill:var(--sc-ro)} .sc-rh{fill:var(--sc-rh)}

/* A world: a round picture on the road (map-ui.js places them; --r = a stop's radius in px) */
.map-stop{position:absolute; left:0; top:0; width:calc(var(--r) * 2); height:calc(var(--r) * 2); margin:calc(var(--r) * -1) 0 0 calc(var(--r) * -1); padding:0; border:0; border-radius:50%;
  background:none; -webkit-tap-highlight-color:transparent; touch-action:manipulation}
.map-stop:focus-visible{outline:3px solid var(--you); outline-offset:4px}
.map-disc{position:absolute; inset:0; box-sizing:border-box; border-radius:50%; overflow:hidden; background:var(--map-cream);
  border:calc(var(--r) * .1) solid var(--map-rim); box-shadow:0 calc(var(--r) * .1) 0 var(--map-rim-edge), 0 calc(var(--r) * .26) calc(var(--r) * .34) rgba(10,40,10,.24);
  transition:opacity .5s, filter .5s}
.map-disc canvas,.map-disc img{position:absolute; inset:0; width:100%; height:100%; display:block; border-radius:50%}
.map-disc img{object-fit:cover; opacity:0; transition:opacity .4s}
.map-disc img.in{opacity:1}
.map-stop[aria-current="true"] .map-disc{border-color:var(--you)}
/* not opened yet: soft and grey, a small padlock, no words */
.map-stop.locked{cursor:default}
.map-stop.locked .map-disc{filter:grayscale(1) contrast(.72) brightness(1.08); opacity:.62}
.map-lock{position:absolute; left:50%; top:50%; width:calc(var(--r) * .7); height:calc(var(--r) * .7); margin:calc(var(--r) * -.35) 0 0 calc(var(--r) * -.35); opacity:0; transition:opacity .3s; pointer-events:none; transform-origin:50% 20%}
.map-stop.locked .map-lock{opacity:.9}
.map-stop.shake .map-lock{animation:mapShake .42s ease-in-out}
@keyframes mapShake{0%,100%{transform:none} 20%{transform:rotate(-13deg)} 45%{transform:rotate(11deg)} 70%{transform:rotate(-7deg)} 88%{transform:rotate(4deg)}}
/* the best medal: gold, silver or bronze, with its place on it (not colour alone) */
.map-medal{position:absolute; right:calc(var(--r) * -.18); top:calc(var(--r) * -.18); width:calc(var(--r) * .74); height:calc(var(--r) * .74); box-sizing:border-box; border-radius:50%;
  display:none; place-items:center; font:700 calc(var(--r) * .44)/1 var(--font-display); color:#3a2c0a; background:var(--mc, #ffc83d);
  border:calc(var(--r) * .06) solid #ffffff; box-shadow:0 calc(var(--r) * .05) 0 rgba(0,0,0,.22); pointer-events:none; z-index:1}
.map-stop[data-medal="1"] .map-medal{display:grid; --mc:#ffc83d}
.map-stop[data-medal="2"] .map-medal{display:grid; --mc:#c9d2e3}
.map-stop[data-medal="3"] .map-medal{display:grid; --mc:#e09a5b}
/* raced to the end off the podium: a tick (it counts toward the group) */
.map-stop[data-medal="done"] .map-medal{display:grid; --mc:#8fdc8a; color:#1d4a22}
.map-medal.land{animation:mapMedal .55s cubic-bezier(.3,1.5,.5,1) both}
@keyframes mapMedal{0%{opacity:0; transform:translateY(calc(var(--r) * -1.1)) scale(2.2) rotate(-25deg)} 60%{opacity:1} 100%{opacity:1; transform:none}}
/* the next world(s) pulse gently */
.map-stop.newest::after{content:""; position:absolute; inset:calc(var(--r) * -.1); border-radius:50%; border:calc(var(--r) * .08) solid var(--gold, #ffc83d); pointer-events:none;
  animation:mapPulse 1.9s ease-out infinite}
@keyframes mapPulse{0%{opacity:.95; transform:scale(.94)} 70%,100%{opacity:0; transform:scale(1.24)}}
.map-stop.opening .map-disc{animation:mapOpen .5s cubic-bezier(.3,1.5,.5,1)}
@keyframes mapOpen{0%{transform:scale(.86)} 100%{transform:none}}

/* The gate on the road into a closed group: a lock and how many of the group before it are finished ("5 of 8") */
.map-gate{position:absolute; left:0; top:0; z-index:1; display:flex; align-items:center; gap:calc(var(--r) * .12); transform:translate(-50%, -50%);
  padding:calc(var(--r) * .1) calc(var(--r) * .26) calc(var(--r) * .1) calc(var(--r) * .14); border-radius:999px; background:var(--tile); border:1px solid var(--panel-line);
  box-shadow:0 calc(var(--r) * .08) 0 var(--tile-edge); font:700 calc(var(--r) * .4)/1 var(--font-display); color:var(--ink); white-space:nowrap; pointer-events:none;
  opacity:0; transition:opacity .5s}
.map-gate.shut{opacity:1}
.map-gate .map-lock{position:static; width:calc(var(--r) * .5); height:calc(var(--r) * .5); margin:0; opacity:1}

/* the player: a small canvas moved along the road (transform only), above the stops */
.map-hero{position:absolute; left:0; top:0; z-index:2; pointer-events:none; will-change:transform; transition:opacity .2s}

@media (prefers-reduced-motion: reduce){
  .map-medal.land,.map-stop.shake .map-lock,.map-stop.opening .map-disc{animation:none!important}
  .map-stop.newest::after{animation:none; opacity:.9}
  .map-disc{transition:none}
}
html.calm :is(.map-medal.land,.map-stop.shake .map-lock,.map-stop.opening .map-disc){animation:none!important}
html.calm .map-stop.newest::after{animation:none; opacity:.9}
html.calm .map-disc{transition:none}
