/* habillage : theme « ruby-realty » du landing-deck (cle racine `theme`) */
/* THÈME : Ruby Realty — Clair + rubis, immobilier. (généré, palette originale) */
:root {
  --bg:#fbf7f7; --bg-alt:#f3e7e7; --ink:#241619; --muted:#766065;
  --accent:#b11d33; --accent-2:#c99a5b; --accent-ink:#ffffff;
  --card-bg:#fffafa; --nav-bg:rgba(251,247,247,.82); --nav-blur:13px;
  --footer-bg:#241619; --footer-ink:#eedee2;
  --font-display:'Syne',sans-serif; --font-body:'Manrope',sans-serif; --weight-display:700;
  --radius:6px; --radius-lg:14px;
  --border:1px solid rgba(36,22,25,.10);
  --shadow:0 14px 38px -16px rgba(177,29,51,.42);
  --shadow-lg:0 30px 60px -26px rgba(36,22,25,.20);
  --maxw:1180px; --section-pad:96px;
}

/* couleur de marque du client + `theme_overrides` explicites, par-dessus le theme */
:root {
  --accent:#a61c30;
  --accent-2:#f0a3ad;
  --footer-bg:#1c2a4a;
  --footer-ink:#e6ebf5;
  --muted:#5e4a4f;
}

/* ===== base.css (landing-deck) ===== */
/* ============================================================================
   LANDING-DECK — base.css
   STRUCTURE COMMUNE. AUCUNE COULEUR NI POLICE EN DUR.
   Tout passe par des variables CSS redéfinies dans themes/<nom>.css.
   Contrat de variables attendu (voir README.md) :
     Couleurs : --bg --bg-alt --ink --muted --accent --accent-2 --accent-ink
                --card-bg --card-border --nav-bg --footer-bg --footer-ink
     Typo     : --font-display --font-body --weight-display
     Forme    : --radius --radius-lg --shadow --shadow-lg --border
     Divers   : --maxw --section-pad --nav-blur
   base.css ne fait QUE consommer ces variables (jamais de #hex ici).
   ========================================================================= */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* COUPER LE DEBORDEMENT HORIZONTAL SANS CASSER LA BARRE COLLANTE (09/09/2026).
     Ces deux lignes se lisent ensemble, ne jamais en retirer une seule.

     LE FAIT, ET IL SUFFIT A JUSTIFIER CES DEUX LIGNES. `overflow-x: hidden` sur le
     `body` ou sur `html` casse `position: sticky` : c'est un defaut connu, reproduit
     partout, et il n'existe pas avec `clip`. Notre `.nav` est `sticky` et enfant direct
     du `body`. C'est la seule anomalie trouvee sur cette page apres avoir passe les six
     regles iOS du skill, toutes conformes.

     L'EXPLICATION, DOUTEE PUIS MESUREE (lire les deux paragraphes qui suivent). On lit partout
     que `overflow-x: hidden` force le calcul de `overflow-y: auto` sur le meme element,
     que le `body` devient une BOITE DE DEFILEMENT, et qu'un `sticky` prend cette boite
     pour repere au lieu de la fenetre. MAIS une autre regle CSS s'y oppose : quand
     `html` est en `overflow: visible` -- c'est notre cas, aucune regle `html{overflow}`
     dans cette feuille -- l'`overflow` du `body` est PROPAGE au viewport, et le `body`
     lui-meme redevient `visible`. Si cette propagation s'applique, le `body` n'est une
     boite de defilement dans AUCUN moteur et l'explication ci-dessus est fausse ; le
     defaut iOS serait alors un autre bug WebKit, que `clip` corrige peut-etre quand
     meme, mais pas pour cette raison.

     MESURE FAITE, ET ELLE TRANCHE (CEO, 09/09/2026 a 16h29). Sur les deux pages SERVIES
     d'Issou Debouchage, qui portaient encore `hidden` seul, a 390 px :
     `/debouchage-wc` et `/debouchage-evier` rendent tous deux **`body hidden/auto`**.
     `overflow-y` CALCULE a `auto` : la propagation vers le viewport ne s'applique donc
     PAS, et le `body` est bien une boite de defilement. **L'explication ci-dessus est la
     bonne**, et le paragraphe qui la donnait pour douteuse est corrige par cette mesure.
     Reserve residuelle, honnete et mineure : un navigateur peut rendre la valeur
     specifiee la ou la propagation joue sur la valeur utilisee. Elle ne change rien au
     correctif.

     CE QUE FRED A VU, le 09/09/2026 a 16h07 (capture
     `inocom-os/logs/telegram-images/2026-09-09-160737_953.jpg`, page /fenetres de Gautier,
     iPhone) : le corps de la page etait defile jusqu'a « Pourquoi passer par nous »,
     et derriere la barre translucide de Safari on voyait encore la PHOTO DU HERO,
     c'est-a-dire le HAUT du document. Cette image seule est COMPATIBLE avec
     l'explication, elle ne l'isole pas : un `sticky` qui decroche pour d'autres raisons
     WebKit donne la meme chose. C'est la mesure du 16h29, pas la capture, qui tranche.
     Troisieme fois que ce genre de defaut arrive (26/07, 08/09, 09/09).

     POURQUOI `clip` ET PAS AUTRE CHOSE. `overflow-x: clip` coupe le debordement SANS
     creer de boite de defilement, et il laisse `overflow-y` a `visible` : quelle que
     soit la lecture retenue ci-dessus, il retire la seule anomalie de la page sans rien
     rendre. Deplacer le `hidden` sur `html` ne reglerait rien, ca deplacerait le
     probleme d'un cran.

     POURQUOI LES DEUX LIGNES. Un navigateur qui ne connait pas `clip` ignore la seconde
     et garde `hidden` : le debordement reste coupe partout, et c'est non negociable
     (le `overflow-x` avait ete pose pour ca). Les autres ecrasent avec `clip`.

     CE QUE LES CONTROLES NE VOIENT PAS, et il faut le savoir avant d'en ajouter un :
     `check_page_mobile.sh` regarde les couleurs, la translucidite, le grain et le
     `::before` -- pas la chaine des ancetres d'un `sticky`. `qa_visuelle.sh` mesure dans
     Chromium sans tete, qui ne reproduit pas le defilement de Safari sur iOS. Les deux
     etaient VERTS sur la page que Fred a trouvee cassee.

     ET CE QUE CELLE-CI NE PROUVE PAS. Cette correction n'a ete verifiee sur AUCUN
     iPhone au moment ou elle est ecrite. Elle retire une anomalie reelle ; elle ne
     constate pas la disparition du defaut. Tant qu'une capture iPhone apres defilement
     n'a pas ete faite, ne pas ecrire ailleurs que le sujet est clos. */
  overflow-x: hidden;
  overflow-x: clip;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; }
ul { margin: 0; padding: 0; list-style: none; }

/* ---- Typo ---------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-display, 700);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ink);
}
h1 { font-size: clamp(2.4rem, 6vw, 4.2rem); }
h2 { font-size: clamp(1.9rem, 4.2vw, 3rem); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); }
p  { margin: 0; }

.accent { color: var(--accent); }
.serif-accent { font-family: var(--font-display); font-style: italic; color: var(--accent); }

/* ---- Layout -------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--maxw, 1180px);
  margin: 0 auto;
  padding: 0 24px;
}
section { padding: var(--section-pad, 96px) 0; position: relative; }
.section-alt { background: var(--bg-alt); }

.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 16px;
}
.section-head { max-width: 680px; margin: 0 auto 56px; text-align: center; }
.section-head p { color: var(--muted); margin-top: 18px; font-size: 1.1rem; }

/* ---- Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 15px 30px;
  border-radius: var(--radius, 12px);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.98rem;
  letter-spacing: -0.01em;
  transition: transform .2s ease, box-shadow .2s ease, background .2s ease, color .2s ease;
  white-space: nowrap;
}
.btn-primary { background: var(--accent); color: var(--accent-ink); box-shadow: var(--shadow); }
.btn-primary:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.btn-ghost { background: transparent; color: var(--ink); border: var(--border); }
.btn-ghost:hover { background: var(--card-bg); transform: translateY(-3px); }
.btn-lg { padding: 18px 40px; font-size: 1.05rem; }

/* ---- Navbar -------------------------------------------------------------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  /* Barre 100 % OPAQUE, jamais rgba, jamais backdrop-filter (regle Inocom du 26/07/2026,
     reposee ici a la source le 08/09/2026). Sur iOS le flou d'arriere-plan ne s'applique pas
     toujours : il ne reste alors qu'un voile a 82 % et le contenu de la page se LIT A TRAVERS
     la barre pendant le defilement. Fred l'a signale le 08/09 sur le monitor, capture a
     l'appui ; le funnel-builder a trouve le meme defaut le meme soir dans ce deck, donc chez
     TOUS les clients qu'il sert. Corrige ICI et non par une surcharge : une surcharge laisse
     la regle translucide dans la feuille, ou le prochain lecteur la croit encore active.
     `--nav-bg` reste defini par les themes, il ne sert simplement plus a la barre.
     Controle : scripts/check_page_mobile.sh sur la page GENEREE. */
  background: var(--bg);
  border-bottom: var(--border);
}
.nav .container { display: flex; align-items: center; justify-content: space-between; height: 72px; }
.nav-logo { font-family: var(--font-display); font-weight: 800; font-size: 1.3rem; letter-spacing: -0.03em; }
.nav-logo span { color: var(--accent); }
.nav-links { display: flex; gap: 30px; align-items: center; }
.nav-links a { color: var(--muted); font-size: 0.95rem; font-weight: 500; transition: color .2s; }
.nav-links a:hover { color: var(--ink); }
.nav-cta { display: flex; gap: 12px; align-items: center; }
.nav-burger { display: none; font-size: 1.5rem; color: var(--ink); }

/* ---- Hero ---------------------------------------------------------------- */
.hero { padding-top: clamp(56px, 8vw, 110px); padding-bottom: clamp(56px, 8vw, 110px); overflow: hidden; }
.hero .container { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 56px; align-items: center; }
.hero-badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 16px; border-radius: 999px;
  background: var(--card-bg); border: var(--border);
  font-size: 0.8rem; font-weight: 600; color: var(--muted); margin-bottom: 26px;
}
.hero-badge::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 25%, transparent); }
.hero h1 { margin-bottom: 22px; }
.hero-sub { font-size: 1.2rem; color: var(--muted); max-width: 540px; margin-bottom: 34px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-visual {
  aspect-ratio: 4 / 3.4;
  border-radius: var(--radius-lg, 24px);
  background-image: var(--img, linear-gradient(135deg, var(--accent), var(--accent-2)));
  background-size: cover; background-position: center;
  border: var(--border);
  box-shadow: var(--shadow-lg);
}

/* ---- Logos band ---------------------------------------------------------- */
.logos { padding: 44px 0; border-top: var(--border); border-bottom: var(--border); }
.logos-label { text-align: center; color: var(--muted); font-size: 0.82rem; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 26px; }
.logos-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 40px 56px; }
.logos-row span { font-family: var(--font-display); font-weight: 700; font-size: 1.35rem; color: var(--ink); opacity: .42; transition: opacity .2s; }
.logos-row span:hover { opacity: .85; }

/* ---- Features grid ------------------------------------------------------- */
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
/* QUATRE cartes sur une grille a trois colonnes laissent la quatrieme SEULE sur une deuxieme
   rangee. Cas d'origine : la page portails de Pierre Gautier, ou la cloture est entree comme
   quatrieme intervention le 09/09/2026. C'est le meme defaut que le bandeau `.reassure-grid` a
   cinq items, corrige la veille en retirant un item -- ici on ne peut pas, les quatre cartes sont
   du contenu valide. Le selecteur ne mord QUE sur exactement quatre enfants : a trois
   `:nth-child(4)` n'existe pas, a cinq il n'est pas `:last-child`.

   POURQUOI ELLE EST ENFERMEE DANS UN `min-width`, et ce n'est pas une precaution :
   `.features-grid:has(> :nth-child(4):last-child)` pese (0,3,0) -- une classe plus les deux
   pseudo-classes de l'argument de `:has()` -- alors que les deux regles qui la degradent plus
   bas (celles qui listent `.features-grid, .testimonials-grid, .pricing-grid`, dans les blocs
   `max-width: 960px` puis `max-width: 640px`) ne pesent que (0,1,0). Sans cette borne, la regle
   GAGNE la cascade a toutes les largeurs et la page portails resterait a DEUX COLONNES sur un
   telephone. Mesure faite au premier rebuild du 09/09 a 22h47, avant que ca parte.

   POURQUOI 960.02 ET PAS 961 : `max-width: 960px` et `min-width: 961px` laissent un trou sur les
   largeurs fractionnaires -- a 960,5 px, ce que produisent un zoom ou un ecran HiDPI, AUCUNE des
   deux ne s'applique, la grille repasse a trois colonnes et la quatrieme carte redevient
   orpheline. Trouve par la relecture croisee le 09/09 a 22h50.

   ET POURQUOI CE COMMENTAIRE NE CITE AUCUN NUMERO DE LIGNE : j'en ai ecrit deux ici, ils
   pointaient juste, puis j'ai rallonge le commentaire de neuf lignes au-dessus d'eux et ils
   sont devenus faux sans que rien ne le signale. Un numero de ligne qui designe une autre ligne
   du MEME fichier se perime a la premiere edition de ce fichier. On designe par le contenu. */
@media (min-width: 960.02px) {
  .features-grid:has(> :nth-child(4):last-child) { grid-template-columns: repeat(2, 1fr); }
}
.feature-card {
  background: var(--card-bg); border: var(--border); border-radius: var(--radius-lg, 20px);
  padding: 32px; transition: transform .25s ease, box-shadow .25s ease;
}
.feature-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
.feature-icon {
  width: 48px; height: 48px; border-radius: var(--radius, 12px);
  display: grid; place-items: center; margin-bottom: 20px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.feature-icon svg { width: 24px; height: 24px; }
.feature-card h3 { margin-bottom: 10px; }
.feature-card p { color: var(--muted); font-size: 0.98rem; }

/* ---- Split (image + texte alternés) -------------------------------------- */
.split .container { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; }
.split + .split { padding-top: 0; }
.split-media {
  aspect-ratio: 5 / 4; border-radius: var(--radius-lg, 24px);
  background-image: var(--img, linear-gradient(135deg, var(--accent-2), var(--accent)));
  background-size: cover; background-position: center;
  border: var(--border); box-shadow: var(--shadow);
}
.split-reverse .split-media { order: 2; }
.split-body .eyebrow { margin-bottom: 14px; }
.split-body h2 { margin-bottom: 18px; }
.split-body p { color: var(--muted); margin-bottom: 18px; }
.split-list li { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 12px; color: var(--ink); font-weight: 500; }
.split-list li::before {
  content: '✓'; flex: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; font-size: 0.72rem; font-weight: 800; margin-top: 2px;
}

/* ---- Testimonials -------------------------------------------------------- */
.testimonials-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.testi-card {
  background: var(--card-bg); border: var(--border); border-radius: var(--radius-lg, 20px);
  padding: 30px; display: flex; flex-direction: column;
}
.testi-featured { grid-column: span 3; padding: 46px; position: relative; overflow: hidden; }
.testi-featured::before {
  content: '\201C'; position: absolute; top: -30px; right: 20px;
  font-family: var(--font-display); font-size: 200px; line-height: 1;
  color: var(--accent); opacity: 0.12;
}
.testi-card .stars { color: var(--accent); letter-spacing: 2px; margin-bottom: 16px; font-size: 0.95rem; }
.testi-quote { font-size: 1.05rem; line-height: 1.55; margin-bottom: 22px; color: var(--ink); }
.testi-featured .testi-quote { font-size: clamp(1.3rem, 2.4vw, 1.7rem); font-family: var(--font-display); font-weight: 500; line-height: 1.4; max-width: 80%; }
.testi-author { display: flex; align-items: center; gap: 13px; margin-top: auto; }
.testi-avatar { width: 46px; height: 46px; border-radius: 50%; background: linear-gradient(135deg, var(--accent), var(--accent-2)); flex: none; }
.testi-author b { display: block; font-size: 0.95rem; }
.testi-author small { color: var(--muted); font-size: 0.85rem; }

/* ---- Stats --------------------------------------------------------------- */
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; }
.stat .num {
  font-family: var(--font-display); font-weight: var(--weight-display, 800);
  font-size: clamp(2.6rem, 5vw, 3.8rem); line-height: 1; letter-spacing: -0.04em;
  color: var(--accent);
}
.stat .label { color: var(--muted); margin-top: 10px; font-size: 0.95rem; }

/* ---- Pricing ------------------------------------------------------------- */
.pricing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: stretch; }
.price-card {
  background: var(--card-bg); border: var(--border); border-radius: var(--radius-lg, 20px);
  padding: 36px 30px; display: flex; flex-direction: column;
}
.price-card.featured {
  background: var(--ink); color: var(--bg);
  transform: scale(1.03); box-shadow: var(--shadow-lg); position: relative; z-index: 2;
}
.price-card.featured h3, .price-card.featured .price { color: var(--bg); }
.price-card.featured .price-feat li { color: color-mix(in srgb, var(--bg) 78%, var(--ink)); }
.price-tag { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); margin-bottom: 14px; }
.price-card .price { font-family: var(--font-display); font-weight: var(--weight-display, 800); font-size: 3rem; letter-spacing: -0.03em; margin: 6px 0 4px; }
.price-card .price small { font-size: 1rem; font-weight: 500; color: var(--muted); }
.price-desc { color: var(--muted); font-size: 0.92rem; margin-bottom: 24px; }
.price-feat { margin-bottom: 28px; flex: 1; }
.price-feat li { display: flex; gap: 10px; padding: 8px 0; font-size: 0.95rem; color: var(--ink); border-bottom: var(--border); }
.price-feat li::before { content: '✓'; color: var(--accent); font-weight: 800; }
.price-card .btn { width: 100%; }
.price-card.featured .btn-ghost { color: var(--bg); border-color: color-mix(in srgb, var(--bg) 40%, transparent); }

/* ---- FAQ (accordéon) ----------------------------------------------------- */
.faq-wrap { max-width: 760px; margin: 0 auto; }
.faq-item { border-bottom: var(--border); }
.faq-q {
  width: 100%; text-align: left; display: flex; justify-content: space-between; align-items: center;
  gap: 20px; padding: 24px 4px; font-family: var(--font-display); font-weight: 600; font-size: 1.12rem; color: var(--ink);
}
.faq-q .sign { flex: none; width: 26px; height: 26px; border-radius: 50%; border: var(--border); display: grid; place-items: center; color: var(--accent); font-size: 1.2rem; transition: transform .25s; }
.faq-item.open .faq-q .sign { transform: rotate(45deg); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height .3s ease; }
.faq-a p { color: var(--muted); padding: 0 4px 24px; font-size: 1rem; }

/* ---- CTA final ----------------------------------------------------------- */
.cta-final { text-align: center; }
.cta-box {
  background: var(--accent); color: var(--accent-ink);
  border-radius: var(--radius-lg, 28px); padding: clamp(48px, 7vw, 84px) 32px;
  position: relative; overflow: hidden; box-shadow: var(--shadow-lg);
}
.cta-box h2 { color: var(--accent-ink); max-width: 720px; margin: 0 auto 18px; }
.cta-box p { color: color-mix(in srgb, var(--accent-ink) 82%, transparent); max-width: 540px; margin: 0 auto 32px; font-size: 1.15rem; }
.cta-box .btn-primary { background: var(--accent-ink); color: var(--accent); }
.cta-box .btn-primary:hover { box-shadow: 0 16px 40px -12px color-mix(in srgb, var(--accent-ink) 50%, transparent); }

/* ---- Footer -------------------------------------------------------------- */
.footer { background: var(--footer-bg); color: var(--footer-ink); padding: 64px 0 32px; }
.footer-top { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 40px; padding-bottom: 44px; border-bottom: 1px solid color-mix(in srgb, var(--footer-ink) 14%, transparent); }
.footer-brand .nav-logo { font-size: 1.4rem; margin-bottom: 14px; display: inline-block; }
.footer-brand p { color: color-mix(in srgb, var(--footer-ink) 65%, transparent); max-width: 280px; font-size: 0.95rem; }
.footer-col h4 { font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; opacity: .55; margin-bottom: 16px; }
.footer-col a { display: block; color: color-mix(in srgb, var(--footer-ink) 72%, transparent); padding: 6px 0; font-size: 0.94rem; transition: color .2s; }
.footer-col a:hover { color: var(--footer-ink); }
.footer-bottom { padding-top: 26px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; color: color-mix(in srgb, var(--footer-ink) 55%, transparent); font-size: 0.86rem; }

/* ---- Hero : badges de stats flottants (pattern Lead Gen / SaaS) ---------- */
.hero-visual { position: relative; }
.hero-stat {
  position: absolute; display: flex; align-items: center; gap: 11px;
  background: var(--card-bg); border: var(--border); border-radius: 16px;
  padding: 12px 16px; box-shadow: var(--shadow-lg);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.hero-stat .ico {
  width: 36px; height: 36px; border-radius: 11px; flex: none; display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent);
}
.hero-stat .ico svg { width: 18px; height: 18px; }
.hero-stat b { font-family: var(--font-display); font-weight: var(--weight-display, 700); font-size: 1.1rem; line-height: 1; display: block; }
.hero-stat small { color: var(--muted); font-size: 0.74rem; }
.hero-stat--tr { top: 18px; right: 16px; }
.hero-stat--bl { bottom: 20px; left: 16px; }

/* ---- Lead Gen : section photo/texte + carte formulaire ------------------- */
.lead .container { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 54px; align-items: center; }
.lead-body h2 { margin: 14px 0 18px; }
.lead-body > p { color: var(--muted); margin-bottom: 22px; font-size: 1.08rem; }
.form-card {
  background: var(--card-bg); border: var(--border); border-radius: var(--radius-lg, 22px);
  padding: 34px; box-shadow: var(--shadow-lg);
}
.form-card h3 { margin-bottom: 6px; }
.form-card .sub { color: var(--muted); font-size: 0.95rem; margin-bottom: 22px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.field input, .field select {
  width: 100%; padding: 13px 15px; border-radius: var(--radius, 12px);
  border: var(--border); background: var(--bg); color: var(--ink);
  font-family: var(--font-body); font-size: 0.96rem;
}
.field input:focus, .field select:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.form-card .btn { width: 100%; margin-top: 8px; }
.form-note { text-align: center; color: var(--muted); font-size: 0.8rem; margin-top: 12px; }

/* ---- Reveal on scroll ---------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(34px); transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1); }
.reveal.in { opacity: 1; transform: none; }

/* ---- Responsive ---------------------------------------------------------- */
@media (max-width: 960px) {
  .hero .container { grid-template-columns: 1fr; gap: 40px; }
  .hero-visual { order: -1; }
  .features-grid, .testimonials-grid, .pricing-grid { grid-template-columns: repeat(2, 1fr); }
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 36px 24px; }
  .testi-featured { grid-column: span 2; }
  .price-card.featured { transform: none; }
  .lead .container { grid-template-columns: 1fr; gap: 36px; }
  .footer-top { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  body { font-size: 16px; }
  section { padding: 64px 0; }
  .nav-links { display: none; }
  .nav-burger { display: block; }
  .split .container { grid-template-columns: 1fr; gap: 32px; }
  .split-reverse .split-media { order: 0; }
  .features-grid, .testimonials-grid, .pricing-grid { grid-template-columns: 1fr; }
  .testi-featured, .testi-featured .testi-quote { grid-column: auto; max-width: 100%; }
  .footer-top { grid-template-columns: 1fr 1fr; }
  .hero-actions .btn, .cta-box .btn { width: 100%; }
}

/* ===== bloc du gabarit t-localservice ===== */

/* ---- Spécifique t-localservice : cabinet dentaire ---- */
.nav-phone {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 0.95rem; color: var(--ink);
  padding: 9px 14px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: var(--border);
}
.nav-phone svg { width: 16px; height: 16px; color: var(--accent); }

/* Hero : badges de confiance en pastilles */
.trust-pills { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.trust-pill {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 15px; border-radius: 999px;
  background: var(--card-bg); border: var(--border);
  font-size: 0.84rem; font-weight: 600; color: var(--ink);
  box-shadow: var(--shadow);
}
.trust-pill .ico {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}
.trust-pill .ico svg { width: 15px; height: 15px; }
.trust-pill b { font-family: var(--font-display); font-weight: var(--weight-display, 700); }

/* Infos pratiques */
.info-grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: 28px; }
.info-card {
  background: var(--card-bg); border: var(--border);
  border-radius: var(--radius-lg, 20px); padding: 32px;
}
.info-card h3 { display: flex; align-items: center; gap: 11px; margin-bottom: 22px; }
.info-card h3 .ico {
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.info-card h3 .ico svg { width: 20px; height: 20px; }
.hours-list li {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 0; border-bottom: var(--border);
  font-size: 0.96rem;
}
.hours-list li:last-child { border-bottom: none; }
.hours-list li span:first-child { color: var(--ink); font-weight: 600; }
.hours-list li span:last-child { color: var(--muted); }
.hours-list li.closed span:last-child { color: var(--accent); font-weight: 700; }
.info-map {
  width: 100%; aspect-ratio: 16 / 8;
  border-radius: var(--radius, 14px); overflow: hidden;
  background-image: linear-gradient(135deg, color-mix(in srgb, var(--accent) 22%, var(--bg-alt)), color-mix(in srgb, var(--accent-2) 22%, var(--bg-alt)));
  border: var(--border); position: relative;
  display: grid; place-items: center; margin-bottom: 22px;
}
.info-map .pin {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--card-bg); border: var(--border);
  border-radius: 999px; padding: 10px 16px;
  font-weight: 700; font-size: 0.9rem; box-shadow: var(--shadow-lg);
}
.info-map .pin svg { width: 17px; height: 17px; color: var(--accent); }
.info-line { display: flex; align-items: flex-start; gap: 12px; padding: 11px 0; }
.info-line .ico {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.info-line .ico svg { width: 16px; height: 16px; }
.info-line small { display: block; color: var(--muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; margin-bottom: 2px; }
.info-line b { font-family: var(--font-display); font-weight: var(--weight-display, 700); font-size: 1.02rem; }

/* Hero gauche : titre serré */
.hero-eyebrow { margin-bottom: 14px; }

@media (max-width: 960px) {
  .team-grid { grid-template-columns: 1fr 1fr; }
  .gallery-row { grid-template-columns: repeat(2, 1fr); }
  .info-grid { grid-template-columns: 1fr; }
  .nav-phone { display: none; }
}
@media (max-width: 640px) {
  .team-grid { grid-template-columns: 1fr; }
  .gallery-row { grid-template-columns: 1fr 1fr; }
}


/* ===== Complements Inocom (hors deck) ===== */
/* Le deck cache TOUT le contenu (.reveal{opacity:0}) et le revele au scroll par un
   IntersectionObserver : sans JS, la page est blanche, et ni un robot d'indexation ni un
   lecteur d'ecran ne scrollent. La charge est donc inversee : visible par defaut, anime
   seulement si le script a pose `html.js`. Piege trouve par le CEO le 07/09/2026. */
.reveal { opacity:1; transform:none; }
html.js .reveal { opacity:0; transform:translateY(34px); }
html.js .reveal.in { opacity:1; transform:none; }
@media (prefers-reduced-motion:reduce) { html.js .reveal { opacity:1; transform:none; } }
.logo-texte { font-family: var(--font-display); font-weight: var(--weight-display,700); font-size: 1.15rem; letter-spacing: -.02em; }
/* La barre est un flex : un <a> qui ne contient qu'une image en width:auto n'a aucune
   largeur intrinseque et s'ecrase a ZERO. Le logo d'Issou etait charge (180x180) et rendu
   en 0x0 -- invisible, sans erreur, sans image cassee. Il faut une hauteur EXPLICITE sur
   l'image et `flex:none` sur le lien. (CEO, 07/09/2026, mesure au navigateur : la balise
   etait la, le fichier repondait en 200, et la case faisait 0 pixel.) */
.nav-logo { flex: none; display: inline-flex; align-items: center; }
/* ---- Bandeau de reassurance (CEO, 07/09/2026) ----
   Remplace .logos-row du deck, prevu pour des logos et non pour du texte. Grille
   reguliere, pictogramme accentue, fait en gras et precision en dessous : la meme
   information devient lisible d'un coup d'oeil au lieu de quatre phrases grises. */
.reassure { padding: 40px 0; border-top: var(--border); border-bottom: var(--border);
            background: var(--bg-alt, var(--bg)); }
.reassure-label { text-align: center; color: var(--muted); font-size: .78rem;
  letter-spacing: .14em; text-transform: uppercase; font-weight: 700; margin-bottom: 26px; }
/* LA GRILLE S'ADAPTE AU NOMBRE D'ELEMENTS, ELLE N'EST PLUS FIGEE A QUATRE (23/09/2026).
   Alixan, retour vocal sur les cinq landings d'EXPERT HABITAT : « on a trois blocs sur la gauche,
   c'est comme s'il y avait la place pour en mettre cinq ». Il avait raison, et la cause etait ici :
   `repeat(4, 1fr)` en dur reservait QUATRE colonnes quel que soit le nombre d'items. A trois items,
   la quatrieme colonne restait vide et les trois blocs se calaient a gauche. MDO Concept ne l'a
   jamais montre parce que son `authbar` porte exactement quatre entrees.
   `auto-fit` effondre les pistes vides : trois items rendent trois colonnes egales, quatre en
   rendent quatre, et la rangee est pleine dans les deux cas. Le `minmax(220px, 1fr)` garde le
   repli automatique aux largeurs intermediaires ; les deux media queries plus bas restent en
   place et continuent de commander en dessous de 960 et de 560 px.
   Le controle visuel du parc ne pouvait pas le voir : il mesure le CONTRASTE, pas l'equilibre. */
.reassure-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }
.reassure-item { display: flex; gap: 12px; align-items: flex-start;
  background: var(--card-bg, transparent); border: var(--border);
  border-radius: var(--radius, 12px); padding: 16px 18px; min-width: 0; }
.reassure-ico { flex: none; width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 13%, transparent); }
.reassure-ico svg { width: 18px; height: 18px; }
.reassure-item > div { min-width: 0; }
.reassure-item b { display: block; font-family: var(--font-display);
  font-weight: var(--weight-display, 700); font-size: .98rem; color: var(--ink);
  line-height: 1.25; margin-bottom: 3px; }
.reassure-item span { display: block; color: var(--muted); font-size: .86rem; line-height: 1.4; }
@media (max-width: 960px) { .reassure-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .reassure-grid { grid-template-columns: 1fr; } }
.nav-logo img { height: 40px; width: auto; max-height: none; display: block; }
/* Le deck masque le telephone de la barre sous 960px (`.nav-phone{display:none}`) : sur un
   site vitrine c'est logique, sur une landing d'urgence c'est le contraire de ce qu'on veut.
   Un visiteur dont les WC debordent arrive au telephone, et Fred a tranche « optimiser pour
   l'appel ». On le garde donc visible, en pastille compacte sous 640px pour qu'il tienne a
   cote du logo. (CEO, 07/09/2026, trouve en mesurant la barre au telephone.) */
@media (max-width: 960px) {
  .nav-phone { display: inline-flex !important; align-items: center; gap: 6px; }
}
/* Dans la barre, sous 960px, on garde le TELEPHONE et on retire le bouton de devis :
   les deux ensemble font 409px pour un ecran de 390, et le second sort de l'ecran. Le
   devis reste accessible par la barre fixe du bas, qui porte deja les deux actions.
   Mesure : nav-cta jusqu'a 409px, detecte par qa_visuelle.py. */
@media (max-width: 960px) {
  .nav-cta .btn:not(.nav-phone) { display: none; }
  .nav .container { gap: 10px; }
}
/* La barre fixe du bas debordait de 19px : ses deux boutons plus les marges depassaient
   la largeur utile. On la contraint et on laisse les boutons se partager la place. */
.sticky-cta { max-width: 100%; box-sizing: border-box; gap: 8px; }
.sticky-cta .btn { flex: 1 1 0; min-width: 0; padding-left: 10px; padding-right: 10px; }

@media (max-width: 520px) {
  .nav-phone { font-size: .86rem; padding: 8px 12px; }
  .nav-logo img { height: 30px; }
}
.lead-form .field textarea { width:100%; padding:13px 15px; border:var(--border); border-radius:var(--radius,12px); background:var(--bg); color:var(--ink); font-family:inherit; font-size:.98rem; resize:vertical; }
.lead-form .form-note { display:flex; align-items:center; justify-content:center; gap:6px; }
/* Questions de qualification cote a cote (form_champs, 15/09/2026). min-width:0 : sans lui un
   input date garde sa largeur intrinseque et fait deborder la carte sur mobile. */
.lead-form .field-row { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.lead-form .field-row .field { min-width:0; }
.lead-form .field input, .lead-form .field select { min-width:0; max-width:100%; box-sizing:border-box; }
@media (max-width:460px) { .lead-form .field-row { grid-template-columns:1fr; gap:0; } }
.split-list li > span { min-width:0; }
.hero-media { position:absolute; inset:0; z-index:-1; background-size:cover; background-position:center; opacity:var(--hero-media-op,.10); }
.hero { position:relative; overflow:hidden; }
.step-num { font-family: var(--font-display); font-weight: var(--weight-display,700); font-size:1.05rem; }
.zone-villes { display:flex; flex-wrap:wrap; gap:10px; margin-top:18px; }
.zone-villes span { padding:8px 14px; border-radius:999px; border:var(--border); background:var(--card-bg); font-size:.86rem; font-weight:600; }
.zone-villes span.main { background:var(--accent); color:var(--accent-ink); border-color:transparent; }
.info-map-live { width:100%; aspect-ratio:16/8; border:0; border-radius:var(--radius,14px); }
.tel-big { display:block; font-family:var(--font-display); font-weight:var(--weight-display,700); font-size:clamp(1.5rem,3vw,2rem); color:var(--accent); margin:6px 0 14px; letter-spacing:-.02em; }
/* Barre d'appel fixe en mobile : le levier de conversion n°1 sur un metier d'urgence. */
.sticky-cta { position:fixed; left:0; right:0; bottom:0; z-index:60; display:none; gap:10px; padding:10px 14px calc(10px + env(safe-area-inset-bottom)); background:var(--card-bg); border-top:var(--border); box-shadow:0 -10px 30px -18px rgba(0,0,0,.4); }
.sticky-cta .btn { flex:1; justify-content:center; }
@media (max-width:820px){ .sticky-cta { display:flex; } body { padding-bottom:76px; } }
@media print { .sticky-cta { display:none; } }

/* ============================================================================
   LISIBILITE : DEUX TEXTES QUE PERSONNE N'AVAIT REGARDES (22/09/2026)
   Fred, vocal du 22/09 a 21h33 et 21h37 : « le texte n'est pas lisible dans la
   hero section » et « le titre ne s'affiche pas car il est ecrit en noir ».
   Mesure sur les pages SERVIES d'EXPERT HABITAT, pas sur une intuition :

   1. LE BOUTON SECONDAIRE DU CTA FINAL ETAIT A 1,54:1. `.btn-ghost` de base.css
      sert `color: var(--ink)`, l'encre sombre, prevue pour un fond clair. Or
      `.cta-box` a un fond `--accent`. Le deck n'avait prevu la correction que
      pour `.price-card.featured .btn-ghost`, une carte de prix que nos landings
      n'ont pas. Resultat : « Demander mon devis par ecrit » en #1b1813 sur
      #1f3a5f, invisible, sur les trois pages carrelage. C'est CE texte que Fred
      a vu manquer en bas de page. Apres : 10,91:1.
      Le defaut est celui du GABARIT, donc commun aux sept clients du skill :
      tout client dont le theme a un `--accent` sombre le sert aussi.

   2. LE SOUS-TITRE DU HERO TOMBAIT A 2,94:1 sur la page salle de bain (seuil AA
      pour du texte courant : 4,5:1), parce qu'il est en `--muted` et qu'une
      photo passe derriere. Deux corrections qui tiennent ensemble : le
      sous-titre passe en `--ink` DES QU'UNE PHOTO est servie, et la colonne de
      texte recoit un voile de la couleur du fond. Sans photo, `.hero-media`
      n'existe pas et rien de tout cela ne s'applique : les clients sans photo
      de heros sortent a l'octet pres comme avant.
   ========================================================================== */
/* LE SOUS-TITRE DU BLOC D'APPEL FINAL ETAIT A 82 % D'OPACITE, ET IL TOMBAIT SOUS LE SEUIL
   (23/09/2026). `base.css` du deck ecrit `.cta-box p { color: color-mix(..., var(--accent-ink)
   82%, transparent) }`. Sur EXPERT HABITAT demoussage, ca rend du #ebe1d1 sur #8f5b02, soit
   **4,44:1** pour un seuil de 4,5 : le texte le plus proche du dernier bouton de la page.
   82 % avait ete choisi pour adoucir un blanc pur ; ca marche tant que l'accent est tres sombre,
   et ca casse des qu'il ne l'est que moyennement. A 92 % l'adoucissement reste visible et la
   marge revient (5,01:1 sur le meme fond). C'est le meme genre de defaut que le `.btn-ghost`
   trouve la veille, au meme endroit et pour la meme raison : une valeur du deck calibree sur un
   seul cas de figure. */
.cta-box p { color: color-mix(in srgb, var(--accent-ink) 92%, transparent); }
.cta-box .btn-ghost { color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent-ink) 45%, transparent); }
/* 3. LES TITRES DE COLONNE DU PIED DE PAGE ETAIENT A 1,00:1 — INVISIBLES.
   Trouve le 22/09/2026 au soir par la mesure de contraste de `qa_visuelle.py`, et
   par personne avant : un texte invisible ne casse rien, ne deborde pas, ne leve
   aucune erreur. Il manque, c'est tout. « Contact » et « Garanties » existaient
   dans le HTML de nos sept clients et n'etaient devant les yeux de personne.
   CAUSE : `base.css` pose `h1,h2,h3,h4 { color: var(--ink) }`, et cette regle bat
   l'heritage de `.footer { color: var(--footer-ink) }`. Or sur 40 des themes du
   deck, `--footer-bg` vaut EXACTEMENT `--ink` : le titre est donc de la couleur
   de son fond, au hex pres. Ce n'est pas un theme rate, c'est la convention du
   deck (le pied de page est l'inverse de la page) qui rencontre une regle de
   titre trop large.
   Le correctif vise les TITRES DU PIED DE PAGE seulement, pas la regle globale :
   toucher `h1,h2,h3,h4` changerait toutes les pages de tous les clients. */
.footer h1, .footer h2, .footer h3, .footer h4 { color: var(--footer-ink); }
.cta-box .btn-ghost:hover { background: color-mix(in srgb, var(--accent-ink) 14%, transparent);
  color: var(--accent-ink); }
/* Le voile : un degrade de la couleur de fond, pose SOUS le texte (z-index 0 contre
   -1 pour la photo) et large de 62 % a gauche. Il rend le texte lisible quelle que
   soit la photo, ce qu'une simple baisse d'opacite ne garantit pas : une photo
   claire en haut et sombre en bas casse le contraste au milieu d'un paragraphe. */
.hero:has(.hero-media) .container { position: relative; z-index: 1; }
.hero:has(.hero-media)::before { content:''; position:absolute; inset:0; z-index:0;
  background: linear-gradient(100deg, var(--bg) 0%,
    color-mix(in srgb, var(--bg) 88%, transparent) 38%,
    color-mix(in srgb, var(--bg) 30%, transparent) 62%,
    transparent 78%); pointer-events:none; }
.hero:has(.hero-media) .hero-sub { color: var(--ink); }
@media (max-width: 820px) {
  /* En une colonne, le texte occupe toute la largeur : le voile doit etre vertical. */
  .hero:has(.hero-media)::before { background: linear-gradient(180deg,
    color-mix(in srgb, var(--bg) 92%, transparent) 0%,
    color-mix(in srgb, var(--bg) 82%, transparent) 55%,
    color-mix(in srgb, var(--bg) 55%, transparent) 100%); }
}
