/* Mise en page TELEPHONE et fenetre etroite.
 *
 * Chargee par index.html avec media="(max-width: 900px)" : une TV, qui affiche
 * un canevas de 1920 px, ne la declenche JAMAIS. Le rendu webOS et Android TV
 * ne peut donc pas en etre affecte -- c'est la raison d'en faire une feuille a
 * part plutot que des @media dans app.css.
 *
 * Aucune contrainte Chromium 79 ici (pas de TV) : aspect-ratio, gap sur flex,
 * env(safe-area-inset-*) et dvh sont disponibles sur les navigateurs mobiles
 * vises. Ce fichier ne surcharge que la MISE EN PAGE ; les composants, les
 * couleurs et le comportement restent ceux de app.css.
 *
 * Principe : le rail vertical devient une barre d'onglets en bas, au pouce ;
 * les colonnes de categories deviennent une rangee de puces qui defile a
 * l'horizontale ; les grilles calculent leur nombre de colonnes. */

:root {
  --safe: 12px;
  --ring: 6px;
  --rail-w: 0px;
  --tabbar-h: 54px;
  /* Sous les onglets : de quoi degager l'indicateur d'accueil de l'iPhone
     (un trait de 5 px a ~8 px du bord), pas TOUTE la zone de securite (34 px) :
     la barre en prenait 92 px de haut, « beaucoup de hauteur » a l'usage.
     6 px au minimum sur un ecran sans indicateur. */
  --tabbar-pad: max(6px, calc(env(safe-area-inset-bottom, 0px) - 16px));
  --tabbar-total: calc(var(--tabbar-h) + var(--tabbar-pad));
}

html, body {
  width: 100%;
  height: 100%;
  font-size: 15px;
  -webkit-text-size-adjust: 100%;
  /* Le tap ne doit pas faire clignoter un fond gris sur chaque bouton. */
  -webkit-tap-highlight-color: transparent;
}
#app { width: 100%; height: 100%; }
.view-host { width: 100%; height: 100%; height: 100dvh; transform: none; }

/* Toutes les vues sont figees a 1080 px de haut dans app.css. */
.home, .live, .organise, .guide, .catalog, .search, .login, .settings,
.shell, .shell-main {
  height: 100%;
}
.detail { height: 100%; padding: var(--safe); padding-bottom: calc(var(--tabbar-total) + var(--safe)); }

/* L'effet de mise en avant au focus est pense pour la telecommande : au doigt,
   il fait sauter la tuile sous le pouce. */
.tile.is-focused { transform: none; }

/* ------------------------------------------------------------------ *
 * Rail -> barre d'onglets
 * ------------------------------------------------------------------ */

.shell { padding-left: 0; padding-bottom: var(--tabbar-total); }
.shell-main::after { display: none; }

/* FIXED, pas absolute. Barre posee en bas de l'ECRAN, pas en bas de son
   conteneur : en PWA installee sur iPhone (barre d'etat black-translucent,
   viewport-fit=cover), 100% / 100dvh peut valoir moins que l'ecran -- d'environ
   la hauteur de la barre d'etat -- et une barre en absolute flottait d'autant,
   avec un vide dessous. Pas de marge fixe ajoutee a bottom : le fond descend
   jusqu'au bord et le contenu est remonte par padding-bottom (zone de securite),
   comme une barre d'onglets native. Si une marge devait s'ajouter un jour, la
   regle est : bottom: max(safe-bottom, marge + safe-bottom - safe-top) -- voir
   la regle du message ci-dessous (.toast). */
.rail,
.rail:focus-within,
.rail.is-open {
  position: fixed;
  top: auto;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  height: var(--tabbar-total);
  flex-direction: row;
  align-items: stretch;
  justify-content: space-around;
  gap: 0;
  padding: 0 0 var(--tabbar-pad);
  background: #151830;
  border-top: 1px solid var(--line);
  box-shadow: none;
}
.rail-sep { display: none; }
.rail-foot { display: contents; }
.rail-item,
.rail:focus-within .rail-item,
.rail.is-open .rail-item {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  height: auto;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  padding: 6px 2px 4px;
  font-size: 11px;
}
.rail-icon { flex: 0 0 24px; width: 24px; height: 24px; }
.rail-icon svg { width: 24px; height: 24px; }
.rail-label,
.rail:focus-within .rail-label,
.rail.is-open .rail-label {
  opacity: 1;
  font-size: 11px;
  line-height: 1.2;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Accueil sans compte ni source : pas de barre d'onglets, donc pas de place a lui
   reserver en bas. */
.shell.no-rail { padding-bottom: 0; }

/* ------------------------------------------------------------------ *
 * En-tetes
 * ------------------------------------------------------------------ */

.sub-head,
.shell .sub-head,
.catalog .sub-head,
.live .sub-head {
  padding: calc(env(safe-area-inset-top, 0px) + 10px) var(--safe) 6px;
}
.sub-head h1 { font-size: 22px; }
/* Les aides de touches (Rouge, Jaune...) n'ont pas de sens au doigt. */
.sub-hints { display: none; }

/* ------------------------------------------------------------------ *
 * Categories : colonne -> rangee de puces
 * ------------------------------------------------------------------ */

.catalog-body,
.live-body {
  flex-direction: column;
  padding: 0;
}
.cat-pane {
  flex: 0 0 auto;
  margin: 0;
  display: flex;
  flex-direction: row;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 4px var(--safe) 10px;
  border-right: 0;
  border-bottom: 1px solid var(--line);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.cat-pane::-webkit-scrollbar { display: none; }
.cat {
  flex: 0 0 auto;
  width: auto;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--panel);
  font-size: 14px;
  white-space: nowrap;
}
.cat::before { display: none; }
.cat.is-active { background: var(--accent-deep); color: #fff; }
.cat-name { flex: 0 0 auto; }
.cat-count { display: none; }

/* ------------------------------------------------------------------ *
 * Grilles Films / Series
 * ------------------------------------------------------------------ */

.catalog-resume .row { margin-bottom: 8px; }
.catalog-resume .tile,
.row-strip.is-wide .tile { flex-basis: 220px; width: 220px; height: 124px; }
.row { margin-bottom: 18px; }
.row-strip { gap: 10px; padding-left: var(--safe); padding-right: var(--safe); }

/* min-height: 0 -- en colonne, `flex: 1` sans lui laisse la grille prendre la
   hauteur de TOUT son contenu : elle ne defilait plus jamais. */
.catalog-grid, .chan-pane { min-height: 0; }
.catalog-grid {
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  padding: 10px var(--safe) 16px;
}
.catalog-grid .tile { height: auto; aspect-ratio: 2 / 3; }
/* Une tuile en aspect-ratio dont tout le contenu est en position absolue
   n'impose AUCUNE hauteur minimale a sa rangee : des que la grille depassait
   l'ecran, le navigateur ecrasait les rangees a ~14 px et les tuiles se
   chevauchaient. Invisible avec 12 films, flagrant avec un vrai catalogue.
   max-content fige chaque rangee a la hauteur reelle de ses tuiles. */
.catalog-grid { grid-auto-rows: max-content; }
.tile-meta { padding: 8px 8px 9px; }
.tile-title { font-size: 13px; line-height: 1.25; }
.tile-sub { margin-top: 2px; font-size: 11px; }
/* Le defilement du titre au focus est un artifice de telecommande ; au doigt,
   il decalait le premier titre hors de sa tuile. */
.marquee-text.is-scrolling { display: -webkit-box; transform: none; animation: none; }

/* ------------------------------------------------------------------ *
 * TV : liste des chaines pleine largeur
 * ------------------------------------------------------------------ */

/* « Maintenant / Ensuite » occupe un tiers d'ecran de TV : sur un telephone,
   le programme en cours est deja sur chaque ligne de chaine. */
.next-pane { display: none; }
.chan-pane { padding: 4px 8px 12px; }
.chan { gap: 10px; padding: 8px 6px; margin-bottom: 2px; }
.chan.is-focused { transform: none; }
.chan-num { flex: 0 0 26px; font-size: 13px; }
.chan-logo { flex: 0 0 52px; width: 52px; height: 32px; }
.chan-label { font-size: 15px; }
.chan-prog { margin-top: 2px; font-size: 13px; }
.chan-time { gap: 8px; margin-top: 4px; font-size: 12px; }
.chan-bar { flex: 1 1 auto; max-width: 140px; height: 3px; }
.chan .tag { flex: 0 0 auto; margin-left: 6px; padding: 2px 6px; font-size: 10px; white-space: nowrap; }

/* L'anneau de focus suit la telecommande. Au doigt, il restait colle sur la
   premiere ligne comme une selection que personne n'a faite. On le garde au
   clavier d'un ordinateur (pas de .is-touch-layout). */
.is-touch-layout [data-focusable].is-focused::after,
.is-touch-layout .chan.is-focused::after { display: none; }

/* ------------------------------------------------------------------ *
 * Fiche detaillee, a la maniere des applis de streaming sur telephone
 *
 * Signale le 18/10/2026 : l'affiche occupait tout le haut de l'ecran et le
 * resume, en taille TV, faisait 500 px -- il fallait defiler pour lire la
 * fiche. Petite affiche a gauche, titre et etiquettes a droite ; resume sur
 * 3 lignes avec « Plus » ; actions sur toute la largeur. `display: contents`
 * laisse les enfants de .detail-meta se placer dans la grille de l'en-tete.
 * ------------------------------------------------------------------ */

.detail-head {
  display: grid;
  grid-template-columns: 104px 1fr;
  /* app.css pose gap: 40px pour la TV : en grille, il s'appliquerait aussi
     ENTRE LES LIGNES (40 px de vide sous le resume, sous « Plus »...). */
  gap: 0 14px;
  grid-gap: 0 14px;
  align-items: start;
  margin-bottom: 14px;
}
.detail-poster {
  grid-column: 1; grid-row: 1 / span 2;
  width: 104px; height: 156px; aspect-ratio: auto;
  border-radius: 12px;
}
.detail-meta { display: contents; }
.detail-meta h1 { grid-column: 2; grid-row: 1; margin: 2px 0 8px; padding-right: 104px; font-size: 22px; line-height: 1.2; }  /* place du bouton Retour */
.detail-chips { grid-column: 2; grid-row: 2; align-self: start; margin-bottom: 0; }
.detail-chips .chip { font-size: 12px; padding: 4px 9px; }
.detail-plot {
  grid-column: 1 / -1;
  margin-top: 14px;
  font-size: 14px;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
.detail-plot.is-open { display: block; -webkit-line-clamp: unset; }
.plot-more {
  grid-column: 1 / -1;
  justify-self: start;
  display: inline-block;
  margin-top: 4px;
  padding: 4px 0;
  color: var(--accent-soft);
  font-size: 14px;
  font-weight: 700;
}
.plot-more[hidden] { display: none; }
.detail-cast { grid-column: 1 / -1; font-size: 13px; }
.detail-actions {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 8px;
  margin-top: 14px;
}
.detail-actions .btn { width: 100%; padding: 11px 12px; font-size: 15px; text-align: center; }
.detail-actions .btn-primary { grid-column: 1 / -1; }

/* Saisons : une grille reguliere sur toute la largeur, au lieu de pastilles
   alignees a gauche qui laissaient la seconde rangee a moitie vide. */
.season-bar {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  grid-gap: 8px;
  margin-bottom: 14px;
}
.season { padding: 9px 6px; font-size: 14px; text-align: center; }

/* Episodes compacts. */
.ep { padding: 10px 12px; margin-bottom: 6px; }
.ep-num { font-size: 15px; min-width: 22px; }
.ep-name { font-size: 15px; }
.ep-plot {
  font-size: 12px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.ep-dur, .ep-seen { font-size: 12px; }

/* ------------------------------------------------------------------ *
 * Reglages
 * ------------------------------------------------------------------ */

.settings-body {
  margin-left: 0;
  padding: 4px var(--safe) 20px;
  max-width: none;
}
.settings-section { margin: 22px 0 8px; font-size: 12px; }
.set-row { gap: 12px; padding: 12px 14px; margin-bottom: 6px; }
.set-label { min-width: 0; font-size: 15px; }
/* Une valeur longue (« Automatique (HLS si disponible) ») ne doit pas pousser
   la ligne hors de l'ecran : elle se tronque, le libelle garde sa place. */
.set-value {
  flex: 0 1 auto;
  max-width: 48%;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.set-chevron { font-size: 18px; }
.settings .hint { padding: 0 4px; font-size: 13px; }

/* ------------------------------------------------------------------ *
 * Recherche et formulaires
 * ------------------------------------------------------------------ */

.search-bar { gap: 10px; padding: 0 var(--safe) 10px; max-width: none; }
.search-bar .field { margin-bottom: 0; }
.btn-mic { flex: 0 0 44px; width: 44px; height: 44px; }
.btn-mic svg { width: 20px; height: 20px; }
.field-label { font-size: 12px; }
/* 16 px minimum : en dessous, Safari iOS zoome sur le champ au focus. */
.input { font-size: 16px; padding: 10px 12px; }
.search-results { padding: 0 var(--safe) 16px; }

/* Les notifications passaient sous la barre d'onglets. */
.toast { bottom: calc(var(--tabbar-total) + 10px); max-width: calc(100% - 2 * var(--safe)); padding: 10px 16px; font-size: 14px; }

/* ------------------------------------------------------------------ *
 * Compte, accueil, boutons
 * ------------------------------------------------------------------ */

/* margin:auto dans une colonne flex fait prendre au corps la largeur de son
   contenu (jusqu'a 720 px) au lieu de celle de l'ecran : tout debordait. */
.settings.is-welcome .settings-body { width: 100%; max-width: none; margin: 0; }
.account-brand { margin: 12px 0 18px; }
.account-brand h1 { font-size: 36px; }
.account-brand p { margin-top: 6px; font-size: 15px; }
.account-actions { flex-wrap: wrap; gap: 10px; margin: 6px 0 16px; }
.btn { padding: 10px 18px; font-size: 15px; }
.btn.is-focused { transform: none; }
.login-form { width: 100%; max-height: none; }

/* Ajout de source */
.login { padding: calc(env(safe-area-inset-top, 0px) + 56px) var(--safe) 24px; overflow-y: auto; }
.login-brand { margin-bottom: 18px; }
.login-brand h1 { font-size: 36px; }
.login-brand p { margin-top: 6px; font-size: 15px; }
.login-tabs { gap: 8px; margin-bottom: 18px; }
.tab { padding: 8px 16px; font-size: 14px; }
.login-form { padding: 0; }
.login .hint, .login p { font-size: 13px; }

/* Fenetres (UI.modal) : app.css les dessine pour un canevas de 1920 px --
   900 px de large, 44 px de marge interieure, titre a 34 px. Sur un telephone,
   la boite collait aux deux bords et le texte gardait sa taille de salon.
   Ici : une carte centree, avec une marge autour, a la taille du texte de
   l'application ; les boutons se partagent la largeur et passent a la ligne
   s'ils ne tiennent pas. */
.modal {
  padding: 16px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
}
.modal-box {
  width: 100%;
  max-width: 440px;
  max-height: calc(100dvh - 32px);
  padding: 24px 20px 20px;
  border-radius: 18px;
}
.modal-box h2 { margin-bottom: 12px; font-size: 22px; line-height: 1.25; }
.modal-box p { font-size: 15px; line-height: 1.55; overflow-wrap: anywhere; }
.modal-actions { flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.modal-actions > * { flex: 1 1 auto; min-height: 44px; }

/* Barre d'onglets : cinq onglets au plus, pas six. TV, Films, Series, puis
   Recherche, puis le profil. « Réglages » quitte la barre des qu'un profil
   y figure : il s'ouvre depuis la page du profil (ligne .only-narrow de
   account.js). Sans profil (deconnecte avec des sources), il reste dans la
   barre, sinon il deviendrait inaccessible. */
.rail-item[data-rail-view="search"] { order: 4; }
.rail-foot > .rail-item { order: 5; }
.rail-foot:has(.rail-profile) > [data-rail-view="settings"] { display: none; }
.set-row.only-narrow { display: flex; }
.settings-section.only-narrow { display: block; }
/* Ecran de connexion d'une personne deconnectee qui garde ses sources :
   acces aux reglages par une roue dans le coin, hors de la colonne centree
   (voir drawSignedOut). */
.account-settings-link.only-narrow {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  right: calc(env(safe-area-inset-right, 0px) + 10px);
  width: 44px; height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-dim, rgba(255, 255, 255, 0.75));
  z-index: 5;
}
.account-settings-link .account-settings-icon,
.account-settings-link .account-settings-icon svg { width: 22px; height: 22px; display: block; }

/* Telecommande : a la taille du pouce. */
.remote .sub-head h1 { font-size: 26px; }
.remote-tv { font-size: 16px; }
.chip-btn { padding: 10px 14px; font-size: 15px; }
.remote-chips { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); grid-gap: 8px; }
.remote-search { grid-gap: 10px; margin-bottom: 22px; }
.remote-key { min-height: 64px; border-radius: 18px; font-size: 18px; }
.remote-row .remote-key { font-size: 15px; min-height: 52px; }
.remote-pad { grid-gap: 10px; max-width: 300px; }
.remote-controls { grid-gap: 14px; }
.remote-pad .remote-key { aspect-ratio: 1 / 1; min-height: 0; }

/* Elements fixes du bas sans barre d'onglets au-dessous (accueil sans menu) :
   marge propre en onglet de navigateur, posee sur la zone de securite en PWA
   installee. En PWA, safe-area-inset-top est grand (~47-59 px) : le second
   terme passe sous safe-bottom et max() ne garde que la zone de securite ; en
   onglet, safe-top vaut 0 et la marge reste. */
body:has(.shell.no-rail) .toast {
  bottom: max(env(safe-area-inset-bottom, 0px),
              calc(16px + env(safe-area-inset-bottom, 0px) - env(safe-area-inset-top, 0px)));
}

/* Lecteur plein ecran : avec black-translucent, la page passe SOUS la barre
   d'etat ; sans zone de securite, le titre se cachait sous l'heure et la
   barre de progression sous l'indicateur d'accueil. */
.pl-ui {
  padding:
    max(var(--safe), env(safe-area-inset-top, 0px))
    max(var(--safe), env(safe-area-inset-right, 0px))
    max(var(--safe), env(safe-area-inset-bottom, 0px))
    max(var(--safe), env(safe-area-inset-left, 0px));
}

/* PWA installee sur iPhone (display-mode: standalone).
 *
 * Avec black-translucent + viewport-fit=cover, WebKit rend la FENETRE plus
 * courte que l'ecran de la hauteur de la barre d'etat (bug WebKit 301108) :
 * 100%, 100svh et 100dvh valent tous ~812 pt sur un ecran de 874, et WebKit
 * cesse de dessiner les elements fixes a ce bord -- la barre d'onglets
 * flottait, vide dessous, meme en position: fixed. La fenetre n'est courte que
 * tant que la PAGE est plus courte que l'ecran : on allonge donc la page de la
 * barre d'etat, plafonnee a 100lvh (sinon, avec une barre d'etat opaque, la
 * page defilerait d'autant). Mesure dans le simulateur iOS (frappe-ui #1284) :
 * innerHeight passe de 812 a 874, barre dessinee en entier.
 * Seul html porte la formule (son 100% est la fenetre) ; le reste suit en %,
 * et non plus en 100dvh, qui reste court dans ce mode. Un onglet Safari n'est
 * pas concerne : la media query ne s'y applique pas. */
@media (display-mode: standalone) {
  html {
    height: min(100lvh, calc(100% + env(safe-area-inset-top, 0px)));
    min-height: min(100lvh, calc(100% + env(safe-area-inset-top, 0px)));
  }
  body, #app, .view-host { height: 100%; }
}

/* Ecran de demarrage (premier import du catalogue) : la barre de progression
   faisait 420 px, la largeur d'un telephone entier. Logo et texte a l'echelle
   du telephone. */
.boot-logo { width: 34vmin; max-width: 150px; }
.boot-progress { width: min(240px, 64vw); }
.boot-label { font-size: 13px; text-align: center; }

/* Carte « Episode suivant » : sur toute la largeur du telephone, au-dessus
   des commandes du lecteur et de l'indicateur d'accueil. */
.pl-upnext {
  left: 12px; right: 12px; width: auto;
  bottom: calc(150px + env(safe-area-inset-bottom, 0px));
  padding: 16px 18px;
  border-radius: 18px;
}
.pl-upnext-eyebrow { font-size: 12px; margin-bottom: 4px; }
.pl-upnext-title { font-size: 18px; margin-bottom: 14px; }
.pl-upnext-btn { padding: 11px 16px; font-size: 15px; }
.pl-upnext-btn + .pl-upnext-btn { margin-left: 8px; }
