/* ==========================================================================
   COMPOSANTS — les briques du site. Règle d'or : ici, aucune valeur en dur,
   uniquement des tokens de rôle (tokens.css). Un composant ne sait pas sur quelle page il est.

   Sommaire : icône · bouton · âme (le cœur) · compteur · perso · ciel
   ========================================================================== */

@layer components {
  /* --- Icône -----------------------------------------------------------------
     Un SVG pixel (public/icons) utilisé comme masque : l'icône prend la couleur du texte.
     <i class="icon icon--heart"></i> */
  .icon {
    --icon-size: 1em;
    display: inline-block;
    flex: none;
    inline-size: var(--icon-size);
    block-size: var(--icon-size);
    vertical-align: -0.12em;
    background: currentColor;
    -webkit-mask: var(--icon) center / contain no-repeat;
    mask: var(--icon) center / contain no-repeat;
  }
  .icon--heart { --icon: url("/icons/heart.svg"); }
  .icon--plus { --icon: url("/icons/plus.svg"); }

  /* --- Bouton : orange au repos, jaune quand on appuie (comme dans Undertale), gris verrouillé ---
     Verrouillé (disabled), il montre le temps restant (.btn__wait) à la place de son icône. */
  .btn {
    --btn-color: var(--color-action);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-block-size: calc(var(--px) * 12);
    padding-inline: var(--space-4);
    border: var(--px) solid var(--btn-color);
    background: var(--color-bg);
    color: var(--btn-color);
    font-size: var(--text-1);
    text-transform: uppercase;
    touch-action: manipulation;
    user-select: none;
    -webkit-user-select: none;
  }
  .btn:focus-visible,
  .btn:active { --btn-color: var(--color-action-hot); }
  @media (hover: hover) {
    .btn:hover { --btn-color: var(--color-action-hot); }
  }
  .btn:disabled {
    --btn-color: var(--color-action-off);
    cursor: default;
  }
  .btn__wait { display: none; font-size: var(--text-0); }
  .btn:disabled .btn__wait { display: inline; }
  .btn:disabled .icon { display: none; }
  .btn--square {
    inline-size: calc(var(--px) * 14);
    block-size: calc(var(--px) * 14);
    padding: 0;
  }
  .btn--square .icon { --icon-size: calc(var(--px) * 6); }

  /* --- Âme : le cœur pixel ------------------------------------------------------
     74 cases, une par pensée de la journée (heart.js), dans la couleur de la personne qui a pensé
     (--person). Le nombre au centre = la somme des deux compteurs. Une case touchée est encadrée
     (.soul__cursor) et sa bulle dit qui l'a posée, et quand. */
  .soul {
    container-type: inline-size; /* le nombre se mesure à la largeur du cœur */
    position: relative;
    display: grid;
    aspect-ratio: 11 / 10;
  }
  .soul__grid {
    grid-area: 1 / 1;
    inline-size: 100%;
    block-size: 100%;
    cursor: pointer;
  }
  .soul__silhouette { fill: var(--color-bg); }
  .soul__cell { fill: var(--color-cell-empty); }
  .soul__cell:not([data-who=""]) { fill: var(--person, var(--color-text)); }
  .soul__cursor {
    fill: none;
    stroke: var(--color-text);
  }
  .soul__count {
    grid-area: 1 / 1;
    place-self: start center;
    margin-block-start: 17%;
    line-height: 1;
    text-shadow: var(--outline-text);
    pointer-events: none; /* on touche la case dessous */
  }
  /* La bulle, au-dessus de la case (placée par app.js : --tip-x, --tip-y en fraction du cœur).
     Près des bords, elle s'aligne sur la case au lieu de se centrer, pour ne pas sortir de l'écran. */
  .soul__tip {
    position: absolute;
    z-index: 1;
    inset-inline-start: calc(var(--tip-x) * 100%);
    inset-block-end: calc((1 - var(--tip-y)) * 100%);
    margin-block-end: var(--space-1);
    translate: -50% 0;
    padding: var(--space-1) var(--space-2);
    border: var(--px) solid var(--color-text);
    background: var(--color-bg);
    font-size: var(--text-0);
    line-height: 1;
    white-space: nowrap;
    pointer-events: none;
  }
  .soul__tip[data-align="start"] { translate: 0 0; }
  .soul__tip[data-align="end"] { translate: -100% 0; }
  .soul__who { color: var(--person, var(--color-text)); }

  /* --- Compteur ----------------------------------------------------------------- */
  .counter {
    font-size: var(--text-2);
    line-height: 1;
    color: var(--person, var(--color-text));
  }
  .counter--xl {
    font-size: min(var(--text-3), 22cqi);
    color: var(--color-text);
  }

  /* --- Perso : nom, sprite (PNG), compteur et bouton ---------------------------- */
  .player {
    display: grid;
    justify-items: center;
    align-content: start;
    gap: var(--space-2);
    color: var(--person, var(--color-text));
  }
  .player > * { background: var(--color-bg); } /* les étoiles ne passent jamais derrière un perso */
  .player__name {
    font-size: var(--text-1);
    text-transform: uppercase;
  }
  .player__sprite {
    display: block;
    block-size: var(--sprite-h);
    inline-size: auto;
    image-rendering: pixelated;
  }
  .player__stats {
    display: flex;
    align-items: center;
    gap: var(--space-3);
  }

  /* --- Ciel : étoiles pixel sur le noir --------------------------------------------
     Chaque « ombre » = 1 pixel d'art. Placées surtout dans les vides de la page ; ce qui tombe derrière
     un bloc est masqué par son fond noir. Scintillement par à-coups (steps), jamais de fondu. */
  .sky {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
  }
  .sky::before,
  .sky::after,
  .sky > i {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    inline-size: var(--px);
    block-size: var(--px);
  }
  /* points et centres des croix : fixes */
  .sky::before {
    color: var(--color-star);
    box-shadow:
      2vw 2vh, 30vw 1vh, 98vw 8vh, 27vw 21vh, 74vw 20vh, 50vw 23vh,
      6vw 55vh, 86vw 62vh, 50vw 65vh, 3vw 76vh, 78vw 98vh, 6vw 21vh,
      91vw 20vh, 50vw 74vh, 5vw 97vh, 93vw 92vh;
  }
  /* branches des croix : elles s'éteignent un instant, la croix redevient un point */
  .sky__glint {
    color: var(--color-star);
    box-shadow:
      calc(6vw - var(--px)) 21vh, calc(6vw + var(--px)) 21vh, 6vw calc(21vh - var(--px)), 6vw calc(21vh + var(--px)),
      calc(91vw - var(--px)) 20vh, calc(91vw + var(--px)) 20vh, 91vw calc(20vh - var(--px)), 91vw calc(20vh + var(--px)),
      calc(50vw - var(--px)) 74vh, calc(50vw + var(--px)) 74vh, 50vw calc(74vh - var(--px)), 50vw calc(74vh + var(--px)),
      calc(5vw - var(--px)) 97vh, calc(5vw + var(--px)) 97vh, 5vw calc(97vh - var(--px)), 5vw calc(97vh + var(--px)),
      calc(93vw - var(--px)) 92vh, calc(93vw + var(--px)) 92vh, 93vw calc(92vh - var(--px)), 93vw calc(92vh + var(--px));
    animation: sky-glint 2.4s steps(1, end) infinite;
  }
  /* quelques points qui clignotent, à un autre rythme */
  .sky__blink {
    color: var(--color-star);
    box-shadow:
      62vw 1vh, 94vw 53vh, 15vw 61vh, 97vw 79vh, 22vw 98vh;
    animation: sky-blink 3.4s steps(1, end) -1.1s infinite;
  }
  /* étoiles lointaines, grises : elles pâlissent par moments */
  .sky::after {
    color: var(--color-star-far);
    box-shadow:
      18vw 1vh, 83vw 1vh, 40vw 22vh, 62vw 22vh, 3vw 30vh, 97vw 33vh,
      2vw 45vh, 98vw 46vh, 30vw 64vh, 70vw 65vh, 12vw 70vh, 88vw 71vh,
      50vw 90vh, 35vw 99vh, 65vw 99vh;
    animation: sky-dim 4.4s steps(1, end) -2s infinite;
  }

  @keyframes sky-glint {
    70% { opacity: 0; }
  }
  @keyframes sky-blink {
    60% { opacity: 0; }
  }
  @keyframes sky-dim {
    50% { opacity: 0.35; }
  }

  @media (prefers-reduced-motion: reduce) {
    .sky::after,
    .sky > i { animation: none; }
  }
}
