/* ==========================================================================
   PAGE PRINCIPALE — CARTE DES 100 NIVEAUX
   Le châssis (header, sidebar, workspace) vient de memory-3d.css.
   Ce fichier ne décrit que la grille de niveaux.

   Chaque cellule porte une variable --row-rgb : la couleur de sa ligne,
   c'est-à-dire son palier de difficulté (ligne 1 = vert, ligne 10 = rouge).
   La variable est héritée par la tuile et par le tube.
   ========================================================================== */

/* -------------------------------------------------------- BARRE DU HAUT */
/* La barre reste PLATE sur les deux premiers tiers — une teinte unie, sans
   variation — puis bascule vers le blanc pur sur le dernier tiers.
   C'est cette descente en fin de course qui pose la barre au-dessus et le
   jeu en dessous, au lieu d'un dégradé continu qui aplatit tout.
   Surcharge propre à cette page — core.css garde la version d'origine. */
.top-inset-bar {
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid rgba(226, 232, 240, 0.9);
  box-shadow: none;
}

/* ---------------------------------------------- PANNEAU LATÉRAL REPLIABLE */
/* Propre à la carte des niveaux : le bouton n'existe que sur cette page. */

.left-sidebar-container,
.workspace {
  transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.25s ease,
              left 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

body.sidebar-closed .left-sidebar-container {
  transform: translateX(calc(-100% - 1.5rem));
  opacity: 0;
  pointer-events: none;
}

/* Le workspace récupère toute la place libérée */
@media (min-width: 1024px) {
  body.sidebar-closed .workspace { left: 0.75rem; }
}

.levels-area {
  width: 100%;
  height: 100%;
  padding: 0.75rem;
  overflow: hidden;
}

/* ------------------------------------------------ JEU DANS LE WORKSPACE */

.game-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: none;
  background: transparent;
}

/* Hôte des jeux livrés en fragment : le contenu injecté s'y centre comme le
   ferait le workspace d'une page de jeu autonome. */
#game-host {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
}

/* body.playing : la grille cède la place au jeu, sans être démontée.
   body.fragment distingue le jeu injecté du jeu encore en iframe. */
body.playing .levels-area { display: none; }
body.playing.fragment  #game-host  { display: flex; }
body.playing:not(.fragment) .game-frame { display: block; }

body.playing #back-btn    { display: inline-flex; }
body.playing #now-playing { display: inline; }

/* La grille occupe exactement le workspace : 10 colonnes, 10 rangées,
   toutes égales. C'est la hauteur d'une rangée qui fixe la taille des tuiles,
   donc tout tient sans défilement quelle que soit la fenêtre. */
.levels-board {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  grid-template-rows: repeat(10, 1fr);
  width: 100%;
  height: 100%;
}

/* ---------------------------------------------------------------- CELLULE */

.level-cell {
  --row-rgb: 99, 102, 241;

  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ------------------------------------------------------ TUBE LUMINEUX */

/* Le tube va du centre de cette cellule au centre de la suivante ; il passe
   sous les deux tuiles, qui sont opaques — on ne le voit donc que dans
   l'intervalle. */
.level-cell::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 3px;
  z-index: 0;
  transform: translateY(-50%);
  border-radius: 999px;
  background-color: var(--kidio-border, #e2e8f0);
  background-image: linear-gradient(90deg, transparent 0%, var(--kidio-accent, #6366f1) 50%, transparent 100%);
  background-size: 45% 100%;
  background-repeat: no-repeat;
  background-position: -50% 0;
  box-shadow:
    inset 1px 1px 2px rgba(15, 23, 42, 0.16),
    inset -1px -1px 1px rgba(255, 255, 255, 0.9);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
  animation: tubeGlow 6s ease-in-out infinite;
}

.level-cell.has-path::after { opacity: 1; }

/* Fin de ligne : pas de tube vers la ligne suivante pour l'instant */
.level-cell:nth-child(10n)::after { content: none; }

/* Glissement lent (0→50%) puis pause immobile (50→100%) avant la reprise,
   plutôt qu'un défilement continu. */
@keyframes tubeGlow {
  0%   { background-position: -50% 0; }
  50%  { background-position: 150% 0; }
  100% { background-position: 150% 0; }
}

/* ---------------------------------------------------------------- TUILE */

/* Carré plein à contour adouci. Le bombé vient de deux couches :
   une lumière radiale en haut, une ombre interne en bas. */
.level-tile {
  position: relative;
  z-index: 1;
  height: 84%;
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 0;
  border: 0;
  border-radius: 16%;
  background-color: #ffffff;
  color: #475569;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-weight: 800;
  line-height: 1;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;
}

.level-num { font-size: 13px; }
.level-lock { font-size: 13px; }
.level-tile.is-locked .level-num { font-size: 9px; }

/* VAGUE DE COULEUR — la teinte de difficulté traverse la grille de temps en
   temps. Le voile est en z-index: -1 : il se pose sur le fond de la tuile mais
   passe SOUS le chiffre, qui reste lisible. Le décalage --tint-delay est posé
   par le JS sur chaque cellule, en diagonale, ce qui fait balayer la vague.

   SYNCHRO LOGO : +2.97s ajoutées à chaque délai — le temps que l'éclat du
   logo du header se termine (voir assets/core.css, .kidio-logo-svg) avant
   que la vague ne parte de la tuile 1. Le décalage relatif entre tuiles
   (--tint-delay lui-même, posé par assets/levels.js) n'est pas touché :
   c'est uniquement le point de départ commun qui recule. Comme les deux
   animations durent 9s, elles restent alignées à chaque boucle, pas
   seulement à la première. */
.level-tile::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: rgb(var(--row-rgb));
  opacity: 0;
  pointer-events: none;
  animation: tileTint 9s ease-in-out infinite;
  animation-delay: calc(2.97s + var(--tint-delay, 0s));
}

@keyframes tileTint {
  0%, 84%, 100% { opacity: 0; }
  92%           { opacity: 0.14; }
}

/* Sur les niveaux fermés, la vague passe deux fois plus discrètement */
.level-tile.is-locked::before,
.level-tile.is-soon::before {
  animation-name: tileTintFaint;
}

@keyframes tileTintFaint {
  0%, 84%, 100% { opacity: 0; }
  92%           { opacity: 0.07; }
}

/* Le galbe, en blanc : un simple dégradé du blanc pur vers un blanc cassé */
.level-tile.is-playable,
.level-tile.is-done,
.level-tile.is-soon {
  background-image: linear-gradient(180deg, #ffffff 0%, #f6f8fb 100%);
}

/* Niveau jouable — le plus décollé de tous, et il respire */
.level-tile.is-playable {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    0 7px 15px -5px rgba(15, 23, 42, 0.20),
    0 0 0 4px rgba(15, 23, 42, 0.045);
  cursor: pointer;
  animation: tileBreathe 2.4s ease-in-out infinite;
}
.level-tile.is-playable:hover { transform: translateY(-3px) scale(1.10); }
.level-tile.is-playable:active { transform: translateY(0) scale(0.97); }

@keyframes tileBreathe {
  50% {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 1),
      0 7px 15px -5px rgba(15, 23, 42, 0.20),
      0 0 0 8px rgba(15, 23, 42, 0.025);
  }
}

/* Niveau terminé — posé, moins décollé que le jouable, sans anneau */
.level-tile.is-done {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    0 4px 10px -4px rgba(15, 23, 42, 0.16);
  cursor: pointer;
}
.level-tile.is-done:hover { transform: translateY(-3px) scale(1.10); }

/* Niveau débloqué dont le jeu n'existe pas encore — à peine décollé */
.level-tile.is-soon {
  color: #cbd5e1;
  box-shadow: 0 1px 4px -1px rgba(15, 23, 42, 0.09);
  cursor: not-allowed;
}

/* Niveau verrouillé — creusé au lieu de bombé, c'est ce qui le dit fermé */
.level-tile.is-locked {
  background-color: #fbfcfe;
  color: #cbd5e1;
  box-shadow:
    inset 2px 3px 6px rgba(15, 23, 42, 0.11),
    inset -1px -2px 4px rgba(255, 255, 255, 1);
  cursor: not-allowed;
}

/* Pastille de validation en angle */
.level-flag {
  position: absolute;
  top: -3px; right: -3px;
  width: 15px; height: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  color: #64748b;
  font-size: 7px;
  box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.10);
}

/* ------------------------------------------------- ÉCRANS ÉTROITS : 5 COL. */

@media (max-width: 720px) {
  .levels-area { overflow-y: auto; }
  .levels-board {
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(20, minmax(52px, 1fr));
    height: auto;
    min-height: 100%;
  }
  .level-cell::after { content: none; }
  .level-num { font-size: 14px; }
  .level-lock { font-size: 13px; }
}

/* ==========================================================================
   THÈME NEUMORPHIQUE — overrides, voir core.css pour le principe général.
   Ne modifie aucune règle ci-dessus ; les couleurs de texte et la vague de
   teinte restent identiques, seul le galbe des tuiles change de langage
   (blanc + ombre portée → gris-bleu + relief doux).
   ========================================================================== */

html[data-theme="neu"] .level-cell::after {
  background-color: var(--card-bg);
}

html[data-theme="neu"] .level-tile {
  background-color: var(--card-bg);
  border: 1px solid var(--border-light);
}

html[data-theme="neu"] .level-tile.is-playable,
html[data-theme="neu"] .level-tile.is-done,
html[data-theme="neu"] .level-tile.is-soon {
  background-image: none;
}

html[data-theme="neu"] .level-tile.is-playable {
  box-shadow: var(--shadow-raised-sm);
  animation-name: tileBreatheNeu;
}
@keyframes tileBreatheNeu {
  50% {
    box-shadow: 2px 2px 5px rgba(166, 180, 200, 0.35), -2px -2px 5px rgba(255, 255, 255, 0.9);
  }
}

/* Niveau réussi : signalé par la couleur, pas seulement le relief */
html[data-theme="neu"] .level-tile.is-done {
  background-color: #ecfdf5;
  border-color: #10b981;
  box-shadow: var(--shadow-raised-sm);
}

html[data-theme="neu"] .level-tile.is-soon {
  border-color: var(--border-subtle);
  box-shadow: 2px 2px 5px rgba(166, 180, 200, 0.25), -2px -2px 5px rgba(255, 255, 255, 0.7);
}

/* Verrouillé : recule dans le fond au lieu de se détacher */
html[data-theme="neu"] .level-tile.is-locked {
  background-color: var(--bg-main);
  border-color: var(--border-subtle);
  box-shadow: var(--shadow-inset);
}

html[data-theme="neu"] .level-flag {
  background: var(--card-bg);
  border: 1px solid var(--border-light);
  box-shadow: var(--shadow-raised-sm);
}
