/* =====================================================
   letter-trace.css — ✏️ Letter Trace (Bella).

   Loaded after css/style.css, css/kid-games.css and css/kid-motion.css, which
   own the tokens, the paper card, .game-msg, .game-toolbar, .kg-replay and the
   shared .kg-target sizing. Nothing here restyles a shared class on its own:
   every selector below either introduces a kg-letter-trace- class or qualifies
   a shared one WITH one, so the other sheets cannot collide with this.

   THREE THINGS ON THIS SCREEN ARE LOAD-BEARING, NOT DECORATIVE
     THE GHOST STROKES   the whole letter, drawn in grey before she starts.
                         This is the instruction. A muted device sees the
                         entire task here and needs no word of it spoken.
     THE START DOT + ARROW   "here" and "that way", with no reading at all.
                         The dot is a solid accent disc with a white ring so
                         it survives any background, never a faint mark.
     THE PRINTED MODEL   the same capital set in --font-literacy, beside the
                         one she is drawing. Andika is not a style choice
                         (css/fonts.css:26-33): it is the face built for
                         beginning readers, and this is the one place on the
                         page where a letterform is the content.

   THE INK IS THE AUTHORED PATH. Her finger's own line is never drawn — the
   game reveals the letter's real stroke with stroke-dashoffset, so the
   finished glyph is always the letterform and the 34px matching corridor is
   invisible. Everything below is styling that one idea.

   Reduced motion is already handled globally at css/style.css:559-562, which
   flattens every animation and transition duration on the page. No
   prefers-reduced-motion block is added here (ADDENDUM). Every state below
   therefore changes a COLOUR, an OPACITY or a STROKE as well as moving, so
   the signal survives when the movement is flattened away.

   Palette is the theme's, via var(--accent)/var(--accent-2) — never
   var(--bella), which would not follow the body theme class.
   ===================================================== */

/* ---------------- The stage ----------------
   position: relative so js/kidgames/motion.js's burst() can drop its absolute
   .kg-particle-layer into it at the celebration. */
.kg-letter-trace-stage {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 3vw, 20px);
}

/* ---------------- The printed model ----------------
   A handwriting workbook puts the letter in print at the head of the line and
   the child copies it along the rest. Same idea, same place. */
.kg-letter-trace-print {
  flex: 0 0 auto;
  width: clamp(52px, 15vw, 82px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  background: var(--paper);
  border: 4px solid var(--accent-2);
  box-shadow: var(--shadow);
  font-family: var(--font-literacy);
  font-weight: 700;
  font-size: clamp(1.9rem, 7vw, 3rem);
  line-height: 1;
  color: var(--accent);
}

.kg-letter-trace-board {
  flex: 0 1 auto;
  width: min(330px, 100%);
  min-width: 0;
}

/* touch-action: none is not optional. Without it a tablet treats the first
   few millimetres of a trace as the start of a page scroll and swallows every
   pointermove that follows. */
.kg-letter-trace-svg {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 120 / 140;
  touch-action: none;
  overflow: visible;
}

/* The whole box takes the finger, not just the 14-unit line: a five-year-old
   who lands two centimetres wide of the start dot must still get an answer,
   and that answer is a wobble rather than nothing at all. */
.kg-letter-trace-hit {
  fill: #fff;
  fill-opacity: 0;
  pointer-events: all;
}

/* ---------------- Ghost, ink, demo ----------------
   Same width, same caps, same joins for all three: they are the same stroke
   in three states, and any difference between them would read as a mistake. */
.kg-letter-trace-ghost,
.kg-letter-trace-ink,
.kg-letter-trace-demo {
  fill: none;
  stroke-width: 14;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The strokes still to come. 15% is the brief's band: present enough to show
   the whole letter, faint enough that it never reads as already drawn. */
.kg-letter-trace-ghost {
  stroke: var(--ink-soft);
  opacity: .15;
  transition: opacity .25s var(--ease);
}
/* The one she is on now. The only stroke that is live, ever. */
.kg-letter-trace-ghost.kg-letter-trace-live { opacity: .3; }

.kg-letter-trace-stop-a { stop-color: var(--accent); }
.kg-letter-trace-stop-b { stop-color: var(--accent-2); }

/* The ink itself. stroke-dashoffset is set from JS on every accepted sample;
   the short transition smooths the step between two samples without ever
   lagging behind the finger. */
.kg-letter-trace-ink {
  transition: stroke-dashoffset .07s linear;
}

/* The lift sits on the GROUP, never on the individual strokes. Per-stroke, an
   H's crossbar casts its own shadow across the two verticals it crosses and
   the finished letter carries a dark seam through the middle of it — which
   looks exactly like a rendering mistake, on the one screen whose whole job is
   to look like a letter she drew. */
.kg-letter-trace-inks {
  filter: drop-shadow(0 3px 0 rgba(53, 49, 94, .10));
}

/* The demo line: the same stroke, shown rather than earned, so it is
   deliberately paler than her own ink and disappears again afterwards. */
.kg-letter-trace-demo {
  stroke: var(--accent);
  opacity: 0;
  transition: opacity .2s var(--ease);
}
.kg-letter-trace-demo.kg-letter-trace-demo-on { opacity: .4; }

/* The travelling dot that leads the demo — a finger, without drawing a hand. */
.kg-letter-trace-runner {
  fill: var(--accent);
  stroke: #fff;
  stroke-width: 3;
  opacity: 0;
  transition: opacity .2s var(--ease);
}
.kg-letter-trace-runner.kg-letter-trace-runner-on { opacity: .95; }

/* ---------------- Start dot and arrow ----------------
   The entire instruction, for a child who cannot hear a word of it. */
.kg-letter-trace-guide {
  transition: opacity .25s var(--ease);
}
.kg-letter-trace-dot {
  fill: var(--accent);
  stroke: #fff;
  stroke-width: 3.5;
  transform-box: fill-box;
  transform-origin: center;
  animation: kg-letter-trace-beat 1.7s var(--ease) infinite;
}
.kg-letter-trace-arrow {
  fill: var(--accent);
  opacity: .8;
  transition: opacity .2s var(--ease);
}
/* Once the ink has started moving, the arrow has said its one word. It sits
   ON the path, so leaving it up puts a darker wedge inside her letter. */
.kg-letter-trace-guide.kg-letter-trace-begun .kg-letter-trace-arrow { opacity: 0; }

@keyframes kg-letter-trace-beat {
  0%, 100% { transform: scale(1);    opacity: .92; }
  50%      { transform: scale(1.28); opacity: 1; }
}

/* While her finger is down the dot stops asking for attention — it has been
   answered. */
.kg-letter-trace-stage.kg-letter-trace-drawing .kg-letter-trace-dot {
  animation: none;
  opacity: .55;
}

/* The replay's visual echo: one swell, then done — AND a heavier ring, which
   is the half that survives when the movement is flattened away. The replay
   button owes a muted child something visible (DESIGN-BRIEF §5) and it must
   not be the swell, because for a great many children there is no swell. */
.kg-letter-trace-guide.kg-letter-trace-say .kg-letter-trace-dot {
  stroke: var(--accent-2);
  stroke-width: 7;
  animation: kg-letter-trace-beat .45s var(--ease) 2;
}

/* ctx.reducedMotion also adds this to the game root, so every pulse is gone by
   CLASS and not only by the global animation-duration flattening — including
   the replay echo above, which is more specific than the base dot rule and
   would otherwise still name a keyframe. The dot stays a solid accent disc
   with a white ring, and the echo stays a ring that thickens: nothing about
   WHERE to start was ever carried by the movement. */
.kg-letter-trace-still .kg-letter-trace-dot,
.kg-letter-trace-still .kg-letter-trace-guide.kg-letter-trace-say .kg-letter-trace-dot {
  animation: none;
}

/* ---------------- "Not there" ----------------
   A wrong start moves the DOT, ±3 user units, three cycles, 300ms — the same
   shape and the same 300ms as js/kidgames/motion.js's MOTION.wobble, in the
   units this coordinate space actually uses. Never a screen shake, and never
   a buzzer: the sound that goes with it is the warm single `nudge` tone.

   The amber ring is the colour half, and it is the whole feedback when the
   travel is flattened away for reduced motion. Amber, never red: red is a
   mistake, amber is a hint. */
.kg-letter-trace-guide.kg-letter-trace-nope {
  animation: kg-letter-trace-nope 300ms var(--ease) both;
}
.kg-letter-trace-guide.kg-letter-trace-nope .kg-letter-trace-dot {
  fill: var(--amber);
  animation: none;
}
.kg-letter-trace-guide.kg-letter-trace-nope .kg-letter-trace-arrow { fill: var(--amber); }

@keyframes kg-letter-trace-nope {
  0%, 100% { transform: translateX(0); }
  16.6%    { transform: translateX(-3px); }
  33.3%    { transform: translateX(3px); }
  50%      { transform: translateX(-2.5px); }
  66.6%    { transform: translateX(1.8px); }
  83.3%    { transform: translateX(-0.9px); }
}

/* The whole letter, once every stroke of it is inked. */
.kg-letter-trace-svg.kg-letter-trace-win .kg-letter-trace-ink {
  animation: kg-letter-trace-cheer .5s var(--ease) 1;
}
@keyframes kg-letter-trace-cheer {
  0%   { stroke-width: 14; }
  45%  { stroke-width: 18; }
  100% { stroke-width: 14; }
}

/* ---------------- Toolbar ----------------
   30px between the two controls, the same floor .kg-choices applies to answer
   targets, so a thumb aimed at "Show me" never lands on the replay. */
.kg-letter-trace-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 30px;
}

/* THE BUTTON THAT MEANS NOBODY IS STUCK.
   Present from the first frame and in the tab order from the first frame, so
   a child with no touchscreen — or no wish to trace today — has a complete
   route through every stroke with Enter or Space. It is quiet to begin with
   because tracing is the lesson; it is never hidden, because being stuck is
   worse than being helped. The hit area is the shared 76px target at every
   step: only the colour changes. */
.kg-letter-trace-show {
  grid-auto-flow: column;
  gap: 10px;
  font-size: 1.05rem;
  border-color: #e6e3f2;
  color: var(--ink-soft);
}
.kg-letter-trace-show-icon { font-size: 1.5rem; line-height: 1; }

/* Two failed tries at the same stroke (rules.scaffold level 2). */
.kg-letter-trace-show.kg-letter-trace-offer {
  border-color: var(--accent-2);
  color: var(--ink);
  transform: scale(1.06);
}
/* Level 3 hands her .kg-hint — the ONE reserved highlight treatment in these
   games, so a glow always means the same thing wherever she meets it. */
.kg-letter-trace-show.kg-hint { color: var(--ink); transform: scale(1.06); }

/* ---------------- Progress ----------------
   Six letters she can count without reading, in the literacy face, filling in
   as she writes them. Nothing here ever goes down. */
.kg-letter-trace-track {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}
.kg-letter-trace-bead {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fff;
  border: 3px solid #e6e3f2;
  font-family: var(--font-literacy);
  font-weight: 700;
  font-size: 1.15rem;
  color: #cfcbe0;
  transition: color .3s var(--ease), border-color .3s var(--ease),
              background-color .3s var(--ease);
}
.kg-letter-trace-bead.kg-letter-trace-inked {
  color: #fff;
  border-color: var(--accent);
  background: var(--accent);
}

/* ---------------- Small screens ----------------
   Only breakpoints the ADDENDUM already names are used. */
@media (max-width: 560px) {
  .kg-letter-trace-bar { gap: 30px; }
  .kg-letter-trace-bead { width: 34px; height: 34px; font-size: 1rem; }
}
@media (max-width: 360px) {
  .kg-letter-trace-stage { gap: 8px; }
  .kg-letter-trace-print { border-width: 3px; }
}

/* A pointing cursor only where a pointer exists, and it carries no state that
   is not already on screen — hover may decorate, never inform. */
@media (hover: hover) {
  .kg-letter-trace-svg { cursor: crosshair; }
}
