/* Same structure as the other toys, its own colours. Copied rather than shared:
   a toy owns everything it needs, so none of them can break another. */

:root {
  --ink:   #eef2ff;
  --dim:   #a3aecb;
  --glass: rgba(8, 10, 26, 0.76);
  --line:  rgba(150, 170, 255, 0.18);
  --hot:   #6ea8ff;
  --warm:  #ff7ad9;
  --pad:   14px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%; overflow: hidden;
  background: #04050c; color: var(--ink);
  font: 14px/1.45 ui-sans-serif, system-ui, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}
body.idle { cursor: none; }

#gl {
  position: fixed; inset: 0; width: 100%; height: 100%; display: block;
  touch-action: none;                 /* we handle every gesture ourselves */
  -webkit-tap-highlight-color: transparent;
  user-select: none; -webkit-user-select: none;
}

/* ── panel ─────────────────────────────────────────────────────────────────── */

#panel {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 10;
  width: 330px; max-width: 94vw;
  /* No top padding: the sticky header below carries it instead. With the
     padding here, sticky cannot rise above the panel's content box and parks
     18px down, leaving a strip for the sliders to slide up into. */
  padding: 0 var(--pad) 28px;
  overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y;
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(1.25);
  -webkit-backdrop-filter: blur(18px) saturate(1.25);
  border-right: 1px solid var(--line);
  transition: transform .32s cubic-bezier(.4,0,.2,1), opacity .32s;
}
/* top/bottom sizes the panel to the LAYOUT viewport, which on iOS is the height
   with the browser toolbars retracted — so the bottom of the panel, and the
   sticky action bar with it, sits under iOS Chrome's toolbar and cannot be
   reached. dvh tracks the viewport actually on screen. @supports so anything
   without dvh keeps the old behaviour rather than losing its height. */
@supports (height: 100dvh) {
  #panel { bottom: auto; height: 100dvh; }
}

body.bare #panel { transform: translateX(-104%); opacity: 0; pointer-events: none; }
body.bare #hud   { opacity: 0; }
#panel::-webkit-scrollbar { width: 8px; }
#panel::-webkit-scrollbar-thumb { background: rgba(150,170,255,.22); border-radius: 4px; }

/* ⚠️ Sticky, and load-bearing rather than decorative.
   On a phone this panel is a long scroll of controls, it covers the canvas
   completely, and the only buttons that dismiss it live in this header. When
   the header scrolled away with everything else, the only route back to the
   picture was to scroll all the way to the top again — through sliders that
   take a vertical drag and change themselves instead of scrolling. Reported
   from iOS Chrome as "I can't scroll up to the top", which is exactly what it
   was. Same trick as .actions at the other end. */
.head {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; justify-content: space-between;
  margin: 0 calc(var(--pad) * -1) 16px;
  padding: 18px var(--pad) 12px;
  background: linear-gradient(to bottom, var(--glass) 72%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.head h1 {
  margin: 0; font-size: 21px; font-weight: 650; letter-spacing: .10em; text-transform: lowercase;
  background: linear-gradient(92deg, var(--hot), var(--warm));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.head-btns { display: flex; gap: 8px; }

p.touch-only, button.touch-only, span.touch-only { display: none; }
@media (hover: none), (pointer: coarse) {
  .pointer-only { display: none; }
  p.touch-only { display: block; } button.touch-only { display: block; } span.touch-only { display: inline; }
}

section { margin-bottom: 16px; }
section h2 {
  margin: 0 0 8px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--dim);
}
.note, .keys, .blurb { margin: 7px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--dim); }
.keys { margin-top: 18px; padding-top: 13px; border-top: 1px solid var(--line); font-size: 11px; }

/* ── controls ──────────────────────────────────────────────────────────────── */

button {
  font: inherit; color: var(--ink); cursor: pointer;
  background: rgba(255,255,255,.07);
  border: 1px solid transparent; border-radius: 9px; padding: 9px 11px;
  transition: background .14s, border-color .14s, transform .07s;
}
button:hover  { background: rgba(255,255,255,.15); }
button:active { transform: translateY(1px); }
button.on { background: rgba(110,168,255,.18); border-color: rgba(110,168,255,.55); color: #fff; }
.perform, .done { padding: 8px 14px; font-size: 12.5px; font-weight: 600; }
.perform { background: linear-gradient(96deg, rgba(110,168,255,.22), rgba(255,122,217,.20)); border-color: rgba(150,170,255,.4); }
button.wide { display: block; width: 100%; text-align: left; }
button.big  { font-size: 15px; font-weight: 650; padding: 13px; }

.row { display: flex; gap: 8px; }
.row button { flex: 1; }

.actions {
  position: sticky; bottom: -28px; z-index: 2;
  display: flex; gap: 8px; margin: 6px -14px -28px; padding: 12px 14px 18px;
  background: linear-gradient(to top, var(--glass) 62%, transparent);
  backdrop-filter: blur(10px);
}
.actions .big { flex: 2; }

.presets { display: grid; grid-template-columns: repeat(2, 1fr); gap: 7px; }
.preset { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 9px 10px; text-align: left; }
.preset .pn { font-size: 13px; }
.preset .pd { font-size: 10.5px; color: var(--dim); }
.preset.on .pd { color: rgba(255,255,255,.7); }

.row-slider { margin-bottom: 8px; }
.lab { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 3px; }
.lab .nm { font-size: 12.5px; }
.lab .val { font-size: 11.5px; color: var(--hot); font-variant-numeric: tabular-nums; }

input[type=range] {
  /* Vertical drags belong to the panel's scroller, horizontal ones to the
     slider. Without this a drag starting on a slider moves the slider instead
     of scrolling, and much of the panel's height is sliders. */
  touch-action: pan-y;
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 24px; background: transparent; cursor: pointer; margin: 0;
}
input[type=range]::-webkit-slider-runnable-track {
  height: 5px; border-radius: 3px;
  background: linear-gradient(90deg, rgba(110,168,255,.55), rgba(255,122,217,.45));
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 19px; height: 19px; margin-top: -7px; border-radius: 50%;
  background: #fff; border: 0; box-shadow: 0 1px 6px rgba(0,0,0,.55);
}
input[type=range]::-moz-range-track {
  height: 5px; border-radius: 3px;
  background: linear-gradient(90deg, rgba(110,168,255,.55), rgba(255,122,217,.45));
}
input[type=range]::-moz-range-thumb { width: 19px; height: 19px; border-radius: 50%; border: 0; background: #fff; }

.palettes { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.pal { height: 28px; padding: 0; border-radius: 7px; border: 1px solid rgba(255,255,255,.14); }
.pal.on { border-color: #fff; box-shadow: 0 0 0 2px rgba(110,168,255,.55); }

/* ── overlays ──────────────────────────────────────────────────────────────── */

#hud {
  position: fixed; right: 12px; bottom: 10px; z-index: 9;
  font: 11px/1.4 ui-monospace, Consolas, monospace;
  color: var(--dim); opacity: .5; pointer-events: none;
  text-shadow: 0 0 8px #000; transition: opacity .3s;
}
#toast {
  position: fixed; left: 50%; top: 26px; transform: translateX(-50%); z-index: 20;
  padding: 10px 18px; border-radius: 10px; pointer-events: none;
  background: var(--glass); backdrop-filter: blur(12px); border: 1px solid var(--line);
  font-size: 13px; opacity: 0; transition: opacity .3s;
}
#toast.on { opacity: 1; }
#err {
  position: fixed; inset: 0; z-index: 40; display: none; overflow: auto;
  margin: 0; padding: 28px; white-space: pre-wrap;
  background: rgba(4,5,12,.96); color: #9fc4ff;
  font: 12px/1.55 ui-monospace, Consolas, monospace;
}
#hint {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 9;
  padding: 9px 16px; border-radius: 9px;
  background: var(--glass); border: 1px solid var(--line);
  font-size: 12.5px; color: var(--dim);
  opacity: 0; transition: opacity .4s; pointer-events: none;
}
body.bare #hint { opacity: .8; }
body.bare.idle #hint { opacity: 0; }

@media (hover: none), (pointer: coarse) {
  button { padding: 11px 12px; }
  .pal { height: 36px; }
  input[type=range] { height: 34px; }
  input[type=range]::-webkit-slider-thumb { width: 26px; height: 26px; margin-top: -10.5px; }
  input[type=range]::-moz-range-thumb { width: 26px; height: 26px; }
  #panel   { padding-bottom: calc(28px + env(safe-area-inset-bottom)); }
  .actions { padding-bottom: calc(18px + env(safe-area-inset-bottom)); }
  #hint    { bottom: calc(22px + env(safe-area-inset-bottom)); font-size: 13.5px; }
  #toast   { font-size: 15px; padding: 12px 22px; }
}
@media (max-width: 640px) { #panel { width: 100%; max-width: 100%; } }

/* on a touch screen the toy opens without its panel, which would cover the
   whole picture, and this says for a few seconds how to bring it up */
body.bare.intro #hint, body.bare.intro.idle #hint { opacity: .85; }

/* ── the way round (the same in each toy with this panel) ──────────────────── */
/* while the panel is away: the controls, home, and the next toy */
#way {
  position: fixed; z-index: 11; display: flex; gap: 6px; align-items: center;
  top: calc(10px + env(safe-area-inset-top)); left: calc(10px + env(safe-area-inset-left));
  transition: opacity .35s;
}
#way a, #way button {
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 8px 13px;
  font: 600 13px/1 ui-sans-serif, system-ui, "Segoe UI", sans-serif; color: var(--ink); text-decoration: none;
  background: rgba(14, 14, 22, .62); border: 1px solid rgba(255, 255, 255, .16); border-radius: 999px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); cursor: pointer;
}
#way a:hover, #way button:hover { background: rgba(40, 36, 56, .8); }
#way a:focus-visible, #way button:focus-visible, .onward a:focus-visible, .head h1 a:focus-visible,
#panel button:focus-visible, #panel summary:focus-visible { outline: 2px solid var(--warm); outline-offset: 2px; }
body:not(.bare) #way { opacity: 0; pointer-events: none; }
body.bare.idle:not(.intro) #way { opacity: 0; pointer-events: none; }
@media (hover: none), (pointer: coarse) { #way a, #way button { min-height: 44px; padding: 11px 15px; font-size: 14px; } }
/* the title leads home */
.head h1 a { color: inherit; text-decoration: none; }
.head h1 a:hover { text-decoration: underline; text-decoration-color: var(--warm); text-underline-offset: 4px; }
/* and the foot of the panel, home and onward */
.onward { display: flex; justify-content: space-between; gap: 10px; margin: 14px 0 0; font-size: 13px; }
.onward a { color: var(--ink); text-decoration: none; padding: 8px 0; }
.onward a:hover { text-decoration: underline; }
/* section headings above the labels they head, not below them */
section h2 { font-size: 12px; color: var(--ink); opacity: .82; }
/* the fine-tuning, folded */
details.more { margin: 4px 0 12px; border-top: 1px solid var(--line); padding-top: 10px; }
details.more > summary {
  cursor: pointer; list-style: none; font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--dim); padding: 6px 0;
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::before { content: '+ '; }
details.more[open] > summary::before { content: '– '; }
details.more > section { margin-top: 10px; }
/* the frames and counts are for the workshop: D shows them */
#hud { display: none; }
body.hud #hud { display: block; }
/* when it cannot start: what happened, in words, and the way back */
#oops {
  display: none; position: fixed; inset: 0; z-index: 40; padding: 28px; place-content: center;
  background: rgba(8, 6, 12, .95); color: var(--ink); text-align: left;
}
#oops:has(#err:not(:empty)) { display: grid; }
#oops > div { max-width: 520px; }
#oops h2 { margin: 0 0 10px; font-size: 22px; }
#oops p { margin: 0 0 14px; line-height: 1.5; color: var(--dim); }
#oops #err {
  position: static; inset: auto; display: block !important; z-index: auto; margin: 0 0 18px; padding: 10px 12px;
  max-height: 30vh; overflow: auto; font-size: 12px; white-space: pre-wrap; background: rgba(255, 255, 255, .06); border-radius: 8px;
}
#oops a { color: var(--ink); font-weight: 600; }

/* the drawn icons: one stroke for all of them */
svg.i { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; vertical-align: -3px; }
.onward a, #oops a { display: inline-flex; align-items: center; gap: 6px; }
details.more > summary { display: flex; align-items: center; gap: 6px; }
details.more > summary::before { content: none !important; }
details.more > summary svg.i { width: 13px; height: 13px; transition: transform .2s; }
details.more[open] > summary svg.i { transform: rotate(90deg); }

/* notes and keys at a size that can be read without leaning in */
.note, .keys, .blurb { font-size: 12.5px; }
.keys { font-size: 12px; }
