/* ==========================================================================
   SP Maquettes — charte graphique
   Feuille de référence unique : variables, composants, utilitaires.
   Thème sombre par défaut ; le thème clair est prêt mais non exposé
   (pas de bouton de bascule dans la maquette validée).
   ========================================================================== */

/* --- Polices -------------------------------------------------------------
   Orbitron      : titres, navigation, libellés de blocs (identité SF du site)
   Chakra Petch  : texte courant, listes, formulaires
   JetBrains Mono: données, compteurs, pagination, langue
-------------------------------------------------------------------------- */

:root {
  /* Fonds : du plus profond (page) au plus clair (surface) */
  --bg:  #070c11;
  --bg2: #0d151c;
  --bg3: #121c25;

  /* Filets */
  --line:  rgba(125,195,212,.16);
  --line2: rgba(125,195,212,.30);

  /* Texte : principal / secondaire / tertiaire */
  --tx:  #dae6ec;
  --tx2: #8ba0ab;
  --tx3: #62757f;

  /* Accent cyan (liens, titres de blocs, éléments actifs) */
  --cy:  #5cc8e8;
  --cyd: rgba(92,200,232,.16);   /* halo / survol / fond léger d'accent */

  /* Ambre : réservé au bandeau (nom du site, titre de page) */
  --am:   #eec06a;
  --on-am: #05080b;              /* texte posé sur un aplat ambre */

  /* Niveaux de difficulté — seuls porteurs d'une couleur propre.
     Feu tricolore : vert, jaune, rouge, dans le registre désaturé de la
     charte pour ne pas jurer avec le cyan dominant. Le jaune est poussé vers
     l'or plutôt que l'orange, pour rester franchement distinct du rouge. */
  --lv-base:     #7cc9a4;
  --lv-standard: #d4b445;
  --lv-avance:   #e3766e;

  /* Matière des blocs */
  --blk:      linear-gradient(180deg,#141c23,#0d151b);
  --blk-edge: rgba(120,200,225,.22);
  --blk-head: rgba(92,200,232,.07);   /* en-tête et pied de bloc */

  /* Divers */
  --ph:         rgba(140,200,215,.07);              /* trame « image manquante » */
  --sh:         rgba(0,0,0,.45);                    /* ombre de cadre */
  --scrim:      rgba(7,12,17,.6);                   /* voile plein */
  --scrim-grad: linear-gradient(transparent,rgba(5,9,13,.86)); /* voile de légende */
  --scrim-band: rgba(5,9,13,.58);                   /* bandeau de légende */

  /* Rythme */
  --gap:   26px;   /* marge de page et gouttière principale */
  --gap-s: 18px;
  --notch: 16px;   /* profondeur des coins coupés */

  /* Ajouts hors charte d'origine, nécessaires à l'intégration.
     Aucune couleur nouvelle : uniquement des rôles dérivés. */
  --danger: #e88b8b;             /* erreurs de formulaire, suppression */
  --ok:     var(--lv-base);      /* confirmations */
  --edge-grad: linear-gradient(90deg, rgba(92,200,232,.25), var(--cy) 35%, var(--cy) 65%, rgba(92,200,232,.25));
  --page-max: 1400px;            /* largeur maximale du contenu */
}

/* Alias de compatibilité : les écrans d'administration, hors périmètre de la
   refonte, référencent encore les noms de l'ancienne feuille. Ils pointent vers
   les rôles de la charte pour rester cohérents sans être réécrits. */
:root {
  --bg-dark:        var(--bg);
  --bg-panel:       var(--bg2);
  --border-glow:    var(--cy);
  --border-glow-alt: var(--line2);
  --text-primary:   var(--tx);
  --text-accent:    var(--cy);
  --text-title:     var(--am);
  --text-muted:     var(--tx2);
  --link-color:     var(--cy);
}

/* Les écrans d'administration rendent les textes d'aide en .help-text, que
   Bootstrap colore en quasi-noir : illisible sur le fond sombre de la charte. */
.help-text { color: var(--tx2); }

[data-theme="light"] {
  --bg: #e9edee; --bg2: #f5f8f8; --bg3: #ffffff;
  --line: rgba(18,54,64,.16); --line2: rgba(18,54,64,.32);
  --tx: #16232a; --tx2: #566a73; --tx3: #7b8c94;
  --cy: #1e7d88; --cyd: rgba(30,125,136,.10);
  --am: #8a6520; --on-am: #f7fafa;
  --lv-base: #2f7d5c; --lv-standard: #8a7310; --lv-avance: #a33430;
  --blk: linear-gradient(180deg,#ffffff,#eef3f4);
  --blk-edge: rgba(18,80,95,.26); --blk-head: rgba(20,110,130,.07);
  --ph: rgba(18,60,70,.07); --sh: rgba(20,40,50,.12);
  --scrim: rgba(255,255,255,.78);
  --scrim-grad: linear-gradient(transparent,rgba(255,255,255,.92));
  --scrim-band: rgba(255,255,255,.72);
  --danger: #a3312f;
}

/* --- Base ---------------------------------------------------------------- */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--tx);
  font-family: 'Chakra Petch', system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  /* Empêche tout débordement horizontal résiduel sur petits écrans. */
  overflow-x: hidden;
}

a         { color: var(--cy); text-decoration: none; }
a:hover   { color: var(--tx); }

h1, h2, h3, .sp-title {
  font-family: Orbitron, sans-serif;
  font-weight: 500;
  letter-spacing: .06em;
  margin: 0;
}

p { text-wrap: pretty; }

img { max-width: 100%; }

/* Règle de couleur — à respecter strictement :
   ambre = bandeau uniquement · cyan = liens, titres de blocs, éléments actifs
   couleurs de niveau = pastilles de difficulté uniquement
   tout le reste = --tx / --tx2 / --tx3.
   Deux textes de même fonction ne portent jamais deux couleurs. */

/* --- Barre de navigation ------------------------------------------------- */

.sp-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 74px;
  padding: 0 var(--gap);
  border-bottom: 3px solid transparent;
  background-image:
    linear-gradient(180deg, var(--bg3), var(--bg2)),
    linear-gradient(90deg, rgba(92,200,232,.25), var(--cy) 35%, var(--cy) 65%, rgba(92,200,232,.25));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  box-shadow: 0 6px 20px var(--cyd);
  position: relative;
  z-index: 20;
}

/* The cosmonaut rests on the cyan bottom border of the bar, hiding the flat
   cut at the bottom of the bust while keeping the normal left padding. */
.sp-nav__brand      { display: flex; align-items: flex-end; gap: 13px; align-self: stretch; }
.sp-nav__logo {
  display: flex; align-items: flex-end; justify-content: center;
  flex: none;
}
.sp-nav__logo picture { display: block; font-size: 0; }
.sp-nav__logo img {
  width: 73px; height: 58px;
  display: block;
}
.sp-nav__name {
  align-self: center;
  font-family: Orbitron, sans-serif; font-weight: 500;
  font-size: 14px; letter-spacing: .2em; color: var(--tx);
  white-space: nowrap;
}

.sp-nav__menu       { display: flex; align-items: center; gap: 30px; }
.sp-nav__link {
  font-family: Orbitron, sans-serif;
  font-size: 14px; letter-spacing: .14em;
  color: var(--tx2);
  padding-bottom: 5px;
  border-bottom: 2px solid transparent;
  transition: color .18s;
  white-space: nowrap;
}
.sp-nav__link:hover        { color: var(--tx); }
.sp-nav__link--active      { color: var(--cy); border-bottom-color: var(--cy); }

.sp-nav__side { display: flex; align-items: center; gap: 22px; }

.sp-nav__lang {
  font-family: 'JetBrains Mono', monospace; font-size: 13px; color: var(--tx3);
  white-space: nowrap;
}
.sp-nav__lang a { color: var(--tx3); }
.sp-nav__lang a:hover { color: var(--tx); }
.sp-nav__lang b { color: var(--tx); font-weight: 400; }
.sp-nav__lang .is-on { color: var(--cy); }

/* Bouton burger : n'apparaît qu'en dessous du seuil de bascule. */
.sp-nav__burger {
  display: none;
  width: 42px; height: 42px;
  align-items: center; justify-content: center;
  flex-direction: column; gap: 5px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line2);
  cursor: pointer;
}
.sp-nav__burger span {
  display: block; width: 20px; height: 2px; background: var(--cy);
  transition: transform .2s, opacity .2s;
}
.sp-nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.sp-nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.sp-nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- Menu du compte (remplace le dropdown Bootstrap côté public) ---------- */

.sp-account { position: relative; }
.sp-account__toggle {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  font-family: Orbitron, sans-serif; font-size: 13px; letter-spacing: .1em;
  color: var(--tx2);
  background: transparent;
  border: 1px solid var(--line2);
  cursor: pointer;
  transition: color .18s, border-color .18s;
}
.sp-account__toggle:hover,
.sp-account__toggle[aria-expanded="true"] { color: var(--cy); border-color: var(--cy); }
.sp-account__menu {
  position: absolute; right: 0; top: calc(100% + 10px);
  min-width: 240px;
  padding: 6px 0;
  background: var(--bg2);
  border: 1px solid var(--blk-edge);
  box-shadow: 0 10px 30px var(--sh);
  z-index: 40;
}
.sp-account__menu[hidden] { display: none; }
.sp-account__menu a {
  display: block;
  padding: 10px 16px;
  font-size: 15px; color: var(--tx2);
}
.sp-account__menu a:hover { background: var(--cyd); color: var(--cy); }
/* Un <span> reste inline : sans display:block, sa hauteur est ignorée et le
   filet de séparation ne se voit pas. */
.sp-account__sep { display: block; height: 1px; margin: 6px 0; background: var(--line); }

/* --- Bandeau (toutes les pages) ------------------------------------------ */

.sp-banner {
  position: relative;
  padding: 34px var(--gap) 30px;
  text-align: center;
  background:
    radial-gradient(120% 200% at 50% 0%, rgba(92,200,232,.13), transparent 62%),
    linear-gradient(180deg, var(--bg3), var(--bg));
}
.sp-banner::after {            /* trait lumineux de fin de bandeau */
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--cy), transparent);
  box-shadow: 0 0 8px var(--cyd);
}
.sp-banner__title {            /* nom du site (accueil) ou titre de la page/article */
  font-family: Orbitron, sans-serif; font-weight: 500;
  font-size: 40px; letter-spacing: .1em;
  color: var(--am);
  /* Un titre d'article long ne doit jamais élargir la page. */
  overflow-wrap: break-word;
}
.sp-banner__title--home  { font-size: 48px; }
.sp-banner__subtitle     { margin-top: 14px; font-size: 17px; letter-spacing: .06em; color: var(--am); }
.sp-banner__meta {         /* niveau de difficulté d'un article, centré sous le titre */
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 14px; font-size: 14px; color: var(--tx2);
}

/* --- Ossature de page ---------------------------------------------------- */

.sp-page { display: flex; flex-direction: column; min-height: 100vh; }
.sp-main { flex: 1 0 auto; }
/* Les écrans d'administration n'utilisent pas .sp-wrap : la classe container
   de Bootstrap leur donne leur gouttière, mais elle est absente quand seule la
   charte est chargée. On garantit une marge latérale par défaut. */
.sp-main > .container,
.sp-main > .container-fluid { padding-inline: var(--gap); }
.sp-main > :not(.sp-wrap):not(.sp-article):not(.container):not(.container-fluid):not(script):not(style) {
  padding-inline: var(--gap);
}

/* Conteneur horizontal partagé : tous les blocs d'une page portent la même
   marge latérale. */
.sp-wrap {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--gap);
}
.sp-wrap--tight { padding-top: 20px; }

/* Grille de l'accueil : le minmax(0,1fr) est indispensable, sans quoi la
   colonne du carrousel refuse de se comprimer et fait déborder la seconde. */
.sp-home {
  display: grid;
  grid-template-columns: minmax(0,1fr) 384px;
  gap: var(--gap);
  align-items: stretch;
}
.sp-home > * { min-width: 0; }

/* En-tête de section : fil d'ariane à gauche, compteur à droite. */
.sp-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
  margin-bottom: var(--gap-s);
}

/* Atelier : colonne de filtres + résultats. */
.sp-workshop {
  display: grid;
  grid-template-columns: 264px minmax(0,1fr);
  gap: var(--gap);
  align-items: start;
}
.sp-workshop > * { min-width: 0; }

/* --- Bloc (unité de mise en page) ---------------------------------------- */

.sp-block {
  position: relative;
  background: var(--blk);
  border: 1px solid var(--blk-edge);
  box-shadow: 0 2px 0 rgba(0,0,0,.25);
  /* Un bloc en grille doit remplir la hauteur de sa colonne. */
  display: flex;
  flex-direction: column;
}
.sp-block::before {            /* arête haute, reprise du dégradé du bandeau */
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, rgba(92,200,232,.25), var(--cy) 35%, var(--cy) 65%, rgba(92,200,232,.25));
  box-shadow: 0 0 10px var(--cyd);
  z-index: 1;
}
.sp-block__head,
.sp-block__foot {
  padding: 18px 20px;
  background: var(--blk-head);
  font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: .1em;
}
.sp-block__head { border-bottom: 1px solid var(--blk-edge); }
.sp-block__foot { border-top: 1px solid var(--blk-edge); color: var(--cy); cursor: pointer; }
.sp-block__foot:hover { background: var(--cyd); }
.sp-block__foot a { display: block; color: inherit; }
.sp-block__title {
  font-family: Orbitron, sans-serif; font-size: 16px; letter-spacing: .1em; color: var(--cy);
}
.sp-block__body  { padding: 20px; flex: 1 1 auto; }
/* Corps qui centre son contenu verticalement (carrousel de l'accueil). */
.sp-block__body--center { display: flex; flex-direction: column; justify-content: center; }
/* Le pied doit rester collé en bas quand la liste est plus courte. */
.sp-block__fill { flex: 1 1 auto; }

/* --- Liste (derniers tutoriels) ------------------------------------------ */

/* Entrée à deux lignes : titre, puis type de difficulté sous-titré.
   Les entrées se répartissent la hauteur du bloc pour s'aligner sur la colonne
   voisine plutôt que de se tasser en haut. */
.sp-list__item {
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid transparent;
  cursor: pointer;
  transition: background .18s, border-color .18s;
}
.sp-list__item:hover     { background: var(--cyd); border-left-color: var(--cy); }
/* Entrée courante : la page qu'on lit reste dans la liste, mise en relief au
   lieu d'en être retirée, pour que le lecteur garde ses repères. */
.sp-list__item--current  { background: var(--cyd); border-left-color: var(--cy); cursor: default; }
.sp-list__label          { font-family: Orbitron, sans-serif; font-size: 15px; line-height: 1.35; color: var(--tx); }
.sp-list__item:hover .sp-list__label { color: var(--tx); }
.sp-list__item--current .sp-list__label { color: var(--cy); }
.sp-list__meta {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--tx2);
}

/* Répartition verticale des entrées dans la hauteur disponible. */
.sp-block__fill--spread { display: flex; flex-direction: column; }
.sp-block__fill--spread .sp-list__item { flex: 1 1 0; }

/* --- Bandeau d'actualités (haut de l'accueil) ---------------------------- */

/* Une ligne pleine largeur : le libellé à gauche sur fond appuyé, puis les
   actualités en colonnes séparées par un filet. Le bandeau n'existe que
   lorsqu'une actualité est publiée, le reste de la page ne l'attend pas. */
.sp-newsbar {
  display: flex;
  align-items: stretch;
  margin-bottom: var(--gap);
  border: 1px solid var(--line);
  border-top: 2px solid var(--cy);
  background: var(--bg2);
}
.sp-newsbar__label {
  display: flex; align-items: center; gap: 10px;
  padding: 0 26px;
  font-family: Orbitron, sans-serif;
  font-size: 14px; letter-spacing: .16em;
  color: var(--cy);
  background: var(--bg3);
  border-right: 1px solid var(--line);
  white-space: nowrap;
}
.sp-newsbar__dot {
  width: 7px; height: 7px; flex: none;
  border-radius: 50%;
  background: var(--cy);
}
.sp-newsbar__item {
  position: relative;
  flex: 1 1 0;
  padding: 16px 24px;
  border-right: 1px solid var(--line);
  min-width: 0;
}
/* Crayon d'édition, révélé au survol de l'actualité comme les zones de texte
   modifiables du bas de page. */
.sp-newsbar__edit {
  position: absolute;
  top: 10px; right: 10px;
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  color: var(--cy);
  background: var(--bg2);
  border: 1px solid var(--line2);
  opacity: 0;
  transition: opacity .18s, border-color .18s;
}
.sp-newsbar__edit svg { width: 13px; height: 13px; }
.sp-newsbar__edit svg path {
  stroke: currentColor; stroke-width: 1.8; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.sp-newsbar__edit:hover { border-color: var(--cy); }
.sp-newsbar__item:hover .sp-newsbar__edit,
.sp-newsbar__edit:focus-visible { opacity: 1; }
.sp-newsbar__item:last-child { border-right: none; }
.sp-newsbar__date {
  display: block;
  font-family: Orbitron, sans-serif;
  font-size: 12px; letter-spacing: .08em;
  color: var(--tx3);
}
.sp-newsbar__title {
  margin: 6px 0 0;
  font-family: Orbitron, sans-serif; font-weight: 500;
  font-size: 16px; line-height: 1.3;
  color: var(--tx);
}
.sp-newsbar__text {
  margin: 8px 0 0;
  font-size: 14px; line-height: 1.55;
  color: var(--tx2);
}
.sp-newsbar__more {
  display: inline-block;
  margin-top: 8px;
  font-size: 13px;
  color: var(--cy);
}
.sp-newsbar__more:hover { text-decoration: underline; }

/* --- Actualité (page d'une actualité) ------------------------------------ */

.sp-news        { display: flex; gap: var(--gap-s); }
.sp-news--next  { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--line); }
.sp-news__media { flex: 0 0 190px; height: 140px; overflow: hidden; border: 1px solid var(--line); }
.sp-news__text  { min-width: 0; }
.sp-news__title { font-family: Orbitron, sans-serif; font-size: 17px; line-height: 1.35; color: var(--cy); }
.sp-news__body  { margin-top: 10px; font-size: 15px; line-height: 1.65; color: var(--tx2); }
.sp-news__body p:first-child { margin-top: 0; }
.sp-news__body img { display: block; max-width: 100%; height: auto; margin-top: 12px; border: 1px solid var(--line); }
/* Page d'une actualité : l'image passe au-dessus du texte, en pleine largeur,
   au lieu de la vignette latérale utilisée dans les listes. */
.sp-news--full        { flex-direction: column; }
.sp-news__media--full { flex: none; width: 100%; height: 320px; }
.sp-news__back        { margin-top: 28px; font-size: 15px; }
.sp-news__back a      { color: var(--cy); }
.sp-news__back a:hover { text-decoration: underline; }

@media (max-width: 560px) {
  .sp-news        { flex-direction: column; }
  .sp-news__media { flex: none; width: 100%; height: 180px; }
}

/* --- Carte (vignette de tutoriel) --------------------------------------- */

.sp-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--blk);
  border: 1px solid var(--blk-edge);
  box-shadow: 0 2px 0 rgba(0,0,0,.25);
  cursor: pointer;
  transition: transform .2s, border-color .2s, box-shadow .2s;
}
.sp-card::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, rgba(92,200,232,.25), var(--cy) 35%, var(--cy) 65%, rgba(92,200,232,.25));
  box-shadow: 0 0 8px var(--cyd);
  z-index: 1;
}
.sp-card:hover {
  transform: translateY(-5px);
  border-color: var(--cy);
  box-shadow: 0 2px 0 rgba(0,0,0,.25), 0 0 16px var(--cyd);
}
.sp-card__media  { height: 184px; margin-top: 3px; border-bottom: 1px solid var(--blk-edge); overflow: hidden; }
.sp-card__media img,
.sp-card__media picture { display: block; width: 100%; height: 100%; object-fit: cover; }
.sp-card__body   { padding: 18px; display: flex; flex-direction: column; flex: 1 1 auto; }
.sp-card__title  { font-family: Orbitron, sans-serif; font-size: 18px; line-height: 1.3; color: var(--cy); }
.sp-card__excerpt{ margin-top: 12px; font-size: 15px; line-height: 1.65; color: var(--tx2); }
.sp-card__foot {   /* dernière ligne : difficulté seule, jamais de donnée inventée */
  display: flex; align-items: center; gap: 9px;
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 14px; color: var(--tx2);
}
/* Pousse le pied en bas quand les extraits ont des longueurs inégales. */
.sp-card__spacer { flex: 1 1 auto; }

/* --- Pastille de difficulté --------------------------------------------- */

.sp-level            { width: 10px; height: 10px; border-radius: 50%; background: var(--tx3); flex: none; }
.sp-level--base      { background: var(--lv-base); }
.sp-level--standard  { background: var(--lv-standard); }
/* Le code stocke le niveau sous la clé « advanced » ; la charte nomme la
   variable et la classe « avance ». Les deux sélecteurs pointent la même
   couleur pour que le gabarit puisse écrire la valeur brute de la base. */
.sp-level--avance,
.sp-level--advanced  { background: var(--lv-avance); }

/* --- Carrousel de photomontages (accueil) ------------------------------- */

.sp-carousel        { position: relative; display: grid; grid-template-columns: 96px minmax(0,1fr) 96px; gap: 14px; align-items: center; min-width: 0; }
.sp-carousel__side  { height: 300px; border: 1px solid var(--line); cursor: pointer; transition: border-color .2s; overflow: hidden; }
.sp-carousel__side:hover { border-color: var(--cy); }
.sp-carousel__main {
  position: relative; height: 426px;
  border: 1px solid var(--cy);
  box-shadow: 0 0 20px var(--cyd);
  clip-path: polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px);
}
.sp-carousel__caption {   /* légende sur voile dégradé, jamais de couleur en dur */
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px;
  background: var(--scrim-grad);
  pointer-events: none;
  font-size: 14px; color: var(--tx);
}
/* Cadre à deux coins coupés opposés, dessiné en SVG plutôt qu'avec clip-path :
   clip-path rogne la bordure au lieu de la tracer, ce qui laisse les côtés
   biseautés sans trait. Le SVG donne un contour net sur tout le pourtour.
   Les couleurs y sont écrites en dur faute de pouvoir interpoler une variable
   dans une data: URI — elles reprennent --bg2 (#0d151c) et --cy (#5cc8e8). */
.sp-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  /* Carré : les biseaux du cadre SVG restent à 45°, comme à l'origine. */
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: var(--cy);
  border: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M12 1 H47 V36 L36 47 H1 V12 Z' fill='%230d151c' stroke='%235cc8e8' stroke-width='1.5'/%3E%3C/svg%3E")
    center / 100% 100% no-repeat;
  box-shadow: 0 0 14px var(--cyd);
  cursor: pointer;
  transition: background .18s, color .18s;
  z-index: 3;
  padding: 0;
}
.sp-arrow:hover {
  color: var(--bg);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M12 1 H47 V36 L36 47 H1 V12 Z' fill='%235cc8e8' stroke='%235cc8e8' stroke-width='1.5'/%3E%3C/svg%3E")
    center / 100% 100% no-repeat;
}
.sp-arrow--prev   { left: 26px; }
.sp-arrow--next   { right: 26px; }
.sp-arrow svg     { width: 22px; height: 22px; }
.sp-arrow svg path{ stroke: currentColor; stroke-width: 2.4; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* Reskin du « peek slider » existant : la mécanique JavaScript (clones,
   translation, voisins atténués) est conservée, seule l'apparence change. */
.peek-slider   { position: relative; }
/* Les voisins qui dépassent sont rognés au bord du bloc : sans cela la
   diapositive suivante déborde par-dessus la bordure. */
.peek-viewport { overflow: hidden; }
.peek-track    { display: flex; transition: transform .6s cubic-bezier(.22,.61,.36,1); }
/* Hauteur des diapositives : la largeur en découle via le format de la photo. */
.peek-slider   { --peek-h: 426px; }
/* La largeur de chaque diapositive suit le format de sa photo (--peek-ratio,
   calculé au rendu depuis les dimensions du fichier) : la hauteur restant fixe,
   l'image entre entière dans son cadre au lieu d'être rognée. Sans mesure, on
   retombe sur la largeur historique. Le ratio est plafonné côté serveur, donc
   seules les panoramiques extrêmes restent rognées — sur les côtés. */
.peek-slide {
  flex: 0 0 auto;
  width: calc(var(--peek-h) * var(--peek-ratio, 1.46) + 16px);
  max-width: 100%;
  padding: 0 8px;
}
/* Hauteur portée par le lien : l'image est positionnée en absolu à l'intérieur
   pour laisser dépasser le trait du cadre. */
.peek-slide a  { position: relative; display: block; height: var(--peek-h); }
.peek-img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  box-shadow: 0 0 20px var(--cyd);
  clip-path: polygon(18px 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%, 0 18px);
  transition: opacity .4s, filter .4s;
}
/* Le trait du cadre est une plaque de couleur posée SOUS l'image et découpée
   à la même forme : ce qui dépasse dessine le contour, biseaux compris. Une
   border classique ne convient pas — clip-path la rogne au lieu de la suivre,
   laissant les côtés coupés sans trait (même raison que le cadre SVG des
   flèches). La plaque reste DANS les limites de la diapositive au lieu de
   déborder : un voisin sort du bloc, et un trait posé à l'extérieur serait
   emporté par le rognage du viewport, laissant son cadre ouvert. */
.peek-slide a::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: var(--cy);
  clip-path: polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px);
  transition: background .4s;
}
/* L'image est rentrée de 2 px dans la plaque : la frange qui reste visible tout
   autour est le trait. Le biseau de l'image suit celui de la plaque pour que
   les deux diagonales restent parallèles. */
.peek-slide picture {
  display: block;
  position: absolute;
  inset: 2px;
  z-index: 1;
}
/* Les voisins qui dépassent de chaque côté jouent le rôle des vignettes
   latérales : cadre discret, sans coin coupé ni halo. Leur bord extérieur
   tombe hors du bloc, un contour tracé là serait de toute façon rogné. */
.peek-slide:not(.is-active) .peek-img {
  opacity: .45;
  filter: saturate(.75);
  box-shadow: none;
  clip-path: none;
}
.peek-slide:not(.is-active) a::before {
  background: var(--line);
  clip-path: none;
}
/* Pendant le saut invisible d'un clone vers sa diapositive réelle, plus rien ne
   doit s'animer : un fondu de 0,4 s pendant un déplacement instantané fait
   clignoter les deux photos l'une sur l'autre. */
.peek-slider--instant .peek-track,
.peek-slider--instant .peek-img,
.peek-slider--instant .peek-slide a::before { transition: none !important; }
/* Le carrousel ne porte aucune légende : les titres de photomontages sont des
   noms de fichiers, et un compteur n'apporte rien sur une sélection aléatoire.
   La photo se suffit à elle-même. */

/* --- Filtres (atelier) --------------------------------------------------- */

.sp-filter        { position: sticky; top: 20px; }
.sp-filter__group { margin-bottom: 24px; }
.sp-filter__title {
  font-family: Orbitron, sans-serif; font-size: 14px; letter-spacing: .1em; color: var(--tx);
  padding-bottom: 9px; border-bottom: 2px solid var(--cy);
  margin-bottom: 10px;
}
.sp-filter__row   { display: flex; align-items: center; gap: 11px; padding: 9px 4px; font-size: 16px; color: var(--tx2); cursor: pointer; }
.sp-filter__row:hover { color: var(--tx); }
.sp-filter__box   { width: 15px; height: 15px; border: 1px solid var(--line2); flex: none; }
.sp-filter__row--on .sp-filter__box {
  border-color: var(--cy); background: var(--cy); box-shadow: inset 0 0 0 3px var(--bg2);
}
/* La case native reste la source de vérité (accessibilité, formulaire) ;
   elle est masquée visuellement au profit du carré dessiné. */
.sp-filter__input {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.sp-filter__input:checked + .sp-filter__box {
  border-color: var(--cy); background: var(--cy); box-shadow: inset 0 0 0 3px var(--bg2);
}
.sp-filter__input:focus-visible + .sp-filter__box { outline: 2px solid var(--cy); outline-offset: 2px; }

.sp-search {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--cy); background: var(--bg2);
  padding: 12px 13px; font-size: 15px; color: var(--tx3);
}
.sp-search input {
  flex: 1 1 auto; min-width: 0;
  background: transparent; border: none; outline: none;
  font-family: inherit; font-size: 15px; color: var(--tx);
}
.sp-search input::placeholder { color: var(--tx3); }
.sp-search svg { width: 16px; height: 16px; flex: none; color: var(--cy); }
.sp-search svg path, .sp-search svg circle { stroke: currentColor; stroke-width: 2; fill: none; }

/* --- Puces du descriptif ------------------------------------------------- */

.sp-points      { display: flex; flex-wrap: wrap; gap: 14px 34px; }
.sp-point       { display: flex; align-items: center; gap: 11px; font-size: 17px; color: var(--tx); }
.sp-point::before { content: ''; width: 8px; height: 8px; background: var(--cy); flex: none; }

/* Descriptif du site : colonnes de texte à intertitres cyan soulignés.
   Le nombre de colonnes suit le nombre de sections rédigées, pour qu'aucune ne
   reste seule sur la dernière ligne (4 sections -> 2x2, jamais 3+1). */
.sp-cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0,1fr));
  gap: var(--gap);
  margin-top: 26px;
}
.sp-cols--1    { grid-template-columns: minmax(0,1fr); }
.sp-cols--2,
.sp-cols--4    { grid-template-columns: repeat(2, minmax(0,1fr)); }
.sp-cols--3    { grid-template-columns: repeat(3, minmax(0,1fr)); }
.sp-cols--auto { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.sp-cols__title {
  font-family: Orbitron, sans-serif; font-size: 15px; letter-spacing: .1em; color: var(--cy);
  padding-bottom: 8px; border-bottom: 1px solid var(--line2);
  margin-bottom: 12px;
}
.sp-cols p { margin: 0; font-size: 16px; color: var(--tx2); }
.sp-lead   { font-size: 18px; line-height: 1.7; color: var(--tx); margin: 0 0 22px; }

/* --- Article (tutoriel) -------------------------------------------------- */

.sp-article        { max-width: 860px; margin: 0 auto; padding: 30px 20px 0; }
/* Crayon d'édition posé sur le contenu : c'est le texte qu'on modifie, pas le
   bandeau. Discret, il ne s'affiche que pour les personnes qui peuvent éditer,
   et le bloc qui le porte devient son référentiel de position. */
.sp-article, .sp-news--full { position: relative; }
.sp-edit-pencil {
  position: absolute; top: 30px; right: -46px; z-index: 5;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line2);
  color: var(--tx2);
  opacity: .5;
  transition: opacity .18s, border-color .18s, color .18s;
}
.sp-edit-pencil:hover { opacity: 1; border-color: var(--cy); color: var(--cy); }
.sp-edit-pencil svg   { width: 16px; height: 16px; }
.sp-edit-pencil svg path {
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Faute de place à côté de la colonne de texte, le crayon revient dedans. */
@media (max-width: 1000px) {
  .sp-edit-pencil { right: 8px; }
}
.sp-article__lead  { font-size: 18px; line-height: 1.75; color: var(--tx); }
.sp-article p      { font-size: 17px; line-height: 1.8; color: var(--tx2); margin: 26px 0 0; }
.sp-article__figure {            /* toute taille, une image à la fois, aucune grille imposée */
  position: relative; margin-top: 26px;
  border: 1px solid var(--line2);
  cursor: zoom-in;
  transition: border-color .2s, box-shadow .2s;
}
.sp-article__figure:hover { border-color: var(--cy); box-shadow: 0 0 12px var(--cyd); }
.sp-article__figure img   { display: block; width: 100%; height: auto; }
.sp-article__figure--narrow { width: 340px; margin-inline: auto; }

/* Contenu rédactionnel importé : le corps est un flux libre texte/image, une
   image après l'autre, de taille variable, sans grille ni numérotation. */
.sp-article__body { }
.sp-article__body h2 {
  font-family: Orbitron, sans-serif; font-size: 22px; letter-spacing: .06em; color: var(--cy);
  margin: 40px 0 0;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line2);
}
.sp-article__body h3 {
  font-family: Orbitron, sans-serif; font-size: 18px; color: var(--cy);
  margin: 32px 0 0;
}
/* Le contenu importé emballe parfois le titre dans un <strong> : il ne doit
   pas se distinguer du reste du titre. */
.sp-article__body h2 strong,
.sp-article__body h2 b {
  font-family: inherit; font-size: inherit; font-weight: inherit;
  letter-spacing: inherit; color: inherit;
}
.sp-article__body p      { font-size: 17px; line-height: 1.8; color: var(--tx2); margin: 26px 0 0; }
.sp-article__body ul,
.sp-article__body ol     { font-size: 17px; line-height: 1.8; color: var(--tx2); margin: 26px 0 0; padding-left: 22px; }
.sp-article__body li     { margin-bottom: 8px; }
.sp-article__body strong { color: var(--tx); }
.sp-article__body a      { color: var(--cy); text-decoration: underline; text-underline-offset: 3px; }
.sp-article__body a:hover{ color: var(--tx); }
.sp-article__body img {
  display: block;
  max-width: 100%; height: auto;
  margin: 10px auto;
  border: 1px solid var(--line2);
  cursor: zoom-in;
  transition: border-color .2s, box-shadow .2s;
}
.sp-article__body img:hover { border-color: var(--cy); box-shadow: 0 0 12px var(--cyd); }
/* Plans et croquis : cadre en relief gris, distinct du filet des photos.
   La couleur doit tenir au survol — sans quoi le filet repasserait au cyan. */
.sp-article__body img.dessin,
.sp-article__body img.dessin:hover {
  border-width: 9px;
  border-color: rgb(169,169,169);
  border-style: ridge;
  padding: 3px;
}
/* webp_content enveloppe chaque image dans un <picture>, inline par défaut :
   laissé tel quel, il crée une ligne dont la hauteur dépend du line-height et
   absorbe les marges de l'image. Le <picture> devient donc le bloc porteur.
   L'écart de 10px est posé tel quel : une ligne de texte réserve un peu de blanc
   autour de ses lettres, mais tenter de le compenser annulait la marge, et cet
   écart varie de toute façon selon les jambages et accents de la ligne voisine. */
.sp-article__body picture {
  display: block;
  margin: 10px auto;
}
.sp-article__body picture img { margin: 0 auto; }
/* Cas le plus fréquent du contenu importé : l'image ouvre le paragraphe du
   texte qui la commente. C'est alors la marge haute du paragraphe (26px) qui
   surplombe l'image, et les 10px du <picture> s'y fondent sans se voir. Le
   paragraphe cède donc sa marge haute à l'image. */
.sp-article__body p:has(> picture:first-child) {
  margin-top: 10px;
}
/* Après un titre, il n'y a pas de blanc de ligne à rattraper : le filet du h2
   est un bord franc, l'écart se mesure à partir de lui. */
.sp-article__body h2 + p:has(> picture:first-child),
.sp-article__body h3 + p:has(> picture:first-child) {
  margin-top: 10px;
}
/* Dans un paragraphe, c'est lui qui porte l'écart au-dessus ; en dessous, le
   texte suit dans le même paragraphe et il faut retrancher le blanc que sa
   première ligne réserve au-dessus de ses lettres. */
.sp-article__body p > picture {
  margin: 0 auto 10px;
}
/* Sauf entre deux images empilées dans le même paragraphe, qui se toucheraient
   sans cela : l'écart est alors porté par la seconde. */
.sp-article__body p > picture + picture {
  margin-top: 10px;
}
/* Le contenu importé place l'image tantôt dans le paragraphe de texte qui la
   suit, tantôt dans un paragraphe à elle seule. Dans le second cas, les 10px de
   l'image s'ajoutaient aux 26px du bloc voisin : l'écart doublait d'une image à
   l'autre. Un paragraphe qui ne porte qu'une image n'est donc pas un bloc de
   texte — il ne garde aucune marge propre, et le bloc qui le suit ne rouvre pas
   la sienne : seuls les 10px de l'image subsistent. */
.sp-article__body p:has(> picture):not(:has(> :not(picture):not(br))) {
  margin: 10px 0;
}
/* Les titres gardent leur respiration : un h2/h3 ouvre une section, l'écart
   qui le précède n'est pas la marge d'une image. */
.sp-article__body p:has(> picture):not(:has(> :not(picture):not(br))) + *:not(h2):not(h3) {
  margin-top: 0;
}
/* Deux images qui se suivent : le paragraphe suivant rouvrirait ses 10px alors
   que le précédent vient de poser les siens. On n'en garde qu'un seul écart. */
.sp-article__body p:has(> picture):not(:has(> :not(picture):not(br))) + p:has(> picture) {
  margin-top: 0;
}
/* Les contenus importés utilisent des tableaux pour juxtaposer des images :
   on les laisse couler mais on interdit le débordement horizontal. */
.sp-article__body table { max-width: 100%; margin: 26px auto 0; border-collapse: collapse; }
.sp-article__body table img { margin: 6px; }
.sp-article__body td { vertical-align: top; }

/* --- Pages rédactionnelles (mentions légales, confidentialité, contact) --- */

.legal-page { max-width: 860px; margin: 0 auto; }
.legal-page h2 {
  font-family: Orbitron, sans-serif; font-size: 20px; letter-spacing: .06em; color: var(--cy);
  margin: 36px 0 0;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line2);
}
.legal-page h3 {
  font-family: Orbitron, sans-serif; font-size: 17px; color: var(--cy);
  margin: 28px 0 0;
}
.legal-page p  { font-size: 17px; line-height: 1.8; color: var(--tx2); margin: 20px 0 0; }
.legal-page ul { font-size: 17px; line-height: 1.8; color: var(--tx2); margin: 20px 0 0; padding-left: 22px; }
.legal-page li { margin-bottom: 8px; }
.legal-page strong { color: var(--tx); }

/* --- Galerie ------------------------------------------------------------- */

.sp-grid      { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap-s); }
.sp-grid--3   { grid-template-columns: repeat(3, minmax(0,1fr)); }
.sp-thumb {
  position: relative; height: 216px; overflow: hidden;
  border: 1px solid var(--line); cursor: zoom-in;
  transition: border-color .2s, transform .2s, box-shadow .2s;
  display: block;
}
.sp-thumb:hover      { border-color: var(--cy); transform: translateY(-4px); box-shadow: 0 0 14px var(--cyd); }
.sp-thumb img,
.sp-thumb picture    { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Le titre repose sur un bandeau plein, et non sur un simple dégradé : sur une
   photo claire ou chargée, le dégradé ne suffisait pas à le rendre lisible. */
.sp-thumb__label {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 5px 13px;
  background: var(--scrim-band);
  backdrop-filter: blur(3px);
  border-top: 1px solid var(--line);
  font-family: Orbitron, sans-serif; font-size: 13px; letter-spacing: .1em; color: var(--cy);
}
.sp-thumb__label span {
  display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Trame de remplacement quand un album n'a pas de photo de couverture. */
.sp-thumb--empty {
  display: flex; align-items: center; justify-content: center;
  color: var(--tx3);
  cursor: pointer;
}

/* --- Pagination --------------------------------------------------------- */

.sp-pager      { display: flex; justify-content: center; flex-wrap: wrap; gap: 9px; padding: 4px 0 30px; font-family: 'JetBrains Mono', monospace; font-size: 14px; }
.sp-pager a {
  border: 1px solid var(--line2); color: var(--tx2); padding: 8px 14px;
  display: block;
}
.sp-pager a:hover        { border-color: var(--cy); color: var(--cy); }
.sp-pager a[aria-current]{ border-color: var(--cy); background: var(--cy); color: var(--bg); }
.sp-pager__gap  { padding: 8px 6px; color: var(--tx3); }
.sp-pager__off  { border: 1px solid var(--line); color: var(--tx3); padding: 8px 14px; opacity: .5; }

/* --- Fil d'ariane et compteurs ------------------------------------------ */

.sp-crumbs   { font-size: 14px; color: var(--tx2); }
.sp-crumbs a { color: var(--cy); }
.sp-crumbs__sep { color: var(--tx3); margin: 0 8px; }
.sp-count    { font-size: 16px; color: var(--tx2); }
.sp-count b  { color: var(--tx); font-family: 'JetBrains Mono', monospace; font-weight: 400; }

/* --- Lightbox ----------------------------------------------------------- */

.sp-lightbox {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  flex-direction: column;
  padding: 60px;
  background: rgba(3,6,9,.88);
  cursor: zoom-out;
}
.sp-lightbox[hidden]  { display: none; }
.sp-lightbox img     { max-width: 100%; max-height: 100%; border: 1px solid var(--line2); object-fit: contain; }
.sp-lightbox__caption{ margin-top: 12px; font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--tx2); text-align: center; }
.sp-lightbox__caption:empty { display: none; }
/* Flèches et fermeture : mêmes coins coupés que les flèches du carrousel. */
/* Même cadre à deux coins coupés que les flèches du carrousel. */
.sp-lightbox__btn {
  position: absolute;
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  color: var(--cy);
  border: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M12 1 H47 V36 L36 47 H1 V12 Z' fill='%230d151c' stroke='%235cc8e8' stroke-width='1.5'/%3E%3C/svg%3E")
    center / 100% 100% no-repeat;
  box-shadow: 0 0 14px var(--cyd);
  cursor: pointer;
  padding: 0;
  transition: background .18s, color .18s;
}
.sp-lightbox__btn:hover {
  color: var(--bg);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M12 1 H47 V36 L36 47 H1 V12 Z' fill='%235cc8e8' stroke='%235cc8e8' stroke-width='1.5'/%3E%3C/svg%3E")
    center / 100% 100% no-repeat;
}
.sp-lightbox__btn[hidden] { display: none; }
.sp-lightbox__btn svg { width: 22px; height: 22px; }
.sp-lightbox__btn svg path { stroke: currentColor; stroke-width: 2.4; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.sp-lightbox__close { top: 24px; right: 24px; }
.sp-lightbox__prev  { left: 24px;  top: 50%; transform: translateY(-50%); }
.sp-lightbox__next  { right: 24px; top: 50%; transform: translateY(-50%); }
/* Signature en bas à droite du visionneur. */
.sp-lightbox__brand {
  position: absolute; right: 24px; bottom: 24px;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  background: var(--scrim);
  border: 1px solid var(--line);
}
.sp-lightbox__brand img { width: 46px; height: 36px; object-fit: contain; border: none; }
.sp-lightbox__brand-name { font-family: Orbitron, sans-serif; font-size: 13px; letter-spacing: .12em; color: var(--tx); }
.sp-lightbox__brand-url  { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--tx3); }

/* --- Trame « image manquante » ------------------------------------------ */

.sp-placeholder {
  background:
    repeating-linear-gradient(135deg, var(--ph) 0 6px, transparent 6px 13px),
    var(--bg3);
}

/* --- Formulaires --------------------------------------------------------- */

.sp-form         { max-width: 620px; }
.sp-form__row    { margin-bottom: 18px; }
.sp-form label {
  display: block; margin-bottom: 7px;
  font-family: Orbitron, sans-serif; font-size: 13px; letter-spacing: .08em; color: var(--tx);
}
.sp-form input[type="text"],
.sp-form input[type="email"],
.sp-form input[type="password"],
.sp-form input[type="search"],
.sp-form textarea,
.sp-form select {
  width: 100%;
  padding: 12px 13px;
  background: var(--bg2);
  border: 1px solid var(--line2);
  color: var(--tx);
  font-family: inherit; font-size: 16px;
  transition: border-color .18s, box-shadow .18s;
}
.sp-form input:focus,
.sp-form textarea:focus,
.sp-form select:focus {
  outline: none;
  border-color: var(--cy);
  box-shadow: 0 0 10px var(--cyd);
}
.sp-form textarea { min-height: 160px; resize: vertical; }
.sp-form ul { margin: 6px 0 0; padding-left: 18px; color: var(--danger); font-size: 14px; }
.sp-hidden  { display: none; }

/* --- Boutons ------------------------------------------------------------- */

.sp-btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 20px;
  font-family: Orbitron, sans-serif; font-size: 13px; letter-spacing: .12em;
  color: var(--cy);
  background: transparent;
  border: 1px solid var(--cy);
  cursor: pointer;
  transition: background .18s, color .18s, box-shadow .18s;
}
.sp-btn:hover { background: var(--cy); color: var(--bg); box-shadow: 0 0 14px var(--cyd); }
.sp-btn--ghost { color: var(--tx2); border-color: var(--line2); }
.sp-btn--ghost:hover { color: var(--tx); background: transparent; border-color: var(--tx2); box-shadow: none; }
.sp-btn svg { width: 16px; height: 16px; }
.sp-btn svg path { stroke: currentColor; stroke-width: 2.2; fill: none; stroke-linecap: round; stroke-linejoin: round; }

.sp-actions { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 34px; }

/* --- Messages ------------------------------------------------------------ */

.sp-note {
  padding: 15px 18px;
  border: 1px solid var(--line2);
  border-left: 3px solid var(--cy);
  background: var(--bg2);
  color: var(--tx2);
  font-size: 16px;
}
.sp-note--ok    { border-left-color: var(--ok); }
.sp-note--error { border-left-color: var(--danger); color: var(--tx); }

/* --- Édition sur place (éditeurs) ---------------------------------------- */

/* Le conteneur ne doit rien changer à la mise en page de la zone qu'il
   enveloppe : il ne sert qu'à ancrer le bouton. */
.sp-editable {
  display: contents;
}
.sp-editable__btn {
  position: absolute;
  z-index: 5;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  color: var(--cy);
  background: var(--bg2);
  border: 1px solid var(--line2);
  cursor: pointer;
  opacity: 0;
  padding: 0;
  transition: opacity .18s, border-color .18s;
}
.sp-editable__btn svg { width: 14px; height: 14px; }
.sp-editable__btn svg path {
  stroke: currentColor; stroke-width: 1.8; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.sp-editable__btn:hover { border-color: var(--cy); }
/* Le bouton se révèle au survol de la zone concernée. */
.sp-banner:hover .sp-editable__btn,
.sp-block:hover .sp-editable__btn { opacity: 1; }
.sp-editable__btn:focus-visible   { opacity: 1; outline: 2px solid var(--cy); }
/* Ancrage : en haut à droite de la zone rendue. */
.sp-banner__subtitle,
.sp-lead,
.sp-points,
.sp-cols { position: relative; }
.sp-banner__subtitle .sp-editable__btn { top: -4px; right: 0; }
.sp-lead .sp-editable__btn,
.sp-points .sp-editable__btn,
.sp-cols .sp-editable__btn { top: -6px; right: -6px; }

/* Panneau d'édition */
.sp-edit {
  position: fixed; inset: 0; z-index: 9998;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(3,6,9,.8);
}
.sp-edit[hidden] { display: none; }
.sp-edit__box {
  width: 100%; max-width: 760px;
  max-height: 90vh;
  display: flex; flex-direction: column;
  background: var(--blk);
  border: 1px solid var(--blk-edge);
  box-shadow: 0 20px 50px var(--sh);
}
.sp-edit__head {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 16px 20px;
  background: var(--blk-head);
  border-bottom: 1px solid var(--blk-edge);
}
.sp-edit__title {
  font-family: Orbitron, sans-serif; font-size: 15px; letter-spacing: .1em; color: var(--cy);
}
.sp-edit__close {
  background: transparent; border: none; cursor: pointer;
  font-size: 26px; line-height: 1; color: var(--tx2); padding: 0 4px;
}
.sp-edit__close:hover { color: var(--tx); }
.sp-edit__tabs { display: flex; gap: 8px; padding: 14px 20px 0; }
.sp-edit__tab {
  padding: 7px 14px;
  font-family: 'JetBrains Mono', monospace; font-size: 13px;
  color: var(--tx2);
  background: transparent;
  border: 1px solid var(--line2);
  cursor: pointer;
  transition: color .18s, border-color .18s;
}
.sp-edit__tab:hover  { color: var(--tx); }
.sp-edit__tab.is-on  { color: var(--cy); border-color: var(--cy); }
.sp-edit__field {
  margin: 14px 20px 0;
  padding: 12px 13px;
  background: var(--bg2);
  border: 1px solid var(--line2);
  color: var(--tx);
  font-family: inherit; font-size: 16px; line-height: 1.6;
  resize: vertical;
  min-height: 120px;
}
.sp-edit__field:focus { outline: none; border-color: var(--cy); box-shadow: 0 0 10px var(--cyd); }
.sp-edit__hint  { margin: 8px 20px 0; font-size: 13px; color: var(--tx3); }
.sp-edit__hint:empty { display: none; }
.sp-edit__foot {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 20px;
  border-top: 1px solid var(--blk-edge);
  margin-top: 16px;
}
.sp-edit__save   { margin-left: auto; }
.sp-edit__status { font-size: 14px; color: var(--tx2); }
.sp-edit__status.is-error { color: var(--danger); }

/* --- Pied de page -------------------------------------------------------- */

.sp-foot {
  flex: none;
  margin-top: 50px;
  padding: 30px var(--gap);
  text-align: center;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg), var(--bg2));
}
.sp-foot__links {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 26px;
  list-style: none; margin: 0 0 16px; padding: 0;
}
.sp-foot__links a { font-size: 15px; color: var(--tx2); }
.sp-foot__links a:hover { color: var(--cy); }
/* Texte courant : --tx2 et non --tx3, qui tomberait sous le seuil AA sur le
   bas du dégradé du pied de page. */
.sp-foot p { margin: 5px 0 0; font-size: 14px; color: var(--tx2); }

/* --- Retour en haut ------------------------------------------------------ */

/* Même cadre à deux coins coupés que les flèches (cf. .sp-arrow), chevron ambre. */
.sp-top {
  position: fixed; right: 26px; bottom: 26px; z-index: 900;
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  color: var(--am);
  border: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M12 1 H47 V36 L36 47 H1 V12 Z' fill='%230d151c' stroke='%235cc8e8' stroke-width='1.5'/%3E%3C/svg%3E")
    center / 100% 100% no-repeat;
  box-shadow: 0 0 16px var(--cyd);
  cursor: pointer;
  padding: 0;
  opacity: 0; pointer-events: none;
  transition: opacity .25s, box-shadow .3s;
}
.sp-top.is-on { opacity: 1; pointer-events: auto; }
.sp-top:hover {
  box-shadow: 0 0 26px var(--cyd);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M12 1 H47 V36 L36 47 H1 V12 Z' fill='%2310333a' stroke='%235cc8e8' stroke-width='1.5'/%3E%3C/svg%3E")
    center / 100% 100% no-repeat;
}
.sp-top svg   { width: 20px; height: 20px; }
.sp-top svg path { stroke: currentColor; stroke-width: 2.4; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* --- Animations --------------------------------------------------------- */

@keyframes sp-blip { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
.sp-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--cy);
  animation: sp-blip 2.6s ease-in-out infinite;
}

/* --- Adaptations d'écran ------------------------------------------------- */

/* Sous 1180 px la colonne latérale de l'accueil passe en dessous. */
@media (max-width: 1180px) {
  /* Une seule colonne : la largeur fixe de 384px doit être abandonnée, sinon
     le bloc des derniers tutoriels déborde sur les écrans étroits. */
  .sp-home     { grid-template-columns: minmax(0,1fr); }
  .sp-home > * { width: auto; }
  .sp-workshop { grid-template-columns: 220px minmax(0,1fr); }
  .sp-grid     { grid-template-columns: repeat(3, minmax(0,1fr)); }
}

/* Seuil de bascule de la navigation : le menu passe en tiroir. */
@media (max-width: 980px) {
  .sp-nav__burger { display: flex; }
  .sp-nav__menu {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: 8px 0;
    background: var(--bg2);
    border-bottom: 1px solid var(--blk-edge);
    box-shadow: 0 12px 30px var(--sh);
  }
  .sp-nav__menu[hidden] { display: none; }
  .sp-nav__link {
    padding: 14px var(--gap);
    border-bottom: none;
    border-left: 3px solid transparent;
  }
  .sp-nav__link--active { border-bottom-color: transparent; border-left-color: var(--cy); }
  .sp-workshop { grid-template-columns: minmax(0,1fr); }
  .sp-filter   { position: static; }
  /* Deux colonnes maximum quel que soit le nombre de sections. */
  .sp-cols,
  .sp-cols--3,
  .sp-cols--4,
  .sp-cols--auto { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .sp-banner__title      { font-size: 32px; }
  .sp-banner__title--home{ font-size: 36px; }
}

@media (max-width: 760px) {
  :root { --gap: 16px; --gap-s: 12px; }
  /* Le bandeau passe en pile : le libellé coiffe les actualités empilées. */
  .sp-newsbar { flex-direction: column; }
  .sp-newsbar__label {
    padding: 12px 18px;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .sp-newsbar__item {
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .sp-newsbar__item:last-child { border-bottom: none; }
  .sp-grid  { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .sp-cols,
  .sp-cols--2,
  .sp-cols--3,
  .sp-cols--4,
  .sp-cols--auto { grid-template-columns: minmax(0,1fr); }
  .sp-carousel { grid-template-columns: minmax(0,1fr); }
  .sp-carousel__side { display: none; }
  .sp-carousel__main { height: 300px; }
  /* La largeur se recalcule seule depuis le ratio de chaque photo. */
  .peek-slider { --peek-h: 300px; }
  .sp-arrow--prev { left: 10px; }
  .sp-arrow--next { right: 10px; }
  .sp-article  { padding: 24px 4px 0; }
  .sp-lightbox { padding: 20px; }
  .sp-lightbox__prev  { left: 8px; }
  .sp-lightbox__next  { right: 8px; }
  .sp-lightbox__brand { display: none; }
  .sp-actions { flex-direction: column; align-items: stretch; }
  .sp-actions .sp-btn { justify-content: center; }
}

@media (max-width: 460px) {
  .sp-grid { grid-template-columns: minmax(0,1fr); }
  .sp-nav  { padding: 0 14px; }
  .sp-nav__brand { gap: 8px; }
  .sp-nav__name  { font-size: 12px; letter-spacing: .14em; }
  .sp-nav__logo img { width: 61px; height: 48px; }
  .sp-nav__side  { gap: 12px; }
  .sp-banner     { padding: 24px 14px 22px; }
  .sp-banner__title      { font-size: 25px; }
  .sp-banner__title--home{ font-size: 27px; }
  .sp-banner__subtitle   { font-size: 15px; }
  .sp-thumb  { height: 190px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
