/* V09 word search illustrated cards.
   Loaded AFTER niko/styles.css, so it may override the base without !important.
   Owned by the V09 build; the JS that renders these surfaces is niko/wordsearch.js.
   Design law: docs/design/NIKOLEARN_DESIGN_CONSTITUTION.md (§2 principles, §8 case registry,
   §8.1 imagery baseline, §8.3 mobile geometry 320/375/390/430, 2 columns on phone). */

/* ── WHY THE CARD LIVES HERE AND THE REST OF THE SCREEN DOES NOT ──────────────────────────
   wordsearch.js injects a <style id="ws-css"> into <head> at first render, so that block
   lands AFTER this link tag and wins every tie. The word CARD is therefore moved out of it
   whole, and nothing there competes with anything here. Everything else on the screen (the
   letter grid, the meadow ground, the owl bubble, the dock, the done card) stays in that
   block, byte for byte. V09 is additive work on a game that is not broken: the card is the
   one surface the founder asked to change, so it is the one surface that moved.
   Geometry note, load-bearing: the box sizes below (disc 42/30, sound mark 22/18, gaps and
   padding) are NOT taste. They are what is left for the WORD after the chrome is paid for.
   The number was re-taken on 2026-08-19, because the line that stood here cited qa/_chip.mjs
   and that file is not in the repo: a citation nobody can open is not evidence. Measured in the
   running app with a Range over the label's own text node (its box is flex-filled, so its width
   answers a different question), driving the whole 19-word corpus through one rendered card with
   the .long step-down the renderer applies at length>=6:
       320  card 149x60  label box 81  longest word „ყვითელი" inks 64  ->  17px free
       390  card 179x66  label box 83  longest word „ყვითელი" inks 71  ->  12px free
       430  card 199x66  label box 103 longest word „ყვითელი" inks 71  ->  32px free
   No word in the corpus wraps at any of the three. 390 is the binding width for the PICTURE the
   way 320 is for the chrome: growing the disc from 42 to 52 would take ten of those twelve pixels
   and put the longest Georgian word two pixels from breaking. So the disc does NOT grow. This pass
   changes what is drawn INSIDE those boxes and changes not one of their dimensions, so the
   Georgian word keeps every pixel it was measured to need. */

#wsscr .ws-clues{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:4px 12px 10px}

/* Strict 2-up, which is what the founder's reference shows and what §8.3 requires on a phone,
   and it holds for every word count the engine produces (3, 4 or 6).
   The card is now a SOFT card rather than a flat tint: the tint moved to background-color so
   background-image can carry a top-down sheen, and the shadow gained a white inner hairline.
   Both are light, because the loudest thing on this card has to stay the word. */
#wsscr .ws-clue{position:relative;display:flex;align-items:center;gap:7px;min-width:0;
  border-radius:18px;padding:8px 9px;min-height:66px;font-weight:800;color:#3A2415;cursor:pointer;
  background-color:#fff;
  background-image:linear-gradient(180deg,rgba(255,255,255,.72),rgba(255,255,255,0) 58%);
  box-shadow:0 2px 8px rgba(74,45,20,.10), inset 0 0 0 1.5px rgba(255,255,255,.60)}
#wsscr .ws-clue:active{transform:scale(.97)}
/* The four soft grounds, sampled from the founder's own sheet and deepened one notch because
   his page cream is cooler than ours (#fff9ed vs #FFF6E9) and the tan card would otherwise
   vanish. background-COLOR only: the sheen above must survive.
   Each tint also declares --disc-lo, the deeper end of its own hue. That variable is what lets the
   picture disc below be made of the SAME light as the card instead of a white chip laid on top of
   it: one hue per card, lit from one side, which is the whole of the shared visual system on a
   42px surface. */
#wsscr .ws-clue[data-t="0"]{background-color:#EAF6FE;--disc-lo:#D8ECFA}
#wsscr .ws-clue[data-t="1"]{background-color:#FBF0DC;--disc-lo:#F1E1C4}
#wsscr .ws-clue[data-t="2"]{background-color:#FDEAE1;--disc-lo:#F7DACD}
#wsscr .ws-clue[data-t="3"]{background-color:#FEF2C9;--disc-lo:#F8E5AB}

/* ── the picture ──────────────────────────────────────────────────────────────────────────
   This box held an emoji at 1.6rem inside 42px, i.e. about 26px of actual drawing, and §8.1
   names exactly that as a defect: an OS glyph changes shape with the phone and belongs to no
   world. It now holds an inline SVG that fills the box edge to edge, so the same 42px of
   layout carries about 42px of picture. The frame stays a soft light disc so the illustration
   reads as an object sitting on the card rather than a stain in the tint.
   WHAT CHANGED IN THIS PASS, and it is the only thing that did. The frame was flat white at 88%
   opacity, so on a blue or a yellow card it read as a sticker peeled off something else and laid
   on top — the object had no ground, no light direction, and no relationship to the card holding
   it. Three background layers replace the one, and the object gains what the world cards gained:
     1. a top-left sheen, so the whole card agrees about where the light comes from,
     2. a soft ellipse of shade at the very bottom, which is a CONTACT SHADOW: the drawings sit at
        y 5..43 of a 48 box, so it reads at the object's feet and it is the single cheapest thing
        that stops nineteen flat silhouettes from floating,
     3. a base that fades from white into --disc-lo, the card's OWN hue one notch deeper.
   The geometry above it is untouched, so the Georgian word keeps every measured pixel. */
#wsscr .ws-clue .em{flex:0 0 auto;width:42px;height:42px;border-radius:14px;overflow:hidden;
  background:
    radial-gradient(112% 92% at 28% 12%, rgba(255,255,255,.95), rgba(255,255,255,0) 68%),
    radial-gradient(56% 22% at 50% 97%, rgba(74,45,20,.20), rgba(74,45,20,0) 74%),
    linear-gradient(180deg,#fff 8%,var(--disc-lo,#F0E7D9) 100%);
  display:flex;align-items:center;justify-content:center;
  box-shadow:inset 0 0 0 1px rgba(74,45,20,.07), inset 0 -3px 7px rgba(74,45,20,.06)}
#wsscr .ws-clue .em svg{width:100%;height:100%;display:block}
/* Last-resort fallback for a word with no drawing (see WS_ART in wordsearch.js): the word's
   first Georgian letter, in the product's own script. It never fires for the shipped corpus,
   and if a future pack adds a word before its art it degrades to typography, not to an emoji. */
#wsscr .ws-clue .em .ltr{font-size:1.5rem;line-height:1;font-weight:800;color:var(--world-ink)}

#wsscr .ws-clue .lbl{flex:1 1 auto;min-width:0;overflow-wrap:anywhere;text-align:center;font-size:.95rem}
/* A long Georgian word is FITTED, not broken mid-word: the reader is a five-year-old sounding
   it out and an orphan letter on a second line is the worst possible break. The length is known
   in JS, so the markup declares it and the type steps down. overflow-wrap stays as the guard of
   last resort, it is simply no longer the first thing that happens. */
#wsscr .ws-clue.long .lbl{font-size:.86rem}

/* ── the sound affordance ─────────────────────────────────────────────────────────────────
   PI-212 asks for „an audio button with a strong but non-noisy affordance". The earlier
   correction on this screen killed a filled orange disc with its own shadow repeated on every
   card, because the whole card is already the control and four saturated discs read as four
   competing CTAs (his Kings English note: one interaction model). Both are satisfied by a
   DEFINED but QUIET mark: a white disc with a hairline ring and the app's own speaker stroked
   in currentColor, still pointer-events:none, still the same 22px box. Defined enough to say
   „tap to hear", quiet enough that the word stays the loudest thing on its own card.
   Drawn with I.speaker rather than 🔊 because `color` is inert on an emoji: the quietening
   below would land on nothing and the glyph would keep its own blue-grey palette at full
   strength, which is the mixed-asset-quality failure repeated four times in one row. */
/* padding, not size, carries the glyph: the 22px box is the measured one and does not move, so
   the only lever on „how strong does the speaker read" is how much of that box the icon gets.
   2.6px leaves a 16.8px glyph and still clears the hairline ring. */
#wsscr .ws-clue .snd{flex:0 0 auto;width:22px;height:22px;border-radius:50%;padding:2.6px;
  background:rgba(255,255,255,.94);color:var(--primary-d);
  box-shadow:0 1px 2px rgba(74,45,20,.14), inset 0 0 0 1px rgba(74,45,20,.08);
  display:flex;align-items:center;justify-content:center;pointer-events:none}
#wsscr .ws-clue .snd svg{width:100%;height:100%;display:block}

/* ── found state ──────────────────────────────────────────────────────────────────────────
   §8.2 corollary: state belongs to the app, never to the paint. This tick is a code-rendered
   overlay switched by the .done class that wsTap already sets, so it can be turned off; it is
   not drawn into any illustration. §2.4 wants a state that does not rely on colour alone, so
   the card carries three independent signals: a tick SHAPE, the strike through the word, and
   the card receding. The whole card no longer drops to opacity .45 — that dimmed the new
   illustration into a smudge; the parts recede individually and the tick stays at full
   strength, so „found" reads from further away than it did before. */
#wsscr .ws-clue .tick{position:absolute;top:5px;left:5px;width:20px;height:20px;border-radius:50%;
  padding:3.5px;background:#2E9E63;color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.24);
  display:none;align-items:center;justify-content:center;pointer-events:none}
#wsscr .ws-clue .tick svg{width:100%;height:100%;display:block}
#wsscr .ws-clue.done .tick{display:flex}
#wsscr .ws-clue.done{box-shadow:0 1px 3px rgba(74,45,20,.07), inset 0 0 0 1.5px rgba(255,255,255,.50)}
#wsscr .ws-clue.done .em{opacity:.38}
#wsscr .ws-clue.done .lbl{text-decoration:line-through;opacity:.55}
#wsscr .ws-clue.done .snd{opacity:.28;box-shadow:none}

/* 320px is the binding case, not an edge case: the card cannot shrink below its own chrome, so
   at 320 a card that will not shrink pushes the whole grid sideways. Shrink the CHROME here,
   never the word, which is the thing the child is reading. Every number in this block is the
   measured one; only the tick is new, sized so it marks the picture without covering it. */
@media (max-width:360px){
  #wsscr .ws-clues{gap:6px;padding:4px 8px 10px}
  #wsscr .ws-clue{gap:4px;padding:6px;min-height:60px}
  #wsscr .ws-clue .em{width:30px;height:30px;border-radius:10px}
  #wsscr .ws-clue .em .ltr{font-size:1.15rem}
  #wsscr .ws-clue .snd{width:18px;height:18px;padding:2px}
  #wsscr .ws-clue .tick{top:4px;left:4px;width:17px;height:17px;padding:3px}
  #wsscr .ws-clue .lbl{font-size:.86rem}
  #wsscr .ws-clue.long .lbl{font-size:.78rem}
}

/* ── the HEIGHT twin of the block above (NB-293, founder 2026-08-30) ──────────────────────
   „სიტყვების თამაშში სრულად არ ჩანს ეკრანზე ფაზლი რომ გამოიცნო და ითამაშო."
   The 360px block shrinks the card's chrome when WIDTH runs out. Nothing shrank it when HEIGHT
   ran out, and height is the side that actually fails: a phone showing browser chrome is 100-115px
   shorter than its spec sheet, so a 375x667 iPhone SE is 375x553 in Safari, and at that height the
   header plus two rows of cards left the board less room than the board needs. Measured before and
   after, 375x553, 9x9 board with a 4-word pack:
       before  chrome above the board 228px  ->  board ran 55px under the meadow band
       after   chrome above the board 170px  ->  board ends clear of it
   Shrink the CHROME, never the word, exactly as the width block does. The word is what the child is
   reading and the cell is what the child is tapping, so those two are the last things to give.
   .short is set by wsRender from window.innerHeight, not by a media query: the game renders inside
   the .device frame, so a height query would answer for the browser window while the layout answers
   for the frame, and on a desktop preview the two disagree by hundreds of pixels. */
#wsscr.short .ws-clues{gap:6px;padding:2px 12px 6px}
#wsscr.short .ws-clue{padding:6px 8px;min-height:52px}
#wsscr.short .ws-clue .em{width:34px;height:34px;border-radius:12px}
/* narrow AND short: width has already taken the disc to 30px and must keep it there, so this
   sits after the 34px line and wins on order at equal specificity. */
@media (max-width:360px){ #wsscr.short .ws-clue .em{width:30px;height:30px;border-radius:10px} }
