/* wondarchive — l'animation d'accueil, en plan-sequence.
   Un seul monde, une seule page : rien ne se coupe, rien n'apparait par
   decoupe. La camera (translation + echelle sur .monde) et l'opacite des
   calques font tout. Le JS pose des valeurs a chaque image ; ici, il n'y a
   donc AUCUNE transition ni animation CSS — sinon les deux se battraient.
   Deux polices d'ecriture hebergees ici (licence OFL), aucun CDN. */
@font-face { font-family: 'Homemade Apple'; src: url('/static/polices/homemade-apple.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Mrs Saint Delafield'; src: url('/static/polices/mrs-saint-delafield.woff2') format('woff2'); font-weight: 400; font-display: swap; }

.anim-boite { width: 100%; max-width: 550px; height: 450px; position: relative; margin-left: auto; }
.anim-boite #anim { position: absolute; left: 0; top: 0; width: 550px; height: 450px; transform-origin: 0 0; overflow: hidden; border-radius: 10px; background: #16181c; box-shadow: 0 14px 36px rgba(0,0,0,.35); font-family: var(--ui, system-ui, sans-serif); user-select: none; }
/* le fond et les coins arrondis sont poses par le script : ils s'effacent avec le bureau */
#anim * { box-sizing: border-box; }
/* Tant que les polices d'ecriture ne sont pas la, le cadre reste vide : sans
   cela on voit le manuscrit se recomposer sous nos yeux au premier plan. */
#anim.chargement > * { visibility: hidden; }
#anim p, #anim span, #anim small, #anim div { max-width: none; }

/* ---------------------------------------------------------------- le monde */
/* Une grande surface ou tout vit aux memes coordonnees : la page, ses voisines,
   le bureau, le volet de traduction, les etiquettes. La camera s'y deplace. */
#anim .monde { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
/* Le plateau, vu de dessus : des lattes, leurs joints, la veinure, et une
   lumiere qui vient du haut a gauche — la meme que celle des ombres portees. */
#anim .bois { position: absolute; inset: 0; background:
    radial-gradient(ellipse 1100px 820px at var(--foyer-x, 38%) 30%, rgba(255,236,200,.20), rgba(0,0,0,0) 62%),
    repeating-linear-gradient(91deg, rgba(0,0,0,.55) 0 2px, rgba(0,0,0,0) 2px 4px, rgba(255,255,255,.035) 4px 6px, rgba(0,0,0,0) 6px 230px),
    repeating-linear-gradient(91deg, rgba(255,255,255,.022) 0 3px, rgba(0,0,0,.03) 3px 9px),
    linear-gradient(163deg, #55452f, #3b2f21 45%, #241b13); }
#anim .poste { position: absolute; width: 300px; height: 424px; }
#anim .bois > .poste { pointer-events: none; }
#anim .poste .carton { position: absolute; left: -250px; top: 236px; width: 232px; height: 178px; border-radius: 3px; transform: rotate(-4deg);
  background: linear-gradient(158deg, #8a7047, #6b5636 46%, #4d3d26);
  box-shadow: 14px 18px 30px rgba(0,0,0,.55), inset 0 0 0 6px rgba(0,0,0,.12); }
#anim .poste .carton::before { content: ''; position: absolute; left: 14px; right: 14px; top: 16px; bottom: 16px; border: 2px solid rgba(0,0,0,.22); border-radius: 2px; }
#anim .poste .carton::after { content: ''; position: absolute; left: 52px; right: 52px; top: 72px; height: 30px; background: rgba(228,218,194,.55); border-radius: 2px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.2); }
#anim .poste .rond { position: absolute; left: 318px; top: 196px; width: 96px; height: 92px; border-radius: 50%; border: 5px solid rgba(58,32,12,.42); border-top-color: rgba(58,32,12,.16); opacity: .75; filter: blur(.7px); }
#anim .poste .mug { position: absolute; left: 336px; top: -46px; }

/* ---------------------------------------------------------------- la page */
#anim .page { position: absolute; width: 300px; height: 424px; padding: 20px 22px 18px 26px; color: #171210; border-radius: 1px; overflow: hidden; transform-origin: 50% 50%;
  background-color: #ece2c6;
  background-image: radial-gradient(ellipse at 18% 12%, rgba(150,110,50,.18), transparent 32%), radial-gradient(ellipse at 85% 75%, rgba(140,100,40,.22), transparent 38%), linear-gradient(180deg, #efe6cf, #e5d9b8);
  box-shadow: 10px 14px 26px rgba(0,0,0,.55); }
#anim .page::before { content: ''; position: absolute; inset: 0; opacity: .35; mix-blend-mode: multiply; pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.45 0 0 0 0 0.35 0 0 0 0 0.2 0 0 0 .55 0'/></filter><rect width='200' height='200' filter='url(%23g)'/></svg>"); }
#anim .corps { position: relative; z-index: 1; font-family: 'Homemade Apple', cursive; font-size: 6.6px; line-height: 1.55; letter-spacing: -.03em; color: var(--encre-page, #2f2820); text-shadow: 0 0 .45px currentColor; }
#anim .corps p { margin: 0 0 5px; font-size: inherit; line-height: inherit; color: inherit; }
#anim .corps .bloc { margin-bottom: 7px; }
#anim .corps .droite { text-align: right; }
#anim .corps .sign { text-align: right; margin-top: 4px; font-family: 'Mrs Saint Delafield', cursive; font-size: 13px; }
#anim .corps .ligne { display: inline-block; }
#anim .corps .rature { position: relative; }
#anim .corps .rature::after { content: ''; position: absolute; left: -1px; right: -1px; top: 55%; height: 1.6px; background: currentColor; transform: rotate(-3deg); }
#anim .tampon { position: absolute; right: 14px; top: 56px; width: 50px; height: 50px; border: 2px solid rgba(150,40,30,.5); border-radius: 50%; font: 700 6px/1.2 var(--mono, monospace); color: rgba(150,40,30,.6); display: grid; place-items: center; text-align: center; transform: rotate(12deg); mix-blend-mode: multiply; z-index: 2; }
#anim .tampon span { display: block; width: 38px; border-top: 1px solid rgba(150,40,30,.5); border-bottom: 1px solid rgba(150,40,30,.5); padding: 2px 0; }
#anim .pli { position: absolute; left: 0; right: 0; top: 212px; height: 1px; background: linear-gradient(90deg, transparent, rgba(60,40,20,.25), transparent); z-index: 2; }

/* la prise de vue : le cadre blanc du polaroid, puis l'eclair du flash */
#anim .polaroid { position: absolute; border: 30px solid #f6f3ec; border-bottom-width: 88px; border-radius: 3px; box-shadow: 12px 16px 30px rgba(0,0,0,.6);
  background:
    repeating-linear-gradient(91deg, rgba(0,0,0,.5) 0 2px, rgba(0,0,0,0) 2px 4px, rgba(255,255,255,.03) 4px 6px, rgba(0,0,0,0) 6px 230px),
    linear-gradient(163deg, #55452f, #3b2f21 45%, #241b13); }
/* La legende, ecrite a la main dans la large marge du bas — la seule raison
   d'etre de cette marge sur un vrai polaroid. */
#anim .polaroid .legende { position: absolute; left: 0; right: 0; bottom: -88px; height: 88px;
  display: flex; align-items: center; justify-content: center;
  font: 400 27px/1 'Homemade Apple', cursive; color: #26324a; transform: rotate(-1.1deg); }
#anim .flash { position: absolute; inset: 0; background: #fff; z-index: 5; pointer-events: none; }

/* la lecture : une ligne de lumiere, et le voile qu'elle laisse */
#anim .scan { position: absolute; background: #d9a441; box-shadow: 0 0 14px 3px rgba(217,164,65,.75); will-change: transform; z-index: 4; }
/* La seconde passe est bleue — la couleur de la marque : on lit en or, on
   traduit en bleu. */
#anim .scan.bleu { background: #3d8bde; box-shadow: 0 0 14px 3px rgba(61,139,222,.75); }
#anim .manus { position: absolute; font: 500 11px/1 var(--mono, monospace); color: #f1eee7; background: rgba(15,16,19,.86); border: 1px solid #2e323a; border-radius: 4px; padding: 5px 7px; white-space: nowrap; }


/* les deux drapeaux des onglets, et celui de la page traduite */
#anim .drapeau.fr { background: linear-gradient(90deg, #23407a 0 33.3%, #f4f2ec 33.3% 66.6%, #a03a28 66.6%); }
#anim .drapeau.de { background: linear-gradient(180deg, #1b1a18 0 33.3%, #a03a28 33.3% 66.6%, #d9a441 66.6%); }

/* la traduction, ecrite a la place du manuscrit : le papier blanchit dessous */
#anim .blanchit { position: absolute; inset: 0; background: #fff; z-index: 1; }
/* Le second calque blanc s'intercale entre les deux textes : il efface la
   transcription allemande au passage de la ligne bleue, sans quoi elle
   transparaitrait entre les lignes du francais. */
#anim .blanchit.deux { z-index: 2; }
/* Les deux passes se distinguent par l'ENCRE, pas seulement par la barre qui
   les révèle. La transcription sort en anthracite — une machine à écrire, un
   ruban noir un peu gris. La traduction, elle, sort dans le bleu de la marque :
   #0a5baa, la teinte médiane du W de logo-source.png (6,8:1 sur blanc, donc
   lisible). Le bleu de la barre de scan reste plus clair, lui : c'est un trait
   lumineux, pas de l'encre. */
#anim .page > .fr.de { color: #2f3438; }
#anim .page > .fr { position: absolute; left: 26px; right: 24px; top: 24px; bottom: 16px; z-index: 2; font: 400 6.4px/1.55 var(--mono, monospace); color: #0a5baa; white-space: pre-wrap; word-break: break-word; }
/* Ce qu'on lit, dit au-dessus de la page : pas un bouton, un intitule. Les deux
   sont poses au meme endroit et se relaient en fondu. */
#anim .titre-volet { position: absolute; height: 28px; }
#anim .titre-volet span { position: absolute; left: 0; right: 0; top: 0;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  font: 500 21px/1.3 var(--ui, sans-serif); color: #f1eee7; white-space: nowrap; }
#anim .titre-volet .drapeau { width: 21px; height: 14px; border-radius: 2px; display: block; box-shadow: 0 1px 2px rgba(0,0,0,.4); }

/* La fiche schematique : ce qui reste lisible quand la page devient une vignette.
   Les mesures de la maquette (barre 15, interligne 12, marges 22/18 sur 200 px
   de large) multipliees par 1,5, la page heroine faisant 300 px. Le bloc des
   lignes est en `display: contents` : les lignes suivent alors le meme `gap` que
   le titre et les etiquettes, si bien que l'interligne ne change JAMAIS — c'est
   la hauteur du bloc qui varie, d'une fiche a l'autre. */
#anim .schema { position: absolute; inset: 0; background: #fff; padding: 33px 27px; z-index: 3; display: flex; flex-direction: column; align-items: stretch; gap: 18px; }
#anim .schema .blk { display: contents; }
#anim .schema .t, #anim .schema .l, #anim .schema .e { height: 22.5px; border-radius: 4.5px; }
#anim .schema .t { background: #8b867c; }
#anim .schema .l { background: #dcd7cc; }
#anim .schema .bas { display: flex; gap: 10.5px; margin-top: 9px; }
#anim .schema .e { background: #EBD19F; }

/* les etiquettes de la fiche : un libelle, une valeur, un trait vers la page */
#anim .tag { position: absolute; font: 600 12px/1.15 var(--mono, monospace); color: #f1eee7; background: rgba(22,24,28,.94); border: 1px solid #3a4049; border-radius: 5px; padding: 6px 9px; white-space: nowrap; box-shadow: 0 6px 16px rgba(0,0,0,.5); }
#anim .tag em { display: block; font: 500 9px/1 var(--mono, monospace); font-style: normal; color: #d9a441; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 4px; }
#anim .tag::after { content: ''; position: absolute; top: 50%; width: 22px; height: 1.5px; background: #d9a441; opacity: .7; }
#anim .tag.d::after { right: 100%; }
#anim .tag.g::after { left: 100%; }

/* les pages voisines : le fonds, deja la, qui se decouvre en reculant */
/* Les liseres sont donnes dans le repere du monde : au recul maximal l'echelle
   est de 0,096, si bien qu'un trait de 19 px y fait moins de 2 px a l'ecran.
   Aucune ombre portee : deux cents ombres floutees a composer par image, c'est
   la quatrieme cause de saccade — et sur fond sombre, la gouttiere suffit. */
#anim .tuile { position: absolute; width: 300px; height: 424px; border-radius: 1px; background-size: cover; }
#anim .tuile.on { z-index: 2; box-shadow: 0 0 0 19px #d9a441, 0 0 160px rgba(217,164,65,.5); }
/* Ce que la recherche ne retient pas ne disparait pas : un seul voile, pose
   au-dessus du fonds, l'eteint d'un coup ; les pages retenues repassent par
   dessus. On voit donc toujours le fonds entier, et ou les trouvailles se
   situent dedans — c'est ce qui distingue une recherche d'un filtre. */
#anim .voile-fonds { position: absolute; left: 0; top: 0; z-index: 1; background: #16181c; }

/* ------------------------------------------------- ce qui est pose sur le cadre */
/* Le fonds vit dans le monde : il ne s'arrete pas de lui-meme au bord du cadre,
   et la colonne suivante deborde toujours de quelques pixels. Cette bordure lui
   rend ses marges, les memes des trois cotes, et c'est ce qui fait tomber
   exactement seize colonnes entieres. En bas, rien : le fonds doit deborder,
   comme un inventaire qu'on parcourt. */
#anim .cadre { position: absolute; inset: 0; border: solid #16181c; border-width: 76px 16px 0; pointer-events: none; }

/* La recherche : une barre, et rien d'autre — pas d'application autour. */
#anim .cherche { position: absolute; left: 50%; top: 18px; width: 400px; height: 40px; border-radius: 20px;
  background: rgba(12,13,16,.94); border: 1px solid #3a4049; box-shadow: 0 14px 34px rgba(0,0,0,.6);
  display: flex; align-items: center; gap: 10px; padding: 0 16px;
  font: 500 13px/1 var(--mono, monospace); color: #f1eee7; white-space: nowrap; }
#anim .cherche .loupe { width: 15px; height: 15px; flex: none; color: #8f939b; }
#anim .cherche .res { margin-left: auto; color: #d9a441; font-weight: 600; }

/* La marque, en grand : c'est sur elle qu'on finit. */
#anim .fin { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; }
/* Le plan fige sur la marque : le cadre entier devient le bouton qui le rejoue. */
#anim.fini { cursor: pointer; }
#anim.fini .fin .marque { transition: transform .25s ease; }
#anim.fini:hover .fin .marque { transform: scale(1.03); }
/* Le cadre est calé sur les VRAIES limites du symbole dans logo-source.png
   (x 77..1178, y 355..898 sur 1254 px), avec 4 px de marge de chaque côté — et
   sans `overflow: hidden` : le reste de l'image est transparent, il n'y a donc
   rien à masquer, et plus rien qui puisse rogner le logo d'une fraction de
   pixel.
   LA BOÎTE DU SYMBOLE NE BOUGE PLUS D'UNE VERSION À L'AUTRE (18 septembre
   2026) : `outils/construire-logos.py` repose le symbole au même bord gauche,
   à la même largeur et sur le même axe, et seule sa HAUTEUR suit le rapport.
   Le v5 (1,952) rend 564 px de haut là où le v2 en rendait 616 : le cadre était
   resté celui du v2 et portait donc dix pixels d'air mort en haut comme en bas.
   v7 (21 septembre 2026, rapport 1,7836) : le symbole occupe y 318..935 dans le
   carré, d'où 192 px de cadre et un décalage de -91. La LARGEUR ne bouge jamais
   (337), puisque `construire-logos.py` repose le symbole au même bord gauche et
   à la même largeur ; seules la hauteur et le décalage vertical suivent.
   375 / 1254 = 0,2990 — c'est ce facteur qui traduit les limites ci-dessus en
   pixels d'écran. */
#anim .fin .marque { width: 337px; height: 192px; position: relative; }
/* `max-width: none` N'EST PAS UNE PRECAUTION, C'EST UNE CORRECTION (18 septembre
   2026). La feuille porte un `img { max-width: 100%; height: auto }` global : il
   ramenait cette image a la largeur du cadre — 337 px — pendant que le
   `height: 375px` ecrit ici tenait bon. Le symbole du plan final etait donc
   ECRASE de 10 % en largeur (337 / 375 = 0,899) depuis toujours, et rien ne le
   signalait : une image deformee ne leve pas d'erreur, elle se contente d'etre
   un peu trop etroite. */
#anim .fin .marque img { position: absolute; left: -19px; top: -91px;
  width: 375px; height: 375px; max-width: none; }
#anim .fin .nom { font: 700 40px/1 var(--titre, Georgia, serif); color: #f1eee7; letter-spacing: -.015em; margin-top: 10px; }
#anim .fin .slogan { font: 400 15px/1.4 var(--ui, system-ui, sans-serif); color: #c0bcb2; text-align: center; max-width: 420px; margin-top: 12px; }

#anim .pause { position: absolute; right: 8px; top: 8px; font: 500 9px/1 var(--mono, monospace); color: #8f939b; background: rgba(15,16,19,.7); padding: 4px 6px; border-radius: 3px; opacity: 0; z-index: 7; }
#anim.en-pause .pause { opacity: 1; }
#anim .lancer { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 8; pointer-events: auto; background: #d9a441; color: #221a06; font: 500 14px/1 var(--ui, system-ui, sans-serif); padding: 12px 18px; border: 0; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,.55); cursor: pointer; }
#anim .lancer:hover { filter: brightness(1.06); }
