/*
 * Memoria Tattica — vestizione del campo.
 *
 * NESSUN VALORE GRAFICO VIVE QUI. Solo i token di ATELIER (tokens.css
 * §court) e le geometrie che il motore calcola in unita' di campo. Se un
 * token manca, la regola cade sul suo fallback dichiarato e la cosa si
 * VEDE — non si inventa un colore per far sembrare che funzioni.
 *
 * I fallback sono `currentColor` o `transparent`: non sono colori scelti da
 * me, sono ereditarieta' e assenza. Un valore esadecimale scritto qui — anche
 * dentro un commento, anche solo per spiegare — sarebbe una seconda sede
 * degli stessi valori, e le due copie divergerebbero. Il controllo guarda il
 * file INTERO, commenti compresi, proprio per questo.
 *
 * TRE LIVELLI, come li ha impostati ATELIER:
 *   contesto  paint e ancore di zona — stanno sotto e non chiedono attenzione
 *   campo     le linee — la mappa
 *   risposta  tracce, dischi, palla — quello che il giocatore fa e sposta
 *
 * Le misure (raggi, spessori) NON stanno qui: nascono in metri di campo in
 * simboli.js e diventano attributi SVG, cosi' scalano col riquadro invece di
 * valere solo a 390 px. Qui restano solo i tratti che non dipendono dalla
 * scala.
 */

.tk-court-root {
  display: block;
  touch-action: none;          /* il drag e' nostro, non dello scroll */
  user-select: none;
  width: 100%;
  height: 100%;
}

/*
 * STRATI. Solo i token si afferrano: tutto il resto deve essere trasparente
 * al dito. Senza questo, un simbolo o la scritta del banner che capitano
 * sopra un giocatore intercettano il pointerdown, `closest()` non trova
 * nessun token e il trascinamento non parte — un difetto che si manifesta
 * solo quando due disegni si sovrappongono, cioe' di rado e a caso.
 */
.tk-segment,
.tk-trace,
.tk-banner,
.tk-zones,
.tk-court,
.tk-hint,
.tk-replay,
.tk-court-symbol {
  pointer-events: none;
}

.tk-tokens {
  pointer-events: auto;
}

/* «Watch again»: il bersaglio e' la fascia, non le lettere. Il riempimento
   e' `transparent` — assenza, non un colore scelto qui — e resta afferrabile
   perche' un'area dipinta di niente e' comunque un'area dipinta. */
.tk-replay__zona {
  fill: transparent;
  pointer-events: auto;
}

.tk-replay__testo {
  fill: var(--tk-player-fill, currentColor);
  font-size: var(--tk-text-body);
  pointer-events: auto;
}

/* I due soli oggetti afferrabili del gioco. Il bersaglio e' il gruppo, non
   il disco: cosi' il numerale non fa da buco dentro il token. */
.tk-token,
.tk-ball {
  cursor: grab;
  pointer-events: auto;
}

.tk-token:active,
.tk-ball:active {
  cursor: grabbing;
}

/* ---------------------------------------------------------- contesto */

/*
 * IL CAMPO E' UN OGGETTO DELL'APP (D-073), non l'unico rettangolo a spigolo
 * vivo dentro un mondo di card.
 *
 * La domanda vera era un'altra — se il campo dovesse restare chiaro dentro
 * un'app scura — e l'ha decisa una misura di 咖啡, non un gusto: su fondo
 * scuro la banda di luminanza della PALLA, che e' il vincolo piu' stretto del
 * §17, si stringerebbe del 41%. Il campo chiaro resta (D-017): la lavagna
 * dell'allenatore E' chiara. Quello che mancava non era il colore, era il
 * trattamento — un pannello senza raggio e senza elevazione si legge come un
 * ritaglio, non come una cosa che sta sopra il telaio.
 *
 * Raggio e ombra sono i valori che questa casa usa gia' per le card: il campo
 * entra nella famiglia degli oggetti che l'app mostra, invece di essere
 * l'eccezione. `drop-shadow` e non `box-shadow` perche' l'ombra deve seguire
 * il rettangolo del parquet, non il riquadro dell'<svg>, che e' tutto il
 * mount: il token si passa verbatim, la forma la decide il filtro.
 *
 * AVVERTENZA di 咖啡 (§17), qui perche' e' qui che si sbaglierebbe: palla e
 * linee di campo stanno a 1,03:1 fra loro APPOSTA, e si distinguono per FORMA
 * — la palla e' piu' piccola e non porta numero. Chi ritocca l'una senza
 * l'altra rompe la coppia in silenzio.
 */
.tk-court__surface {
  fill: var(--tk-court-surface, transparent);
  rx: var(--tk-radius-lg);
  ry: var(--tk-radius-lg);
  filter: drop-shadow(var(--tk-shadow-card));
}

.tk-court__paint {
  fill: var(--tk-court-paint, transparent);
  stroke: var(--tk-court-line, currentColor);
  stroke-width: 1.5;
}

.tk-zones__anchor {
  fill: var(--tk-zone-hint, currentColor);
  opacity: 0.55;
}

/*
 * REGOLA D'INCHIOSTRO (咖啡, 2026-08-05): sul campo il testo piccolo prende
 * l'inchiostro del DIAGRAMMA, mai quello dei suggerimenti.
 *
 * Le etichette di zona non fallivano per il corpo ma per l'accoppiamento:
 * --tk-zone-hint sta a 3,24:1, sotto il pavimento di 4,50 per il testo
 * piccolo. Non e' un difetto del token — e' che non e' un colore da testo:
 * marca un bersaglio, e infatti tokens.css lo chiama «drop targets». Il
 * cerchietto dell'ancora resta suo; la parola no.
 */
.tk-zones__label {
  fill: var(--tk-player-fill, currentColor);
  font-size: var(--tk-text-micro);
  text-anchor: middle;
}

/* ------------------------------------------------------------- campo */

.tk-court__line {
  fill: none;
  stroke: var(--tk-court-line, currentColor);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.tk-court__circle,
.tk-court__arc,
.tk-court__restricted {
  fill: none;
}

/* Il perimetro condivide il raggio del parquet: bordo del pannello e linea
   laterale sono la stessa cosa, quindi devono avere la stessa forma. */
.tk-court__perimetro {
  rx: var(--tk-radius-lg);
  ry: var(--tk-radius-lg);
}

.tk-court__board {
  stroke-width: 2.5;
}

.tk-court__rim {
  fill: none;
  stroke-width: 2;
}

/* ---------------------------------------------------------- risposta */

/*
 * SIMBOLI DA LAVAGNETTA — e' l'app che parla, mostra cosa si deve fare.
 *
 * `line` e `bar` hanno oggi lo stesso valore e DUE nomi: si usano i nomi,
 * mai il valore, cosi' uno dei due puo' muoversi domani senza toccare una
 * riga qui.
 *
 * Il contrasto con la traccia del giocatore e' basso ED E' VOLUTO: domanda
 * e risposta non sono mai a piena forza insieme, perche' durante la
 * dimostrazione la risposta non esiste ancora. A separarle sono peso, stile
 * e tempo — l'ondulato del palleggio, il tratteggio del passaggio, la
 * doppia barretta dell'handoff, la T del blocco. Il colore e' rinforzo, il
 * canale primario e' la forma: gli spessori e i tratteggi qui sotto
 * PORTANO IL SIGNIFICATO e non sono decorazione.
 */
.tk-court-symbol-line {
  fill: none;
  stroke: var(--tk-court-symbol-line, currentColor);
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tk-court-symbol-arrow {
  fill: var(--tk-court-symbol-line, currentColor);
  stroke: none;
}

.tk-court-symbol-bar {
  stroke: var(--tk-court-symbol-bar, currentColor);
  stroke-width: 2.75;
  stroke-linecap: butt;
}

/*
 * IL RIFERIMENTO DEL PARACADUTE. Piu' chiaro apposta: deve leggersi come
 * «ecco com'era», non competere col campo. Il contrasto e' basso e la
 * carenza e' dichiarata e accettata — regge perche' il colore non e' mai
 * l'unico portatore: qui e' sempre tratteggiato ed e' sempre accompagnato
 * dal banner che dice cosa sta succedendo.
 */
.tk-court-symbol--ghost .tk-court-symbol-line,
.tk-court-symbol--ghost .tk-court-symbol-bar {
  stroke: var(--tk-court-symbol-ghost, currentColor);
  stroke-dasharray: 6 5;
}

.tk-court-symbol--ghost .tk-court-symbol-arrow {
  fill: var(--tk-court-symbol-ghost, currentColor);
}

/* Il dito del giocatore mentre trascina: e' il giocatore che risponde, e ha
   un token suo. */
.tk-trace__linea {
  fill: none;
  stroke: var(--tk-trace, currentColor);
  stroke-width: 2;
  stroke-dasharray: 2 5;
  stroke-linecap: round;
  opacity: 0.75;
}

/*
 * IL MOVIMENTO E' IL FEEDBACK.
 *
 * ATELIER ha chiuso la questione in tokens.css §17: su questo campo non
 * esiste una tinta di stato che regga contro fondo, paint, linee, traccia,
 * dischi e palla insieme — «colour cannot be the state channel» — e quindi
 * il feedback viaggia «as motion and words». Queste sono le parole di quel
 * movimento: senza, un disco cambiava posizione fra un fotogramma e l'altro
 * e il giocatore non distingueva un passaggio accettato da un tocco che non
 * aveva prodotto niente.
 *
 * Il fallback e' `0s`, cioe' ASSENZA di transizione: se il token non c'e' si
 * torna al salto secco e la mancanza si vede, che e' la regola di questo
 * file. La durata e' un token di 咖啡 — «state change inside an exercise».
 */
.tk-token,
.tk-ball {
  transition: transform var(--tk-duration-feedback, 0s);
}

/* Un solo --tk-player-fill per tutti e cinque: si distinguono per numerale.
   Cinque tinte sarebbero cinque modi di sbagliare (decisione di ATELIER). */
.tk-token__disco {
  fill: var(--tk-player-fill, currentColor);
}

/* Il 13px del numerale non si muove: 咖啡 l'ha confermato esplicitamente,
   regge il --tk-player-fill unico che distingue i cinque per numerale. */
.tk-token__numero {
  fill: var(--tk-player-text, transparent);
  font-weight: 600;
  font-size: var(--tk-text-mono);
  pointer-events: none;
}

/* Chi deve muoversi adesso porta un anello, non un colore diverso: cosi'
   l'indicazione non consuma una tinta e resta leggibile da chi non
   distingue bene i colori. */
.tk-token--atteso .tk-token__disco {
  stroke: var(--tk-ball, currentColor);
  stroke-width: 2.5;
}

.tk-ball__disco {
  fill: var(--tk-ball, currentColor);
}

/* ------------------------------------------------------------ banner */

/* «From the top!» NON e' rosso: ATELIER ha misurato che sul campo non
   esiste un rosso che regga contro fondo, paint, linee, traccia, dischi e
   palla insieme. Il segnale piu' forte e' il reset stesso.
   Quella misura resta intatta — qui non entra nessuna tinta di stato. Cambia
   solo DOVE atterra il messaggio: sul parquet, dove il giocatore ha gli occhi
   e dove questo inchiostro e' misurato, invece che sulla cornice scura 125 px
   piu' su, dove non lo era. Se ATELIER lo rivuole sulla cornice, serve un suo
   inchiostro per quella superficie: sono due righe, e sono sue. */
.tk-banner__testo {
  fill: var(--tk-player-fill, currentColor);
  font-weight: 600;
  font-size: var(--tk-text-item);
  letter-spacing: 0.01em;
}

/*
 * LA SECONDA RIGA: il perche'. Sta sotto e piu' piccola perche' e' una
 * spiegazione, non un annuncio — e perche' se pesasse quanto «From the
 * top!» il giocatore leggerebbe due titoli e nessuno dei due.
 */
.tk-banner__motivo {
  fill: var(--tk-player-fill, currentColor);
  font-size: var(--tk-text-body);
}

/*
 * SUGGERIMENTO A INATTIVITÀ (D-031).
 *
 * Il campo non si tocca mai: niente frecce, niente zone illuminate. Il testo
 * dice COSA fare, il COME resta da ricostruire — altrimenti sarebbe la guida
 * persistente che abbiamo escluso, e l'esercizio misurerebbe una copia.
 *
 * DOV'E' FINITO. D-031 lo voleva «in fondo, fuori dal campo da gioco», e li'
 * e' stato finche' non l'ha visto un giocatore: fuori dal campo non c'e'
 * nessuna superficie dipinta, quindi questo inchiostro — che e' quello del
 * DIAGRAMMA, misurato contro il parquet bianco — cadeva sulla cornice scura
 * della shell. Grigio su quasi-nero. Adesso sta sulla fascia di parquet
 * libera sopra le teste, che e' la superficie per cui l'inchiostro e' stato
 * scelto; discreto lo resta per corpo e corsivo, non per penombra.
 */
.tk-hint__testo {
  fill: var(--tk-player-fill, currentColor);
  font-size: var(--tk-text-body);
  font-style: italic;
}

@media (prefers-reduced-motion: reduce) {
  .tk-court-symbol-line,
  .tk-court-symbol-arrow,
  .tk-court-symbol-bar,
  .tk-token,
  .tk-ball {
    transition: none;
    animation: none;
  }
}

/*
 * LA LEZIONE (tk-lesson).
 *
 * Insegna sul campo vero, con l'inchiostro del campo vero: nessuna tinta
 * nuova, nessun colore di stato. La regola di tokens.css §17 vale qui piu'
 * che altrove — su questo parquet il feedback viaggia «as motion and words»,
 * quindi la conferma e' un SEGNO che si disegna, non un verde che si accende.
 *
 * Il dito fantasma prende l'inchiostro della traccia (--tk-trace): e'
 * letteralmente la stessa cosa che il giocatore lascera' col dito fra un
 * istante, e vederla dello stesso colore e' meta' della spiegazione.
 */
.tk-lesson {
  pointer-events: none;
}

.tk-lesson__scia {
  fill: none;
  stroke: var(--tk-trace, currentColor);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}

/* Il polpastrello: pieno tenue con bordo pieno, cosi' si legge come un dito
   appoggiato e non come un sesto giocatore entrato in campo. */
.tk-lesson__dito {
  fill: var(--tk-trace, currentColor);
  fill-opacity: 0.22;
  stroke: var(--tk-trace, currentColor);
  stroke-width: 2;
}

.tk-lesson__bersaglio {
  fill: none;
  stroke: var(--tk-court-symbol-line, currentColor);
  stroke-width: 1.5;
  stroke-dasharray: 3 4;
  opacity: 0.8;
}

.tk-lesson__spunta {
  fill: none;
  stroke: var(--tk-court-symbol-line, currentColor);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tk-lesson__testo {
  fill: var(--tk-player-fill, currentColor);
  font-weight: 600;
  font-size: var(--tk-text-item);
  letter-spacing: 0.01em;
}

/* Stessa forma della fascia «Watch again»: il bersaglio e' la banda, non le
   lettere. E resta afferrabile anche se lo strato non lo e'. */
.tk-lesson__zona {
  fill: transparent;
  pointer-events: auto;
}

.tk-lesson__via {
  fill: var(--tk-player-fill, currentColor);
  font-size: var(--tk-text-body);
  font-weight: 600;
  pointer-events: auto;
}

/*
 * LA CORNICE (tk-chrome) — cio' che non e' campo.
 *
 * Vive nelle due fasce scure sopra e sotto il parquet, quindi prende
 * l'inchiostro dell'APP, non quello del diagramma: --tk-ink-secondary sta a
 * 6,17:1 su questo fondo e --tk-ink-primary a 16,53:1, misurati contro
 * --tk-surface-game. L'inchiostro del campo qui sarebbe grigio su
 * quasi-nero, che e' esattamente l'errore che aveva gia' fatto sparire un
 * messaggio per quasi cinque secondi.
 *
 * --tk-ink-faint NON compare: 2,88:1, e tokens.css lo dichiara «NOT for text».
 * La pista della barra non e' testo, quindi puo' usarlo — ed e' l'unico posto
 * dove ha senso, perche' li' serve una traccia, non una parola.
 */
.tk-chrome {
  pointer-events: none;
}

.tk-chrome__titolo {
  fill: var(--tk-ink-secondary, currentColor);
  font-size: var(--tk-text-micro);
  letter-spacing: 0.14em;
  font-weight: 600;
}

.tk-chrome__livello {
  fill: var(--tk-ink-primary, currentColor);
  font-size: var(--tk-text-body);
  letter-spacing: 0.06em;
  font-weight: 600;
}

.tk-chrome__conto {
  fill: var(--tk-ink-secondary, currentColor);
  font-size: var(--tk-text-micro);
  letter-spacing: 0.1em;
}

.tk-chrome__pista {
  fill: var(--tk-ink-faint, currentColor);
}

/* L'avanzamento e' l'unica cosa che si muove qui: la transizione lo rende
   un progresso invece di un salto, e chi ha chiesto meno movimento la perde
   senza perdere il dato — la barra resta lunga uguale. */
.tk-chrome__avanzo {
  fill: var(--tk-ink-primary, currentColor);
  transition: width var(--tk-duration-feedback, 180ms) ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .tk-chrome__avanzo { transition: none; }
}

/*
 * IL SELETTORE DI LIVELLO (D-072) — vive nella fascia scura come la cornice,
 * quindi prende gli inchiostri d'app sanciti in D-069, mai quelli del campo.
 */
.tk-lvl__chip {
  fill: var(--tk-ink-faint, currentColor);
  pointer-events: auto;
}

/* Lo scelto si distingue per DUE canali che non sono la tinta: guadagna un
   anello, e il suo numero sale di peso d'inchiostro. La strada ovvia era
   riempire il chip e scrivere il numero col colore del fondo-stanza — ma
   quel token non e' fra i sanciti per questo file (D-069 ne ha dati tre), e
   auto-assegnarselo per comodita' e' esattamente cio' che il controllo
   impedisce. Due canali con gli inchiostri che ho valgono quanto uno con un
   token che non ho. */
.tk-lvl__chip--scelto {
  stroke: var(--tk-ink-primary, currentColor);
  stroke-width: 2;
}

.tk-lvl__numero {
  fill: var(--tk-ink-secondary, currentColor);
  font-size: var(--tk-text-body);
  font-weight: 600;
  pointer-events: auto;
}

.tk-lvl__numero--scelto {
  fill: var(--tk-ink-primary, currentColor);
}

.tk-lvl__descrizione {
  fill: var(--tk-ink-secondary, currentColor);
  font-size: var(--tk-text-micro);
  letter-spacing: 0.04em;
}
