/* portfolio.lisieresubtil.com
   Les captures occupent la page, le fond se voit à peine. Le nom d'un site paraît
   au survol de sa carte. La police de titre est Bona Nova SC, celle du mot « Bâtir »
   sur batir.lisieresubtil.com. */

:root {
  --papier: #faf8f4;
  --papier-creux: #f2eee7;
  --encre: #17161a;
  --encre-douce: #6b6862;
  --trait: #e0dbd2;
  --vert-wa: #1f7a4d;
  --marge: clamp(1rem, 3.5vw, 2.75rem);
  --joint: clamp(6px, 0.85vw, 12px);
  --trame: rgba(52, 76, 108, 0.10);
  --trame-forte: rgba(52, 76, 108, 0.22);
  --pas: 26px;
  --courbe: 14px;
}

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

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

/* Fond de papier à dessin : une trame fine tous les 26 px, une ligne de coupe tous les
   huit carreaux. Les traits sont posés en gradients répétés plutôt qu'en image, donc
   rien à télécharger et le rendu reste net à toute densité d'écran. */
body {
  margin: 0;
  background-color: var(--papier);
  background-image:
    linear-gradient(to right, var(--trame-forte) 1px, transparent 1px),
    linear-gradient(to bottom, var(--trame-forte) 1px, transparent 1px),
    linear-gradient(to right, var(--trame) 1px, transparent 1px),
    linear-gradient(to bottom, var(--trame) 1px, transparent 1px);
  background-size:
    calc(var(--pas) * 8) calc(var(--pas) * 8),
    calc(var(--pas) * 8) calc(var(--pas) * 8),
    var(--pas) var(--pas),
    var(--pas) var(--pas);
  background-position: -1px -1px;
  color: var(--encre);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.lien-evitement {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--encre); color: var(--papier); padding: 0.75rem 1.25rem;
}
.lien-evitement:focus { left: 0; }

/* ---------- barre du haut : le titre y tient lieu de marque ---------- */

.barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(0.9rem, 2.5vw, 1.75rem) var(--marge);
}

.barre-titre {
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: clamp(1.75rem, 4.5vw, 3rem);
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0;
}

.barre-titre a { text-decoration: none; }

.barre-liens {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2.5vw, 1.75rem);
}

.barre-lien {
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--encre-douce);
  padding-bottom: 2px;
  background-image: linear-gradient(var(--encre), var(--encre));
  background-size: 0 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size 0.45s cubic-bezier(0.22, 1, 0.36, 1), color 0.45s;
}
.barre-lien:hover, .barre-lien:focus-visible { color: var(--encre); background-size: 100% 1px; }
.barre-lien[aria-current='page'] { color: var(--encre); background-size: 100% 1px; }

@media (max-width: 30rem) {
  .barre-lien { font-size: 0.6875rem; letter-spacing: 0.06em; }
}

/* ---------- bouton WhatsApp ---------- */

.bouton-wa {
  --fond: var(--encre);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.5rem;
  border: 1px solid var(--fond);
  border-radius: 999px;
  color: var(--fond);
  text-decoration: none;
  font-size: 0.9375rem;
  line-height: 1;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.bouton-wa::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--fond);
  transform: translateY(101%);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.bouton-wa:hover, .bouton-wa:focus-visible { color: var(--papier); }
.bouton-wa:hover::before, .bouton-wa:focus-visible::before { transform: translateY(0); }
.bouton-wa svg { width: 1.15em; height: 1.15em; flex: none; }

.bouton-wa--vert { --fond: var(--vert-wa); }

/* Le bouton de la barre du haut : même dessin que celui du bas, un cran plus large pour
   qu'il se voie dès l'arrivée sur la page. Sur téléphone il tombe en pastille ronde,
   l'icône seule, sinon il mange la place du titre. */
.bouton-wa--barre {
  padding: 0.95rem 1.75rem;
  font-size: 1.0625rem;
  font-weight: 500;
}
.bouton-wa--barre svg { width: 1.3em; height: 1.3em; }
@media (max-width: 34rem) {
  .bouton-wa--barre { padding: 0.85rem; }
  .bouton-wa--barre span { display: none; }
  .bouton-wa--barre svg { width: 1.6em; height: 1.6em; }
}

/* ---------- les cartes, plein cadre ---------- */

.grille {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--joint);
  padding: var(--joint);
}

@media (min-width: 60rem) {
  .grille { grid-template-columns: 1fr 1fr; }
}

.carte {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--papier-creux);
  text-decoration: none;
  aspect-ratio: 16 / 10;
}

.carte-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Le voile et le nom se lèvent ensemble au survol : la capture reste le sujet. */
.carte-voile {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(15, 14, 18, 0.62) 0%, rgba(15, 14, 18, 0.18) 38%, rgba(15, 14, 18, 0) 68%);
  opacity: 0;
  transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

.carte-nom {
  position: absolute;
  left: clamp(1.1rem, 3vw, 2.25rem);
  right: clamp(1.1rem, 3vw, 2.25rem);
  bottom: clamp(1rem, 2.8vw, 2rem);
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: clamp(1.25rem, 2.2vw, 2rem);
  line-height: 1.1;
  letter-spacing: 0.005em;
  color: #fdfcfa;
  text-shadow: 0 1px 14px rgba(15, 14, 18, 0.45);
  opacity: 0;
  transform: translateY(0.6rem);
  transition: opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

@media (hover: hover) {
  .carte:hover .carte-voile,
  .carte:focus-visible .carte-voile { opacity: 1; }
  .carte:hover .carte-nom,
  .carte:focus-visible .carte-nom { opacity: 1; transform: none; }
  .carte:hover .carte-image,
  .carte:focus-visible .carte-image { transform: scale(1.028); }
}

/* Un écran tactile ne survole rien : le nom reste posé, en retrait. */
@media (hover: none) {
  .carte-voile { opacity: 1; }
  .carte-nom { opacity: 1; transform: none; }
}

/* ---------- témoignages ---------- */

.temoignages {
  padding: clamp(4rem, 11vh, 7.5rem) var(--marge) 0;
}

.temoignages-titre {
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: clamp(2.2rem, 6vw, 4rem);
  letter-spacing: -0.02em;
  line-height: 1;
  text-align: center;
  margin: 0 0 clamp(2.25rem, 5vw, 3.5rem);
}

.temoins {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: clamp(1.25rem, 3vw, 2.25rem);
  max-width: 1100px;
  margin-inline: auto;
}

.temoin { margin: 0; }

/* Quatre témoignages : au-dessus de ~1155 px les quatre tiennent sur un rang, en dessous
   la grille tombe à trois et laisse la quatrième seule. On préfère deux et deux. */
@media (max-width: 1155px) and (min-width: 34rem) {
  .temoins { grid-template-columns: repeat(2, 1fr); }
}

.temoin-cadre {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  border-radius: var(--courbe);
  background: var(--encre);
  transition: box-shadow 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.temoin-cadre video {
  width: 100%; height: 100%;
  object-fit: cover;
  background: var(--encre);
}
.temoin-cadre:hover { box-shadow: 0 18px 40px -18px rgba(23, 22, 26, 0.35); }

/* ---------- le témoignage à deux voix ----------
   Ludivine et Gabriel ont enregistré ensemble, face caméra, en paysage. Le cadre 9/16 des
   quatre autres couperait l'un des deux, donc leur carte traverse la grille et garde le
   format de la vidéo. `object-fit: cover` ne recadre rien puisque le cadre et la source
   ont le même rapport. */
.temoin-large { grid-column: 1 / -1; }
.temoin-large .temoin-cadre { aspect-ratio: 16 / 9; }

.temoin-lecture {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 0;
  padding: 0;
  background: rgba(15, 14, 18, 0.12);
  cursor: pointer;
  transition: background 0.5s, opacity 0.4s;
}
.temoin-lecture::after {
  content: '';
  width: 4.25rem; height: 4.25rem;
  border-radius: 50%;
  background: rgba(250, 248, 244, 0.92) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2317161a'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E") no-repeat center / 1.5rem;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.temoin-lecture:hover::after { transform: scale(1.08); }
.temoin-cadre.joue .temoin-lecture { opacity: 0; pointer-events: none; }

/* ---------- la conversation de Charlotte ----------
   Son témoignage est arrivé en message vidéo : l'image est ronde à la source, masque cuit
   et coins noirs compris. Plutôt que de la recadrer, sa carte rejoue le fil tel qu'il est
   arrivé, ses deux messages et les réactions posées dessus, puis la bulle vidéo. Le décor
   est redessiné ici de bout en bout, motif compris (`/img/fond-conversation.svg`).
   La carte se mesure elle-même : les tailles sont en `cqw`, donc le fil garde ses
   proportions de 168 px de large sur la ligne serrée de cheminer à 300 px dans un deck. */

.temoin-cadre.convers {
  container-type: inline-size;
  background: #191b1c url('/img/fond-conversation.svg') repeat;
  background-size: 250px;
  border: 1px solid #24282a;
}

.convers-fil {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1.6cqw;
  padding: 5cqw 5.5cqw;
}

/* Un message reçu : le texte, puis l'heure posée au bout de la dernière ligne. */
.msg {
  max-width: 88%;
  margin: 0;
  padding: 2.4cqw 3.4cqw 2.6cqw;
  border-radius: 3cqw;
  background: #232527;
  color: #e9edef;
  font-size: max(8.5px, 5.4cqw);
  line-height: 1.32;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}
.msg-h {
  margin-left: 2cqw;
  color: #93a1a8;
  font-size: max(7px, 4.1cqw);
  white-space: nowrap;
}

/* La réaction posée sur le message, dans sa pastille, débordant sous la bulle. */
.msg-reac {
  margin: -3.4cqw 0 0 3cqw;
  padding: 0.8cqw 2cqw 1cqw;
  border-radius: 999px;
  background: #232527;
  border: 1px solid #191b1c;
  font-size: max(9px, 5.6cqw);
  line-height: 1;
}

/* La bulle vidéo, ronde comme à l'envoi. */
.temoin-bulle {
  position: relative;
  display: block;
  align-self: center;
  width: 82%;
  aspect-ratio: 1;
  margin-top: 3cqw;
}

.temoin-disque {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  background: #0e1011;
  box-shadow: 0 6cqw 12cqw -6cqw rgba(0, 0, 0, 0.7);
}
/* Le masque rond de la source laisse un liseré sombre sur son bord : un souffle d'échelle
   le fait passer sous le bord du disque au lieu de se voir. */
.temoin-disque video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.035);
}

.temoin-anneau {
  position: absolute;
  inset: -3.4%;
  width: 106.8%;
  height: 106.8%;
  fill: none;
  pointer-events: none;
  transform: rotate(-90deg);
}
.anneau-fond { stroke: rgba(255, 255, 255, 0.16); stroke-width: 1.1; }
.anneau-trait {
  stroke: #25d366;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-dasharray: 305.4;
  stroke-dashoffset: 305.4;
  opacity: 0;
  transition: opacity 0.4s;
}
.temoin-cadre.convers.joue .anneau-trait { opacity: 1; }

/* Le disque de lecture est posé dans la bulle, jamais au centre de la carte. */
.temoin-play {
  position: absolute;
  top: 50%; left: 50%;
  width: 26cqw; height: 26cqw;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(20, 22, 24, 0.55) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E") no-repeat center / 40%;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.85) inset;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.35s;
}
.temoin-cadre.convers:hover .temoin-play { transform: translate(-50%, -50%) scale(1.07); }

.temoin-duree {
  position: absolute;
  left: 50%; bottom: 5.5cqw;
  transform: translateX(-50%);
  color: #fff;
  font-size: max(7px, 4.2cqw);
  font-weight: 500;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
}

.convers-h {
  align-self: flex-end;
  margin-top: 2cqw;
  color: #93a1a8;
  font-size: max(7px, 4.1cqw);
}

/* Le bouton couvre la carte pour que le clic parte de n'importe où, et laisse voir le
   décor : la lecture se lit au disque posé dans la bulle. */
/* ⚠ Le fil est posé au-dessus du fond avec `z-index: 1`. Sans z-index à son tour, le bouton
   reste sous le décor et aucun clic ne l'atteint : la carte devient muette. */
.temoin-cadre.convers .temoin-lecture { background: transparent; z-index: 2; }
.temoin-cadre.convers .temoin-lecture::after { display: none; }
.temoin-cadre.convers.joue .temoin-lecture { opacity: 1; pointer-events: auto; }
.temoin-cadre.convers.joue .temoin-play { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .anneau-trait, .temoin-play { transition: none; }
}

.temoin-nom {
  margin: 0.85rem 0 0;
  text-align: center;
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: 1.1rem;
}

/* ---------- appel final ---------- */

.final {
  padding: clamp(2rem, 5vh, 3.25rem) var(--marge) clamp(4rem, 11vh, 7rem);
  text-align: center;
}

/* La bulle marche à gauche du bouton : Vie derrière sa grenouille, en rond. */
.final-appel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.85rem, 2.5vw, 1.5rem);
}

.bulle {
  width: clamp(4rem, 9vw, 5.75rem);
  flex: none;
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--papier);
  box-shadow: 0 10px 30px -14px rgba(23, 22, 26, 0.45);
  transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.bulle:hover { transform: rotate(-4deg) scale(1.04); }

/* La signature : Bona Nova SC rend les minuscules en petites capitales, ce qui donne à
   la ligne son air de mention gravée sans crier comme des majuscules pleines.
   Elle mesure 24,235 em dans cette police avec cet interlettrage, d'où le 3,6 vw qui la
   tient sur une seule ligne jusqu'aux petits téléphones. Au-delà de 533 px de large le
   plafond de 1,2 rem prend le relais. Changer le texte oblige à remesurer. */
.final-signature {
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: min(3.6vw, 1.2rem);
  letter-spacing: 0.055em;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--encre-douce);
  margin: clamp(1.5rem, 3.5vw, 2.25rem) 0 0;
}

.final-titre {
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: clamp(1.9rem, 5.5vw, 3.6rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 clamp(1.5rem, 4vw, 2.25rem);
}

/* ---------- page Qui je suis ---------- */

.page {
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--marge);
}

.qui {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
  padding-top: clamp(2rem, 6vh, 4rem);
}
@media (min-width: 60rem) {
  .qui { grid-template-columns: 1.05fr 1fr; }
  .qui-image { position: sticky; top: clamp(2rem, 6vh, 4rem); }
}

.qui-image { overflow: hidden; }
.qui-image img { width: 100%; }

.qui-titre {
  font-family: 'Bona Nova SC', Georgia, serif;
  font-weight: 700;
  font-size: clamp(2.4rem, 7vw, 4.5rem);
  line-height: 0.95;
  letter-spacing: -0.025em;
  margin: 0 0 clamp(1.5rem, 4vw, 2.5rem);
}

.qui-texte p { margin: 0 0 1.4em; max-width: 56ch; }
.qui-texte p:first-of-type {
  font-size: clamp(1.15rem, 1.6vw, 1.35rem);
  line-height: 1.55;
}
.qui-texte strong { font-weight: 600; }

.qui-outils {
  margin: clamp(2rem, 5vw, 3rem) 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--trait);
}
.qui-outils li {
  display: flex;
  gap: 1.25rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--trait);
  font-size: 0.9375rem;
}
.qui-outils b {
  flex: none;
  width: 6.5rem;
  font-weight: 500;
  color: var(--encre-douce);
  letter-spacing: 0.04em;
  font-size: 0.8125rem;
  text-transform: uppercase;
  padding-top: 0.2em;
}

/* ---------- pied de page ---------- */

.pied {
  border-top: 1px solid var(--trait);
  margin-inline: var(--marge);
  padding-block: clamp(2rem, 5vh, 3.5rem);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  align-items: baseline;
  justify-content: space-between;
  font-size: 0.8125rem;
  color: var(--encre-douce);
}
.pied a { text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.4s, color 0.4s; }
.pied a:hover { color: var(--encre); border-color: var(--trait); }
.pied-liens { display: flex; flex-wrap: wrap; gap: 1.5rem; }

/* ---------- entrée au défilement ---------- */

.monte-au-scroll {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.monte-au-scroll.vu { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .monte-au-scroll { opacity: 1; transform: none; }
}
