@charset "UTF-8";
/* ====================================================================
 * lwstuto.fr — feuille de style unique
 * Conception téléphone d'abord. Un seul point de rupture, à 640 px.
 * Palette déduite du logo LWS et de lws.fr :
 *   bleu nuit #001136, bleu LWS #1e499b, orange d'action #ff6600.
 * L'orange est réservé aux boutons d'action et au pictogramme lecture.
 * ================================================================== */

/* ------------------------ Poppins, auto-hébergée --------------------
 * Fichiers dans assets/fonts/. Jamais Google Fonts : cela enverrait
 * l'adresse IP du visiteur chez Google.
 * unicode-range sépare latin et latin-ext : le second (œ, Œ, Ÿ...) n'est
 * téléchargé que si la page en a réellement besoin.
 * ------------------------------------------------------------------ */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/poppins-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/poppins-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/poppins-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/poppins-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------ Jetons ------------------------------ */
:root {
  --bg:          #00102e;
  --bg-deep:     #000b20;
  --surface:     #0a1c3d;
  --surface-2:   #102750;
  --line:        #1d3565;

  --text:        #eef2f9;   /* 15.8:1 sur --bg */
  --muted:       #a8bcdd;   /* 8.1:1  sur --bg */
  --muted-soft:  #8ea4c8;   /* 5.7:1  sur --bg */

  --accent:      #ff6600;   /* orange LWS */
  --accent-hi:   #ff7e28;
  /**
   * Texte et pictogrammes posés sur l'orange : blanc, comme sur lws.fr et
   * comme le symbole du logo. Le ratio blanc sur #ff6600 est de 2,9:1.
   * Choix de marque assumé : voir la note « Contraste des boutons » du README
   * si vous voulez repasser sur une variante conforme AA.
   */
  --on-accent:   #ffffff;
  --focus:       #7fb4ff;

  --r:           12px;
  --r-lg:        16px;
  --pad:         18px;      /* marge latérale de la page */
  --tap:         44px;      /* zone tactile minimale */

  /* Pile système de repli : jamais de Times pendant le chargement. */
  --sans: 'Poppins', system-ui, -apple-system, 'Segoe UI', Roboto,
          'Helvetica Neue', Arial, sans-serif;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  /* Halo discret derrière l'en-tête : conduit l'œil vers le logo et le bouton. */
  background-image:
    radial-gradient(120% 55% at 50% -8%, rgba(30, 73, 155, .55) 0%, rgba(0, 16, 46, 0) 62%),
    radial-gradient(70% 30% at 50% 0%, rgba(255, 102, 0, .13) 0%, rgba(0, 16, 46, 0) 70%);
  background-repeat: no-repeat;
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, p { margin: 0; }
a { color: inherit; text-decoration: none; }

/* Focus clavier visible partout, jamais au clic à la souris. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 6px;
}

.wrap {
  max-width: 560px;
  margin: 0 auto;
  padding: 0 var(--pad) 40px;
}

/* Lien d'évitement : caché jusqu'à la tabulation. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
}
.skip:focus {
  left: 50%;
  transform: translateX(-50%);
  top: 8px;
  padding: 12px 18px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  border-radius: var(--r);
}

/* ---------------------------- En-tête ------------------------------ */
.hero {
  text-align: center;
  padding: 30px 0 4px;
}

.hero__logo {
  height: 46px;
  width: auto;
  margin: 0 auto;
}

/* Repli textuel du logo : visible seulement si logo.svg est absent. */
.hero__fallback {
  font-weight: 600;
  font-size: 34px;
  letter-spacing: .1em;
  color: var(--accent);
  display: none;
}
.hero__fallback--only { display: block; }

.hero__tagline {
  margin: 14px 0 20px;
  font-size: 15px;
  color: var(--muted);
}

.hero__intro {
  margin: 22px 0 0;
  font-size: 14px;
  color: var(--muted-soft);
}

/* ---------------------------- Boutons ------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 12px 24px;
  border-radius: var(--r);
  font-weight: 600;
  font-size: 16px;
  line-height: 1.2;
  transition: background-color .15s ease, transform .1s ease, border-color .15s ease;
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 6px 20px -6px rgba(255, 102, 0, .65);
}
.btn--primary:hover { background: var(--accent-hi); }

.btn--ghost {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line);
  font-size: 15px;
}
.btn--ghost:hover { background: var(--surface-2); border-color: #2a4a86; }

.btn--block { display: flex; width: 100%; }

.btn__arrow { flex: none; }

/* -------------------------- Offre en cours -------------------------
 * Bloc masqué côté PHP quand config.php ne définit pas d'offre.
 * ------------------------------------------------------------------ */
.offer {
  margin: 12px auto 0;
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 10px;
  padding: 7px 14px;
  border: 1px dashed rgba(255, 102, 0, .55);
  border-radius: 999px;
  background: rgba(255, 102, 0, .08);
  font-size: 13.5px;
}
.offer__label { color: #ffc79a; }
.offer__code {
  color: var(--muted);
  border-left: 1px solid rgba(255, 255, 255, .18);
  padding-left: 10px;
}
.offer__code b {
  color: var(--text);
  font-weight: 600;
  letter-spacing: .04em;
}

/* --------------------------- Sections ------------------------------ */
.section { margin-top: 38px; }

.section__head { margin-bottom: 14px; }

.section__title {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -.01em;
}

.section__hint {
  margin-top: 4px;
  font-size: 13px;
  color: var(--muted-soft);
}

/* ----------------- Rangées horizontales, CSS pur -------------------
 * scroll-snap sans une ligne de JavaScript. Les marges négatives
 * laissent les cartes atteindre les bords de l'écran, ce qui montre
 * qu'il y a quelque chose à faire glisser.
 * ------------------------------------------------------------------ */
.rail {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--pad);
  overscroll-behavior-x: contain;      /* n'accroche pas le geste « retour » */
  -webkit-overflow-scrolling: touch;
  margin: 0 calc(var(--pad) * -1);
  padding: 2px var(--pad) 10px;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail:focus-visible { outline-offset: -3px; }

/* ---------------------------- Cartes ------------------------------- */
.card {
  flex: 0 0 auto;
  scroll-snap-align: start;
  width: 45%;
  min-width: 140px;
  max-width: 210px;
}
.card--wide {
  width: 62%;
  min-width: 190px;
  max-width: 260px;
}

.card__link {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
  border-radius: var(--r);
}
.card__link:hover .thumb__img { transform: scale(1.04); }
.card__link:hover .thumb__play { background: var(--accent-hi); }

/* Vignette : le dégradé et le pictogramme vivent sur le conteneur.
 * Si l'image manque (vidéo privée, réseau coupé), il reste un bloc
 * habillé, pas un cadre vide ni une icône d'image cassée. */
.thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: var(--r);
  overflow: hidden;
  background: linear-gradient(135deg, #122a55, #0a1a38);
  border: 1px solid var(--line);
}
.thumb__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .25s ease;
}
/* Image réellement cassée (proxy désactivé + vignette absente chez YouTube) :
   app.js pose cet attribut, le dégradé du conteneur reprend la main. */
.thumb__img[data-broken] { visibility: hidden; }

.thumb__play {
  position: absolute;
  inset: auto 6px 6px auto;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  transition: background-color .15s ease;
}
.thumb__play svg { margin-left: 1px; }

.card__title {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.32;
  color: var(--text);
  /* Un titre très long est coupé à deux lignes : les rangées gardent la
     même hauteur. Le titre complet reste dans l'aria-label du lien. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.card--wide .card__title { font-size: 14.5px; }

.card__date {
  font-size: 11.5px;
  color: var(--muted-soft);
  margin-top: -2px;
}

/* ------------------------ Bloc playlist ----------------------------
 * Une playlist = une ligne compacte : titre, rangée de trois vignettes,
 * lien vers la playlist. Neuf blocs restent parcourables en peu de scroll.
 * ------------------------------------------------------------------ */
.pl {
  padding: 14px 0 6px;
  border-top: 1px solid var(--line);
}
.pl:first-of-type { border-top: 0; padding-top: 0; }

.pl__title {
  font-size: 15.5px;
  font-weight: 600;
  margin-bottom: 10px;
  color: var(--text);
  overflow-wrap: anywhere;
}

.pl__more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: var(--tap);
  padding: 0 2px;
  font-size: 13.5px;
  font-weight: 600;
  color: #9dc0ff;                       /* 6.5:1 sur --bg */
}
.pl__more:hover { color: #c6dcff; text-decoration: underline; }
.pl__more svg { flex: none; }

/* Bouton de fin de section, sous la dernière rangée de playlists.
   La marge le détache franchement du lien « Voir la playlist » qui le
   précède : il porte sur toute la section, pas sur la dernière playlist. */
.pl__all { margin-top: 26px; }

/* ----------------------------- Repli ------------------------------- */
.notice {
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--muted);
  font-size: 14.5px;
}
.notice a { color: #9dc0ff; text-decoration: underline; }

/* -------------------------- Pied de page --------------------------- */
.foot {
  margin-top: 44px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
  text-align: center;
}

.social {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin: 22px 0 18px;
}
.social__link {
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  border-radius: var(--r);
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  transition: color .15s ease, background-color .15s ease;
}
.social__link:hover { color: var(--text); background: var(--surface-2); }
.social__text { font-size: 11px; font-weight: 600; padding: 0 6px; }

.foot__legal {
  font-size: 12px;
  color: var(--muted-soft);
  max-width: 34ch;
  margin: 0 auto;
  line-height: 1.55;
}

/* =========================== Tablette ==============================
 * À partir de 640px la rangée cesse de défiler : les vignettes tiennent
 * côte à côte, la grille remplace le défilement horizontal.
 * ================================================================== */
@media (min-width: 640px) {
  :root { --pad: 24px; }

  .wrap { max-width: 720px; }

  .hero { padding-top: 48px; }
  .hero__logo { height: 56px; }
  .section { margin-top: 48px; }
  .section__title { font-size: 22px; }

  /* Les rangées de trois vignettes tiennent désormais côte à côte : la
     grille remplace le défilement.
     La rangée des cinq dernières vidéos en est exclue volontairement :
     cinq ne se divise pas par trois et donnerait une ligne bancale de
     3 + 2. Elle continue de défiler ici, et passera sur une seule ligne
     à partir de 1024px, où les cinq tiennent enfin. */
  .pl .rail {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    overflow: visible;
    scroll-snap-type: none;
    margin: 0;
    padding: 2px 0 6px;
  }
  .pl .rail .card {
    width: auto;
    min-width: 0;
    max-width: none;
  }
  /* Les rangées de thèmes ne glissent plus : la consigne n'a plus d'objet. */
  .section__hint { display: none; }
}

/* Tablette tactile : le doigt reprend la main, on rétablit le glissement
   des rangées de thèmes et la consigne qui va avec. */
@media (min-width: 640px) and (pointer: coarse) {
  .pl .rail {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    margin: 0 calc(var(--pad) * -1);
    padding: 2px var(--pad) 10px;
  }
  .pl .rail .card { width: 31%; }
  .section__hint { display: block; }
}

/* =========================== Desktop ===============================
 * Conteneur classique de 1140px et échelle typographique agrandie : à
 * 1440px, une colonne de 560px paraissait perdue au milieu de l'écran.
 *
 * Deux changements de structure ici :
 *  - les cinq dernières vidéos passent sur une seule ligne, au lieu de
 *    se casser en 3 + 2 ;
 *  - chaque playlist devient deux colonnes, titre et lien à gauche,
 *    vignettes à droite. Cela garde une playlist par ligne, donc le
 *    balayage des neuf thèmes reste immédiat, tout en divisant la
 *    hauteur de la section.
 * ================================================================== */
@media (min-width: 1024px) {
  :root { --pad: 32px; --tap: 48px; }

  body { font-size: 17px; }

  .wrap {
    max-width: 1140px;
    padding-bottom: 64px;
  }

  /* ---- En-tête ---- */
  .hero { padding: 64px 0 8px; }
  .hero__logo { height: 68px; }
  .hero__fallback { font-size: 44px; }
  .hero__tagline { font-size: 19px; margin: 20px 0 26px; }
  .hero__intro { font-size: 16px; margin-top: 30px; }

  /* ---- Boutons ---- */
  .btn { font-size: 17px; padding: 14px 30px; }
  .btn--primary { font-size: 18px; padding: 17px 40px; }
  .btn--ghost { font-size: 16px; }
  /* Un bouton de 1140px de large serait grotesque : on le recentre. */
  .btn--block {
    max-width: 420px;
    margin-left: auto;
    margin-right: auto;
  }
  /* Les vignettes agrandies laissent moins d'air qu'en mobile sous la
     dernière ligne de dates : on redonne de la respiration au bouton. */
  .section > .btn--block { margin-top: 22px; }

  .offer { font-size: 15px; padding: 9px 18px; }

  /* ---- Sections ---- */
  .section { margin-top: 68px; }
  .section__head { margin-bottom: 20px; }
  .section__title { font-size: 26px; }

  .pl .rail { gap: 20px; }

  /* Les cinq dernières vidéos cessent de défiler et tiennent sur une
     seule ligne : c'est la section prioritaire, elle doit se lire d'un
     coup d'œil sans aucun geste. */
  .rail--wide {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 20px;
    overflow: visible;
    scroll-snap-type: none;
    margin: 0;
    padding: 2px 0 6px;
  }
  .rail--wide .card--wide {
    width: auto;
    min-width: 0;
    max-width: none;
  }

  .card__title,
  .card--wide .card__title { font-size: 14.5px; line-height: 1.35; }
  .card__date { font-size: 12.5px; }

  .thumb__play { width: 38px; height: 38px; inset: auto 8px 8px auto; }
  .thumb__play svg { width: 15px; height: 15px; }

  /* ---- Playlists en deux colonnes ---- */
  .pl {
    display: grid;
    grid-template-columns: 288px minmax(0, 1fr);
    column-gap: 40px;
    align-items: start;
    padding: 26px 0 12px;
  }
  .pl__title {
    grid-column: 1;
    grid-row: 1;
    font-size: 20px;
    line-height: 1.3;
    margin-bottom: 4px;
  }
  .pl__more {
    grid-column: 1;
    grid-row: 2;
    /* Sans ces deux lignes, l'élément de grille s'étirerait sur toute la
       cellule : la zone cliquable dépasserait largement le texte et le
       lien flotterait au milieu de la hauteur des vignettes au lieu de
       rester solidaire de son titre. */
    justify-self: start;
    align-self: start;
    font-size: 15px;
  }
  .pl .rail {
    grid-column: 2;
    grid-row: 1 / span 2;
    /* Sur un portable tactile, le bloc « pointer: coarse » plus haut pose
       des marges négatives pour que les vignettes touchent les bords de
       l'écran. Dans cette mise en page en deux colonnes, elles feraient
       déborder la rangée hors du conteneur : on les annule. */
    margin: 0;
    padding: 0 0 6px;
  }

  .pl__all { margin-top: 34px; }

  .notice { font-size: 16px; padding: 22px; }

  /* ---- Pied de page ---- */
  .foot { margin-top: 72px; padding-top: 36px; }
  .social { gap: 10px; margin: 28px 0 22px; }
  .foot__legal { font-size: 13.5px; max-width: 52ch; }
}

/* Très grands écrans : on laisse le conteneur respirer un peu plus,
   sans jamais étirer les lignes de texte au-delà du confortable. */
@media (min-width: 1400px) {
  .wrap { max-width: 1240px; }
  .pl { grid-template-columns: 320px minmax(0, 1fr); }
}

/* ------------------------- Préférences système ---------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .card__link:hover .thumb__img { transform: none; }
}

@media (prefers-contrast: more) {
  :root {
    --muted: #d5e2f5;
    --muted-soft: #c3d3ee;
    --line: #3d5f9e;
  }
}

/* Impression : rare pour ce type de page, mais aucune raison que ce soit illisible. */
@media print {
  body { background: #fff; color: #000; }
  .rail { flex-wrap: wrap; overflow: visible; }
  .btn--primary { box-shadow: none; }
}
