/* =====================================================================
   teletexte.css — l'allure du télétexte suisse

   Les 8 couleurs pleines du télétexte (noir, rouge, vert, jaune, bleu,
   magenta, cyan, blanc) sur fond noir, une grille de 40 colonnes.
   Chaque caractère vit dans sa propre case : l'alignement est donc parfait
   quelle que soit la police de l'appareil.
   ===================================================================== */

/* Police « Bedstead » de John Hawkins : une reproduction de la puce SAA5050 des vrais télétextes (programme et nouveaux glyphes dans le domaine public).
   Fichier WOFF2 converti tel quel depuis l'OTF d'origine. Chaque caractère fait 0,6 em de large et 1 em de haut.
   Sans elle, c'est la police à chasse fixe de l'appareil qui sert. */
@font-face {
  font-family: "Teletexte";
  src: url("fonts/bedstead.woff2") format("woff2");
  font-display: block;
}

:root {
  --noir: #000;    --rouge: #f00;   --vert: #0f0;   --jaune: #ff0;
  --bleu: #00f;    --magenta: #f0f; --cyan: #0ff;   --blanc: #fff;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #000;
  color: var(--blanc);
  -webkit-text-size-adjust: 100%;
  touch-action: manipulation;
}

.tele {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}

/* Texte réservé aux lecteurs d'écran : sorti de l'écran mais pas en display:none (sinon il ne serait pas lu) */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---------- L'écran ---------- */
.ecran {
  width: min(100vw, calc((100vh - 150px) * 4 / 3));   /* 4:3 comme un téléviseur, sans dépasser l'écran */
  aspect-ratio: 4 / 3;
  min-height: 0;                                       /* sinon la hauteur du texte (1 em par ligne) agrandit l'écran au-delà du 4:3 */
  container-type: inline-size;                        /* sert à calculer la taille du texte (voir .c) */
  display: flex;
  flex-direction: column;
  background: var(--noir);
  font-family: "Teletexte", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-weight: 400;                                    /* Bedstead n'a qu'une graisse : pas de faux gras */
  user-select: none;
}

.grille {
  display: grid;
  grid-template-columns: repeat(40, 1fr);
  grid-auto-rows: minmax(0, 1fr);                      /* 0 et non « auto » : la hauteur du texte ne doit pas agrandir les lignes */
}
#entete { flex: 1; min-height: 0; }
#corps  { flex: 23; min-height: 0; }

/* --etire = de combien on étire les caractères en hauteur pour remplir la case (les cases sont plus hautes que larges) */
.ecran { --etire: .7; }

/* Sur téléphone (écran étroit et haut) : cases plus hautes, sinon le texte est minuscule */
@media (max-aspect-ratio: 1/1) {
  .ecran { aspect-ratio: 5 / 7; --etire: 1.1; width: 100vw; }
  .tele { justify-content: flex-start; padding-top: max(env(safe-area-inset-top), 4px); }
}

/* Téléphone en paysage : l'écran prend la hauteur disponible, la télécommande passe à droite */
@media (orientation: landscape) and (max-height: 520px) {
  .tele { flex-direction: row; gap: 10px; padding: 0 env(safe-area-inset-right) 0 env(safe-area-inset-left); }
  .ecran { width: min(calc(100vw - 250px), calc(100vh * 4 / 3)); }
  .telecommande { flex-direction: column; gap: 10px; padding: 8px 8px 8px 0; }
  .nav button { height: 34px; min-width: 44px; font-size: 14px; }
  .couleurs { grid-template-columns: repeat(2, 84px); gap: 6px; }
  .couleurs button { height: 34px; }
}

/* Une case = un caractère. La taille du texte suit la largeur de l'écran (100cqw) :
   40 colonnes, et un caractère de Bedstead fait 0,6 em de large : 40 colonnes = 24 em, d'où 100cqw / 24. */
.c {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(100cqw / 24);
  line-height: 1;
  overflow: hidden;
  white-space: pre;
}
.c i { font-style: normal; display: block; transform: scaleY(var(--etire)); }

/* Double hauteur : la case occupe 2 lignes et le caractère est étiré 2 fois plus */
.c.h { grid-row: span 2; }
.c.h i { transform: scaleY(calc(var(--etire) * 2)); }

/* Couleurs du texte (f-) et du fond (b-) */
.f-noir{color:var(--noir)}   .f-rouge{color:var(--rouge)}     .f-vert{color:var(--vert)}   .f-jaune{color:var(--jaune)}
.f-bleu{color:var(--bleu)}   .f-magenta{color:var(--magenta)} .f-cyan{color:var(--cyan)}   .f-blanc{color:var(--blanc)}
.b-noir{background:var(--noir)}   .b-rouge{background:var(--rouge)}     .b-vert{background:var(--vert)}   .b-jaune{background:var(--jaune)}
.b-bleu{background:var(--bleu)}   .b-magenta{background:var(--magenta)} .b-cyan{background:var(--cyan)}   .b-blanc{background:var(--blanc)}

/* Le curseur de saisie d'un numéro de page clignote, comme sur une vraie télécommande */
.clignote { animation: clignote 1s steps(1) infinite; }
@keyframes clignote { 50% { opacity: 0; } }

/* Anneau de focus clavier visible partout (WCAG 2.4.7), jaune comme le texte important : 19:1 sur le noir, 12:1 sur les touches grises */
button:focus-visible { outline: 3px solid var(--jaune); outline-offset: 2px; }

/* ---------- La télécommande ---------- */
.telecommande {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  padding: 0 12px 12px;
}
.nav { display: flex; gap: 8px; }
.nav button, .couleurs button {
  height: 46px;
  border: 0;
  border-radius: 8px;
  background: #222;
  color: var(--blanc);
  font: 700 16px/1 ui-monospace, Menlo, monospace;
  touch-action: manipulation;
}
.nav button { min-width: 58px; }
.nav button:active { background: #555; }
/* Les touches de couleur portent le nom de leur destination (écrit par le JavaScript, il change selon la page) */
.couleurs { display: grid; grid-template-columns: repeat(4, 78px); gap: 8px; }
.couleurs button { font-size: 12px; padding: 0 2px; overflow: hidden; white-space: nowrap; }
.couleurs .rouge { background: var(--rouge); color: var(--noir); }   /* noir sur rouge pur : 5,25:1 (le blanc ne faisait que 4,0:1, sous le minimum WCAG de 4,5:1) */
.couleurs .vert  { background: var(--vert);  color: var(--noir); }
.couleurs .jaune { background: var(--jaune); color: var(--noir); }
.couleurs .cyan  { background: var(--cyan);  color: var(--noir); }
.couleurs button:active { filter: brightness(.6); }

/* Téléphone étroit : six touches (dont PAUSE) doivent tenir sur une ligne */
@media (max-width: 430px) {
  .nav { gap: 5px; }
  .nav button { min-width: 40px; padding: 0 10px; }
}

/* Sur grand écran, la télécommande reste discrète, sur une seule ligne */
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .telecommande { flex-direction: row; gap: 28px; }
  .couleurs button, .nav button { height: 40px; }
}

/* ---------- La barre de couleurs du bas : 4 boutons invisibles posés sur la dernière ligne de l'écran ---------- */
.fastext { position: absolute; left: 0; right: 0; bottom: 0; height: calc(100% / 24); display: grid; grid-template-columns: repeat(4, 1fr); z-index: 2; }
.fastext button { position: relative; padding: 0; border: 0; background: transparent; cursor: pointer; touch-action: manipulation; }
/* zone de toucher agrandie vers le haut (la ligne est mince sur téléphone) */
.fastext button::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 80%; }
.fastext button:hover { background: rgba(255, 255, 255, .22); }
.fastext button:active { background: rgba(0, 0, 0, .4); }
.fastext button:focus-visible { outline: 3px solid #fff; outline-offset: -4px; }

/* ---------- Le panneau de saisie d'un numéro de page ---------- */
.saisie { position: fixed; inset: 0; z-index: 10; display: flex; flex-direction: column; justify-content: flex-end; }
.saisie[hidden] { display: none; }
.saisie:focus { outline: none; }                      /* focus donné par le script à l'ouverture : pas d'anneau sur tout l'écran */
.saisie-fond { position: absolute; inset: 0; background: rgba(0, 0, 0, .93); }
.saisie-corps {
  position: relative;                                  /* au-dessus du fond */
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  max-width: 460px; width: 100%; margin: 0 auto;
  padding: 12px 12px max(12px, env(safe-area-inset-bottom));
  max-height: 100%; overflow-y: auto;
}
.saisie-fermer {
  position: absolute; top: 4px; right: 12px; width: 44px; height: 44px;
  border: 0; background: none; color: #999; font-size: 34px; line-height: 1;
}
.saisie-numero {
  font: 400 clamp(44px, 16vw, 84px)/1.2 "Teletexte", ui-monospace, Menlo, monospace;
  color: var(--jaune); letter-spacing: .12em; padding: 14px 0 6px;
}
.saisie-numero .vide { color: #555; }
.saisie-numero .curseur { animation: clignote 1s steps(1) infinite; border-bottom: 4px solid var(--jaune); }
.saisie-titre { align-self: flex-start; color: #888; font: 12px/1 ui-monospace, Menlo, monospace; text-transform: uppercase; letter-spacing: .1em; }
.saisie-pages { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; width: 100%; }
.saisie-pages button {
  display: flex; flex-direction: column; gap: 3px; align-items: center; justify-content: center;
  height: 50px; border: 1px solid #333; border-radius: 8px; background: #181818; color: var(--blanc);
  font: 12px/1 ui-monospace, Menlo, monospace;
}
.saisie-pages b { color: var(--jaune); font-size: 16px; }
.saisie-couleurs { width: 100%; grid-template-columns: repeat(4, 1fr); }
.saisie-couleurs button { font-size: 13px; }
.saisie-pave { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; width: 100%; padding-top: 4px; }
.saisie-pave button {
  height: 58px; border: 0; border-radius: 10px; background: #2a2a2a; color: var(--blanc);
  font: 600 26px/1 ui-sans-serif, system-ui, sans-serif; touch-action: manipulation;
}
.saisie-pave button:active, .saisie-pages button:active { background: #555; }
@media (max-height: 640px) { .saisie-pave button { height: 46px; font-size: 22px; } .saisie-numero { padding: 6px 0 2px; } }

@media (prefers-reduced-motion: reduce) {
  .clignote { animation: none; }
}

/* Léger quadrillage de lignes, comme un vieux tube cathodique (désactivé si l'appareil le demande) */
.ecran { position: relative; }
.ecran::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,.18) 0, rgba(0,0,0,.18) 1px, transparent 1px, transparent 3px);
}
@media (prefers-reduced-motion: reduce), (prefers-contrast: more) {
  .ecran::after { display: none; }
}

/* ---------- Effet « écran cathodique » (allumé par défaut, bouton CRT ou touche E pour l'éteindre) ----------
   Un halo dans la couleur de chaque caractère, un léger assombrissement des bords (vignettage)
   et des lignes de balayage un peu plus marquées. <html data-crt="off"> l'éteint (voir le script dans index.html). */
:root:not([data-crt="off"]) .c i { text-shadow: 0 0 3px currentColor; }
:root:not([data-crt="off"]) .ecran::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;                                          /* au-dessus du texte, sous la barre Fastext cliquable (z-index 2) */
  pointer-events: none;
  /* Deux couches : un reflet de la lumière sur la vitre (en haut à gauche), puis le vignettage des bords */
  background:
    radial-gradient(ellipse 60% 45% at 28% 18%, rgba(255,255,255,.07), transparent 70%),
    radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,.4) 120%);
  box-shadow: inset 0 0 28px 6px rgba(0,0,0,.45);       /* l'ombre qui suit les coins arrondis donne l'impression d'une vitre bombée */
}
/* Vrai bombé : le texte est déformé en barillet par le filtre SVG « tonneau » (voir index.html).
   .verre remplit l'écran comme le faisaient #entete et #corps avant lui. */
.verre { flex: 1; min-height: 0; display: flex; flex-direction: column; }
:root:not([data-crt="off"]) .verre { filter: url(#tonneau); }
@media (prefers-contrast: more) {
  :root:not([data-crt="off"]) .verre { filter: none; }
}

/* Effet « bombé » : les angles du tube sont arrondis (rayon en %, donc plus large que haut pour rester circulaire en 4:3).
   overflow: hidden rogne aussi les fonds colorés (bandeaux) qui sortiraient des coins. */
:root:not([data-crt="off"]) .ecran,
:root:not([data-crt="off"]) .ecran::before { border-radius: 4% / 5.3%; }
:root:not([data-crt="off"]) .ecran { overflow: hidden; }
@media (max-aspect-ratio: 1/1) {
  :root:not([data-crt="off"]) .ecran,
  :root:not([data-crt="off"]) .ecran::before { border-radius: 5% / 3.6%; }   /* écran 5:7 */
}
:root:not([data-crt="off"]) .ecran::after {
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,.22) 0, rgba(0,0,0,.22) 1px, transparent 1px, transparent 3px);
}
/* Sur téléphone les lettres sont petites : on réduit le halo pour garder le texte net */
@media (max-aspect-ratio: 1/1) {
  :root:not([data-crt="off"]) .c i { text-shadow: 0 0 1.5px currentColor; }
}
/* Pour qui demande plus de contraste : pas d'effet */
@media (prefers-contrast: more) {
  :root:not([data-crt="off"]) .c i { text-shadow: none; }
  :root:not([data-crt="off"]) .ecran::before { display: none; }
  :root:not([data-crt="off"]) .ecran { border-radius: 0; overflow: visible; }
}

/* Léger scintillement du tube : l'écran perd 2 à 3,5 % de luminosité quelques instants, une fois toutes les quelques secondes.
   Seuls quelques sauts d'opacité (steps) : le navigateur ne redessine presque jamais, c'est peu coûteux. */
@keyframes crt-scintille {
  0%, 100% { opacity: 1; }
  41%      { opacity: .965; }
  43%      { opacity: 1; }
  77%      { opacity: .98; }
  79%      { opacity: 1; }
}
:root:not([data-crt="off"]) .ecran { animation: crt-scintille 5s steps(1) infinite; }
/* Pas d'animation pour qui demande moins de mouvement (le scintillement est aussi coupé si l'effet est éteint) */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-crt="off"]) .ecran { animation: none; }
}

/* Bouton pause du défilement : enfoncé (fond clair) quand le défilement est arrêté */
.nav .pause { font-size: 12px; letter-spacing: .5px; padding: 0 10px; }
.nav .pause[aria-pressed="true"] { background: var(--jaune); color: var(--noir); }

/* Le petit bouton qui allume ou éteint l'effet */
.nav .crt { font-size: 13px; letter-spacing: .5px; }
:root[data-crt="off"] .nav .crt { color: #999; }          /* 5,6:1 sur le fond #222 (#777 ne faisait que 3,5:1) */

/* ---------- Easter egg : la mouche (voir « mouche » dans teletexte.js) ----------
   Une couche à part par-dessus l'écran, qui rogne la mouche quand elle entre ou sort. Seule la mouche reçoit les clics. */
.mouche-couche { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 3; }
.mouche { position: absolute; left: 0; top: 0; pointer-events: auto; cursor: pointer; will-change: transform; }
.mouche svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(1px 2px 1.5px rgba(0,0,0,.65)); transition: transform .25s, filter .25s; }
.mouche .corps { fill: #26221f; stroke: #36332f; stroke-width: .6; }         /* gris foncé + liseré clair : une mouche noire serait invisible sur le fond noir du télétexte */
.mouche .oeil { fill: #8a1c10; }
.mouche .pattes { fill: none; stroke: #36332f; stroke-width: .9; stroke-linecap: round; }
.mouche .pb { opacity: 0; }
/* Posée, elle replie ses ailes sur le dos ; en vol elle est « plus haut » (plus grosse, ombre plus décalée) et ses ailes battent */
.mouche .ailes { fill: rgba(225,238,255,.45); transform-origin: 50% 50%; transform: scale(.7); }
.mouche.vol svg { transform: scale(1.35); filter: drop-shadow(4px 8px 3px rgba(0,0,0,.35)); }
.mouche.vol .ailes { transform: scale(1.5, 1.1); animation: mouche-bat .06s steps(1) infinite alternate; }
.mouche.vol .pattes { opacity: 0; }
@keyframes mouche-bat { 0% { opacity: .9; } 100% { opacity: .35; } }
/* Marche : deux jeux de pattes en alternance */
.mouche.marche .pa, .mouche.marche .pb { animation: mouche-pas .22s steps(1) infinite; }
.mouche.marche .pb { animation-delay: -.11s; }
@keyframes mouche-pas { 0% { opacity: 1; } 50% { opacity: 0; } }
/* Pause « se frotter les pattes » : un petit frétillement */
.mouche.frotte svg { animation: mouche-frotte .18s steps(1) infinite; }
@keyframes mouche-frotte { 0% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } }
