/* Site public. Il partage la typographie de l'application, mais pas sa densité :
   une page qu'on lit en trois minutes n'a pas les contraintes d'un outil qu'on
   utilise trois heures. */
:root {
  --ink:   #1F2A1C;  --ink2: #4A553F;  --ink3: #7A8470;
  --amber: #C76A0A;  --amber2: #E08A1E;
  --fond:  #F7F8F4;  --fond2: #EEF2EC;  --trait: rgba(20,40,16,0.12);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--fond); color: var(--ink2);
  font-family: 'Inter', system-ui, sans-serif; font-size: 16px; line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
.centre { width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 22px; }
h1, h2, h3 { font-family: 'Outfit', sans-serif; color: var(--ink); letter-spacing: -.02em; line-height: 1.15; }
a { color: var(--amber); }
strong { color: var(--ink); font-weight: 600; }

/* ── Barre du haut ───────────────────────────────────────────────────────── */
.barre {
  position: sticky; top: 0; z-index: 50; background: rgba(247,248,244,.92);
  backdrop-filter: blur(10px); border-bottom: 1px solid var(--trait);
}
.barre .centre { display: flex; align-items: center; gap: 18px; height: 66px; }
.marque { display: flex; align-items: center; gap: 11px; text-decoration: none; margin-right: auto; }
.marque-pastille {
  width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center;
  justify-content: center; color: #fff; font-size: 16px;
  background: linear-gradient(150deg, var(--amber2), #B25C06);
}
.marque-nom { font-family: 'Outfit', sans-serif; font-weight: 800; font-size: 20px; color: var(--ink); }
.marque-nom span { color: var(--amber); }
.barre a.lien { color: var(--ink2); text-decoration: none; font-size: 14.5px; font-weight: 500; }
.barre a.lien:hover { color: var(--amber); }

.bouton {
  display: inline-block; padding: 11px 20px; border-radius: 11px; border: 0;
  font-family: inherit; font-size: 14.5px; font-weight: 600; cursor: pointer;
  text-decoration: none; text-align: center; transition: filter .12s, transform .12s;
}
.bouton-plein { background: var(--amber); color: #fff; }
.bouton-plein:hover { filter: brightness(.93); }
.bouton-vide { background: #fff; color: var(--ink); border: 1px solid var(--trait); }
.bouton-vide:hover { border-color: var(--amber); color: var(--amber); }
.bouton:disabled { opacity: .5; cursor: not-allowed; }

/* ── Accroche ────────────────────────────────────────────────────────────── */
.hero { padding: 76px 0 64px; background: linear-gradient(170deg, var(--fond2), var(--fond) 65%); }
.hero h1 { font-size: clamp(32px, 5.2vw, 52px); font-weight: 800; margin: 0 0 18px; max-width: 16ch; }
.hero h1 em { font-style: normal; color: var(--amber); }
.hero-sous { font-size: clamp(16px, 2vw, 19px); max-width: 56ch; margin: 0 0 30px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.hero-note { font-size: 13px; color: var(--ink3); margin-top: 16px; }

/* ── Sections ────────────────────────────────────────────────────────────── */
section { padding: 62px 0; }
section.pale { background: #fff; border-block: 1px solid var(--trait); }
.section-ttl { font-size: clamp(24px, 3.4vw, 33px); font-weight: 700; margin: 0 0 10px; max-width: 22ch; }
.section-sous { font-size: 16.5px; max-width: 62ch; margin: 0 0 38px; }

.grille { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.carte {
  background: #fff; border: 1px solid var(--trait); border-radius: 16px; padding: 24px 24px 26px;
}
section.pale .carte { background: var(--fond); }
.carte h3 { font-size: 17.5px; font-weight: 600; margin: 0 0 8px; }
.carte p { margin: 0; font-size: 14.5px; line-height: 1.6; }
.carte-ico { font-size: 22px; display: block; margin-bottom: 12px; }

/* ── Récit ───────────────────────────────────────────────────────────────── */
.recit {
  background: #fff; border: 1px solid var(--trait); border-left: 3px solid var(--amber);
  border-radius: 14px; padding: 26px 28px; max-width: 760px;
}
.recit p { margin: 0 0 12px; font-size: 15.5px; }
.recit p:last-child { margin-bottom: 0; }

/* ── Étapes ──────────────────────────────────────────────────────────────── */
.etapes { counter-reset: e; display: grid; gap: 26px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.etape { counter-increment: e; }
.etape::before {
  content: counter(e); display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; background: var(--amber); color: #fff;
  font-family: 'Outfit', sans-serif; font-weight: 700; font-size: 15px; margin-bottom: 12px;
}
.etape h3 { font-size: 16.5px; margin: 0 0 6px; }
.etape p { margin: 0; font-size: 14.5px; }

/* ── Tarifs ──────────────────────────────────────────────────────────────── */
.tarifs { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: start; }
.tarif {
  background: #fff; border: 1px solid var(--trait); border-radius: 18px;
  padding: 28px 26px; display: flex; flex-direction: column; height: 100%;
}
.tarif-phare { border-color: var(--amber); box-shadow: 0 10px 34px rgba(199,106,10,.12); }
.tarif-badge {
  align-self: flex-start; background: rgba(199,106,10,.12); color: #9A5208;
  font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 999px; margin-bottom: 12px;
}
.tarif h3 { font-size: 21px; font-weight: 700; margin: 0 0 4px; }
.tarif-accroche { font-size: 14px; color: var(--ink3); margin: 0 0 20px; min-height: 2.8em; }
.tarif-prix { font-family: 'Outfit', sans-serif; color: var(--ink); margin-bottom: 4px; }
.tarif-prix b { font-size: 38px; font-weight: 800; letter-spacing: -.03em; }
.tarif-prix span { font-size: 15px; color: var(--ink3); font-weight: 500; }
.tarif-ht { font-size: 12.5px; color: var(--ink3); margin-bottom: 20px; }
.tarif-quota {
  font-family: 'JetBrains Mono', monospace; font-size: 12.5px; color: var(--ink);
  background: var(--fond); border-radius: 9px; padding: 9px 12px; margin-bottom: 18px;
}
.tarif ul { list-style: none; margin: 0 0 24px; padding: 0; flex: 1; }
.tarif li { position: relative; padding-left: 24px; margin-bottom: 9px; font-size: 14.5px; line-height: 1.5; }
.tarif li::before { content: '✓'; position: absolute; left: 0; color: var(--amber); font-weight: 700; }
.tarif .bouton { width: 100%; }
.tarif-msg { font-size: 12.5px; color: #8C2F24; margin-top: 10px; }

/* ── Franchise ───────────────────────────────────────────────────────────── */
.franchise { background: #2F3B2A; color: #DDE5D6; }
.franchise h2 { color: #fff; }
.franchise .section-sous { color: #B6C2AC; }
.franchise .carte { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.12); }
.franchise .carte h3 { color: #fff; }
.franchise .carte p { color: #C6D1BC; }

/* ── Questions ───────────────────────────────────────────────────────────── */
.question { border-top: 1px solid var(--trait); padding: 18px 0; }
.question:last-of-type { border-bottom: 1px solid var(--trait); }
.question summary {
  cursor: pointer; font-family: 'Outfit', sans-serif; font-size: 16.5px; font-weight: 600;
  color: var(--ink); list-style: none; display: flex; justify-content: space-between; gap: 16px;
}
.question summary::-webkit-details-marker { display: none; }
.question summary::after { content: '+'; color: var(--amber); font-size: 21px; line-height: 1; }
.question[open] summary::after { content: '−'; }
.question p { margin: 12px 0 0; font-size: 15px; max-width: 70ch; }

/* ── Pied ────────────────────────────────────────────────────────────────── */
footer { background: #fff; border-top: 1px solid var(--trait); padding: 40px 0 46px; }
.pied { display: flex; flex-wrap: wrap; gap: 14px 26px; align-items: center; font-size: 13.5px; color: var(--ink3); }
.pied a { color: var(--ink3); text-decoration: none; }
.pied a:hover { color: var(--amber); text-decoration: underline; }
.pied-legal { width: 100%; font-size: 12.5px; color: var(--ink3); margin-top: 6px; }

/* Bandeau des personnes déjà connectées : on ne redirige pas de force, on
   propose. Quelqu'un peut vouloir relire ses propres tarifs. */
.bandeau-session {
  background: var(--amber); color: #fff; font-size: 14px; text-align: center; padding: 9px 16px;
}
.bandeau-session a { color: #fff; font-weight: 600; }

@media (max-width: 640px) {
  .barre .centre { height: 60px; gap: 10px; }
  .barre .masque-mobile { display: none; }
  /* « Se connecter » passait à la ligne et cassait la hauteur de la barre. */
  .barre a.lien { white-space: nowrap; font-size: 13.5px; }
  .barre .bouton { padding: 9px 15px; font-size: 13.5px; white-space: nowrap; }
  .marque-nom { font-size: 18px; }
  .hero { padding: 52px 0 46px; }
  section { padding: 46px 0; }
}

/* ═══ Le décor : des terres vues du ciel ═════════════════════════════════════
   Première version : un plan au trait fin, puis une maison en élévation.
   Verdict à l'usage — « dessin d'enfant » pour la maison, « moche » pour le
   fond. Les deux reproches tiennent au TRAIT : un contour dit schéma
   technique, et rien de ce qui est contourné ne paraît haut de gamme.

   D'où le renversement : plus aucun contour, rien que des aplats. Une mosaïque
   de terres, une lumière qui passe, un grain de papier. La matière fait tout.
   ═══════════════════════════════════════════════════════════════════════════ */

.hero { position: relative; overflow: hidden; }
.hero > .centre { position: relative; z-index: 1; }

.champ-hote { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.champ-hote svg.champ { width: 100%; height: 100%; display: block; }

/* La mosaïque se dissout vers la gauche — l'accroche y vit — et vers le bas,
   pour qu'il n'y ait pas de bord franc là où la section s'arrête. */
.champ-fond .champ {
  -webkit-mask-image:
    linear-gradient(100deg, transparent 6%, #000 54%),
    linear-gradient(#000 58%, transparent 97%);
  mask-image:
    linear-gradient(100deg, transparent 6%, #000 54%),
    linear-gradient(#000 58%, transparent 97%);
  -webkit-mask-composite: source-in; mask-composite: intersect;
}

/* ── La lumière ──────────────────────────────────────────────────────────────
   Deux masses très larges et très floues qui dérivent lentement. C'est elle
   qui fait vivre des aplats immobiles : sans elle, la mosaïque est une image ;
   avec elle, c'est un paysage sous un ciel qui bouge.

   `filter: blur()` sur 60 px plutôt qu'un dégradé plus doux : le flou lisse
   aussi les bords du dégradé lui-même, qui sinon se voient. */
.lueur { position: absolute; border-radius: 50%; filter: blur(64px); will-change: transform; }
.lueur-a {
  width: 72%; aspect-ratio: 1.7; top: -22%; left: 16%;
  background: radial-gradient(closest-side, rgba(255,231,186,.85), rgba(255,231,186,0) 72%);
  animation: derive-a 41s ease-in-out infinite alternate;
}
.lueur-b {
  width: 58%; aspect-ratio: 1.35; bottom: -28%; right: 2%;
  background: radial-gradient(closest-side, rgba(199,106,10,.15), rgba(199,106,10,0) 70%);
  animation: derive-b 57s ease-in-out infinite alternate;
}
@keyframes derive-a {
  from { transform: translate3d(-7%, -2%, 0) scale(1); }
  to   { transform: translate3d(9%, 7%, 0) scale(1.14); }
}
@keyframes derive-b {
  from { transform: translate3d(5%, 3%, 0) scale(1.06); }
  to   { transform: translate3d(-9%, -5%, 0) scale(1); }
}
.en-pause .lueur, .sans-mouvement .lueur { animation-play-state: paused; }

/* ── Le grain ────────────────────────────────────────────────────────────────
   PAS UN ORNEMENT. Des aplats aussi pâles se découpent en bandes visibles sur
   un écran 8 bits. Un bruit à 4 % casse ces bandes et donne au fond une
   matière de papier au lieu d'une surface plastique. C'est ce détail, plus que
   la couleur, qui sépare un aplat propre d'un aplat bon marché. */
.grain {
  position: absolute; inset: 0; opacity: .042; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/></filter><rect width='140' height='140' filter='url(%23b)'/></svg>");
  background-size: 140px 140px;
}

/* ── L'intro ─────────────────────────────────────────────────────────────── */
html.intro-en-cours, html.intro-en-cours body { overflow: hidden; }

.intro {
  position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center;
  background: transparent;   /* le fond est porté par les volets, sinon il resterait */
}
/* ON S'OUVRE, on ne se dissout pas. Deux volets portent chacun sa moitié du
   décor et s'écartent sur le site — un fondu fait disparaître un écran de
   chargement, deux volets qui s'ouvrent font entrer quelque part.
   101 % : à 100 % pile, un cheveu du volet reste visible sur le bord. */
.intro-volet {
  position: absolute; inset: 0; overflow: hidden;
  background: linear-gradient(165deg, #FBF9F5 0%, #F4F1E9 58%, #EFEBE0 100%);
  transition: transform 1s cubic-bezier(.62,.02,.26,1) .12s;
  will-change: transform;
}
.volet-g { clip-path: inset(0 50% 0 0); }
.volet-d { clip-path: inset(0 0 0 50%); }
.intro.partie { pointer-events: none; }
.intro.partie .volet-g { transform: translateX(-101%); }
.intro.partie .volet-d { transform: translateX(101%); }
/* La scène s'efface d'abord : les volets s'ouvrent sur le site, pas sur une
   villa coupée en deux. */
.intro-scene { position: relative; z-index: 1; transition: opacity .4s ease, transform .55s cubic-bezier(.4,0,.2,1); }
.intro.partie .intro-scene { opacity: 0; transform: translateY(-12px) scale(.97); }

.champ-intro { animation: leve-toi 2.4s cubic-bezier(.22,.61,.36,1) both; }
@keyframes leve-toi {
  from { opacity: 0; transform: scale(1.06); filter: saturate(.4) brightness(1.08); }
  to   { opacity: 1; transform: none;        filter: none; }
}
.champ-intro .lueur-a { animation: derive-a 41s ease-in-out infinite alternate, aube 2.6s ease-out both; }
@keyframes aube { from { opacity: 0; } to { opacity: 1; } }

.intro-marque {
  position: relative; display: grid; justify-items: center; gap: 5px;
  animation: marque-apparait 1.1s cubic-bezier(.22,.61,.36,1) 1.5s both;
}
@keyframes marque-apparait {
  from { opacity: 0; transform: translateY(10px); letter-spacing: .04em; }
  to   { opacity: 1; transform: none; letter-spacing: -.025em; }
}
.intro-nom {
  font-family: 'Outfit', sans-serif; font-weight: 800; font-size: clamp(38px, 7vw, 60px);
  letter-spacing: -.025em; color: var(--ink); line-height: 1;
}
.intro-nom span { color: var(--amber); }
.intro-tag {
  font-size: 14px; color: var(--ink3); letter-spacing: .01em;
  animation: marque-apparait 1.1s cubic-bezier(.22,.61,.36,1) 1.78s both;
}

/* ── La villa, en plans de lumière ───────────────────────────────────────── */
/* Aucun contour : des faces, et une lumière qui vient d'en haut à gauche.
   Ce qui regarde vers nous-à-gauche est au jour, ce qui regarde vers la droite
   est à l'ombre. C'est l'écart entre deux faces d'un MÊME matériau — deux
   versants, deux murs — qui fait tenir les volumes. Entre matériaux, non : la
   tuile reste plus sombre que l'enduit, même en plein soleil.
   Les points sont calculés par scripts/villa.py, jamais à la main. */
.intro-scene { display: grid; justify-items: center; gap: 18px; }
.villa-svg { display: block; width: clamp(280px, 54vw, 512px); overflow: visible; }

.v-pelouse  { fill: #C3D2A6; }   /* l'herbe : c'est elle, le terrain */
.v-dalle    { fill: #E3D3B6; }   /* la terrasse */
.v-margelle { fill: #EFE3CB; }
.v-bassin   { fill: #8FC6D6; }
.v-reflet   { fill: #BFE0E8; }   /* la bande de ciel sur l'eau : sans elle, une dalle */
.v-ombre    { fill: rgba(70,50,30,.13); }
.v-pied     { fill: rgba(70,50,30,.12); }
.v-arbre    { fill: #4F6347; }
.v-massif   { fill: #6F8257; }
.v-fleur    { fill: #D98BA6; }   /* lauriers-roses */
.v-transat  { fill: #F6F1E4; }
.v-transat-ombre { fill: rgba(70,50,30,.10); }
.v-mat      { fill: #A99070; }
.v-parasol  { fill: #F6F0E2; }

/* La couverture : QUATRE pans, quatre tons. La croupe éloignée regarde vers le
   haut-gauche, donc vers la lumière — c'est la face la plus claire du toit. */
.v-toit-croupe-jour { fill: #E09A6A; }
.v-toit-jour   { fill: #D98C5C; }
.v-toit-ombre  { fill: #C07A50; }
.v-toit-croupe { fill: #AB6A45; }
.v-faitage     { fill: #97593A; }
.v-mur-jour    { fill: #EFD6B4; }   /* l'enduit, face à la lumière */
.v-mur-ombre   { fill: #D2B08A; }
/* L'ombre que le débord de toiture porte sur le mur. Sans elle, le toit est
   posé dessus comme un couvercle au lieu de le coiffer. */
.v-sousface    { fill: #BE9C78; }
.v-chem-toit   { fill: #EFE0C4; }
.v-chem-jour   { fill: #E5CDAB; }
.v-chem-ombre  { fill: #C1A17C; }
/* Une baie dans un mur ÉCLAIRÉ est sombre : on voit le dedans, pas la lumière. */
.v-baie        { fill: #55503F; }
.v-volet       { fill: #F7F3EA; }   /* les volets : le Sud tient dans ces deux rectangles */
.v-porte       { fill: #7E6446; }

.v-terrain > * { animation: v-parait 1.2s ease-out .04s both; }
.v-fond > *    { animation: v-monte .9s cubic-bezier(.22,.61,.36,1) .12s both; }
/* Les volumes montent du sol, du plus lointain au plus proche. C'est ce
   décalage qui fait lire un chantier plutôt qu'une image qui apparaît. */
.v-bas > *, .v-haut > *, .v-porche > * { animation: v-monte .85s cubic-bezier(.22,.61,.36,1) both; }
.v-bas > *    { animation-delay: .22s; }
.v-haut > *   { animation-delay: .48s; }
.v-porche > * { animation-delay: .66s; }
.v-jardin > * { animation: v-monte .9s cubic-bezier(.22,.61,.36,1) .92s both; }
/* Dernier geste : on allume. Sélecteur plus précis que `.v-haut > *`, sinon
   la lueur s'allumerait avec les murs. */
.v-haut > .v-lueur, .v-haut > .v-halo { animation-delay: 1.16s; }

@keyframes v-monte  { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes v-parait { from { opacity: 0; } to { opacity: 1; } }}}

@media (prefers-reduced-motion: reduce) {
  .intro, .intro-marque, .intro-tag, .champ-intro, .lueur,
  .villa * { animation: none !important; }
  .intro { transition: none !important; }
}
