/* Feuille de style unique, sans dépendance externe.
 *
 * Contraintes : pas de défilement, cibles tactiles énormes, contraste élevé,
 * aucune police téléchargée (le navigateur de la Tesla reste la référence).
 */

:root {
  --bg: #fff8ee;
  --bg-top: #fffdf9;
  --ink: #1b1b20;
  --ink-soft: #6f6a60;
  --line: #e8dfd0;
  --card: #ffffff;
  --accent: #2f9e5f;
  --accent-soft: #eaf6ee;
  --radius-card: 28px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font);
  color: var(--ink);
  background: radial-gradient(120% 90% at 50% 0%, var(--bg-top), var(--bg) 70%);
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

button { font-family: inherit; }

.screen {
  position: fixed;
  inset: 0;
}

.screen[hidden] { display: none; }

/* ---------------------------------------------------------------- accueil */

.screen-start {
  display: grid;
  place-items: center;
  text-align: center;
  padding: 24px;
}

.start-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(16px, 4vh, 40px);
}

.brand {
  margin: 0;
  font-size: clamp(2.2rem, 9vh, 5.5rem);
  font-weight: 800;
  letter-spacing: 0.14em;
}

.start-button {
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: clamp(1.2rem, 4.2vh, 2.4rem);
  font-weight: 800;
  letter-spacing: 0.08em;
  padding: 0.75em 1.8em;
  box-shadow: 0 6px 0 rgba(27, 27, 32, 0.12), 0 18px 40px rgba(27, 27, 32, 0.14);
  cursor: pointer;
  transition: transform 0.12s ease;
}

.start-button:active { transform: translateY(3px); }

.offline-badge {
  margin: 0;
  font-size: clamp(0.7rem, 1.7vh, 0.95rem);
  color: var(--ink-soft);
}

.offline-badge::before {
  content: "";
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  margin-right: 0.5em;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
}

.offline-badge[data-state="ready"] { color: var(--accent); }
.offline-badge[data-state="ready"]::before { opacity: 1; }

/* --------------------------------------------------------------- exercice */

.screen-game {
  display: grid;
  /* consigne | repère du mot | plateau | propositions */
  grid-template-rows: auto auto auto minmax(0, 1fr);
  gap: clamp(4px, 1vh, 14px);
  padding: clamp(6px, 1.2vh, 18px) clamp(12px, 2vw, 34px) clamp(10px, 1.6vh, 22px);
  /* Durée posée par src/ui.js (variable `--fade`), pour que la transition suive
     exactement le minuteur : 360 ms, et 520 ms après une mauvaise réponse. */
  transition: opacity var(--fade, 0.36s) ease;
}

.screen-game.is-leaving { opacity: 0; }

/* Placement explicite : quand le plateau est masqué (exercice « mot entier »),
 * les propositions doivent occuper toute la hauteur restante, et non se
 * retrouver dans une seule ligne. */
.screen-game > .hint { grid-row: 1; }
.screen-game > .word { grid-row: 2; }
.screen-game > .board { grid-row: 3; }
.screen-game > .options { grid-row: 4; }

/* Exercice « mot entier » : la grande zone du haut laisse la place aux mots. */
.screen-game.is-words .board { display: none; }
.screen-game.is-words > .options { grid-row: 3 / -1; }

.hint {
  margin: 0;
  font-size: clamp(0.8rem, 2.1vh, 1.2rem);
  color: var(--ink-soft);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Le mot de la consigne est en minuscules : un enfant qui débute ne lit pas
 * encore les minuscules, alors que le parent, si. */
.hint-word {
  color: var(--ink);
  font-weight: 700;
}

.board {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(6px, 2vh, 28px);
  min-height: 0;
}

.word {
  margin: 0;
  min-height: 1.5em;
  font-size: clamp(0.75rem, 2.6vh, 1.5rem);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-align: center;
  color: var(--ink-soft);
  transition: color 0.25s ease;
}

/* Exercice « mot entier » : aucun repère à montrer, mais la ligne reste
 * réservée pour que le plateau ne saute pas d'un exercice à l'autre. */
.word:empty { visibility: hidden; }

.word.is-confirmed { color: var(--accent); }

/* Sans animations, le mode « Pulse » est remplacé par un changement de couleur. */
.word.is-pulsing-static,
.prompt.is-pulsing-static { color: var(--accent); transition: color 0.25s ease; }

/* Le mode « Pulse » fait grossir la zone de réponse : les syllabes en
 * construction, ou à défaut la proposition choisie. */
.word.is-pulsing,
.prompt.is-pulsing,
.option.is-pulsing { animation: feedback-pulse 0.55s ease-out; }

@keyframes feedback-pulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.07); }
  100% { transform: scale(1); }
}

.prompt {
  display: flex;
  align-items: center;
  gap: clamp(6px, 2vh, 26px);
  font-size: clamp(1.6rem, min(20vh, 15vw), 20rem);
  font-weight: 800;
  line-height: 1;
  transition: gap 0.45s ease;
}

/* Fusion : la case se dissout et l'espace se referme, les deux syllabes se
 * collent et se lisent d'un seul mot (`LO` `LA` -> `LOLA`). */
.prompt.is-fusing { gap: 0; }

/* La case vide : carrée, sans lettre dedans. */
.prompt .slot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: auto;
  min-width: 1.1em;
  height: 1.1em;
  padding: 0;
  border: 0.06em dashed var(--ink-soft);
  border-radius: 0.2em;
  background: var(--card);
  color: var(--ink-soft);
  transition: min-width 0.4s ease, padding 0.4s ease, border-width 0.4s ease,
              color 0.25s ease, border-color 0.25s ease, background-color 0.25s ease;
}

.prompt .slot.is-filled {
  min-width: 0;
  padding: 0 0.15em;
  border-style: solid;
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}

/* À la fusion, la case redevient une syllabe ordinaire : plus de cadre ni de
 * marge, pour que la syllabe trouvée se colle à la précédente. */
.prompt.is-fusing .slot {
  padding: 0;
  border-width: 0;
  background: none;
}

.options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(8px, 1.8vh, 24px);
  min-height: 0;
}

/* Exercice « mot entier » : trois mots empilés sur toute la hauteur. */
.options.is-words {
  grid-template-columns: 1fr;
  grid-template-rows: repeat(3, minmax(0, 1fr));
}

.option {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--ink);
  font-size: clamp(1.6rem, min(22vh, 16vw), 20rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.04em;
  padding: 0;
  cursor: pointer;
  box-shadow: 0 5px 0 rgba(27, 27, 32, 0.07), 0 16px 34px rgba(27, 27, 32, 0.08);
  transition: transform 0.12s ease, background-color 0.15s ease,
              border-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}

/* Un mot entier est plus long qu'une syllabe : on baisse un peu la taille. */
.option-word { font-size: clamp(1.3rem, min(23vh, 17vw), 18rem); }

.option:active { transform: translateY(3px) scale(0.985); }

.option.is-correct {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  box-shadow: 0 5px 0 rgba(27, 27, 32, 0.12), 0 16px 40px rgba(47, 158, 95, 0.35);
}

.option.is-dim { opacity: 0.3; }

.option.is-reveal {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* -------------------------------------------------------------- feedback */

.feedback-layer {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 5;
}

/* Célébration de réussite : plein écran, deux formes (visage ou animal).
 * Elle vit dans une couche à part, au-dessus de l'écran de jeu mais sous les
 * confettis, et n'est jamais effacée par le fondu : l'enfant la voit pendant
 * tout l'enchaînement.
 *
 * C'est l'interface qui décide quand elle apparaît et quand elle s'efface, pour
 * que la durée d'un animal colle exactement à celle de son cri. Le pire cas en
 * cas de minuteur perdu est un voile déjà invisible, jamais un écran bloqué. */
.celebration {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0;
  pointer-events: none;
  z-index: 4;
  transition: opacity 0.35s ease;
}

.celebration.is-on { opacity: 1; }
.celebration.is-hiding { opacity: 0; transition-duration: 0.45s; }

.celebration-backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(78% 78% at 50% 44%, #fffdf7, #fff3d6 55%, #ffe7a8);
}

/* Un visage est rond : sur un écran 16/10 il ne peut pas remplir les deux
 * dimensions sans être écrasé. Il remplit donc la hauteur, et le fond chaud
 * couvre le reste : c'est tout l'écran qui devient la célébration. */
.celebration-face {
  position: relative;
  width: min(92vh, 92vw);
  height: auto;
  filter: drop-shadow(0 14px 34px rgba(176, 126, 16, 0.28));
}

.celebration-animal {
  position: relative;
  font-size: min(76vh, 76vw);
  line-height: 1;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  text-shadow: 0 14px 34px rgba(176, 126, 16, 0.22);
}

/* Navigateur sans police emoji : on montre le nom de l'animal plutôt qu'un
 * carré vide. C'est dégradé, mais lisible. */
.celebration-animal[data-fallback="text"] {
  font-family: var(--font);
  font-weight: 800;
  font-size: min(18vh, 18vw);
  color: var(--ink);
}

.celebration[data-kind="smiley"] .celebration-animal { display: none; }
.celebration[data-kind="animal"] .celebration-face { display: none; }

.celebration.is-on .celebration-face,
.celebration.is-on .celebration-animal {
  animation: celebration-pop 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes celebration-pop {
  0% { transform: scale(0.45); }
  55% { transform: scale(1.06); }
  100% { transform: scale(1); }
}

.confetti {
  position: absolute;
  top: -7vh;
  width: 12px;
  height: 18px;
  border-radius: 3px;
  animation-name: confetti-fall;
  animation-timing-function: cubic-bezier(0.3, 0.7, 0.6, 1);
  animation-fill-mode: forwards;
}

@keyframes confetti-fall {
  from { transform: translateY(0) rotate(0deg); }
  to { transform: translateY(118vh) rotate(560deg); }
}

/* Version statique, pour le réglage système « réduire les animations » : les
 * confettis sont dispersés dans l'écran et s'effacent par transition. Sans
 * cette variante, ils resteraient hors écran et l'enfant ne verrait rien. */
.confetti-static {
  animation: none !important;
  opacity: 1;
  transition: opacity 1.1s ease 0.25s;
}

.confetti-static.is-out { opacity: 0; }

/* --------------------------------------------- panneau parent (discret) */

/* Coin haut-gauche : au-dessus de la consigne (jamais d'un bouton, pour ne pas
 * avaler un appui destiné à une proposition) et à l'écart des surcouches du
 * navigateur, qui se logent plutôt à droite. */
.settings-dot {
  position: fixed;
  top: 0;
  left: 0;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 0;
  background: none;
  cursor: default;
  z-index: 10;
}

.settings-dot::after {
  content: "";
  position: absolute;
  top: 20px;
  left: 20px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--ink-soft);
  opacity: 0.22;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

/* Retour visuel pendant l'appui long : sans lui, on ne sait pas que ça compte. */
.settings-dot.is-pressed::after {
  transform: scale(2.1);
  opacity: 0.45;
}

/* Entrée visible depuis l'écran d'accueil. Le libellé est en minuscules :
 * un enfant qui débute ne le déchiffre pas encore. */
.parent-link {
  border: 0;
  background: none;
  color: var(--ink-soft);
  font-size: clamp(0.75rem, 1.8vh, 1rem);
  letter-spacing: 0.01em;
  padding: 10px 14px;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: rgba(111, 106, 96, 0.35);
  text-underline-offset: 4px;
}

.panel {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(27, 27, 32, 0.5);
}

.panel[hidden] { display: none; }

.panel-card {
  width: min(660px, 94vw);
  max-height: 90vh;
  overflow: auto;
  padding: 18px 22px 14px;
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}

.panel-title {
  margin: 0 0 4px;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

.panel-status {
  margin: 0 0 10px;
  min-height: 1.2em;
  font-size: 0.82rem;
  color: var(--accent);
}

.panel-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 6px 0;
  border-top: 1px solid #f0ece4;
}

.panel-label {
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.segment {
  display: flex;
  gap: 5px;
  padding: 3px;
  border-radius: 12px;
  background: #f4f1ea;
}

.segment button {
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--ink-soft);
  font-size: 0.8rem;
  font-weight: 600;
  padding: 6px 10px;
  cursor: pointer;
}

.segment button.is-active {
  background: #fff;
  color: var(--ink);
  box-shadow: 0 1px 4px rgba(27, 27, 32, 0.14);
}

.panel-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}

.ghost {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: 600;
  padding: 8px 12px;
  cursor: pointer;
}

.ghost-strong {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
}

.panel-meta {
  margin: 12px 0 0;
  font-size: 0.68rem;
  color: var(--ink-soft);
}

/* ------------------------------------------------------- adaptations */

@media (orientation: portrait) {
  .options:not(.is-words) { grid-template-columns: 1fr; }
  .word { font-size: clamp(1.8rem, min(16vh, 22vw), 8rem); }
  .prompt { font-size: clamp(1.4rem, min(10vh, 14vw), 5rem); }
  .option { font-size: clamp(1.4rem, min(11vh, 15vw), 5rem); }
}

@media (prefers-reduced-motion: reduce) {
  .confetti, .word.is-pulsing, .prompt.is-pulsing, .option.is-pulsing { animation: none !important; }
  .option, .start-button, .screen-game { transition: none; }
}
