/* =====================================================================
   Doodle Zoo
   Layout rules that matter for the audience:
   - every interactive target is >= 60px; primary ones are 72px+
   - nothing depends on reading: icons and colour carry all meaning
   - the drawing surface never scrolls, bounces, or zooms under a hand
   - one stylesheet, no framework, no webfont -> instant first paint
   ===================================================================== */

:root {
  /* The app's world is a box of crayons on drawing paper. The paper is a
     warm cream, the ink is a deep story-book navy, and the crayon set below
     is used functionally: each category and each tool owns a crayon. */
  --ink: #2d2a55;
  --ink-soft: #6a6592;
  --paper: #fff6e9;
  --card: #ffffff;
  --brand: #4438ca;
  --brand-soft: #efeaff;
  --go: #0f9e50;
  --warn: #B23C00; /* white-on-warn ≈ 5.9:1 */
  --shadow: 0 4px 0 rgba(45, 42, 85, 0.14);
  --radius: 20px;

  --c-red: #ff5a4e;
  --c-orange: #ff9838;
  --c-yellow: #ffc933;
  --c-green: #3fc463;
  --c-blue: #3da9ff;
  --c-purple: #9b6dff;
  --c-pink: #ff7bac;

  /* NN/g measured young children missing 7mm targets ~30% of the time and
     recommends 2cm (~76px) — roughly 4x the adult 1cm guideline. These sizes
     follow that, not Apple's 44pt, because the users here are five. */
  --tap: 72px;      /* minimum interactive size */
  --tap-lg: 80px;   /* primary actions */
  --swatch: 62px;

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  /* touch-action alone does not stop iOS rubber-band or pull-to-refresh —
     that is a document-level behaviour, so it needs overscroll-behavior AND
     a fixed document. Without this a child dragging near the top of the
     picture drags the whole page instead of drawing. */
  overscroll-behavior: none;
  position: fixed;
  inset: 0;
  overflow: hidden;
  -webkit-text-size-adjust: 100%;
}

body {
  /* ui-rounded resolves to SF Pro Rounded on Apple devices — soft, friendly,
     and free: no webfont, no network request, instant first paint. */
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  color: var(--ink);
  background: var(--paper);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;          /* no double-tap zoom anywhere */
}

/* 100vh on iOS Safari measures the toolbar-hidden viewport, so the bottom of
   the app sits under the toolbar. dvh is correct; vh is the fallback. */
.screen { height: 100vh; height: 100dvh; }

/* Screens fade-and-rise as they appear — the animation runs each time the
   hidden attribute is removed, which is exactly the picker/studio handoff. */
@keyframes screen-in {
  from { opacity: 0; transform: translateY(14px) scale(.992); }
  to   { opacity: 1; transform: none; }
}
.screen:not([hidden]) { animation: screen-in .26s ease-out; }
[hidden] { display: none !important; }

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: none;
  background: none;
}

/* ============================== PICKER ============================== */

.screen-picker {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding:
    calc(20px + var(--safe-t))
    calc(20px + var(--safe-r))
    calc(28px + var(--safe-b))
    calc(20px + var(--safe-l));
  background:
    radial-gradient(820px 420px at 6% -10%, rgba(255, 123, 172, .14) 0%, transparent 60%),
    radial-gradient(700px 400px at 98% 2%, rgba(61, 169, 255, .14) 0%, transparent 62%),
    var(--paper);
}

.picker-top { text-align: center; margin-bottom: 16px; position: relative; }

/* current player, one tap from anywhere on the home screen */
.profile-btn {
  position: absolute;
  top: 0; right: 0;
  width: var(--tap); height: var(--tap);
  border-radius: 50%;
  background: var(--card);
  border: 3px solid var(--c-purple);
  box-shadow: var(--shadow);
  font-size: 30px;
  display: grid; place-items: center;
  z-index: 2;
  transition: transform .12s ease;
}
.profile-btn:active { transform: scale(.92); }

.players-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 18px;
}
.player {
  aspect-ratio: 1;
  min-height: var(--tap);
  border-radius: 22px;
  background: var(--brand-soft);
  box-shadow: var(--shadow);
  font-size: 34px;
  display: grid; place-items: center;
  transition: transform .12s ease;
}
.player:active { transform: scale(.92); }
.player[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-purple); }
.player-add { color: var(--brand); font-weight: 900; }
.sheet-actions-one { grid-template-columns: 1fr; }

/* The wordmark: every letter is a crayon-coloured sticker chip, tilted like a
   child stuck them on. This is the one loud thing on the page — everything
   around it stays quiet. */
.brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 0;
  font-size: clamp(28px, 5.4vw, 44px);
  font-weight: 900;
  letter-spacing: 0;
}
.brand .bl {
  display: inline-grid;
  place-items: center;
  min-width: 1.28em;
  height: 1.5em;
  padding: 0 .1em;
  border-radius: .34em;
  color: #fff;
  text-shadow: 0 2px 0 rgba(45, 42, 85, .22);
  box-shadow: 0 3px 0 rgba(45, 42, 85, .18);
}
.brand .bl-sp { min-width: .34em; background: none; box-shadow: none; }
.brand .bl:nth-child(7n + 1) { background: var(--c-red);    transform: rotate(-4deg); }
.brand .bl:nth-child(7n + 2) { background: var(--c-orange); transform: rotate(3deg); }
.brand .bl:nth-child(7n + 3) { background: var(--c-yellow); transform: rotate(-2deg); }
.brand .bl:nth-child(7n + 4) { background: var(--c-green);  transform: rotate(4deg); }
.brand .bl:nth-child(7n + 5) { background: var(--c-blue);   transform: rotate(-3deg); }
.brand .bl:nth-child(7n + 6) { background: var(--c-purple); transform: rotate(2deg); }
.brand .bl:nth-child(7n + 7) { background: var(--c-pink);   transform: rotate(-2deg); }
.brand .bl-sp { background: none !important; transform: none !important; }

.brand-scribble { width: min(300px, 56vw); margin: 6px auto 0; display: block; }
.brand-sub { margin: 4px 0 0; font-size: clamp(16px, 2.6vw, 20px); color: var(--ink-soft); font-weight: 800; }

.row-title {
  margin: 0 0 10px;
  font-size: 19px;
  font-weight: 800;
  color: var(--ink-soft);
  display: flex; align-items: center; gap: 8px;
}
.continue-row { margin-bottom: 22px; }

.cat-bar {
  display: flex;
  /* Wrap instead of scroll: a hidden-scrollbar strip made the rightmost
     categories unreachable with a mouse. Every shelf stays visible. */
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  padding: 4px 2px 14px;
}

.cat-chip {
  flex: 0 0 auto;
  min-height: var(--tap);
  padding: 0 22px;
  border-radius: 999px;
  background: var(--card);
  border: 3px solid transparent;
  box-shadow: var(--shadow);
  font-weight: 800;
  font-size: 17px;
  color: var(--ink);
  display: flex; align-items: center; gap: 8px;
  transition: transform .12s ease;
}
/* Each category owns a crayon. The border shows it when idle; pressing the
   chip fills it in — colour, not reading, is how a four-year-old finds
   "Dinosaurs" again tomorrow. */
.cat-chip:nth-child(7n + 1) { border-color: var(--c-red); }
.cat-chip:nth-child(7n + 2) { border-color: var(--c-orange); }
.cat-chip:nth-child(7n + 3) { border-color: var(--c-yellow); }
.cat-chip:nth-child(7n + 4) { border-color: var(--c-green); }
.cat-chip:nth-child(7n + 5) { border-color: var(--c-blue); }
.cat-chip:nth-child(7n + 6) { border-color: var(--c-purple); }
.cat-chip:nth-child(7n + 7) { border-color: var(--c-pink); }
.cat-chip:nth-child(7n + 1)[aria-pressed="true"] { background: var(--c-red); }
.cat-chip:nth-child(7n + 2)[aria-pressed="true"] { background: var(--c-orange); }
.cat-chip:nth-child(7n + 3)[aria-pressed="true"] { background: var(--c-yellow); color: var(--ink); }
.cat-chip:nth-child(7n + 4)[aria-pressed="true"] { background: var(--c-green); }
.cat-chip:nth-child(7n + 5)[aria-pressed="true"] { background: var(--c-blue); }
.cat-chip:nth-child(7n + 6)[aria-pressed="true"] { background: var(--c-purple); }
.cat-chip:nth-child(7n + 7)[aria-pressed="true"] { background: var(--c-pink); }
.cat-chip[aria-pressed="true"] { color: #fff; }
.cat-chip:active { transform: scale(.95); }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
}
.card-grid-scroll {
  display: flex;
  overflow-x: auto;
  gap: 14px;
  padding-bottom: 6px;
  scrollbar-width: none;
}
.card-grid-scroll::-webkit-scrollbar { display: none; }
.card-grid-scroll .card { flex: 0 0 150px; }

.card {
  position: relative;
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: 0 5px 0 rgba(45, 42, 85, .12), 0 10px 24px rgba(45, 42, 85, .07);
  padding: 10px 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: transform .16s ease;
  text-align: center;
}
/* Stickers slapped on a fridge: every other card leans a little. Touching a
   card straightens it, which makes the whole wall feel physical. */
.card:nth-child(3n + 1) { transform: rotate(-1.3deg); }
.card:nth-child(3n + 2) { transform: rotate(1.1deg); }
.card:nth-child(4n + 3) { transform: rotate(-0.7deg); }
.card:hover, .card:focus-visible { transform: rotate(0) scale(1.03); }
.card:active { transform: rotate(0) scale(.96); }
.card img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  display: block;
  border-radius: 12px;
  background: #fff;
  pointer-events: none;
}
.card-name { font-size: 16px; font-weight: 800; color: var(--ink); }

/* Cards drift in as the grid renders — staggered for the first rows so the
   wall of stickers feels placed, not dumped. */
@keyframes card-in {
  from { opacity: 0; transform: translateY(16px); }
}
.card { animation: card-in .3s ease-out backwards; }
.card:nth-child(1) { animation-delay: .02s; }
.card:nth-child(2) { animation-delay: .05s; }
.card:nth-child(3) { animation-delay: .08s; }
.card:nth-child(4) { animation-delay: .11s; }
.card:nth-child(5) { animation-delay: .14s; }
.card:nth-child(6) { animation-delay: .17s; }
.card:nth-child(7) { animation-delay: .2s; }
.card:nth-child(8) { animation-delay: .23s; }
.card-flag {
  position: absolute; top: 8px; right: 8px;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--go); color: #fff;
  display: grid; place-items: center;
  font-size: 16px;
  box-shadow: 0 2px 0 rgba(0,0,0,.15);
}

.picker-foot { margin-top: 30px; text-align: center; color: var(--ink-soft); font-size: 15px; font-weight: 600; }
.text-btn {
  margin-top: 8px; min-height: 48px; padding: 0 16px;
  text-decoration: underline; font-weight: 700; color: var(--ink-soft); font-size: 14px;
}

/* ============================== STUDIO ============================== */

.screen-studio {
  display: grid;
  grid-template-areas:
    "top   top"
    "stage stage"
    "tools tools"
    "pal   pal";
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  grid-template-columns: 1fr;
  height: 100dvh;
  overflow: hidden;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
  background: var(--paper);
}

.topbar {
  grid-area: top;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--card);
  box-shadow: 0 2px 10px rgba(36,31,71,.08);
  z-index: 3;
}
.art-title {
  flex: 1; margin: 0; text-align: center;
  font-size: clamp(17px, 2.4vw, 23px); font-weight: 800; color: var(--brand);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-actions { display: flex; gap: 8px; }

.icon-btn {
  width: var(--tap); height: var(--tap);
  min-width: var(--tap);
  border-radius: 18px;
  display: grid; place-items: center;
  background: var(--brand-soft);
  color: var(--brand);
  box-shadow: var(--shadow);
  transition: transform .1s ease, opacity .1s ease;
}
.icon-btn svg { width: 55%; height: 55%; display: block; }
.icon-btn:active { transform: scale(.92); }
.icon-btn:disabled { opacity: .32; box-shadow: none; }
.icon-btn-lg { width: var(--tap-lg); height: var(--tap-lg); min-width: var(--tap-lg); }
.icon-btn-go { background: var(--go); color: #fff; }

/* --- stage --- */
.stage-wrap {
  grid-area: stage;
  position: relative;
  min-height: 0;
  min-width: 0;
  padding: 10px;
  display: grid;
  place-items: center;
}
.stage {
  position: relative;
  /* The artwork is square, so the paper is square too — a white card wider
     than the picture inside it reads as a bug to a child. Sizing from the
     definite height and clamping the width keeps the ratio in both
     orientations without any JS. */
  aspect-ratio: 1;
  height: 100%;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--radius);
  background: #fff;
  box-shadow: 0 6px 22px rgba(36,31,71,.12);
  overflow: hidden;
  /* the single most important line in this file: no panning, no pinch,
     no scroll-chaining while a child drags a finger across the picture */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.layer { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.layer-fill  { z-index: 1; }
.layer-paint { z-index: 2; position: absolute; inset: auto; }
.layer-ink   { z-index: 3; pointer-events: none; }

.region { fill: #fff; stroke: none; transition: fill .08s linear; }
/* Focusable shapes pick up the browser's default ring when tapped, which
   leaves a stray blue box on the picture. Keyboard focus still gets a cue. */
.region:focus { outline: none; }
/* SVG shapes cannot take an outline reliably, so the keyboard focus cue is a
   drawn stroke instead — same two-tone idea as the buttons. */
.region:focus-visible {
  outline: none;
  stroke: #1B1B1B;
  stroke-width: 10;
  stroke-dasharray: 14 10;
  paint-order: stroke;
}
/* In fill mode the SVG takes taps; in every drawing mode the canvas does. */
.stage[data-tool="fill"] .layer-paint { pointer-events: none; }
.stage:not([data-tool="fill"]) .layer-fill { pointer-events: none; }
.stage[data-tool="fill"] .region { cursor: pointer; }

/* --- tools --- */
.toolrail {
  grid-area: tools;
  display: flex;
  gap: 8px;
  padding: 8px 10px;
  overflow-x: auto;
  scrollbar-width: none;
  background: var(--card);
}
.toolrail::-webkit-scrollbar { display: none; }

.tool {
  flex: 0 0 auto;
  width: var(--tap); height: var(--tap);
  border-radius: 18px;
  display: grid; place-items: center;
  background: var(--brand-soft);
  box-shadow: var(--shadow);
  position: relative;
  transition: transform .1s ease;
}
.tool svg { width: 60%; height: 60%; display: block; }
.tool:active { transform: scale(.92); }

/* Every tool owns a crayon colour — picking up the crayon turns the button
   crayon-red, the spray can turns it green. Colour confirms the choice for a
   child who cannot read the tooltip. */
.tool[aria-pressed="true"] {
  background: var(--brand);
  color: #fff;
  box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--brand);
}
.tool[data-tool="fill"][aria-pressed="true"]    { background: var(--c-blue);   box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-blue); }
.tool[data-tool="crayon"][aria-pressed="true"]  { background: var(--c-red);    box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-red); }
.tool[data-tool="brush"][aria-pressed="true"]   { background: var(--c-orange); box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-orange); }
.tool[data-tool="rainbow"][aria-pressed="true"] { background: var(--ink);      box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--ink); }
.tool[data-tool="glitter"][aria-pressed="true"] { background: var(--c-yellow); color: var(--ink); box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-yellow); }
.tool[data-tool="neon"][aria-pressed="true"]    { background: var(--c-purple); box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-purple); }
.tool[data-tool="spray"][aria-pressed="true"]   { background: var(--c-green);  box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-green); }
.tool[data-tool="erase"][aria-pressed="true"]   { background: var(--c-pink);   box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--c-pink); }

/* --- palette --- */
.palette {
  grid-area: pal;
  background: var(--card);
  border-top: 3px solid var(--brand-soft);
  padding: 8px 10px calc(8px + var(--safe-b));
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  /* Without this the tray simply spills past the bottom of the viewport on
     short screens, taking the "more colours" button — and with it 60 of the
     72 colours — somewhere unreachable. */
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* The + stays pinned below the grid rather than scrolling away with it. */
.sticker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 10px;
  padding: 6px 2px;
}
.sticker {
  aspect-ratio: 1;
  min-height: var(--swatch);
  border-radius: 18px;
  background: var(--card);
  box-shadow: inset 0 0 0 2px #D8D4CE, var(--shadow);
  font-size: 32px;
  display: grid; place-items: center;
  transition: transform .12s ease;
}
.sticker:active { transform: scale(.9); }
.sticker[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--brand); }

.more-btn { flex: 0 0 auto; }

/* Grid, not flex: three equal columns shrink to the tray rather than
   overflowing it on a narrow palette. */
.size-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.size-btn { width: 100%; }
.pattern-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 12px;
}

.tab-row { display: flex; gap: 10px; }
.tab-btn {
  flex: 1;
  min-height: 54px;
  border-radius: 16px;
  background: var(--brand-soft);
  box-shadow: var(--shadow);
  font-size: 24px;
  display: grid; place-items: center;
}
.tab-btn[aria-pressed="true"] { background: var(--brand); }
.tab-panel { display: flex; flex-direction: column; gap: 10px; min-height: 0; flex: 1; }

.sticker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 10px;
  padding: 6px 2px;
}
.sticker {
  aspect-ratio: 1;
  min-height: var(--swatch);
  border-radius: 18px;
  background: var(--card);
  box-shadow: inset 0 0 0 2px #D8D4CE, var(--shadow);
  font-size: 32px;
  display: grid; place-items: center;
  transition: transform .12s ease;
}
.sticker:active { transform: scale(.9); }
.sticker[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--brand); }

.more-btn {
  min-height: 56px;
  border-radius: 16px;
  background: var(--brand-soft);
  color: var(--brand);
  font-size: 30px; font-weight: 800;
  box-shadow: var(--shadow);
  display: grid; place-items: center;
}

.size-btn {
  flex: 0 0 auto;
  width: var(--tap); height: var(--tap);
  border-radius: 16px; background: var(--brand-soft);
  display: grid; place-items: center; box-shadow: var(--shadow);
}
.size-btn i { display: block; border-radius: 50%; background: var(--brand); }
.size-btn[aria-pressed="true"] { background: var(--brand); }
.size-btn[aria-pressed="true"] i { background: #fff; }

.pat {
  flex: 0 0 auto;
  width: var(--swatch); height: var(--swatch);
  border-radius: 14px;
  box-shadow: var(--shadow);
  overflow: hidden;
  background: #fff;
  position: relative;
}
.pat svg { width: 100%; height: 100%; display: block; }
.pat[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 8px var(--brand); }
.pat-none { display: grid; place-items: center; font-size: 24px; }

/* Hug the swatches rather than stretching, so the "more colours" button sits
   directly under the grid instead of floating at the bottom of the tray. */
.swatch-wrap {
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  flex: 0 1 auto;
  -webkit-overflow-scrolling: touch;
}
.swatch-grid {
  display: grid;
  /* 12+ px gutters: below ~10px, four-year-olds mis-tap the neighbouring swatch */
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 12px;
  padding: 16px 10px 10px;
}

/* Tiering: every swatch is rendered once and stays put; higher tiers are
   simply revealed. Re-flowing the grid would destroy positional memory. */
.swatch-grid[data-tier="0"] .swatch[data-tier="1"],
.swatch-grid[data-tier="0"] .swatch[data-tier="2"],
.swatch-grid[data-tier="1"] .swatch[data-tier="2"] { display: none; }

.swatch {
  aspect-ratio: 1;
  min-height: var(--swatch);
  border-radius: 50%;
  /* Every swatch owns a hairline border so a white swatch stays visible on
     a white tray, independent of any selection ring. */
  box-shadow: inset 0 0 0 2px #D8D4CE, var(--shadow);
  transition: transform .18s cubic-bezier(.34, 1.56, .64, 1);
  position: relative;
}
.swatch:active { transform: scale(.92); }

/* The selected swatch reads as a crayon lifted out of the box: it grows,
   rises, gains a white-inside/dark-outside double ring, and shows a tick.
   No single ring colour can contrast against swatches spanning white to
   black, which is why the cue is redundant rather than clever. */
.swatch[aria-pressed="true"] {
  transform: scale(1.2) translateY(-6px);
  box-shadow: 0 0 0 4px #FFFFFF, 0 0 0 7px #1B1B1B, 0 6px 10px rgba(0,0,0,.28);
  z-index: 2;
}
.swatch[aria-pressed="true"]::after {
  content: "✓";
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 24px; font-weight: 900;
  color: #fff;
  text-shadow: 0 0 3px rgba(0,0,0,.85), 0 1px 2px rgba(0,0,0,.9);
}

/* ---------- tablet / desktop landscape: tools left, palette right -------
   The height guard matters: a phone held sideways is wide enough to match a
   width-only query, and the vertical tool rail would then push half the tools
   — including the rubber — off the bottom of a rail with no visible
   scrollbar. Short landscape screens fall through to the phone layout. */
@media (min-width: 760px) and (min-height: 620px) and (orientation: landscape) {
  .screen-studio {
    grid-template-areas:
      "top   top   top"
      "tools stage pal";
    grid-template-columns: 96px minmax(0, 1fr) 268px;
    grid-template-rows: auto minmax(0, 1fr);
  }
  .toolrail {
    flex-direction: column;
    overflow-x: hidden;
    overflow-y: auto;
    align-items: center;
    padding: 12px 8px;
  }
  .palette { border-top: none; border-left: 3px solid var(--brand-soft); }
  .stage-wrap { padding: 14px; }
}

/* Laptop and short-tablet landscape: eight 72px tools plus gaps need ~656px
   of rail, which a 720px-tall window cannot give once the top bar is taken
   out — the eraser ends up below the fold behind a hidden scrollbar. Two
   columns instead of one. */
@media (min-width: 760px) and (orientation: landscape) and (max-height: 860px) {
  .screen-studio { grid-template-columns: 176px minmax(0, 1fr) 276px; }
  .toolrail {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
    align-content: start;
    overflow: visible;
  }
  .tool { width: 100%; }
}

@media (min-width: 1100px) and (min-height: 861px) and (orientation: landscape) {
  .screen-studio { grid-template-columns: 112px minmax(0, 1fr) 330px; }
}

/* ---------- portrait phones ---------- */
/* ---------- phone held sideways ----------
   Short and wide. Stacking rows here would leave the picture a postage stamp,
   so keep the three-column layout and instead make the tool rail two columns
   so all eight tools still fit in the available height. */
@media (orientation: landscape) and (max-height: 619px) {
  :root { --tap: 54px; --tap-lg: 54px; --swatch: 44px; }

  .screen-studio {
    grid-template-areas:
      "top   top   top"
      "tools stage pal";
    /* nine tools: three columns of three keeps every one on screen */
    grid-template-columns: 172px minmax(0, 1fr) 190px;
    grid-template-rows: auto minmax(0, 1fr);
  }
  .toolrail {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    padding: 6px;
    align-content: start;
    overflow: visible;
  }
  .tool { width: 100%; }
  .palette {
    border-top: none;
    border-left: 3px solid var(--brand-soft);
    padding: 6px 8px;
    gap: 5px;
  }
  .swatch-grid { grid-template-columns: repeat(3, 1fr); gap: 7px; padding: 8px 4px 4px; }
  .tab-btn { min-height: 42px; font-size: 18px; }
  .sticker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 10px;
  padding: 6px 2px;
}
.sticker {
  aspect-ratio: 1;
  min-height: var(--swatch);
  border-radius: 18px;
  background: var(--card);
  box-shadow: inset 0 0 0 2px #D8D4CE, var(--shadow);
  font-size: 32px;
  display: grid; place-items: center;
  transition: transform .12s ease;
}
.sticker:active { transform: scale(.9); }
.sticker[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--brand); }

.more-btn { min-height: 40px; font-size: 22px; }
  .size-btn { height: 42px; }
  .topbar { padding: 4px 8px; }
  .art-title { display: none; }
  .stage-wrap { padding: 6px; }
}

@media (max-width: 759px) and (orientation: portrait),
       (orientation: portrait) and (max-width: 900px) {
  :root { --swatch: 48px; --tap: 62px; }

  /* The top bar holds five buttons. At a fixed 80px each they need 458px,
     which overflows every phone in portrait and pushes Save off the right
     edge. Size them from the width that actually exists. */
  .topbar { gap: 6px; }
  .topbar-actions { gap: 6px; flex: 0 1 auto; min-width: 0; }
  .topbar .icon-btn,
  .topbar .icon-btn-lg {
    width: min(var(--tap-lg), calc((100vw - 56px) / 5));
    min-width: 0;
    height: min(var(--tap-lg), calc((100vw - 56px) / 5));
  }

  /* The picture is the product, and on a portrait phone the artwork is square,
     so its size is capped by the screen WIDTH, not the height. Give the stage
     enough rows to reach that width cap (~46dvh) and trim the padding so the
     paper fills the screen edge to edge — the picture jumps from ~324px to
     ~376px. The palette keeps min-height:0 + overflow, so it yields the height
     and scrolls its own overflow rather than shrinking the canvas; the two
     core colour rows and all nine tools stay on screen. */
  /* The palette row is a FIXED track (not auto): an auto row grows to its
     tallest content, so the brush-size row that drawing tools add would push
     the canvas smaller. Pinning the track keeps the stage — the 1fr row —
     exactly the same size whichever tool is chosen. */
  .screen-studio { grid-template-rows: auto minmax(0, 1fr) auto 31dvh; }
  .stage-wrap { padding: 6px; }
  /* Fixed tray height, not max-height: drawing tools add a brush-size row that
     is taller than the colour grid, and letting the tray grow for them would
     shrink and re-centre the picture every time a child picked up the crayon.
     A fixed height keeps the canvas rock-steady across tools; the taller
     drawing content scrolls within the tray instead. Sized to fit the two
     colour rows in fill mode so no swatch is ever hidden. */
  .palette { height: 31dvh; max-height: 31dvh; gap: 5px; padding: 5px 10px calc(5px + var(--safe-b)); }
  .toolrail { padding: 5px 10px; }
  .tab-btn { min-height: 44px; font-size: 21px; }
  .sticker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 10px;
  padding: 6px 2px;
}
.sticker {
  aspect-ratio: 1;
  min-height: var(--swatch);
  border-radius: 18px;
  background: var(--card);
  box-shadow: inset 0 0 0 2px #D8D4CE, var(--shadow);
  font-size: 32px;
  display: grid; place-items: center;
  transition: transform .12s ease;
}
.sticker:active { transform: scale(.9); }
.sticker[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--brand); }

.more-btn { min-height: 44px; font-size: 24px; }
  .swatch-wrap { min-height: calc(2 * var(--swatch) + 8px); flex: 1 1 auto; }

  /* All nine tools stay on screen — five across, two rows. Hiding tools
     behind a scroll or a "tap again for more" caret is a documented way to
     lose a child completely. */
  .toolrail {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 8px;
    overflow: visible;
  }
  .tool { width: 100%; }

  /* Six per row means the twelve core colours are exactly two rows —
     visible at a glance, no scrolling to discover that red exists. */
  .swatch-grid { grid-template-columns: repeat(6, 1fr); gap: 10px; }

  /* No room for the title next to five buttons; the picture itself says
     which page you are on, and the audience cannot read it anyway. */
  .art-title { display: none; }
  .topbar { justify-content: space-between; }
}

/* Short phones.
   A phone 390px wide cannot give six columns of the 76px swatch the research
   wants for tablets AND leave the picture any room — six 76px swatches alone
   are 456px. So the phone tier drops to the 44px WCAG 2.5.5 AAA floor and
   spends the reclaimed height on the canvas. Tablets, which this app is aimed
   at first, keep the full 72-80px sizing. */
@media (max-height: 740px) and (orientation: portrait) {
  :root { --tap: 58px; --tap-lg: 60px; --swatch: 44px; }
  .screen-studio { grid-template-rows: auto minmax(0, 1fr) auto 34dvh; }
  .stage-wrap { padding: 5px; }
  /* Same fixed-tray reasoning as the portrait tier: constant height so the
     canvas never resizes when the tool changes. */
  .palette { height: 34dvh; max-height: 34dvh; gap: 4px; }
  .tab-btn { min-height: 44px; font-size: 20px; }
  .sticker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--swatch), 1fr));
  gap: 10px;
  padding: 6px 2px;
}
.sticker {
  aspect-ratio: 1;
  min-height: var(--swatch);
  border-radius: 18px;
  background: var(--card);
  box-shadow: inset 0 0 0 2px #D8D4CE, var(--shadow);
  font-size: 32px;
  display: grid; place-items: center;
  transition: transform .12s ease;
}
.sticker:active { transform: scale(.9); }
.sticker[aria-pressed="true"] { box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--brand); }

.more-btn { min-height: 44px; font-size: 24px; }
  .size-btn { height: 48px; }
  /* Just enough headroom for the selected swatch's lift without spending a
     row's worth of height on padding. */
  .swatch-grid { padding: 9px 4px 3px; gap: 8px; }
  .topbar { padding: 5px 8px; }
}

/* ============================== SHEET / TOAST ============================== */

.sheet {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(36,31,71,.55);
  display: grid; place-items: center;
  padding: 20px;
}
.sheet-card {
  background: var(--card);
  border-radius: 28px;
  padding: 28px 24px 22px;
  max-width: 440px; width: 100%;
  text-align: center;
  box-shadow: 0 18px 50px rgba(0,0,0,.3);
}
.sheet-emoji { font-size: 54px; margin: 0 0 6px; }
.sheet-title { margin: 0 0 6px; font-size: 25px; font-weight: 800; }
.sheet-body { margin: 0 0 20px; color: var(--ink-soft); font-size: 17px; font-weight: 600; }
.sheet-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.big-btn {
  min-height: var(--tap-lg);
  border-radius: 18px;
  font-weight: 800; font-size: 17px;
  box-shadow: var(--shadow);
  padding: 0 12px;
}
.big-btn-ghost { background: var(--brand-soft); color: var(--brand); }
.big-btn-warn  { background: var(--warn); color: #fff; }
.big-btn:active { transform: scale(.96); }

.toast {
  position: fixed; left: 50%; bottom: calc(24px + var(--safe-b));
  transform: translateX(-50%);
  background: var(--ink); color: #fff;
  padding: 14px 22px; border-radius: 999px;
  font-weight: 800; font-size: 17px;
  z-index: 60;
  box-shadow: 0 8px 24px rgba(0,0,0,.28);
}

/* ============================== A11Y ============================== */

/* Two-tone ring: no single colour contrasts against a palette spanning white
   to black, so the dark ring carries the contrast and the white halo keeps it
   visible on dark swatches and on the brand-coloured active tools. */
:focus-visible {
  outline: 4px solid #1B1B1B;
  outline-offset: 3px;
  box-shadow: 0 0 0 3px #fff;
}

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

@media (prefers-contrast: more) {
  .swatch { box-shadow: inset 0 0 0 3px rgba(0,0,0,.55), var(--shadow); }
  .card, .tool, .icon-btn { outline: 2px solid var(--ink); }
}
