/* ============================================================================
   VELIX DIGITAL — Composants « Projets »
   Listing filtrable, carte de projet, page détail, comparateur avant/après.
   Réutilise les tokens de styles.css : aucune couleur ni police redéfinie.
   ============================================================================ */

/* ============ FILTRES DU LISTING ============ */
.projets-filtres {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  margin-top: var(--sp-6); padding: 8px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 999px; width: fit-content; max-width: 100%;
  box-shadow: var(--pill-shadow);
  /* Centrée sous le titre et la description, qui sont eux-mêmes centrés :
     la barre appartient au même axe de composition. */
  margin-inline: auto;
}
/* Sans libellé, la barre se centre sur ses boutons seuls. */
.projets-filtres { justify-content: center; }
.filtre-btn {
  display: inline-flex; align-items: center; min-height: 32px;
  padding: 7px 16px; border: none; border-radius: 999px;
  background: transparent; color: var(--ink-soft);
  font-family: inherit; font-size: 14px; font-weight: 500; cursor: pointer;
  transition: background 0.22s, color 0.22s;
}
.filtre-btn:hover { background: rgba(184, 77, 214, 0.09); color: var(--ink-strong); }
/* Violet plutôt que noir : le filtre actif est un état de marque, pas un bouton
   système. Le dégradé reprend celui des accents du site (titres, chiffres). */
.filtre-btn.is-active {
  background: linear-gradient(96deg, var(--purple-deep), var(--purple));
  color: #fff; font-weight: 600;
  box-shadow: 0 2px 10px -2px rgba(120, 36, 194, 0.5);
}
.filtre-btn:focus-visible { outline: 2px solid var(--purple); outline-offset: 2px; }

@media (max-width: 700px) {
  .projets-filtres { border-radius: var(--radius-md); width: 100%; }
}

.filtres-noscript { margin-top: var(--sp-4); display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.filtres-noscript a {
  padding: 7px 15px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 14px; color: var(--ink-soft);
}

/* ============ GRILLE ============ */
.projets-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(22px, 3vw, 38px);
}
@media (max-width: 860px) { .projets-grid { grid-template-columns: 1fr; } }

/* Les cartes d'une même ligne s'étirent à la même hauteur. Sans ça, une carte
   sans extrait est plus courte que sa voisine et les « Voir le projet » ne
   s'alignent pas — le listing paraît bancal alors que seul le texte varie. */
.projets-grid > .projet-carte { align-self: stretch; }

/* `hidden` n'est qu'un `display: none` dans la feuille par défaut du navigateur :
   le `display: flex` de .projet-carte (spécificité de classe) le battait, et le
   filtrage JS n'avait plus aucun effet visible. Cette règle rend l'attribut
   opérant à nouveau. Elle doit rester après toute règle qui pose un `display`. */
.projet-carte[hidden] { display: none; }

.projets-vide,
.projets-aucun {
  padding: 60px 20px; text-align: center;
  font-size: 16.5px; color: var(--ink-soft);
}

/* ============ CARTE PROJET ============ */
.projet-carte {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--card-shadow);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
  /* Colonne : le média garde sa hauteur propre, le corps occupe le reste.
     C'est ce qui permet d'aligner le lien de bas de carte d'une carte à l'autre. */
  display: flex; flex-direction: column;
}
.projet-carte:hover {
  transform: translateY(-5px);
  box-shadow: var(--card-shadow-hover);
}

.projet-carte-media {
  position: relative; display: block;
  aspect-ratio: 16 / 10; overflow: hidden;
  background: linear-gradient(140deg, #ece1f8, #f7f2fd);
  /* La carte étant en flex-column, le média ne doit pas se comprimer quand le
     corps de texte d'une carte voisine est plus long. */
  flex: none;
}
.projet-carte-media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 0.6s var(--ease);
}
.projet-carte:hover .projet-carte-media img { transform: scale(1.035); }
.projet-carte-vide { display: block; width: 100%; height: 100%; }

/* ---- Projet en cours ----
   La carte garde le comportement des autres : elle se soulève au survol, l'image
   zoome, tout est identique. Ce qui change tient en deux signaux — le curseur
   `not-allowed` et le bouton en apparence désactivée. L'utilisateur comprend en
   approchant la souris, avant de cliquer, et la grille reste homogène.

   Un projet en cours est une preuve d'activité : le griser entièrement le
   dévaloriserait. On signale l'indisponibilité, on ne cache pas le projet. */
.projet-carte.is-pending {
  /* Fond identique aux autres cartes : seul l'état du bouton diffère. */
  background: var(--card);
}
/* Curseur sur toute la carte : c'est le signal principal, il doit être partout
   où l'utilisateur pourrait croire qu'un clic mène quelque part. */
.projet-carte.is-pending,
.projet-carte.is-pending .projet-carte-media,
.projet-carte.is-pending .case-link.is-disabled { cursor: not-allowed; }

/* Voile discret + désaturation légère : l'image reste lisible et reconnaissable,
   elle indique seulement que le site n'est pas encore en ligne. */
.projet-carte.is-pending .projet-carte-media img { filter: saturate(0.55); }
.projet-carte.is-pending .projet-carte-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(28, 22, 38, 0.26), rgba(28, 22, 38, 0.42));
}

/* ---- Bouton indisponible ----
   Même position et même graisse que « Voir le projet » actif, mais atone : gris,
   estompé, et surtout il ne réagit pas au survol (l'actif écarte ses éléments de
   sp-2 à sp-3). Cette absence de réponse est le second signal. */
.case-link.is-disabled {
  color: var(--ink-soft);
  opacity: 0.72;
  /* Aucune transition de gap : le bouton reste inerte sous la souris. */
}
/* Neutralise le :hover de base (.case-link:hover écarte le gap) dans les deux cas :
   souris sur la carte, et souris directement sur le bouton. */
.projet-carte.is-pending:hover .case-link.is-disabled,
.case-link.is-disabled:hover { gap: var(--sp-2); }
.case-link-note {
  /* Précise pourquoi le bouton est inerte — sans quoi « désactivé » resterait
     une énigme. Discret : c'est une note, pas un second bouton. */
  font-size: 12.5px; font-weight: 500; opacity: 0.85;
}
.case-link-note::before { content: "· "; }

.projet-carte-overlay {
  position: absolute; top: 50%; left: 50%; z-index: 2;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4); border-radius: 999px;
  background: rgba(28, 22, 38, 0.82);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: #fff; font-size: 12.5px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  white-space: nowrap;
}
.projet-carte-overlay .ico {
  width: 15px; height: 15px; stroke: currentColor; stroke-width: 1.8; fill: none;
}

.projet-carte-body {
  padding: clamp(20px, 2.4vw, 28px);
  /* Occupe la hauteur restante pour que « Voir le projet » se cale en bas,
     à la même ligne sur toutes les cartes, quelle que soit la longueur du texte.
     align-items reste à stretch (défaut) : sans ça, titre et extrait se
     rétréciraient à la largeur de leur texte au lieu de remplir la carte. */
  flex: 1; display: flex; flex-direction: column;
}
/* Le lien, lui, ne doit pas s'étirer sur toute la largeur : sa zone cliquable
   doit se limiter au texte. */
.projet-carte-body > .case-link { align-self: flex-start; }
 /* Le niveau du titre varie selon le contexte (h2 sur le listing, h3 ailleurs) :
    on stylise la classe, pas la balise. */
.projet-carte-titre { font-size: 20px; font-weight: 700; color: var(--ink-strong); }
.projet-carte-titre a { color: inherit; }
.projet-carte-titre a:hover { color: var(--purple-deep); }

.projet-carte-tags {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3);
}
.projet-carte-tags .tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px; border-radius: 999px;
  background: rgba(184, 77, 214, 0.09);
  color: var(--purple-deep);
  font-size: 12.5px; font-weight: 600;
}
.projet-carte-tags .tag-distinction {
  background: rgba(89, 216, 201, 0.16); color: #12796c;
}
.projet-carte-tags .tag-distinction .ico {
  width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.9;
}

.projet-carte-copy {
  margin-top: var(--sp-3); font-size: 15px; line-height: 1.62; color: var(--ink-soft);
}
/* margin-top auto : le lien est repoussé en bas de carte. Le padding-top garde
   une respiration minimale quand le texte est court et que rien ne l'éloigne. */
.projet-carte .case-link { margin-top: auto; padding-top: var(--sp-4); }

/* ============ PAGE PROJET ============ */
.projet-badge-encours {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin-bottom: var(--sp-4); padding: 8px 16px; border-radius: 999px;
  background: rgba(255, 189, 89, 0.18);
  border: 1px solid rgba(255, 189, 89, 0.42);
  color: #8a5a00; font-size: 13px; font-weight: 600;
  letter-spacing: 0.03em; text-transform: uppercase;
}
/* Doit être plus spécifique que `.page-head .page-sub` (0,2,0), sinon la taille
   de l'en-tête vitrine écrase celle-ci et l'accroche perd son accent. */
.page-head .projet-accroche { font-size: 19.5px; }

.projet-hero-visual { padding: 8px 0 clamp(30px, 4vw, 52px); }
.projet-shot {
  position: relative; margin: 0;
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 8px 24px rgba(60, 30, 90, 0.1), 0 40px 90px -24px rgba(60, 30, 90, 0.3);
}
.projet-shot img { width: 100%; height: auto; display: block; }
.projet-shot.is-pending img { filter: brightness(0.62) saturate(0.85); }
.projet-shot-overlay {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 13px 24px; border-radius: 999px;
  background: rgba(28, 22, 38, 0.8);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff; font-size: 13.5px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase; text-align: center;
}

.projet-grid {
  display: grid; grid-template-columns: 320px 1fr;
  gap: clamp(28px, 4vw, 56px); align-items: start;
}
@media (max-width: 940px) { .projet-grid { grid-template-columns: 1fr; } }

/* La colonne d'infos suit la lecture sur grand écran */
@media (min-width: 941px) {
  .projet-aside { position: sticky; top: 110px; }
}
.projet-aside { display: flex; flex-direction: column; gap: var(--sp-4); }

/* Intitulé de bloc, pas un titre de contenu : il nomme la colonne sans entrer
   en concurrence avec le <h1>. Remplace l'ancien .projet-client, qui répétait
   le nom du client une troisième fois dans le premier écran. */
.aside-card-label {
  font-size: 12px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-soft);
  margin-bottom: var(--sp-3);
}

/* Pas de margin-top : l'intitulé du bloc porte déjà l'écart. */
.projet-meta { display: flex; flex-direction: column; gap: var(--sp-3); }
.projet-meta li {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  font-size: 14.5px; color: var(--ink-soft); line-height: 1.5;
}
.projet-meta .ico {
  flex-shrink: 0; width: 17px; height: 17px; margin-top: 1px;
  fill: none; stroke: var(--purple); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.projet-meta a { color: var(--purple-deep); text-decoration: underline; text-underline-offset: 3px; }

.projet-cta-card { text-align: center; }
.projet-cta-title {
  font-size: 17px; font-weight: 700; line-height: 1.35;
  color: var(--ink-strong); margin-bottom: var(--sp-4);
}
.projet-cta-card .cta-note { margin-top: var(--sp-3); justify-content: center; }

.projet-block { margin-bottom: clamp(var(--sp-6), 4vw, var(--sp-7)); }
.projet-block h2 {
  font-size: clamp(22px, 2.6vw, 30px); font-weight: 700;
  color: var(--ink-strong); margin-bottom: var(--sp-4); letter-spacing: -0.01em;
}
.projet-res-intro {
  font-size: 16.5px; line-height: 1.7; color: var(--ink-soft); margin-bottom: var(--sp-4);
}

/* Constats : puce d'alerte. Résultats : coche verte.
   Le contraste entre les deux listes raconte l'avant et l'après. */
.liste-constats, .liste-resultats {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.liste-constats li, .liste-resultats li {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: 15px 18px; border-radius: var(--radius-md);
  font-size: 15.5px; line-height: 1.6; color: var(--ink);
}
.liste-constats li { background: rgba(211, 69, 91, 0.06); border: 1px solid rgba(211, 69, 91, 0.16); }
.liste-resultats li { background: rgba(46, 168, 124, 0.07); border: 1px solid rgba(46, 168, 124, 0.18); }

.liste-constats .ico {
  flex-shrink: 0; width: 19px; height: 19px; margin-top: 1px;
  fill: none; stroke: #c13650; stroke-width: 1.9; stroke-linecap: round;
}
.liste-resultats .ico { flex-shrink: 0; width: 19px; height: 19px; margin-top: 1px; }
.liste-resultats .check-bg { fill: rgba(46, 168, 124, 0.2); stroke: none; }
.liste-resultats .check-mark { fill: none; stroke: #1a7f5a; stroke-width: 2.3; stroke-linecap: round; stroke-linejoin: round; }

/* ============ COMPARATEUR AVANT / APRÈS ============ */
.ba-compare {
  position: relative; border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--card-shadow); background: var(--card);
  line-height: 0; touch-action: pan-y; /* le glissement horizontal pilote la poignée */
}
.ba-compare img { width: 100%; height: auto; display: block; }
.ba-before {
  position: absolute; inset: 0; overflow: hidden;
  width: var(--ba-pos, 50%);
  border-right: 2px solid #fff;
}
.ba-before img {
  /* L'image conserve sa largeur d'origine : c'est le conteneur qui est rogné,
     sinon l'image se déformerait au lieu d'être révélée. */
  width: var(--ba-width, 100%); max-width: none;
}
.ba-range {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: ew-resize; z-index: 3;
}
.ba-range:focus-visible + .ba-handle {
  outline: 3px solid var(--purple); outline-offset: 3px;
}
.ba-handle {
  position: absolute; top: 50%; left: var(--ba-pos, 50%); z-index: 2;
  transform: translate(-50%, -50%);
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: #fff; box-shadow: 0 4px 16px rgba(28, 22, 38, 0.3);
  pointer-events: none;
}
.ba-handle svg {
  width: 22px; height: 22px;
  fill: none; stroke: var(--ink-strong); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.ba-tag {
  position: absolute; top: 14px; z-index: 2;
  padding: 5px 12px; border-radius: 999px;
  background: rgba(28, 22, 38, 0.72);
  color: #fff; font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  line-height: 1.4; pointer-events: none;
}
.ba-tag-before { left: 14px; }
.ba-tag-after { right: 14px; }

/* ============ TÉMOIGNAGE ============ */
.projet-temoignage {
  margin: 0 0 clamp(var(--sp-6), 4vw, var(--sp-7));
  padding: clamp(26px, 3.2vw, 40px);
  border-radius: var(--radius-lg);
  background: linear-gradient(150deg, rgba(184, 77, 214, 0.07), rgba(120, 36, 194, 0.04));
  border: 1px solid rgba(184, 77, 214, 0.18);
}
.projet-temoignage blockquote {
  margin: 0; font-size: clamp(16px, 1.9vw, 19px); line-height: 1.65;
  color: var(--ink-strong); font-weight: 500;
}
.projet-temoignage blockquote::before { content: "« "; }
.projet-temoignage blockquote::after { content: " »"; }
.projet-temoignage figcaption {
  display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-5);
}
.projet-temoignage .temoin-photo {
  width: 46px; height: 46px; border-radius: 50%; object-fit: cover;
}
.projet-temoignage .quote-avatar {
  display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: linear-gradient(140deg, var(--purple-deep), var(--purple));
  color: #fff; font-size: 15px; font-weight: 700; letter-spacing: 0.02em;
}
.projet-temoignage .quote-id { display: flex; flex-direction: column; gap: 2px; }
.projet-temoignage .quote-id b { font-size: 15.5px; color: var(--ink-strong); }
.projet-temoignage .quote-id small { font-size: 13.5px; color: var(--ink-soft); }

/* ============ GALERIE ============ */
.galerie-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-4);
}
@media (max-width: 640px) { .galerie-grid { grid-template-columns: 1fr; } }
.galerie-item {
  margin: 0; border-radius: var(--radius-md); overflow: hidden;
  border: 1px solid var(--line); background: var(--card);
  box-shadow: 0 2px 8px rgba(60, 30, 90, 0.06);
}
.galerie-item img { width: 100%; height: auto; display: block; }

.projet-retour { margin-top: var(--sp-6); font-size: 15px; }
.projet-retour a { color: var(--ink-soft); transition: color 0.22s; }
.projet-retour a:hover { color: var(--purple-deep); }

.projet-autres { padding-top: clamp(var(--sp-6), 5vw, var(--sp-8)); }
.projet-autres .section-head { text-align: center; margin-inline: auto; }
.projet-autres .section-head h2 em {
  font-style: normal;
  background: linear-gradient(96deg, var(--purple-deep), var(--purple));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* Titre nécessaire à la structure du document mais redondant visuellement. */
.sr-only-visually {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ============ THÈME SOMBRE ============ */
html[data-theme="dark"] .projets-filtres,
html[data-theme="dark"] .projet-carte { background: var(--card); border-color: var(--line); }
/* Même dégradé qu'en clair, mais éclairci : sur fond sombre, le violet profond
   manquerait de contraste avec le texte blanc. */
html[data-theme="dark"] .filtre-btn.is-active {
  background: linear-gradient(96deg, var(--purple), #d06ef0);
  color: #fff; box-shadow: none;
}
html[data-theme="dark"] .filtre-btn:hover { background: rgba(184, 77, 214, 0.18); color: #fff; }
html[data-theme="dark"] .projet-badge-encours {
  background: rgba(255, 189, 89, 0.14); border-color: rgba(255, 189, 89, 0.34); color: #ffd08a;
}
html[data-theme="dark"] .liste-constats li { background: rgba(211, 69, 91, 0.12); border-color: rgba(211, 69, 91, 0.26); }
html[data-theme="dark"] .liste-resultats li { background: rgba(46, 168, 124, 0.12); border-color: rgba(46, 168, 124, 0.28); }
html[data-theme="dark"] .liste-constats .ico { stroke: #ff8ba0; }
html[data-theme="dark"] .liste-resultats .check-mark { stroke: #59d8c9; }
/* En sombre, .case-link passe en #c9a0f2 : le bouton désactivé doit rester gris,
   sinon il reprend la couleur d'un lien actif. */
html[data-theme="dark"] .case-link.is-disabled { color: var(--ink-soft); }
html[data-theme="dark"] .projet-carte-tags .tag { background: rgba(184, 77, 214, 0.2); color: #d9b6f5; }
html[data-theme="dark"] .projet-carte-tags .tag-distinction { background: rgba(89, 216, 201, 0.16); color: #7fe6d8; }
html[data-theme="dark"] .projet-temoignage {
  background: linear-gradient(150deg, rgba(184, 77, 214, 0.14), rgba(120, 36, 194, 0.08));
  border-color: rgba(184, 77, 214, 0.28);
}
html[data-theme="dark"] .ba-handle { background: #241d2b; }
html[data-theme="dark"] .ba-handle svg { stroke: #fff; }
html[data-theme="dark"] .ba-before { border-right-color: #241d2b; }

/* ============ MOUVEMENT RÉDUIT ============ */
@media (prefers-reduced-motion: reduce) {
  .projet-carte, .projet-carte-media img { transition: none; }
  .projet-carte:hover { transform: none; }
  .projet-carte:hover .projet-carte-media img { transform: none; }
}
