/* ===========================================================================
   Liseuse Spartacus-IDH — habillage commun à tous les ouvrages.
   Ce fichier est chargé par TOUTES les liseuses publiées : chaque règle doit
   rester valable pour un ilect.php généré il y a des années comme pour un
   ouvrage mis en ligne demain.

   1. Réglages           2. Base et cadre        3. Flipbook et pages
   4. Curseur de pages   5. Régions (liens)      6. Miniatures
   7. Infobulles         8. Sommaire             9. Barre d'outils
  10. Zoom              11. Recherche           12. Résultats
  13. Polices           14. Attente
   ========================================================================= */

/* --- 1. Réglages -------------------------------------------------------- */

:root {
  --fond: #dcdcdc;              /* cadre autour du livre */
  --barre-fond: rgba(220, 220, 220, .92);
  --menu-fond: #d5d5d5;
  --menu-fond-alt: #c9c9c9;
  --menu-texte: #1a1a1a;
  --texte: #333;
  --icone: #555;
  --icone-active: #111;
  --accent: #973c3e;            /* rouge Spartacus, déjà utilisé en favicon */
  --accent-clair: #1b6ea8;      /* traits et bordures de la recherche */
  --signal: #c0504d;            /* remplace le « salmon » historique */
  --panneau: rgba(0, 0, 0, .82);
  --panneau-texte: whitesmoke;

  /* Couleur d'action de la boîte de recherche : bouton de validation et
     interrupteurs. L'ancien #38a3d4 ne donnait que 2,85:1 sous un libellé
     blanc ; celle-ci en donne 5,47. */
  --action-fond: #1b6ea8;
  --action-texte: #fff;

  /* Boîte de recherche */
  --boite-fond: rgba(255, 255, 255, .96);
  --boite-texte: #1a1a1a;
  --champ-fond: #fff;
  --champ-bordure: #b9b9b9;
  --piste: #e4e4e7;             /* fond des interrupteurs */
  --piste-texte: #3f3f46;

  --barre-h: 54px;              /* hauteur de la barre d'outils */
  --icone-h: 44px;              /* cible tactile : 44 px, minimum recommandé */
  --rayon: 6px;
  --sw-rayon: 9px;              /* interrupteurs d'options */
  --ombre: 0 6px 18px rgba(0, 0, 0, .18), 0 2px 6px rgba(0, 0, 0, .12);
  --transition: .2s ease;
}

/* Habillage sombre : seul le cadre change, jamais les pages du livre, dont les
   couleurs sont celles de l'édition imprimée.

   Trois cas : le lecteur n'a rien choisi et son système demande le sombre
   (premier bloc) ; il a demandé le sombre (second bloc) ; il a demandé le clair
   (data-theme="light", aucun bloc ne s'applique). Le second bloc est dérivé du
   premier : toute modification doit porter sur les deux. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fond: #1c1c1e;
    --barre-fond: rgba(38, 38, 40, .92);
    --menu-fond: #2c2c2e;
    --menu-fond-alt: #37373a;
    --menu-texte: #f2f2f2;
    --texte: #e8e8e8;
    --icone: #c8c8c8;
    --icone-active: #fff;

    --accent-clair: #4aa3dd;
    --action-fond: #4aa3dd;
    --action-texte: #08202e;

    /* La boîte de recherche suit le cadre : un panneau blanc éblouirait
       au-dessus d'un livre lu de nuit. */
    --boite-fond: rgba(30, 30, 34, .96);
    --boite-texte: #ececee;
    --champ-fond: #2a2a2e;
    --champ-bordure: #55555c;
    --piste: #2a2a2e;
    --piste-texte: #d4d4d8;
  }
}

:root[data-theme="dark"] {
  --fond: #1c1c1e;
  --barre-fond: rgba(38, 38, 40, .92);
  --menu-fond: #2c2c2e;
  --menu-fond-alt: #37373a;
  --menu-texte: #f2f2f2;
  --texte: #e8e8e8;
  --icone: #c8c8c8;
  --icone-active: #fff;

  --accent-clair: #4aa3dd;
  --action-fond: #4aa3dd;
  --action-texte: #08202e;

  /* La boîte de recherche suit le cadre : un panneau blanc éblouirait
     au-dessus d'un livre lu de nuit. */
  --boite-fond: rgba(30, 30, 34, .96);
  --boite-texte: #ececee;
  --champ-fond: #2a2a2e;
  --champ-bordure: #55555c;
  --piste: #2a2a2e;
  --piste-texte: #d4d4d8;
}


/* Respecte le réglage système « réduire les animations ». */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* --- 2. Base et cadre --------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: var(--fond);
}

body {
  font-family: 'Open Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  color: var(--texte);
  -webkit-text-size-adjust: 100%;
}

.catalog-app {
  width: 100%;
  height: 100%;
  /* dvh suit la barre d'adresse mobile : remplace le décalage de 20 px qui
     était appliqué à l'iPad en paysage. */
  height: 100dvh;
  overflow: hidden;
  position: relative;
  background-color: var(--fond);
}

#viewer {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.ui-flipbook,
#controls {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Le clavier doit rester visible : sans cela, la liseuse est inutilisable
   sans souris. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- 3. Flipbook et pages ----------------------------------------------- */

.ui-flipbook .page,
.ui-flipbook .cover { background-color: #fff; }

.ui-flipbook .page-wrapper { perspective: 2000px; }

/* Page remontée en canvas : une seule image cohérente, mise à l'échelle par le
   navigateur comme un <img>. Remplace le remontage en cinq calques CSS, dont
   les arrondis fractionnaires produisaient des coutures mobiles au zoom. */
/* Conteneur du contenu de page. Sa hauteur doit être définie, sinon le
   height:100% du canvas ne peut pas se résoudre et celui-ci retombe sur sa
   hauteur intrinsèque (1820 px), débordant de la boîte de page. */
.page-contenu { width: 100%; height: 100%; }

.page-canvas { display: block; width: 100%; height: 100%; }

/* Repli si le canvas est indisponible : ancien remontage, conservé à
   l'identique. */
.img-bande   { background-size: cover; width: 100%; height: 20%; }
.img-bande-1 { background-position: 100% top; }
.img-bande-2 { background-position: 75% top; }
.img-bande-3 { background-position: 50% top; }
.img-bande-4 { background-position: 25% top; }
.img-bande-5 { background-position: 0% top; }

/* Gouttière : ombre douce dans le pli, côté intérieur de chaque page.

   Ces pages doivent rester en content-box, contrairement au reste de la v2 qui
   est en border-box (réinitialisateur global plus haut). La bordure de 9 px doit
   s'ajouter À L'EXTÉRIEUR de la boîte : les deux pages se chevauchent alors de
   9 px, et le translate(-9px) de .page-even les remet bord à bord.
   En border-box la bordure passe à l'intérieur, les pages se touchent déjà, et
   la translation devient une sur-correction qui ouvre un vide de 9 px au pli —
   tout en rabotant la boîte de contenu de 430 à 421 px, ce qui écrasait le
   canvas de 2 % horizontalement. */
.page-odd:not(.cover-no-gradient),
.page-even:not(.cover-no-gradient) { box-sizing: content-box; }

.page-odd:not(.cover-no-gradient) {
  border-style: solid;
  border-image: linear-gradient(to right, rgba(200, 200, 200, 1), rgba(200, 200, 200, 0) 5px) 5/10px;
  border-width: 0 0 0 9px;
}

.page-even:not(.cover-no-gradient) {
  transform: translate(-9px);
  border-style: solid;
  border-image: linear-gradient(to left, rgba(200, 200, 200, 1), rgba(200, 200, 200, 0) 5px) 5/10px;
  border-width: 0 9px 0 0;
}

.display-single .page-odd,
.display-single .page-even {
  border-style: none !important;
  border-image: none !important;
  border-width: 0 !important;
}

.page-odd .ui-region-page,
.page-odd .ui-region-link { transform: translate(9px); }

.display-single .page-odd .ui-region-page,
.display-single .page-odd .ui-region-link { transform: translate(0) !important; }

/* Flèches de tourne-page. */
.ui-arrow-next-page,
.ui-arrow-previous-page {
  width: 30px;
  height: 60px;
  position: absolute;
  top: calc(50% - 30px);
  right: -40px;
  z-index: 10;
  background-image: url(../media/arrows@2x.png);
  background-size: 60px 120px;
  background-position: 0 0;
  opacity: .5;
  transition: opacity var(--transition);
  cursor: pointer;
}

.ui-arrow-previous-page {
  background-position: 30px 0;
  right: auto;
  left: -40px;
}

.ui-arrow-control-hover { transition: none; opacity: .7; }
.ui-arrow-control-tap { opacity: 1; }
.first-page .ui-arrow-previous-page { opacity: 0; }
.last-page .ui-arrow-next-page { opacity: 0; }

.touch-device.display-single .ui-arrow-next-page,
.touch-device.display-single .ui-arrow-previous-page { display: none; }

/* Invite à tourner la première page. */
.first-page .ui-arrow-next-page {
  animation: next-page 1s infinite ease-in-out;
}

@keyframes next-page {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(6px); }
}

/* Message affiché lorsque le serveur refuse les sprites — cas d'un navigateur
   qui ne transmet pas l'en-tête Referer. Voir signaleImagesBloquees(). */
.ui-message-bloque {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 9999;
  max-width: 32em;
  padding: 1.5em 1.8em;
  background: #fff;
  color: #222;
  border: 1px solid var(--accent);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  font-size: 15px;
  line-height: 1.5;
  text-align: left;
}

.ui-message-bloque p { margin: 0; }

/* --- 4. Curseur de pages ------------------------------------------------ */
/* Le widget de turn.js pilote .progress en pourcentage : la largeur peut donc
   être fluide sans rien casser. Remplace les trois paliers fixes
   (500 / 300 / 100 px) d'origine. */

.ui-slider {
  width: clamp(120px, 45vw, 500px);
  height: var(--icone-h);
  display: inline-block;
  vertical-align: middle;   /* « center » n'existe pas : d'où l'ancien décalage */
  cursor: pointer;
}

.ui-slider .bar {
  width: 100%;
  height: 6px;
  background-color: #999;
  margin-top: 19px;
  overflow: hidden;
  border-radius: 5px;
}

.ui-slider .progress { position: relative; height: 6px; }

.ui-slider .progress-width {
  margin-left: 5px;
  width: calc(100% - 10px);
  height: 6px;
  transition: all 100ms;
}

.ui-slider .handler {
  height: 6px;
  width: 10px;
  background-color: #000;
  position: absolute;
  top: 0;
  right: -5px;
  opacity: .5;
  border-radius: 5px;
  transition: all 100ms;
}

.ui-slider.changing { cursor: none; }
.ui-slider.changing .handler { width: 50px; right: -25px; opacity: .8; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ui-slider .bar { background-color: #5a5a5c; }
  :root:not([data-theme="light"]) .ui-slider .handler { background-color: #f0f0f0; }
}

:root[data-theme="dark"] .ui-slider .bar { background-color: #5a5a5c; }
:root[data-theme="dark"] .ui-slider .handler { background-color: #f0f0f0; }


/* --- 5. Régions (liens internes et occurrences trouvées) ---------------- */

/* La largeur et la hauteur reçues valent exactement celles du mot dans la page.
   Le remplissage de 2 px et les marges négatives sont là pour dégager un peu
   d'air autour, en débordant vers l'extérieur — ce qui suppose « content-box ».

   Sous le « border-box » global de la ligne 122, remplissage et bordure rognent
   au contraire vers l'intérieur : la boîte perdait 6 px dans chaque dimension
   tout en restant décalée de -2 px et -4 px. Le bord droit tombait donc au
   milieu de la dernière lettre — « rest|é », « es|t » — et le bas coupait les
   jambages. Même piège que sur .page-odd, même correctif. */
.ui-region {
  box-sizing: content-box;
  position: absolute;
  overflow: hidden;
  z-index: 1;
  margin-top: -4px;
  margin-left: -2px;
  padding: 2px;
}

.ui-region-link {
  margin-left: -2px !important;
  padding-right: 2px !important;
  cursor: pointer;
  border-bottom: 1px solid #2f5fd0;
}

.ui-region-page {
  background-color: rgba(255, 235, 0, .22);
  border: 1px solid var(--signal);
  border-radius: 5px;
}

.ui-region-tooltip { font-size: 13px !important; }

@media (max-width: 600px) {
  .ui-region { margin-top: -3px; }
}

/* --- 6. Miniatures ------------------------------------------------------ */

#miniatures {
  position: absolute;
  bottom: var(--barre-h);
  left: 0;
  width: 100%;
  height: 126px;
  background-color: var(--barre-fond);
}

.ui-miniatures-slider {
  text-align: center;
  height: 180px;
  opacity: 0;
  z-index: 100;
  transition: opacity 200ms 100ms;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.ui-miniatures-slider .container {
  margin-top: 25px;
  position: relative;
  height: 100px;
}

.ui-miniatures-slider .ui-page {
  background-color: #fff;
  display: inline-block;
  vertical-align: middle;
  position: relative;
  cursor: pointer;
  box-shadow: 0 -2px 6px rgba(0, 0, 0, .1);
}

.ui-miniatures-slider .page-img {
  width: calc(100% - 8px);
  height: calc(100% - 8px);
  margin: 4px;
  background-color: #fff;
}

.ui-miniatures-slider .left-page .page-img  { width: 96%; margin-right: 0; }
.ui-miniatures-slider .right-page .page-img { width: 96%; margin-left: 0; }

.ui-miniatures-slider .focused-page { background-color: var(--accent); }

.ui-miniatures-slider .animated-page { transition: transform ease-in-out 200ms; }

.ui-miniatures-slider .page-number { display: none; }

.ui-miniatures-slider .page-number-bis {
  font: 300 11px/1 'Open Sans', system-ui, sans-serif;
  color: #000;
  text-shadow: 0 0 2px #fff;
  position: absolute;
  top: 8px;
  left: 0;
  width: 100%;
}

.show-miniatures .ui-miniatures-slider { opacity: 1; }

/* --- 7. Infobulles ------------------------------------------------------ */

.ui-tooltip {
  position: absolute;
  float: left;
  background: rgba(33, 33, 33, .88);
  padding: 6px 10px;
  font: 400 11px/1.2 'Open Sans', system-ui, sans-serif;
  color: #fff;
  letter-spacing: .5px;
  white-space: nowrap;
  z-index: 1000;
  opacity: 0;
  cursor: default;
  border-radius: 5px;
  transition: opacity .1s;
}

.ui-tooltip-visible { opacity: 1; }

.ui-tooltip-top::before,
.ui-tooltip-bottom::before,
.ui-tooltip-left::before,
.ui-tooltip-right::before {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
}

.ui-tooltip-top::before {
  bottom: -5px; left: 50%; margin-left: -4px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid rgba(33, 33, 33, .88);
}

.ui-tooltip-bottom::before {
  top: -5px; left: 50%; margin-left: -4px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid rgba(33, 33, 33, .88);
}

.ui-tooltip-left::before {
  right: -5px; top: 50%; margin-top: -4px;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 5px solid rgba(33, 33, 33, .88);
}

.ui-tooltip-right::before {
  left: -5px; top: 50%; margin-top: -4px;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 5px solid rgba(33, 33, 33, .88);
}

/* --- 8. Sommaire -------------------------------------------------------- */
/* Le panneau s'appuie sur la barre d'outils au lieu de la recouvrir (il
   descendait 10 px trop bas), et sa hauteur suit maintenant le nombre de
   chapitres au lieu d'étirer un aplat gris jusqu'en haut de l'écran. */

.ui-menu {
  position: absolute;
  right: 10px;
  bottom: calc(var(--barre-h) + 6px);
  top: auto;
  z-index: 102;
  width: min(260px, calc(100vw - 20px));
  max-height: calc(100% - var(--barre-h) - 16px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background-color: var(--menu-fond);
  color: var(--menu-texte);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  opacity: 0;
  transition: opacity var(--transition);
}

.ui-menu-visible { opacity: 1; }

.ui-menu-wrapper {
  border-collapse: collapse;
  width: 100%;
}

.ui-menu .ui-menu-item-s:nth-child(even) { background-color: var(--menu-fond-alt); }
.ui-menu .ui-menu-item-s:last-child { border-bottom: none; }

/* Les titres longs tenaient sur deux lignes avec un interligne de 34 px. */
.ui-menu .ui-menu-item-desc-s {
  font: 400 14px/1.35 'Open Sans', system-ui, sans-serif;
  padding: 9px 16px;
}

.tdm-s-a {
  color: var(--menu-texte) !important;
  text-decoration: none !important;
  display: block;
}

.tdm-s-a:hover { text-decoration: underline !important; }

/* Chapitre en cours de lecture, repéré à l'ouverture du sommaire. */
.ui-menu-item-courant .tdm-s-a { font-weight: 700; }

.ui-menu-item-courant .ui-menu-item-desc-s {
  border-left: 3px solid var(--accent);
  padding-left: 13px;
}

/* --- 9. Barre d'outils -------------------------------------------------- */

#controls {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: var(--barre-h);
  text-align: center;
  z-index: 101;
}

/* .all n'avait pas de hauteur propre : elle valait 49 px en mode quirks
   (5 px de page visibles sous la barre) et 70 px en mode standards
   (la barre débordait sous l'écran). */
#controls .all {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--barre-fond);
  transition: opacity .5s;
}

#controls #page-slider { margin: 0; }

#controls .ui-options {
  position: absolute;
  top: calc((var(--barre-h) - var(--icone-h)) / 2);
  right: 5px;
  height: var(--icone-h);
  display: flex;
  align-items: center;
}

/* Centrage en flex : supprime les calages au pixel (padding-bottom, marges
   négatives) qui désalignaient l'icône « Outils » de 6 px. */
#controls .ui-icon {
  width: var(--icone-h);
  height: var(--icone-h);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--icone);
  fill: currentColor;
  cursor: pointer;
  border-radius: var(--rayon);
  transition: color .1s, background-color .1s;
}

#controls .ui-icon:hover { color: var(--icone-active); }

#controls .ui-ui-icon-on {
  background-color: #666;
  color: #fff !important;
  text-shadow: 0 0 2px #333;
  border-radius: var(--rayon);
}

#controls #ui-icon-zoom { position: relative; z-index: 101; }

.ui-icon-svg { opacity: .7; transition: opacity .1s; }
.ui-icon:hover .ui-icon-svg,
.ui-icon-svg:hover { opacity: 1; }

.outils-ouverts,
.outils-fermes { width: 30px; height: 30px; margin: 0; padding: 0; }

/* Le bouton « Outils » de la barre et celui qui la rappelle affichaient la
   même image au même endroit, décalée de 5 px : d'où l'effet de doublon flou.
   Le second ne paraît plus que lorsque la barre est repliée ou estompée. */
#controls #ui-icon-expand-options {
  position: absolute;
  top: calc((var(--barre-h) - var(--icone-h)) / 2);
  right: 5px;
  width: var(--icone-h);
  height: var(--icone-h);
  background-color: var(--barre-fond);
  border-radius: var(--rayon);
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s;
}

#controls.hidden-controls .all { opacity: 0; pointer-events: none; }

/* Le bouton de rappel n'existe que sous 1000 px (voir plus bas) : sur grand
   écran, un mouvement de souris suffit à ramener la barre. */

/* Bouton clair/sombre, à l'opposé des outils. Il porte les deux icônes ; le CSS
   montre celle de l'action possible — un croissant sur fond clair, un soleil sur
   fond sombre —, ce qui évite d'aller la changer en JavaScript. */
#controls #options-gauche {
  position: absolute;
  top: calc((var(--barre-h) - var(--icone-h)) / 2);
  left: 5px;
  height: var(--icone-h);
  display: flex;
  align-items: center;
}

#ui-icon-theme .icone-clair { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #ui-icon-theme .icone-clair { display: block; }
  :root:not([data-theme="light"]) #ui-icon-theme .icone-sombre { display: none; }
}

:root[data-theme="dark"] #ui-icon-theme .icone-clair { display: block; }
:root[data-theme="dark"] #ui-icon-theme .icone-sombre { display: none; }

/* Écrans étroits : les outils se replient derrière un seul bouton. */
@media screen and (max-width: 1000px) {
  #controls #page-slider {
    position: relative;
    z-index: 2;
    transition: transform var(--transition);
  }

  #controls .ui-options .ui-icon {
    transition: opacity .2s cubic-bezier(.515, .01, .225, 1.345);
  }

  #controls .ui-options #ui-icon-toggle { display: inline-flex !important; }

  #controls .ui-options .ui-icon:nth-child(1),
  #controls .ui-options .ui-icon:nth-child(2),
  #controls .ui-options .ui-icon:nth-child(3),
  #controls .ui-options .ui-icon:nth-child(4),
  #controls .ui-options .ui-icon:nth-child(5) {
    opacity: 0;
    pointer-events: none;
  }

  /* Barre repliée : c'est le bouton de rappel qui répond. Barre dépliée :
     c'est celui de la barre, sinon taper dessus rouvrait au lieu de fermer. */
  #controls:not(.extend-ui-options) #ui-icon-expand-options {
    opacity: 1;
    pointer-events: auto;
    cursor: pointer;
  }

  #controls.extend-ui-options #page-slider { transform: translate3d(-250px, 0, 0); }

  /* Le curseur vient alors recouvrir le bouton clair/sombre : on l'efface le
     temps que les outils sont dépliés. */
  #controls.extend-ui-options #options-gauche {
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
  }

  /* .ui-options est indispensable ici : sans lui, la règle attrapait aussi
     l'unique .ui-icon du bouton de rappel, qui redevenait cliquable par-dessus
     celui de la barre — taper dessus rouvrait au lieu de fermer. */
  #controls.extend-ui-options .ui-options .ui-icon:nth-child(1),
  #controls.extend-ui-options .ui-options .ui-icon:nth-child(2),
  #controls.extend-ui-options .ui-options .ui-icon:nth-child(3),
  #controls.extend-ui-options .ui-options .ui-icon:nth-child(4),
  #controls.extend-ui-options .ui-options .ui-icon:nth-child(5) {
    pointer-events: auto;
    opacity: 1;
  }
}

/* --- 10. Zoom ----------------------------------------------------------- */

.zoom-slider {
  position: absolute;
  z-index: 100;
  width: var(--icone-h);
  height: 150px;
  opacity: 0;
  top: 0;
  left: -100px;
  transform: translateY(100%);
  transition: transform .1s .1s, opacity .2s .1s;
}

.zoom-slider .bg {
  width: var(--icone-h);
  height: 150px;
  border-radius: 10px;
  background-color: #ccc;
}

.zoom-slider .ui-slider {
  width: var(--icone-h);
  height: 90px;
  cursor: pointer;
  opacity: 1;
}

.zoom-slider .ui-slider .bar {
  width: 6px;
  height: 90px;
  background-color: rgba(0, 0, 0, .5);
  margin: 19px 0 0 19px;
  border-radius: 5px;
}

.zoom-slider .ui-slider .progress { position: relative; width: 6px; }

.zoom-slider .ui-slider .progress-width {
  margin: 3px 0 0;
  width: 6px;
  height: 84px;
  transition: all 100ms;
}

.zoom-slider .ui-slider .handler {
  height: 6px;
  width: 6px;
  background-color: #fff;
  position: absolute;
  top: auto;
  right: auto;
  left: 0;
  bottom: -3px;
  opacity: .8;
  border-radius: 5px;
  transition: all 100ms;
}

.zoom-slider.show-zoom-slider {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0s;
}

.zoom-slider .ui-slider:hover .handler { opacity: .8; }

/* --- 11. Recherche ------------------------------------------------------ */
/* Les dimensions étaient exprimées en vw : la boîte devenait minuscule sur un
   écran étroit et démesurée sur un grand. clamp() borne les deux extrêmes. */

.ui-share-box {
  position: fixed;
  inset: 0;
  z-index: 101;
  background-color: rgba(0, 0, 0, .6);
  /* Estompe le livre sans le repeindre, contrairement à filter: blur() sur
     #flipbook, qui faisait recalculer les 130 pages en canvas. */
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  visibility: hidden;           /* remplace le renvoi à left:-10000px */
  transition: opacity var(--transition), visibility var(--transition);
}

.ui-share-box.show-ui-share-box { opacity: 1; visibility: visible; }

.ui-share-options {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  overflow: auto;
  text-align: center;
}

.search-wrapper {
  position: relative;
  width: min(560px, 100%);
  padding: clamp(12px, 2vw, 20px);
  background-color: var(--boite-fond);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
}

.search-title {
  font-size: clamp(16px, 2.2vw, 21px);
  font-weight: 600;
  margin-bottom: 10px;
  padding: 0 28px;              /* laisse la place à la croix de fermeture */
  color: var(--boite-texte);
}

.close-mark {
  display: block;
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  fill: var(--signal);
  cursor: pointer;
  opacity: .8;
  transition: opacity .1s;
}

.close-mark:hover { opacity: 1; }

fieldset {
  border: 1px solid var(--accent-clair);
  border-radius: var(--rayon);
  margin: 3px 0;
  padding: 6px 10px 10px;
}

legend {
  text-align: left;
  font-size: clamp(12px, 1.4vw, 14px);
  padding: 0 6px;
  color: var(--boite-texte);
}

.search-andor { margin-bottom: 10px; }

/* Les deux interrupteurs occupent désormais la même largeur : ils étaient
   dimensionnés par leur texte, d'où un alignement bancal. */
.table-search-option {
  width: 100%;
  border-collapse: separate;
  border-spacing: 8px 0;
  table-layout: fixed;
}

.table-search-option td { width: 50%; font-size: clamp(11px, 1.1vw, 13px); }

.table-search-option label {
  display: block;
  cursor: pointer;
  font-size: inherit;
}

.search-mot {
  display: block;
  width: 100%;
  height: clamp(30px, 4vw, 38px);
  margin-bottom: 6px;
  padding-left: 8px;
  font-size: clamp(14px, 1.6vw, 17px);
  font-family: inherit;
  color: var(--boite-texte);
  background: var(--champ-fond);
  border: 1px solid var(--champ-bordure);
  border-radius: 6px;
}

.search-mot:focus {
  border-color: var(--accent-clair);
  outline: 2px solid var(--accent-clair);
  outline-offset: -2px;
}

input[type=search] { -webkit-appearance: none; appearance: none; }

.search-ok-td { width: clamp(64px, 9vw, 92px); }

.search-ok {
  height: clamp(64px, 9vw, 92px);
  width: clamp(64px, 9vw, 92px);
  margin-left: 8px;
  padding: 18px;
  text-align: center;
  border: 0;
  border-radius: 10px;
  background: #d7d7d7;
  box-shadow: 0 3px 6px rgba(0, 0, 0, .16);
  transition: background .1s, box-shadow .15s;
}

.search-ok svg { fill: #f2f2f2; width: 100%; height: 100%; }

.search-ok:enabled { background: var(--action-fond); color: var(--action-texte); cursor: pointer; }
.search-ok:enabled:hover { filter: brightness(1.12); box-shadow: 0 10px 20px rgba(0, 0, 0, .22); }
.search-ok:enabled svg { fill: var(--action-texte); }

.search-consigne {
  display: block;
  text-align: left;
  font-size: clamp(11px, 1.2vw, 14px);
  opacity: .75;                 /* consigne neutre tant qu'elle n'est pas enfreinte */
  color: var(--boite-texte);
}

.search-wrong { color: var(--signal); }

/* --- 11b. Interrupteurs d'options --------------------------------------- */
/* Reprise condensée de css-toggle-switch (Ionuț Colceriu, ghinda.net) : sur les
   cinq thèmes et deux variantes de la bibliothèque, la liseuse n'emploie que
   « switch-light ». Le thème d'origine imitait un bouton physique — piste
   creusée par une ombre interne, curseur en dégradé bordé, texte en relief ;
   celui-ci est plat, dans l'esprit d'un sélecteur segmenté, et reprend les
   couleurs du bouton de validation. Le curseur glisse à l'intérieur de la
   piste, que le retrait de 3 px laisse apparaître tout autour. */

.switch-light {
  position: relative;
  display: block;
}

.switch-light::after { clear: both; content: ''; display: table; }

/* La case reste là pour le clavier et les lecteurs d'écran, mais invisible. */
.switch-light input {
  position: absolute;
  opacity: 0;
  z-index: 3;
}

/* La piste */
.switch-light > span {
  position: relative;
  display: block;
  overflow: hidden;
  min-height: 2em;
  padding: 3px;
  text-align: left;
  background-color: var(--piste);
  border-radius: var(--sw-rayon);
}

/* Les deux libellés, côte à côte */
.switch-light span span {
  position: relative;
  z-index: 2;
  display: block;
  float: left;
  width: 50%;
  text-align: center;
  font-weight: 500;
  color: var(--piste-texte);
  user-select: none;
  transition: color .2s ease-out;
}

/* Le curseur coulissant */
.switch-light a {
  position: absolute;
  top: 3px;
  right: 50%;
  z-index: 1;
  display: block;
  width: calc(50% - 3px);
  height: calc(100% - 6px);
  background-color: var(--action-fond);
  border-radius: calc(var(--sw-rayon) - 3px);
  transition: all .2s ease-out;
}

.switch-light input:checked ~ span a { right: 3px; }

/* Le libellé que le curseur recouvre */
.switch-light input ~ span span:first-child,
.switch-light input:checked ~ span span:nth-child(2) {
  color: var(--action-texte);
}

/* L'interrupteur n'a pas de contour propre : c'est la piste qui le porte. */
.switch-light input:focus-visible ~ span {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- 12. Résultats de recherche ---------------------------------------- */

#search-result {
  display: none;
  position: absolute;
  top: 10px;
  left: 10px;
  width: min(320px, 50vw);
  /* Le panneau s'arrête au-dessus de la barre : il passait dessous. */
  height: calc(100% - var(--barre-h) - 20px);
  z-index: 100;
  text-align: center;
  color: var(--panneau-texte);
  background-color: var(--panneau);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  transition: height var(--transition);
  overflow: hidden;
}

.search-result {
  padding-top: 10px;
  font-weight: 600;
  font-size: clamp(13px, 1.4vw, 16px);
}

/* Libellé des résultats, jusqu'ici dans mainFR.css et mainEN.css — deux
   feuilles d'une règle chacune. L'attribut lang de <html> suffit à les
   départager. */
html[lang="fr"] .search-result::after { content: "Résultats\00a0 de\00a0la\00a0recherche\2009:"; }
html[lang="en"] .search-result::after { content: "Search\00a0results\2009:"; }

@media screen and (max-width: 500px) {
  html[lang="fr"] .search-result::after { content: "Résultats\2009:"; }
  html[lang="en"] .search-result::after { content: "Results\2009:"; }
}

.search-result-top {
  height: 57px;
  border-bottom: 2px solid var(--panneau-texte);
  padding-bottom: 5px;
}

.found-total { font-size: .9em; }

/* Message affiché quand le serveur de recherche ne répond pas. */
.search-indispo {
  padding: 20px 18px;
  font-size: clamp(13px, 1.4vw, 15px);
  line-height: 1.5;
  text-align: left;
  color: var(--panneau-texte);
}

.found-close,
.expand-mark {
  position: absolute;
  width: 20px;
  height: 20px;
  right: 6px;
  fill: var(--signal);
  cursor: pointer;
  opacity: .8;
  transition: opacity .1s;
}

.found-close { top: 6px; }
.expand-mark { top: 38px; }
.found-close:hover,
.expand-mark:hover { opacity: 1; }

/* La liste occupe ce qui reste sous l'en-tête. Le retrait de 115 px laissait
   une bande vide : l'en-tête n'en mesure que 57, bordure comprise.
   Volontairement sans flex — les liseuses servies par l'ancien app.min.js
   affichent ce panneau en display:block. */
.table-found-wrapper {
  height: calc(100% - 57px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

#found-table { width: 100%; padding: 10px; font-size: .85em; }

.found-page { text-align: center; color: var(--panneau-texte); }
.found-page a { color: var(--panneau-texte); text-decoration: underline; cursor: pointer; }
.found-page a:visited { color: var(--panneau-texte); }
.found-page a:hover { color: #bfbfbf; }

.found-page-separe { border-top: 2px solid var(--panneau-texte); padding-top: 10px; }

.found-word { text-align: left; color: var(--signal); }
.found-occ  { text-align: right; color: #9ecbe8; font-style: italic; }

/* --- 13. Polices -------------------------------------------------------- */
/* font-display: swap — le texte de l'interface s'affiche sans attendre le
   téléchargement de la police. */

@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/opensans/light/opensans-300.woff2') format('woff2'),
       url('../fonts/opensans/light/opensans-300.woff') format('woff');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/opensans/regular/opensans-400.woff2') format('woff2'),
       url('../fonts/opensans/regular/opensans-400.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/opensans/semibold/opensans-600.woff2') format('woff2'),
       url('../fonts/opensans/semibold/opensans-600.woff') format('woff');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Open Sans';
  src: url('../fonts/opensans/bold/opensans-700.woff2') format('woff2'),
       url('../fonts/opensans/bold/opensans-700.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* --- 14. Attente -------------------------------------------------------- */

.lds-default {
  z-index: 10000;
  position: absolute;
  width: 64px;
  height: 64px;
  top: calc(50% - 32px);
  left: calc(50% - 32px);
}

.lds-default div {
  position: absolute;
  width: 5px;
  height: 5px;
  background: var(--signal);
  border-radius: 50%;
  animation: lds-default 1.2s linear infinite;
}

.lds-default div:nth-child(1)  { animation-delay:    0s; top: 29px; left: 53px; }
.lds-default div:nth-child(2)  { animation-delay:  -.1s; top: 18px; left: 50px; }
.lds-default div:nth-child(3)  { animation-delay:  -.2s; top:  9px; left: 41px; }
.lds-default div:nth-child(4)  { animation-delay:  -.3s; top:  6px; left: 29px; }
.lds-default div:nth-child(5)  { animation-delay:  -.4s; top:  9px; left: 18px; }
.lds-default div:nth-child(6)  { animation-delay:  -.5s; top: 18px; left:  9px; }
.lds-default div:nth-child(7)  { animation-delay:  -.6s; top: 29px; left:  6px; }
.lds-default div:nth-child(8)  { animation-delay:  -.7s; top: 41px; left:  9px; }
.lds-default div:nth-child(9)  { animation-delay:  -.8s; top: 50px; left: 18px; }
.lds-default div:nth-child(10) { animation-delay:  -.9s; top: 53px; left: 29px; }
.lds-default div:nth-child(11) { animation-delay:   -1s; top: 50px; left: 41px; }
.lds-default div:nth-child(12) { animation-delay: -1.1s; top: 41px; left: 50px; }

@keyframes lds-default {
  0%, 20%, 80%, 100% { transform: scale(1); }
  50% { transform: scale(1.5); }
}

