/* landing/histoires/app.css — Bibliothèque d'histoires, outil offert Direkol
 *
 * Deux interfaces dans une seule page : l'écran des enfants (grille d'images,
 * lecture, rien d'autre) et l'écran de l'enseignant (import, tri, choix des
 * histoires visibles).
 *
 * CIBLE : iPad sous iOS 12 (Safari 12). Contraintes qui expliquent des choix
 * qui paraîtraient datés ailleurs :
 *   — `gap` ne marche PAS en flexbox avant Safari 14.1 : espacement en margin,
 *     ou grille CSS avec `grid-gap` (celle-là est bien supportée depuis 10.1).
 *   — `clamp()` est Safari 13.1 : les tailles fluides passent par des media
 *     queries et des calc(), jamais par clamp().
 *   — `aspect-ratio` est Safari 15 : les vignettes gardent leur format par le
 *     bourrage en pourcentage (padding-top) et une image en absolute.
 *   — `touch-action` est Safari 13 : le double-tap-zoom est écarté par le
 *     viewport de la page, pas par le CSS.
 * Aucune de ces trois modernités ne doit être réintroduite sans vérifier
 * qu'iOS 12 n'est plus une cible.
 */

/* ── Jetons ──────────────────────────────────────────────────────────────── */
:root {
  --v: #7B5BF0;
  --vd: #6A4AE0;
  --v-soft: #f3efff;
  --navy: #1A0F3D;
  --g: #1f2937;
  --g2: #6b7280;
  --brd: #e5e7eb;
  --rouge: #E24A4A;
  --fd: 'Inter Tight', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  /* Retraits d'encoche : l'app tourne en plein écran depuis l'écran d'accueil. */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  overflow: hidden;               /* l'app ne scrolle pas, ses écrans si */
  background: #FBF7FF;
  color: var(--g);
  font-family: var(--fd);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

/* Des doigts d'enfants sur un écran tactile : ni sélection de texte, ni menu
   contextuel au maintien du doigt (qui volerait l'appui long du bouton
   enseignant). Le panneau enseignant relève l'interdit là où on saisit du texte. */
body {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

button { font-family: inherit; color: inherit; }

/* ── Écrans ──────────────────────────────────────────────────────────────── */
.screen {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  display: none;
  -webkit-overflow-scrolling: touch;
}
.screen.is-on { display: block; }

/* ── Écran enfant : la grille ────────────────────────────────────────────── */
#screenHome { overflow-y: auto; }

.grid {
  display: grid;
  /* Sans ça, la grille étire chaque carte à la hauteur de la plus haute de sa
     rangée — et un <button> CENTRE verticalement son contenu : un titre sur
     deux lignes suffisait à décaler les vignettes voisines de dix pixels, et
     à rogner celles du bord. Les cartes gardent leur hauteur propre, les
     images restent alignées. */
  -webkit-box-align: start; align-items: start;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-gap: 22px;
  gap: 22px;
  padding: calc(22px + var(--safe-t)) calc(22px + var(--safe-r))
           calc(112px + var(--safe-b)) calc(22px + var(--safe-l));
  margin: 0 auto;
  max-width: 1400px;
}
/* 210 px et non 230 : le seuil décide du nombre de colonnes sur la seule
   tablette qui compte ici. Un iPad tenu debout donne trois colonnes, couché
   quatre ; à 230 px il n'en donnait que deux debout, et quatre histoires
   remplissaient tout l'écran. */
@media (min-width: 700px) {
  .grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); grid-gap: 28px; gap: 28px; }
}

/* Une carte = une histoire. Toute la carte est la cible tactile ; rien d'autre
   n'est cliquable sur cet écran. */
.card {
  display: block; width: 100%; padding: 0;
  border: 0; border-radius: 22px;
  background: #fff;
  box-shadow: 0 2px 4px rgba(26, 15, 61, .06), 0 10px 26px rgba(123, 91, 240, .10);
  overflow: hidden;
  text-align: center;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
  transition: -webkit-transform 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.card:active {
  -webkit-transform: scale(.96);
  transform: scale(.96);
  box-shadow: 0 1px 2px rgba(26, 15, 61, .08);
}

.card-img {
  display: block;                 /* un <span> reste inline, et le bourrage en
                                     pourcentage ci-dessous n'y ferait aucune
                                     hauteur : la vignette serait un trait */
  position: relative;
  width: 100%;
  padding-top: 75%;               /* 4:3, faute d'aspect-ratio sur iOS 12 */
  background: var(--v-soft);
  overflow: hidden;
}
.card-img img {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* Vignette de repli quand l'enseignant n'a pas mis d'image : une pastille de
   couleur et une note de musique. Un enfant doit pouvoir distinguer deux
   histoires même sans photo — la teinte est tirée du titre, donc stable. */
.card-fallback {
  position: absolute; top: 0; left: 0; right: 0; bottom: 0;
  display: -webkit-box; display: flex;
  -webkit-box-align: center; align-items: center;
  -webkit-box-pack: center; justify-content: center;
}
.card-fallback svg { width: 46%; height: 46%; opacity: .85; }

.card-title {
  display: block;
  padding: 14px 12px 18px;
  font-size: 1.15rem; font-weight: 700; line-height: 1.25;
  color: var(--navy);
  word-wrap: break-word;
}
@media (min-width: 700px) { .card-title { font-size: 1.3rem; } }

/* Écran vide : ce que voit l'enseignant à la première ouverture. */
.empty {
  display: none;
  position: absolute; top: 50%; left: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  width: 86%; max-width: 460px;
  text-align: center;
}
.empty.is-on { display: block; }
.empty h1 { font-size: 1.5rem; margin: 0 0 10px; color: var(--navy); }
.empty p { font-size: 1rem; line-height: 1.6; color: var(--g2); margin: 0 0 22px; }
.empty svg { width: 84px; height: 84px; color: var(--v); opacity: .5; margin-bottom: 16px; }

/* ── Le bouton de l'enseignant ───────────────────────────────────────────── */
/* Discret et à l'appui maintenu : un enfant de maternelle tape, il ne maintient
   pas une seconde et demie. L'anneau qui se remplit dit à l'adulte que c'est en
   cours ; il ne dit rien à l'enfant qui aurait posé un doigt par hasard. */
.teacher-btn {
  position: fixed;
  right: calc(16px + var(--safe-r));
  bottom: calc(16px + var(--safe-b));
  width: 62px; height: 62px;
  border: 0; border-radius: 50%;
  background: rgba(26, 15, 61, .05);
  color: rgba(26, 15, 61, .30);
  padding: 0;
  -webkit-appearance: none; appearance: none;
  cursor: pointer;
}
.teacher-btn svg.gear { position: absolute; top: 19px; left: 19px; width: 24px; height: 24px; }
.teacher-btn svg.ring { position: absolute; top: 0; left: 0; width: 62px; height: 62px; -webkit-transform: rotate(-90deg); transform: rotate(-90deg); }
.teacher-btn svg.ring circle {
  fill: none; stroke: var(--v); stroke-width: 4; stroke-linecap: round;
  stroke-dasharray: 176; stroke-dashoffset: 176;
}
.teacher-btn.is-holding svg.ring circle {
  stroke-dashoffset: 0;
  -webkit-transition: stroke-dashoffset 1500ms linear;
  transition: stroke-dashoffset 1500ms linear;
}

/* ── Écran de lecture ────────────────────────────────────────────────────── */
/* L'image passe en petit, au centre. Un seul bouton, et il arrête. Rien
   d'autre n'est atteignable : pas de pause, pas de piste suivante, pas de
   réglage de volume — l'enfant ne peut pas se coincer dans un état. */
#screenPlay {
  background: var(--navy);
  color: #fff;
  text-align: center;
}
.play-wrap {
  position: absolute; top: 50%; left: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  width: 100%;
  padding: 0 24px;
}

.play-cover {
  position: relative;
  width: 190px; height: 190px;
  margin: 0 auto;
  border-radius: 28px;
  overflow: hidden;
  background: rgba(255, 255, 255, .10);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
}
@media (min-height: 700px) { .play-cover { width: 240px; height: 240px; } }
/* `contain` et non `cover` comme sur la grille : ici l'image est regardée, et
   une couverture de livre est presque toujours en hauteur — la recadrer au
   carré lui coupe le titre et la moitié du dessin. Sur la grille, au contraire,
   `cover` remplit la carte : l'enfant y reconnaît une vignette, il ne la lit
   pas. */
.play-cover img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Respiration lente de la pochette : le seul signe, sans texte, que le son
   tourne — utile quand le volume de l'iPad est au minimum. */
@-webkit-keyframes souffle { 0%,100% { -webkit-transform: scale(1); } 50% { -webkit-transform: scale(1.035); } }
@keyframes souffle { 0%,100% { transform: scale(1); } 50% { transform: scale(1.035); } }
.play-cover.is-playing { -webkit-animation: souffle 3.6s ease-in-out infinite; animation: souffle 3.6s ease-in-out infinite; }

.play-title {
  font-size: 1.35rem; font-weight: 700; line-height: 1.3;
  margin: 26px auto 0; max-width: 520px;
}

/* Avancement : une barre, pas un compteur. « C'est bientôt fini » se lit, ne se
   compte pas, à cet âge. */
.play-bar {
  width: 220px; height: 8px;
  margin: 20px auto 0;
  border-radius: 4px;
  background: rgba(255, 255, 255, .18);
  overflow: hidden;
}
.play-bar span {
  display: block; height: 100%; width: 0;
  border-radius: 4px;
  background: #FFD23F;
}

/* Une commande dans chaque coin bas, et pas rouges. Ces commandes ne sont pas
   l'objet de l'écran : l'enfant écoute. Un gros rond rouge au centre attirait le
   doigt sur la seule action qui interrompt l'histoire — c'était en faire le
   sujet de la page.
   Séparées aux deux bords plutôt que côte à côte : sur une tablette tenue à
   deux mains, chaque pouce tombe sur la sienne, et deux cibles éloignées de
   toute la largeur de l'écran ne se confondent pas. C'est la position, plus que
   l'icône, qui les distingue pour un enfant qui ne lit pas.
   64 px, bien au-dessus des 44 px qu'un doigt réclame. */
.act-btn {
  position: fixed;
  bottom: calc(20px + var(--safe-b));
  width: 64px; height: 64px;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .13);
  color: #fff;
  padding: 0;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
  transition: -webkit-transform 120ms ease, transform 120ms ease, background 120ms ease;
}
.act-btn:active {
  -webkit-transform: scale(.92); transform: scale(.92);
  background: rgba(255, 255, 255, .30);
}
.act-btn svg { width: 24px; height: 24px; }

.restart-btn { left: calc(20px + var(--safe-l)); }
/* L'arrêt est la commande la plus demandée : un rien plus marquée que le retour
   au début, sans pour autant redevenir un appel au doigt. */
.stop-btn { right: calc(20px + var(--safe-r)); background: rgba(255, 255, 255, .20); }

/* ── Panneau enseignant ──────────────────────────────────────────────────── */
#screenTeacher {
  background: #fff;
  overflow-y: auto;
  -webkit-user-select: text; user-select: text;
  -webkit-touch-callout: default;
}
.t-head {
  position: -webkit-sticky; position: sticky; top: 0; z-index: 5;
  background: #fff;
  border-bottom: 1px solid var(--brd);
  padding: calc(14px + var(--safe-t)) calc(18px + var(--safe-r)) 14px calc(18px + var(--safe-l));
  display: -webkit-box; display: flex;
  -webkit-box-align: center; align-items: center;
}
.t-head h1 { -webkit-box-flex: 1; flex: 1; font-size: 1.1rem; margin: 0; color: var(--navy); }
.t-body {
  max-width: 780px; margin: 0 auto;
  padding: 22px calc(18px + var(--safe-r)) calc(40px + var(--safe-b)) calc(18px + var(--safe-l));
}

.btn {
  display: inline-block;
  border: 0; border-radius: 12px;
  padding: 13px 20px;
  font-size: .95rem; font-weight: 700;
  background: var(--v); color: #fff;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.btn:active { background: var(--vd); }
.btn--ghost { background: var(--v-soft); color: var(--v); }
.btn--wide { display: block; width: 100%; padding: 17px; font-size: 1.02rem; }

/* Une ligne = une histoire de la banque. La coche à gauche décide de sa
   présence sur l'écran des enfants ; elle ne supprime rien. */
.t-list { list-style: none; margin: 22px 0 0; padding: 0; }
.t-item {
  display: -webkit-box; display: flex;
  -webkit-box-align: center; align-items: center;
  border: 1px solid var(--brd); border-radius: 14px;
  padding: 12px;
  margin-bottom: 12px;
  background: #fff;
}
.t-item.is-hidden { background: #fafafa; border-style: dashed; }
.t-item.is-hidden .t-thumb, .t-item.is-hidden .t-name { opacity: .45; }

.t-check {
  -webkit-flex-shrink: 0; flex-shrink: 0;
  width: 44px; height: 44px;      /* 44, et pas 34 : au-dessous, le doigt rate */
  margin-right: 12px;
  border: 2px solid var(--brd); border-radius: 10px;
  background: #fff; color: #fff;
  padding: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.t-check.is-on { background: var(--v); border-color: var(--v); }
.t-check svg { width: 18px; height: 18px; display: none; }
.t-check.is-on svg { display: inline; }

.t-thumb {
  display: block;
  position: relative;
  -webkit-flex-shrink: 0; flex-shrink: 0;
  width: 62px; height: 62px;
  margin-right: 12px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--v-soft);
  border: 0; padding: 0;
  cursor: pointer;
}
.t-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.t-thumb-hint {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: rgba(26, 15, 61, .62);
  color: #fff;
  font-size: .58rem; font-weight: 700;
  padding: 2px 0;
  letter-spacing: .02em;
}

.t-mid { -webkit-box-flex: 1; flex: 1; min-width: 0; }
.t-name {
  display: block; width: 100%;
  border: 1px solid transparent; border-radius: 8px;
  padding: 5px 7px;
  font-family: inherit; font-size: .97rem; font-weight: 600;
  color: var(--navy);
  background: transparent;
  -webkit-appearance: none; appearance: none;
}
.t-name:focus { border-color: var(--v); background: #fff; outline: none; }
.t-meta { font-size: .76rem; color: var(--g2); padding: 0 7px; }

.t-acts { -webkit-flex-shrink: 0; flex-shrink: 0; margin-left: 8px; }
.t-icon {
  display: block;
  /* 44 px de côté, dessin inchangé : c'est la ZONE qui manquait, pas l'icône.
     À 34 × 30, deux commandes distinctes tenaient dans la pulpe d'un doigt —
     on visait la corbeille et on touchait la rotation, ou rien. */
  width: 44px; height: 44px;
  border: 0; border-radius: 10px;
  background: transparent; color: var(--g2);
  padding: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.t-icon:active { background: var(--v-soft); }
.t-icon svg { width: 18px; height: 18px; }
.t-icon.t-del { color: var(--rouge); }
.t-icon.t-del:active { background: #FDECEC; }
.t-icon[disabled] { opacity: .22; }

/* La ligne dont la suppression attend un oui. La question remplace les quatre
   commandes : pas de dialogue système, donc rien à rater et rien qui puisse
   rester muet selon le navigateur. */
.t-item.is-doomed { border-color: var(--rouge); background: #FFF7F7; }
.t-confirm {
  -webkit-flex-shrink: 0; flex-shrink: 0;
  display: -webkit-box; display: flex;
  -webkit-box-align: center; align-items: center;
  margin-left: 8px;
}
/* La question remplace le champ de titre : posée à côté, elle poussait le titre
   hors de la ligne, coupé net au milieu d'un mot. Le titre y est repris entre
   guillemets, tronqué proprement s'il est long. */
.t-doom {
  display: block;
  padding: 5px 7px;
  font-size: .97rem; font-weight: 700; color: var(--rouge);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.t-yes, .t-no {
  border: 0; border-radius: 10px;
  min-width: 62px; height: 44px;
  margin-left: 8px;
  font-family: inherit; font-size: .92rem; font-weight: 700;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.t-yes { background: var(--rouge); color: #fff; }
.t-no { background: var(--brd); color: var(--g); }

/* Sur un écran étroit, la question passe sous le titre au lieu d'écraser tout
   le reste de la ligne. */
@media (max-width: 560px) {
  .t-yes, .t-no { min-width: 54px; }
}

.t-note {
  border-radius: 12px;
  background: var(--v-soft);
  padding: 14px 16px;
  margin: 24px 0 0;
  font-size: .84rem; line-height: 1.6; color: #4b3f6b;
}
.t-note b { color: var(--navy); }
.t-note + .t-note { margin-top: 12px; }
.t-quota { font-size: .82rem; color: var(--g2); margin: 16px 0 0; }
.t-quota b { color: var(--navy); }

.t-empty { text-align: center; color: var(--g2); font-size: .95rem; padding: 30px 0 6px; }

/* Bandeau d'import : l'attente compte, un mp3 de 20 Mo n'est pas instantané
   sur un iPad de 2018. */
.t-busy {
  display: none;
  border-radius: 12px; background: var(--navy); color: #fff;
  padding: 13px 16px; margin: 16px 0 0;
  font-size: .88rem; font-weight: 600;
}
.t-busy.is-on { display: block; }
.t-busy.is-bad { background: var(--rouge); }

/* État hors connexion. Une pastille et une phrase : la seule question que se
   pose l'enseignant avant d'emporter la tablette en classe est « est-ce que je
   peux couper le wifi ? ». */
.t-net {
  border-radius: 12px;
  padding: 12px 14px 12px 34px;
  margin: 14px 0 0;
  position: relative;
  font-size: .84rem; line-height: 1.55;
}
.t-net:before {
  content: ''; position: absolute; left: 14px; top: 17px;
  width: 10px; height: 10px; border-radius: 50%;
}
.t-net.is-ok { background: #EAF7EF; color: #1B5E32; }
.t-net.is-ok:before { background: #2E9E5B; }
.t-net.is-wait { background: #FFF6E5; color: #7A5A12; }
.t-net.is-wait:before { background: #E0A020; }
.t-net.is-ko { background: #FDECEC; color: #8C2B2B; }
.t-net.is-ko:before { background: var(--rouge); }

/* Champ de fichiers rendu invisible mais TAPABLE, étalé sur toute la surface de
   son étiquette. Il ne doit être ni `display:none`, ni réduit à un pixel : dans
   ces deux états il ne reçoit plus l'appui, et l'ouverture du sélecteur devrait
   alors venir d'un `.click()` en JavaScript — ce qu'iOS refuse dans une app
   posée sur l'écran d'accueil. Le `font-size` démesuré agrandit le bouton natif
   que certains WebKit sont seuls à rendre tapable à l'intérieur du champ. */
.file-label { position: relative; overflow: hidden; text-align: center; cursor: pointer; }
.file-label input[type="file"] {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
  font-size: 200px;
}

@media (prefers-reduced-motion: reduce) {
  .card, .stop-btn { transition: none; }
  .play-cover.is-playing { -webkit-animation: none; animation: none; }
  .teacher-btn.is-holding svg.ring circle { -webkit-transition: none; transition: none; }
}
