/* site.css: the one shared layer every page loads, last in <head>.
 *
 * Why it exists (fall 2026 audit, plan in the vault: duo-vert/full-site-review-plan):
 * 56 of 70 pages carry their own copy of the site CSS, in 23 drifted versions
 * (only 163 rules are common to all of them). Merging those copies risks moving
 * desktop layouts nobody meant to touch, so they stay as they are and every new
 * rule lives here instead: one edit, every page.
 *
 * Page <style> blocks also sit in <body>, after this file, so a rule here that
 * must win over an old one is written with `html body` in front (specificity
 * 0,1,2 beats a single class). Every change here is proven with
 * `node scripts/shots.mjs diff` against the previous run.
 *
 * Linked by scripts/sync-shell.mjs; scripts/check-shell.mjs fails the lint when
 * a page is missing it.
 */

/* Closed FAQ questions kept an empty 24px strip: the answer's bottom padding
   survives the closed (0fr) grid row. The space moves inside the answer, where
   closing hides it. Same fix as public/css/article.css, proven there 2026-09-23. */
html body .faq-answer-inner { padding-bottom: 0; }
html body .faq-answer-inner::after { content: ''; display: block; height: 24px; }
/* Links inside FAQ answers and under section titles (the homepage FAQ points
   to the service, city and price pages since 2026-09-26): they looked like
   plain text, since the page styles strip link colour. */
html body .faq-answer-inner a,
html body .section-subtitle a {
  color: var(--dv-green);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
html body .faq-answer-inner a[href^="tel:"],
html body .section-subtitle a[href^="tel:"] { white-space: nowrap; }
/* Reviews are shown whole: they are quoted word for word, so none is cut to
   five lines with an ellipsis any more (content/google-reviews.mjs). */
html body #testimonials-carousel-section .testimonial-text {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}

/* ===================================================================
 * Palette "Pierre chaude" (Emile's pick, 2026-09-24; vault:
 * duo-vert/brand-2027-colour-system). His four colours (stone, green, forest,
 * gold) plus a fixed set of shades, all of one warm temperature:
 *   page  #f7f3ea  his stone, the background of every light section
 *   band  #efe8da  a step deeper, for every other section
 *   card  #fffdf8  a step lighter, so cards stand out from the page
 *   line  #e4dccb  borders
 *   tint  #ebe4d4  small light chips (badges, active menu items)
 * No pale or mint green anywhere: "I don't wanna see like pale ... green
 * things ... in the cream". Green text on dark surfaces (headline words,
 * underlines, "Vert" in the logo, big numbers) is the site's old green
 * #4caf50, his "deep green we used to use" (5.8:1 on forest); on light
 * surfaces green is #2f6b3f. Gold is only small shapes: dots, checkmarks,
 * stars. Never text, never an underline, never anything big.
 * Measured before (2026-09-24): the light side mixed warm cream, cool mint
 * (#eaf4ea, #f2faf2, #d8eedb, #dcefe1) and white cards, and the 2027 repaint
 * had turned page, sections and cards into one cream.
 * The page CSS keeps its own variable names; --white, --off and --pale are
 * re-pointed here (html:root outranks the pages' :root).
 * =================================================================== */
:root {
  --dv-stone: #f7f3ea;
  --dv-band: #efe8da;
  --dv-card: #fffdf8;
  --dv-line: #e4dccb;
  --dv-pale: #ebe4d4;
  --dv-green: #2f6b3f;
  --dv-green-hover: #3b874f;
  --dv-bright: #4caf50;
  --dv-forest: #14251a;
  --dv-gold: #f2c14e;
  --dv-body: #34463b;
  --dv-muted: #4f6958;
  --dv-ease: cubic-bezier(0.25, 1, 0.5, 1); /* ease-out-quart */
}
html:root {
  --white: #fffdf8;
  --off: #f7f3ea;
  --pale: #ebe4d4;
  /* Two pages (Gatineau FR and EN) had their own lighter grey-green, 4.2:1
     on the page colour; now the same as the other 52. */
  --muted: #4f6958;
}
html body { background-color: var(--dv-stone); }

/* ===================================================================
 * Section rhythm (Emile, 2026-09-24: "plusieurs sections d'affilées ont le
 * même couleur de background, c'est dur pour les yeux"; 2026-09-25 he picked
 * trial A, "Rythme", with "a bit of green like for the reviews").
 * scripts/sync-shell.mjs writes data-surface on every top-level section and
 * the footer: "stone" and "light" alternate, the reviews are "green" where no
 * dark band touches them, and the dark bands keep their forest. The old band
 * (#efe8da) was only 0.033 from the page in OKLab, about one just-noticeable
 * step, so neighbours read as one; stone #e6dac3 is 0.076 away.
 * `shots.mjs audit` fails when two neighbouring sections still look alike.
 * Research: NN/g common region (a shared background is what makes a group
 * read as one), Refactoring UI (neighbouring areas need visibly different
 * backgrounds, or a shadow, or space).
 * =================================================================== */
:root {
  --dv-surface-stone: #e6dac3;
  --dv-surface-light: #f7f3ea;
  --dv-surface-green: #1f472a;
}
/* :not(#dv) lifts these over the pages' own inline and id rules. */
html body [data-surface="stone"]:not(#dv) { background-color: var(--dv-surface-stone) !important; }
html body [data-surface="light"]:not(#dv) { background-color: var(--dv-surface-light) !important; }
html body [data-surface="green"]:not(#dv) { background-color: var(--dv-surface-green) !important; background-image: none !important; }
/* Sections without the attribute (none today, but a new page before
   sync-shell runs) keep the old alternate band. */
html body main section.section-grey:not([data-surface]),
html body main section.trust-row-section:not([data-surface]) { background-color: var(--dv-band); }
/* The FAQ pages' question list is itself the centred column
   (section.container), so its band stopped 120 px short of each screen edge
   and read as a strip on the page. The colour is drawn out to the edges;
   box-shadow does not widen the page, and clip-path keeps it to the band's
   own height. */
html body section.container[data-surface] { clip-path: inset(0 -100vmax); }
html body section.container[data-surface="stone"] { box-shadow: 0 0 0 100vmax var(--dv-surface-stone); }
html body section.container[data-surface="light"] { box-shadow: 0 0 0 100vmax var(--dv-surface-light); }
/* An article's author box was the page colour on the page colour: now a card,
   the same recipe as the homepage's quote steps. */
html body .article-author {
  background: var(--dv-card) !important;
  border: 1px solid rgba(20, 37, 26, 0.08);
  box-shadow: 0 1px 2px rgba(20, 37, 26, 0.05), 0 10px 28px rgba(20, 37, 26, 0.07);
}
/* The FAQ photo veil follows its section's tone. */
html body [data-surface="stone"] .faq-bg-overlay { background: linear-gradient(rgba(230, 218, 195, 0.9), rgba(230, 218, 195, 0.9)) !important; }
html body [data-surface="light"] .faq-bg-overlay { background: linear-gradient(rgba(247, 243, 234, 0.9), rgba(247, 243, 234, 0.9)) !important; }
/* The grey-green small text was 4.3:1 on stone; one step darker it is 5.4:1. */
html body [data-surface="stone"] { --muted: #435a4b; --dv-muted: #435a4b; }
html body [data-surface="stone"] .section-subtitle { color: #435a4b !important; }
/* The reviews on green: cream title and line under it (9.5:1), the cards stay
   cream, the dots cream with the old green for the current one. */
html body [data-surface="green"] h2 { color: var(--dv-stone) !important; }
html body [data-surface="green"] h2 + p,
html body [data-surface="green"] .section-subtitle { color: rgba(247, 243, 234, 0.84) !important; }
html body [data-surface="green"] .carousel-dot { background-color: rgba(247, 243, 234, 0.4) !important; }
html body [data-surface="green"] .carousel-dot.active { background-color: var(--dv-bright) !important; }
html body [data-surface="green"] .testimonial-card { box-shadow: 0 18px 40px rgba(8, 20, 12, 0.28) !important; border-color: transparent !important; }
html body [data-surface="green"] .dv-reviews-more a { border-color: transparent !important; }
/* Sections that took the card colour through --white stay on the page. */
html body #testimonials-carousel-section,
html body section.sec-white,
html body main section[style*="background-color: var(--white"],
html body main section[style*="background: var(--white"],
html body main section.document-section { background-color: transparent !important; }
/* The pale green bands (24 city and service pages carry one inline) join the
   warm family. */
html body main section[style*="#dcefe1"],
html body main section[style*="220, 239, 225"],
html body main section#degradation,
html body main section.sec-pale,
html body main section.section-pale,
html body main section.section-rassurance { background-color: var(--dv-band) !important; }
/* The blurred decorative blobs were mint (#eaf4ea, #f2faf2, #d8eedb) and read
   as green stains on the cream. */
html body .bg-ambient-blob,
html body .f-blob { display: none !important; }
/* The FAQ photo sat under a pale green veil (rgba(220, 239, 225, 0.65)). */
html body .faq-bg-overlay { background: linear-gradient(rgba(239, 232, 218, 0.88), rgba(239, 232, 218, 0.88)) !important; }
/* The closing section's blurred backdrop is a pool photo, saturated to a
   bright blue; it stays as a faint texture on the forest instead. */
html body .cta-final { background-color: var(--dv-forest) !important; }
html body .cta-final-blur-bg { opacity: 0.35; filter: blur(24px) brightness(0.55) saturate(0.4) !important; }
/* Cards: one colour, one border. */
html body .faq-item,
html body .form-guarantee-card,
html body #testimonials-carousel-section .testimonial-card,
html body .testimonial-card,
html body .service-block,
html body .dv-reviews-more a {
  background-color: var(--dv-card) !important;
  border: 1px solid var(--dv-line) !important;
}
html body .dv-quick-card.form-box { border-color: var(--dv-line); }
html body .footer,
html body .f-footer { background-color: var(--dv-band) !important; }
/* Footer text strong enough to read on the band (Lighthouse, 2026-09-24:
   column titles were at 1.85:1, the description 4.0:1 and the city line
   2.4:1; the floor for small text is 4.5:1). Now 5.4 to 6.3:1. The titles
   are h3 (were h4 right after h2 sections), so their size stays set here. */
html body .f-footer .f-title { color: var(--dv-muted) !important; margin-top: 0; line-height: 1.3; }
html body .f-footer .f-desc { color: rgba(20, 37, 26, 0.75) !important; }
html body .f-footer .f-contact-loc { color: rgba(20, 37, 26, 0.7) !important; }
/* Review carousel dots (computer and tablet; phones stack the reviews): each
   dot was a 10 px button, under the 24 px minimum target (WCAG 2.2, flagged
   by Lighthouse). The button is now 24 px tall and the dot is drawn inside it
   at the same size, so the dots look the same and sit a little further apart. */
html body #testimonials-carousel-section .carousel-dot {
  width: 24px !important;
  height: 24px !important;
  padding: 7px !important;
  background-clip: content-box !important;
  border-radius: 12px !important;
}
html body #testimonials-carousel-section .carousel-dot.active { width: 38px !important; }
html body .header.scrolled { background-color: var(--dv-card); }
/* Review avatars: the team greens from the colour system, instead of teal and
   amber. */
html body .testimonial-avatar { background-color: var(--dv-green) !important; color: #ffffff !important; }
html body .carousel-slide:nth-child(3n + 2) .testimonial-avatar { background-color: #1f472a !important; }
html body .carousel-slide:nth-child(3n) .testimonial-avatar { background-color: #419558 !important; }
/* The scrolling band's dots were green on the same green, invisible. Dots
   are small shapes, so gold. */
html body .ticker-dot { background-color: var(--dv-gold) !important; }
/* The "Qui sommes-nous ?" badge on the dark founders section was pale green
   text (#b9dcc3). */
html body .badge[style*="#b9dcc3"] { color: var(--dv-bright) !important; }

/* -------------------------------------------------------------------
 * Hero, every width. White text on the photo (the cream is for the rest of
 * the page, not the hero: Emile, 2026-09-24), the coloured headline words
 * and their underline in the old green, the button in the site's green.
 * Nothing in a hero fades in any more: an invisible headline does not count
 * for LCP and stays hidden if the script fails (web.dev).
 * ------------------------------------------------------------------- */
html body section[class^="hero"] .reveal,
html body section[class^="hero"].reveal {
  opacity: 1;
  transform: none;
  transition: none;
}
html body section[class^="hero"] h1,
html body section[class^="hero"] .hero-subtitle,
html body section[class^="hero"] .hero-desc,
html body section[class^="hero"] .container > p { color: #ffffff !important; }
/* The coloured words of every hero headline, underlined in the same green. */
html body section[class^="hero"] h1 [style*="color"],
html body section[class^="hero"] h1 .accent,
html body section[class^="hero"] h1 .text-green {
  color: var(--dv-bright) !important;
  text-decoration: underline !important;
  text-decoration-color: var(--dv-bright) !important;
  text-decoration-thickness: 0.07em !important;
  text-underline-offset: 0.14em !important;
}
html body section[class^="hero"] .brand-vert { color: var(--dv-bright) !important; }
/* Two-part hero headlines (titles step, 2026-09-24): the place in the big
   line, the services in a smaller line under it, inside the same H1 so Google
   reads the whole phrase the title uses ("Pavé uni à Hull : nettoyage, joints
   et scellant"). The colon stays in the text for Google and screen readers but
   is not drawn; the line break does its job on screen. */
html body section[class^="hero"] h1 .dv-h1-sep {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
html body section[class^="hero"] h1 .dv-h1-sub {
  display: block;
  margin-top: 0.55em;
  font-size: clamp(1.15rem, 0.85rem + 1.5vw, 2.1rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.92);
}
html body section[class^="hero"] h1 .dv-h1-sub::first-letter { text-transform: uppercase; }
/* On the lighter hero photos (Aylmer, the Glebe, /tarifs/...) the green words
   and the header logo sat on bright leaves and sky. A soft dark shade at the
   top of every hero (where the header sits) and a light shadow behind the
   headline keep them readable without darkening the photo overall. */
/* The shade is its own layer: written as the overlay's background-image
   (2026-09-24 to 25) it replaced the darkening gradient six pages draw there
   (à propos, avant-après, contact, FR and EN), and their text sat on the bare
   photo. `shots.mjs audit` now measures hero text against the photo behind it. */
html body section[class^="hero"] .hero-overlay::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(10, 20, 14, 0.6) 0, rgba(10, 20, 14, 0.25) 140px, rgba(10, 20, 14, 0) 280px);
}
html body section[class^="hero"] h1,
html body .header:not(.scrolled) .logo {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.28), 0 4px 22px rgba(0, 0, 0, 0.32);
}
/* The hero button is the same green as the closing call to action
   (.btn-premium-green), with a faint edge so it holds its shape on the dark
   photo. White on #2f6b3f reads at 6.4:1. */
html body section[class^="hero"] .hero-btn-primary {
  background: linear-gradient(135deg, var(--dv-green) 0%, var(--dv-green-hover) 100%);
  color: #ffffff;
  border: 1px solid rgba(76, 175, 80, 0.45);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3);
}
html body section[class^="hero"] .hero-btn-primary:hover {
  background: var(--dv-green-hover);
}
/* No writing is ever gold (Emile, 2026-09-24: "i dont want any writing in
   gold, just like some little lines or stuff like this"). */
html body section[class^="hero"] .hero-link-sec {
  color: #ffffff;
  opacity: 0.88;
}

/* The Google rating above every hero headline (sync-shell piece "rating"). */
.dv-rating {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
  padding: 8px 16px 8px 14px;
  border-radius: 999px;
  background: rgba(20, 37, 26, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: #ffffff;
  font: 500 0.92rem/1.2 'Inter', sans-serif;
  text-decoration: none;
  position: relative;
  z-index: 3;
  transition: background-color 0.2s var(--dv-ease);
}
.dv-rating:hover { background: rgba(20, 37, 26, 0.8); }
.dv-rating strong { font-weight: 800; }
.dv-rating-stars { color: var(--dv-gold); letter-spacing: 2px; font-size: 0.95rem; }

/* Over the dark hero the header is transparent: "Vert" in the old green, and
   the menu button in white. It was forest-on-dark (invisible) on every phone
   before 2026-09-23; a mobile media rule forced it to --ink with !important. */
html body .header:not(.scrolled) .mobile-menu-toggle { color: #ffffff !important; }
html body .hero-home-new p.hero-desc span.accent-underline::after { background-color: var(--dv-bright); }
html body .header:not(.scrolled) .logo .brand-vert { color: var(--dv-bright) !important; }
/* Computer header over the photo: the current page's link and the
   "Recevez 150 $ !" button were the 2027 forest green on a dark photo
   (about 2.5:1). Over the photo they take the old green; once the header
   turns light on scroll they go back to the forest green. */
html body .header:not(.scrolled) .nav-link.active { color: var(--dv-bright) !important; }
html body .header:not(.scrolled) .nav-link.active::after { background-color: var(--dv-bright) !important; }
html body .header:not(.scrolled) .nav-ref-btn { color: var(--dv-bright) !important; border-color: rgba(76, 175, 80, 0.75) !important; }

/* Scroll reveal, everywhere else: shorter and smaller (was 0.7 to 0.9 s over
   28 to 30 px; NN/g puts most UI motion at 100 to 500 ms). */
html body .reveal {
  transform: translateY(12px);
  transition: opacity 0.45s var(--dv-ease), transform 0.5s var(--dv-ease);
}

/* The action bar exists in every page's HTML; it only shows on phones. */
.dv-bar { display: none; }

/* ===================================================================
 * Phones (the site's own mobile breakpoint is 768px)
 * =================================================================== */
@media (max-width: 768px) {
  /* The social top bar leaves phones; the same links sit in the menu and footer. */
  html:root { --topbar-h: 0px; }
  html body .topbar { display: none; }

  /* Header slides away while scrolling down, returns on scroll up (site.js). */
  html body .header {
    transition: transform 0.3s var(--dv-ease), background-color 0.4s ease, box-shadow 0.4s ease;
  }
  html body .header.dv-hide { transform: translateY(-100%); }

  /* Hero: about four fifths of the screen, so the next section peeks in and the
     first screen never looks like the end of the page. */
  /* The homepage photo only slid under the header up to 640 px; from 641 to
     768 px it started below it, so the transparent header sat on a plain
     strip with its white "Duo" and its menu button invisible (before this
     audit too). Every other page slides it under at all phone and tablet
     widths. */
  html body main section.hero-home-new { margin-top: -64px; }
  html body section.hero,
  html body section.hero-home-new {
    min-height: 0 !important;
    min-height: min(80svh, 720px) !important; /* /tarifs/ sets 100dvh inline */
    padding-top: 104px;
    padding-bottom: 72px;
  }
  /* The homepage H1 lines were set to never wrap; at phone size that cut
     "à Gatineau et Ottawa" off at both edges. */
  html body section[class^="hero"] h1 span:not(.dv-h1-sub):not(.dv-h1-sep) { white-space: normal !important; display: inline !important; }
  html body section[class^="hero"] h1 br { display: none; }
  html body section[class^="hero"] h1 {
    font-size: clamp(2.2rem, 1.5rem + 3.2vw, 2.8rem);
    line-height: 1.04;
    letter-spacing: -0.035em;
    margin-bottom: 16px;
  }
  html body section[class^="hero"] .hero-subtitle,
  html body section[class^="hero"] .hero-desc {
    font-size: 1.06rem;
    line-height: 1.5;
    margin-bottom: 28px;
  }
  html body section[class^="hero"] .hero-btn-primary {
    width: 100%;
    max-width: 360px;
    padding: 17px 24px;
    font-size: 1.05rem;
    border-radius: 16px;
  }
  .dv-rating { font-size: 0.85rem; margin-bottom: 16px; }

  /* The bottom action bar replaces the floating call button. */
  html body .fab { display: none !important; }
  .dv-bar {
    display: grid;
    grid-template-columns: 1fr 1.5fr;
    gap: 10px;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1030;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    background: rgba(247, 243, 234, 0.97);
    border-top: 1px solid rgba(20, 37, 26, 0.1);
    box-shadow: 0 -10px 30px rgba(20, 37, 26, 0.1);
    transform: translateY(110%);
    transition: transform 0.35s var(--dv-ease);
  }
  .dv-bar.dv-on { transform: none; }
  .dv-bar a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 50px;
    border-radius: 14px;
    font: 800 1rem/1 'Outfit', sans-serif;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
  }
  .dv-bar-call {
    color: var(--dv-forest);
    border: 1.5px solid rgba(20, 37, 26, 0.22);
    background: transparent;
  }
  .dv-bar-quote {
    color: var(--dv-stone);
    background: var(--dv-green);
  }
  .dv-bar a:active { transform: scale(0.98); }
  /* No room is reserved under the footer: the bar steps aside once the footer
     is on screen (site.js), and the reserved strip showed as an empty stone
     band under the footer. */
}

@media (prefers-reduced-motion: reduce) {
  html body .header,
  .dv-bar,
  html body .reveal { transition: none; }
}

/* ===================================================================
 * Early quote form (homepage, right after the hero). Its first step shows
 * within the first moments of scrolling: 74% of viewing time is spent in
 * the first two screenfuls (NN/g 2018). Same Netlify form name and CRM
 * fields as before (check-lead-fields holds the contract).
 * =================================================================== */
.fs-form { --fs-gold: var(--dv-gold); }
.dv-quick {
  position: relative;
  z-index: 4;
  margin-top: -96px;
  padding: 0 0 72px;
}
.dv-quick-card.form-box {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.25fr);
  gap: 44px;
  align-items: start;
  max-width: 1080px;
  padding: 40px 44px;
  background: var(--dv-card);
  border: 1px solid rgba(20, 37, 26, 0.07);
  border-radius: 28px;
  box-shadow: 0 30px 70px rgba(20, 37, 26, 0.16), 0 2px 6px rgba(20, 37, 26, 0.05);
}
.dv-quick-head { padding-top: 6px; }
.dv-quick-kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  color: var(--dv-green);
  font: 700 0.88rem/1.3 'Inter', sans-serif;
}
.dv-quick-kicker::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dv-gold);
  box-shadow: 0 0 0 4px rgba(242, 193, 78, 0.22);
}
.dv-quick-head h2 {
  margin: 0 0 12px;
  color: var(--dv-forest);
  font: 900 clamp(1.7rem, 1.2rem + 1.6vw, 2.35rem)/1.05 'Outfit', sans-serif;
  letter-spacing: -0.035em;
}
.dv-quick-note { margin: 0; color: var(--dv-muted); font-size: 1rem; line-height: 1.5; }
.dv-quick-form .dv-hint { display: block; margin-top: 3px; color: var(--dv-muted); font-weight: 500; font-size: 0.85rem; }
.dv-quick-form .dv-step-label,
.dv-quick-form .fs-step[data-step="1"] > .form-label {
  text-align: left;
  margin: 0 0 12px;
  color: var(--dv-forest);
  font-size: 0.95rem;
}
.dv-quick-form .fs-choice:has(input:checked) {
  background: var(--dv-band);
  border-color: var(--dv-green);
}
.dv-quick-form .fs-choice-check { color: var(--dv-green); font-weight: 900; }
.dv-quick-form .fs-nav { margin-top: 16px; }
.dv-quick-form .submit-button { min-height: 54px; font-size: 1.05rem; border-radius: 14px; }
.dv-quick-form .form-input { font-size: 16px; min-height: 52px; }
.dv-field-why { margin: 8px 0 0; color: var(--dv-muted); font-size: 0.85rem; line-height: 1.4; }

@media (max-width: 768px) {
  .dv-quick { margin-top: -44px; padding: 0 0 48px; }
  .dv-quick .container { padding-left: 14px; padding-right: 14px; }
  .dv-quick-card.form-box {
    grid-template-columns: 1fr;
    gap: 18px;
    padding: 22px 18px 20px;
    border-radius: 24px;
  }
  .dv-quick-head { padding-top: 0; }
  .dv-quick-kicker { margin-bottom: 10px; font-size: 0.82rem; }
  .dv-quick-head h2 { margin-bottom: 6px; }
  .dv-quick-note { font-size: 0.92rem; }
}
.dv-quick-form .fs-encourage { text-align: left; }
.dv-quick-form .form-group { margin-bottom: 16px; }
.dv-quick-form .form-group:last-of-type { margin-bottom: 0; }

/* ===================================================================
 * The homepage's quote section ("Soumission gratuite pour la restauration
 * de votre pavé uni"): the three steps of a quote, and the form right there
 * (Emile, 2026-09-25). Before, it explained the quote and ended on a
 * guarantee with nothing to fill in, and the three steps were bare text on
 * the band: "your eyes need to really search for where to look".
 * Now each step is a card on the stone band (NN/g common region: a shared
 * background and edge is what makes a block read as one thing) and the form
 * card sits beside them on a computer, under them on a phone and tablet.
 * The steps are not links, so they no longer move on hover.
 * =================================================================== */
html body .trust-step {
  padding: 20px 22px;
  background: var(--dv-card);
  border: 1px solid rgba(20, 37, 26, 0.08);
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(20, 37, 26, 0.05), 0 10px 28px rgba(20, 37, 26, 0.07);
}
html body .trust-step:hover { transform: none; }
html body .trust-step:hover .trust-icon-box {
  background-color: rgba(47, 107, 63, 0.05);
  border-color: rgba(47, 107, 63, 0.12);
  color: var(--g-dark);
  box-shadow: none;
}
html body .trust-step-content h3 {
  font-family: 'Outfit', sans-serif;
  font-weight: 800;
  font-size: 1.1rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--dv-forest);
  margin: 0 0 6px;
}
html body .trust-step-content p { color: var(--dv-body); }
/* The guarantee closes the list as a quieter line, not a fourth card. */
html body .dv-howto .form-guarantee-card {
  max-width: none;
  margin: 0;
  padding: 18px 22px !important;
  background: rgba(255, 253, 248, 0.45) !important;
  border: 1px solid rgba(47, 107, 63, 0.28) !important;
  border-radius: 18px !important;
  box-shadow: none;
}
html body .dv-howto .form-guarantee-card:hover { transform: none; box-shadow: none; background: rgba(255, 253, 248, 0.45) !important; }
html body .dv-howto .form-guarantee-card h3 {
  margin: 0 0 4px;
  color: var(--dv-green);
  font: 800 0.95rem/1.3 'Outfit', sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
html body .dv-howto .form-guarantee-card p { color: var(--dv-body); font-size: 0.92rem; line-height: 1.5; margin: 0; }
html body .dv-howto .trust-row-steps { grid-template-columns: 1fr; gap: 12px; margin-bottom: 12px; }
html body .dv-howto .trust-row-intro { text-align: left; max-width: 60ch; margin: 0 0 28px; }

/* The form card. Its own card, so the form panel it has under the hero
   (a second box inside the card) is undone here: no box in a box. */
html body .dv-again-card.form-box {
  max-width: none !important;
  margin: 0 !important;
  padding: 32px 32px 26px !important;
  background: var(--dv-card);
  border: 1px solid rgba(20, 37, 26, 0.07);
  border-radius: 26px !important;
  box-shadow: 0 30px 70px rgba(20, 37, 26, 0.16), 0 2px 6px rgba(20, 37, 26, 0.05);
}
.dv-again-title {
  margin: 0 0 6px;
  color: var(--dv-forest);
  font: 900 clamp(1.45rem, 1.1rem + 1vw, 1.8rem)/1.1 'Outfit', sans-serif;
  letter-spacing: -0.03em;
}
.dv-again-note { margin: 0 0 22px; color: var(--dv-muted); font-size: 0.98rem; line-height: 1.5; }
html body .dv-again-card .dv-quick-form {
  display: block;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}
html body .dv-again-card .fs-choice-grid { grid-template-columns: repeat(2, 1fr); }
html body .dv-again-card .dv-quick-form .fs-choice,
html body .dv-again-card .dv-quick-form .form-input { background: var(--dv-stone); }
html body .dv-again-card .dv-quick-form .fs-choice:has(input:checked) { background: var(--dv-card); }

@media (min-width: 960px) {
  html body .dv-howto {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 460px);
    gap: 64px;
    align-items: start;
  }
}
/* The card stays in view while the steps beside it are read. The page's
   script sets overflow: hidden on every section (for the old decorative
   blobs, hidden above), which makes the section the card's scroll box: the
   card never followed the page and sat 120 px low. `clip` cuts the same way
   without being a scroll box (!important to beat the script's inline style);
   browsers without it keep the card in place at the top. */
@supports (overflow: clip) {
  @media (min-width: 960px) {
    html body .trust-row-section { overflow: clip !important; }
    /* The fixed header ends 114 px down on a computer. */
    html body .dv-howto-form { position: sticky; top: 140px; }
  }
}
@media (max-width: 959px) {
  html body .dv-howto-form { margin-top: 28px; }
}
@media (max-width: 768px) {
  html body .trust-step { padding: 18px 18px; border-radius: var(--dv-radius); }
  html body .dv-howto .trust-row-intro { margin-bottom: 22px; }
  html body .dv-again-card.form-box { padding: 24px 20px 20px !important; border-radius: 22px !important; }
  html body .dv-howto .form-guarantee-card h3 { font-size: 0.9rem !important; }
}

/* ===================================================================
 * Sections
 * =================================================================== */
/* Service cards: the bullet dot shrank to nothing whenever its line wrapped
   (a flex item with no flex-basis), which is why some bullets had no dot. */
html body .service-small-card ul li::before { flex: none; }
/* On the dark photo cards, forest-green checks and dots read at 2.5:1.
   Checks and dots are small things, so gold. */
html body .service-main-list li svg { color: var(--dv-gold); flex: none; }
html body .service-small-card ul li::before { background-color: var(--dv-gold); }
html body .service-small-card ul li { align-items: baseline; }

@media (max-width: 768px) {
  html body .service-small-card h3 { text-align: left; margin-bottom: 14px; }
  html body .service-main-list li { font-size: 0.9rem !important; align-items: flex-start; }
  html body .service-main-list li svg { margin-top: 2px; }

  /* How we work: four steps as a compact list with a photo thumbnail, instead
     of four photo tiles with small text laid over busy pictures. Only the
     homepage's cards (the ones with a photo element); service pages build
     their step cards differently and keep them. */
  html body .process-grid:has(> .step-card > .step-bg-img) { grid-template-columns: 1fr !important; gap: 10px; }
  html body .step-card:has(> .step-bg-img) {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr);
    gap: 16px;
    align-items: center;
    min-height: 0;
    padding: 10px 16px 10px 10px;
    background: var(--dv-card);
    border: 1px solid rgba(20, 37, 26, 0.08);
    border-radius: 18px;
    box-shadow: 0 6px 18px rgba(20, 37, 26, 0.06);
  }
  html body .step-card:has(> .step-bg-img) .step-bg-img {
    position: static;
    width: 84px;
    height: 84px;
    border-radius: 12px;
  }
  html body .step-card:has(> .step-bg-img) .step-overlay { display: none; }
  html body .step-card:has(> .step-bg-img) .step-content-wrap { display: block; height: auto; }
  html body .step-card:has(> .step-bg-img) .step-num {
    margin: 0 0 4px;
    color: var(--dv-green);
    font-size: 0.8rem;
    line-height: 1;
    letter-spacing: 0.02em;
  }
  html body .step-card:has(> .step-bg-img) h3 { color: var(--dv-forest); font-size: 1.05rem; margin-bottom: 4px; }
  html body .step-card:has(> .step-bg-img) p { color: var(--dv-body); font-size: 0.9rem; line-height: 1.45; }

  /* Reviews: the first three stacked, then a link to all of them on Google
     (NN/g: visitors trust the review platform over a site's own carousel).
     Not yet checked that these three are Google reviews: Phase 4 picks a
     different real review per page. */
  html body #testimonials-carousel-section .carousel-window { overflow: visible; }
  html body #testimonials-carousel-section .carousel-track {
    flex-direction: column;
    gap: 12px;
    transform: none !important;
  }
  html body #testimonials-carousel-section .carousel-slide { flex: none !important; padding: 0 !important; }
  html body #testimonials-carousel-section .carousel-slide:nth-child(n + 4) { display: none; }
  html body #testimonials-carousel-section .carousel-btn,
  html body #testimonials-carousel-section .carousel-dots { display: none !important; }

  /* Social row: off the screen edges. */
  html body .social-promo-wrap > div { gap: 12px !important; padding: 0 12px; }
}

.dv-reviews-more { margin: 28px 0 0; text-align: center; }
.dv-reviews-more a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 12px 22px;
  border-radius: 14px;
  border: 1.5px solid rgba(20, 37, 26, 0.18);
  color: var(--dv-forest);
  font: 700 0.98rem/1.2 'Inter', sans-serif;
  text-decoration: none;
  background: var(--dv-card);
}
.dv-reviews-more a:hover { border-color: var(--dv-green); }
.dv-reviews-more .dv-rating-stars { font-size: 0.9rem; }
/* The link to every review, with Google's own logo (Emile, 2026-09-25). */
.dv-reviews-more a { gap: 12px; padding: 12px 18px 12px 14px; box-shadow: 0 1px 2px rgba(20, 37, 26, 0.05), 0 8px 22px rgba(20, 37, 26, 0.1); transition: transform 160ms var(--dv-ease), border-color 160ms ease; }
.dv-reviews-more a:active { transform: scale(0.98); }
.dv-reviews-more .dv-g { display: inline-grid; place-items: center; width: 36px; height: 36px; flex: none; border-radius: 50%; background: #ffffff; box-shadow: 0 1px 3px rgba(20, 37, 26, 0.16); }
.dv-reviews-more .dv-g svg { width: 20px; height: 20px; }
.dv-reviews-more .dv-reviews-more-text { text-align: left; }
.dv-reviews-more .dv-reviews-more-arrow { flex: none; color: var(--dv-green); }
@media (max-width: 599px) {
  .dv-reviews-more a { display: flex; width: 100%; }
  .dv-reviews-more .dv-reviews-more-text { flex: 1; }
}

/* Founders: one heading instead of a mobile copy and a desktop copy. On
   phones the text block opens up so the heading can sit above the photo. */
@media (max-width: 768px) {
  html body .about-grid .about-text { display: contents; }
  html body .about-grid .desktop-only-about-title { display: block !important; order: -1; margin-bottom: 0; text-align: left !important; }
  html body .about-grid .desktop-only-about-title h2 { text-align: left !important; }
  html body .about-grid .about-stats { width: 100%; }
  /* The column centred its children, so on tablets the title sat 70 px in
     from the left edge the text below it starts on. */
  html body .about-grid { align-items: stretch !important; }
  html body .about-grid .about-img-box { order: 0; }
  html body .about-grid .about-text > :not(.desktop-only-about-title) { order: 1; }
}
.dv-quick-points { list-style: none; margin: 22px 0 0; padding: 18px 0 0; border-top: 1px solid rgba(20, 37, 26, 0.1); display: grid; gap: 12px; }
.dv-quick-points li { position: relative; padding-left: 28px; color: var(--dv-body); font-size: 0.95rem; line-height: 1.45; }
.dv-quick-points li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--dv-pale) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f6b3f' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center / 11px no-repeat;
}
/* On a phone the card is already the length of a screen: the three points
   stay in the page (Google reads them) but fold away there. */
@media (max-width: 768px) { .dv-quick-points { display: none; } }
.dv-quick { scroll-margin-top: 24px; }
/* Where "Soumission gratuite" buttons land: the card, clear of the header. */
.dv-quick-card { scroll-margin-top: 110px; }
@media (max-width: 768px) { .dv-quick-card { scroll-margin-top: 84px; } }

/* The early form carries its own look, so it is the same on every page (city
   and service pages never had a form, so their CSS has none of these). */
.dv-quick-form .form-label { display: block; font: 700 0.92rem/1.3 'Inter', sans-serif; color: var(--dv-forest); margin-bottom: 8px; }
.dv-quick-form .required-star { color: #b3261e; }
.dv-quick-form .form-input {
  width: 100%;
  box-sizing: border-box;
  padding: 14px 16px;
  border: 1.5px solid rgba(20, 37, 26, 0.16);
  border-radius: 12px;
  background: var(--dv-stone);
  color: var(--dv-forest);
  font-family: 'Inter', sans-serif;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.dv-quick-form .form-input:focus { outline: none; border-color: var(--dv-green); box-shadow: 0 0 0 4px rgba(47, 107, 63, 0.14); }
.dv-quick-form .submit-button {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 22px;
  border: none;
  background: var(--dv-green);
  color: var(--dv-stone);
  font: 900 1.05rem/1.2 'Outfit', sans-serif;
  cursor: pointer;
  box-shadow: 0 10px 24px rgba(47, 107, 63, 0.22);
  transition: background-color 0.2s ease, box-shadow 0.2s ease, transform 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
@media (hover: hover) and (pointer: fine) {
  .dv-quick-form .submit-button:hover { background: var(--dv-green-hover); box-shadow: 0 12px 28px rgba(47, 107, 63, 0.3); }
}
.dv-quick-form .submit-button:active { transform: scale(0.97); transition-duration: 90ms; }
.dv-quick-form .fs-nav { display: flex; align-items: center; gap: 12px; }
/* "Retour" is a small link at the top of steps 2 and 3, so the main button
   has the whole width at the bottom, alone, on one line, in the same place
   on every step (beside Retour, "Recevoir ma soumission gratuite" wrapped to
   two lines on every phone). */
.dv-quick-form .fs-step[data-step="3"] .fs-back-top + .fs-encourage { margin-top: -2px; }
@media (max-width: 374px) {
  html body .dv-quick-card.form-box { padding-left: 16px !important; padding-right: 16px !important; }
  .dv-quick-form .submit-button { font-size: 0.95rem; letter-spacing: -0.01em; padding-left: 12px; padding-right: 12px; }
}
.dv-quick-form .fs-back {
  flex: none;
  min-height: 48px;
  padding: 0 14px;
  border: none;
  background: none;
  color: var(--dv-muted);
  font: 700 0.95rem/1 'Inter', sans-serif;
  cursor: pointer;
}
.dv-quick-form .secure-notice { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 14px; color: var(--dv-muted); font-size: 0.8rem; }
.dv-quick-form .fs-choice { color: var(--dv-forest); }
/* City buttons keep one height on every form: see public/quote-form.css. */

/* City pages: the four service cards were one full phone screen each. On a
   phone they become a list with a photo thumbnail, like the homepage steps. */
@media (max-width: 768px) {
  html body .services-cols { gap: 10px !important; }
  html body .service-block {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    gap: 14px;
    align-items: center;
    padding: 10px 14px 10px 10px;
    border-radius: 18px;
  }
  html body .service-block .service-img-wrap { width: 96px; height: 96px; border-radius: 12px; overflow: hidden; aspect-ratio: auto; }
  html body .service-block .service-img { width: 100%; height: 100%; object-fit: cover; }
  html body .service-block .service-body { padding: 0; }
  html body .service-block h3 { font-size: 1.05rem; margin: 0 0 4px; }
  html body .service-block p { font-size: 0.88rem; line-height: 1.45; margin: 0 0 6px; }
  html body .service-block .service-link { font-size: 0.88rem; }
}

/* Before/after: one large slider per row on phones (two 154px-wide sliders
   side by side before), two side by side from 600px, and a handle you can
   actually grab at any touch width. */
@media (max-width: 768px) {
  html body .ba-handle div { width: 46px !important; height: 46px !important; }
  html body .ba-handle div svg { width: 18px !important; height: 18px !important; }
  html body .ba-before-label,
  html body .ba-after-label { font-size: 0.75rem !important; padding: 6px 14px !important; }
  html body .dv-ba-grid .ba-slider,
  html body .before-after-container .ba-slider { height: 480px !important; touch-action: pan-y; }
}
@media (max-width: 599px) {
  html body .dv-ba-grid,
  html body .before-after-container {
    grid-template-columns: 1fr !important;
    gap: 16px !important;
    max-width: 460px !important;
  }
  html body .dv-ba-grid .ba-slider,
  html body .before-after-container .ba-slider { height: min(112vw, 540px) !important; }
}

/* Service-page step cards keep their photo background; their big step number
   was green, which the 2027 forest makes unreadable on the dark photo. */
html body .step-card:not(:has(> .step-bg-img)) .step-num { color: var(--dv-bright) !important; }
/* The "why us" icons on dark sections were lime (#a3e635), a colour the 2027
   palette does not have. */
html body .section-pourquoi-dark .why-icon { color: var(--dv-bright) !important; }

/* Links inside running text had no colour of their own on some pages, so
   they showed in the browser's default blue (restauration: "entrée",
   "patio"). */
html body main section:not([class*="dark"]):not([data-surface="green"]) p:not(.dv-reviews-more) a:not([class]),
html body main section:not([class*="dark"]):not([data-surface="green"]) li a:not([class]) {
  color: var(--dv-green);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Footer small print was 8 to 10 px and too faint (Lighthouse contrast
   failure on every page). */
html body .f-bottom p,
html body .f-bottom-link,
html body .f-info-icon { color: var(--dv-muted) !important; opacity: 1 !important; }
/* ...and on computer they were still 9 px (the column titles too, and the
   before/after labels 11 px): 12 px everywhere now, the floor the audit
   holds at every width. Phones keep their own slightly larger sizes below. */
html body .f-bottom p,
html body .f-bottom-link,
html body .f-info-icon,
html body .f-title,
html body .ba-before-label,
html body .ba-after-label,
html body .topbar-label { font-size: 0.75rem !important; }
/* At 12 px the footer's bottom row no longer fit with its 0.2em spacing: the
   copyright broke over two lines and "Service local" fell alone to a second
   one. Tighter spacing, the copyright kept whole, and the row may wrap as
   whole pieces. */
@media (min-width: 769px) {
  html body .f-bottom { letter-spacing: 0.08em !important; flex-wrap: wrap !important; row-gap: 16px !important; }
  html body .f-bottom p { white-space: nowrap; }
  html body .f-bottom-links { gap: 12px 28px !important; }
}

/* The progress bars of every form are in public/quote-form.css. */

/* ===================================================================
 * Phone and tablet finish (pass 2, 2026-09-23). Emile: "the boxes and
 * everything don't look well proportioned". Measured at 390 px on the home,
 * restauration and Hull pages before this block:
 *   - boxes sat 14, 24, 33, 36, 45 or 48 px from the screen edge;
 *   - space between sections was 48, 65, 96, 100 or 120 px, by page;
 *   - section titles were 24 to 36 px and centred over left-aligned cards;
 *   - card text went down to 11.2 px, footer text to 8 px;
 *   - card padding ranged from 8 to 40 px.
 * So: one gutter, one section rhythm, one title size, one card shape, and a
 * 14 px floor for reading text. Everything lines up on one left edge
 * (centred titles over left-aligned cards were the main "off" look).
 * The page CSS sets many of these with !important inside its own media
 * queries, so the rules here have to as well. Computer widths (769 px and
 * up) are not touched by this block.
 * =================================================================== */
@media (max-width: 768px) {
  :root { --dv-gutter: 32px; --dv-sec: 72px; --dv-radius: 20px; }
}
@media (max-width: 599px) {
  :root { --dv-gutter: 20px; --dv-sec: 48px; --dv-radius: 18px; }
}

@media (max-width: 768px) {
  /* One gutter. The homepage hero had the section's 24 px plus the
     container's 24 px, so its headline was only 294 px wide. */
  html body main .container:not(.cta-final-card) {
    padding-left: var(--dv-gutter) !important;
    padding-right: var(--dv-gutter) !important;
  }
  html body main section[class^="hero"],
  html body main section.hero { padding-left: 0 !important; padding-right: 0 !important; }
  html body .f-footer { padding-left: var(--dv-gutter) !important; padding-right: var(--dv-gutter) !important; }

  /* One rhythm between sections. */
  html body main section.section,
  html body main .zones-sec {
    padding-top: var(--dv-sec) !important;
    padding-bottom: var(--dv-sec) !important;
  }
  html body main section.cta-final { padding: var(--dv-sec) var(--dv-gutter) !important; }
  html body .dv-quick { padding-bottom: 8px !important; }

  /* Section titles: one size and weight, on the same left edge as the
     cards under them. */
  html body main section:not([class^="hero"]):not(.hero):not(.cta-final):not(.dv-quick) h2 {
    font-size: clamp(1.75rem, 1.35rem + 1.9vw, 2.15rem) !important;
    line-height: 1.1 !important;
    letter-spacing: -0.02em !important;
    font-weight: 800 !important;
    text-align: left !important;
    text-wrap: balance;
  }
  html body main .section-title-wrap,
  html body main section .container > div[style*="text-align"] {
    text-align: left !important;
    margin-bottom: 28px !important;
  }
  html body main .section-title-wrap h2 + div { margin-left: 0 !important; }
  html body main .section-subtitle,
  html body main section:not([class^="hero"]):not(.hero):not(.cta-final):not(.dv-quick) h2 + p {
    font-size: 1.02rem !important;
    line-height: 1.55 !important;
    text-align: left !important;
    margin: 10px 0 0 !important;
    max-width: none !important;
  }

  /* Hero: left-aligned like the rest of the page, one headline size on
     every page (Hull's was 48 px, the others 36 px). */
  html body main section[class^="hero"],
  html body main section[class^="hero"] .container,
  html body main section[class^="hero"] h1,
  html body main section[class^="hero"] p { text-align: left !important; }
  html body main section.hero,
  html body main section.hero-home-new {
    padding-top: 100px !important;
    padding-bottom: 76px !important;
  }
  html body main section[class^="hero"] h1 {
    display: block !important; /* was a centred flex column on the homepage */
    font-size: clamp(2.3rem, 1.6rem + 3.2vw, 2.9rem) !important;
    line-height: 1.04 !important;
    letter-spacing: -0.025em !important;
    margin: 0 0 16px !important;
    max-width: none !important;
  }
  html body main section[class^="hero"] .hero-subtitle,
  html body main section[class^="hero"] .hero-desc {
    font-size: 1.04rem !important;
    line-height: 1.5 !important;
    margin: 0 0 24px !important;
    max-width: 36ch !important;
  }
  html body main section[class^="hero"] .dv-rating { margin: 0 0 18px; }
  html body .hero-home-new .hero-content-wrap { align-items: stretch !important; }
  html body .hero-home-new .hero-content-wrap > .dv-rating { align-self: flex-start; }
  /* Other hero layouts centre their column or their rows of pills
     (/soumission/, /free-quote/, /faq/). */
  html body main section[class^="hero"] .hero-content-left { align-items: flex-start !important; }
  html body main section[class^="hero"] .hero-badges,
  html body main section[class^="hero"] .container > div[style*="justify-content"] { justify-content: flex-start !important; }
  html body main section[class^="hero"] .hero-btn-primary + .hero-link-sec,
  html body main section[class^="hero"] .hero-link-sec {
    display: block;
    width: fit-content;
    margin: 16px auto 0 !important;
    font-size: 0.78rem !important;
    letter-spacing: 0.08em;
    opacity: 0.9;
  }
  html body main section[class^="hero"] .hero-btn-primary {
    display: flex !important;
    justify-content: center;
    width: 100% !important;
    max-width: none !important;
    padding: 17px 16px !important;
    font-size: 1rem !important;
    white-space: nowrap;
  }

  /* Early form card: the full width of the page on tablets too (it was a
     520 px card centred under a left-aligned hero). */
  html body .dv-quick-card.form-box { max-width: none !important; margin: 0 !important; padding: 22px 20px 20px !important; border-radius: 22px !important; }
  html body .dv-quick-head h2 {
    font-size: 1.55rem !important;
    line-height: 1.12 !important;
    letter-spacing: -0.02em !important;
    font-weight: 800 !important;
  }

  /* Reviews: the cards were inset twice (carousel arrows' room plus the
     card's own 32 px), leaving a 230 px column of text. */
  html body #testimonials-carousel-section .carousel-container { padding: 0 !important; }
  html body .testimonial-card {
    padding: 22px 20px !important;
    border-radius: var(--dv-radius) !important;
    min-height: 0 !important;
  }
  .dv-reviews-more { padding: 0 var(--dv-gutter); margin-top: 16px; }
  .dv-reviews-more a { width: 100%; justify-content: center; box-sizing: border-box; }

  /* Homepage service cards: text was 11 to 13 px on dark photos. */
  html body .services-grid { padding: 0 !important; gap: 12px !important; }
  html body .service-main { padding: 24px 20px !important; border-radius: var(--dv-radius) !important; }
  html body .service-main h3 { font-size: 1.45rem !important; line-height: 1.15 !important; }
  html body .service-main-list { grid-template-columns: 1fr !important; gap: 10px !important; }
  html body .service-main-list li { font-size: 0.95rem !important; line-height: 1.4 !important; }
  html body .service-main p { font-size: 0.95rem !important; line-height: 1.5 !important; }
  html body .service-main .btn-large {
    font-size: 0.95rem !important;
    padding: 13px 18px !important;
    min-height: 46px;
    border-radius: 12px !important;
  }
  html body .service-side-stack { gap: 12px !important; }
  html body .service-small-card { padding: 20px !important; border-radius: var(--dv-radius) !important; }
  html body .service-small-card h3 { font-size: 1.12rem !important; margin-bottom: 10px !important; }
  html body .service-small-card ul li { font-size: 0.92rem !important; line-height: 1.4 !important; }

  /* Homepage steps (the list with a thumbnail). */
  html body .process-grid:has(> .step-card > .step-bg-img) { gap: 10px !important; }
  html body .step-card:has(> .step-bg-img) {
    grid-template-columns: 76px minmax(0, 1fr);
    padding: 12px 16px 12px 12px !important;
    min-height: 0 !important;
    border-radius: var(--dv-radius) !important;
  }
  html body .step-card:has(> .step-bg-img) .step-bg-img { width: 76px; height: 76px; }
  html body .step-card:has(> .step-bg-img) .step-num {
    font-size: 0.78rem !important;
    font-weight: 800;
    letter-spacing: 0.06em;
    margin: 0 0 4px !important;
  }
  html body .step-card:has(> .step-bg-img) h3 { font-size: 1.05rem !important; line-height: 1.25 !important; margin-bottom: 4px !important; }
  html body .step-card:has(> .step-bg-img) p { font-size: 0.9rem !important; line-height: 1.45 !important; }

  /* Service-page steps (photo cards). */
  html body .step-card:not(:has(> .step-bg-img)) {
    padding: 26px 22px !important;
    min-height: 0 !important;
    border-radius: var(--dv-radius) !important;
  }
  html body .step-card:not(:has(> .step-bg-img)) .step-num { font-size: 2.6rem !important; line-height: 1 !important; margin-bottom: 10px !important; }
  html body .step-card:not(:has(> .step-bg-img)) h3 { font-size: 1.2rem !important; margin-bottom: 8px !important; }
  html body .step-card:not(:has(> .step-bg-img)) p { font-size: 0.95rem !important; line-height: 1.55 !important; }

  /* "Why us" cards: icon beside the title instead of above it. */
  html body .why-grid { gap: 12px !important; }
  html body .why-card {
    display: grid !important;
    grid-template-columns: 44px minmax(0, 1fr);
    column-gap: 16px;
    align-items: start;
    padding: 22px 20px !important;
    border-radius: var(--dv-radius) !important;
  }
  html body .why-card .why-icon {
    width: 44px !important;
    height: 44px !important;
    margin: 0 !important;
    border-radius: 12px !important;
  }
  html body .why-card .why-icon svg { width: 22px; height: 22px; }
  html body .why-card h3 { font-size: 1.1rem !important; margin: 11px 0 0 !important; }
  html body .why-card p { grid-column: 1 / -1; font-size: 0.95rem !important; line-height: 1.55 !important; margin: 12px 0 0 !important; }
  /* A card with no icon must not squeeze its title into the 44px icon column
     (the sealer page's finish cards did, 2026-09-26). */
  html body .why-card:not(:has(> .why-icon)) { grid-template-columns: minmax(0, 1fr); }
  html body .why-card:not(:has(> .why-icon)) h3 { margin-top: 0 !important; }

  /* Founders */
  html body .about-text p { font-size: 1rem !important; line-height: 1.6 !important; }
  html body .about-stats { gap: 10px !important; }
  html body .about-stat,
  html body .about-stat-link-green { padding: 16px 14px !important; border-radius: 16px !important; }
  html body .about-stat h3,
  html body .about-stat-link-green h3 { font-size: 1rem !important; }
  html body .about-stat p,
  html body .about-stat-link-green p { font-size: 0.84rem !important; line-height: 1.35 !important; }

  /* How a quote works */
  html body .trust-step h3 { font-size: 1.12rem !important; }
  html body .trust-step p { font-size: 0.95rem !important; line-height: 1.55 !important; }
  html body .form-guarantee-card { padding: 20px !important; border-radius: var(--dv-radius) !important; }
  html body .form-guarantee-card h3 { font-size: 1.12rem !important; }
  html body .form-guarantee-card p { font-size: 0.92rem !important; }

  /* FAQ */
  html body .faq-item { border-radius: var(--dv-radius) !important; }
  html body .faq-header {
    padding: 18px 18px 18px 20px !important;
    font-size: 1.05rem !important;
    line-height: 1.3 !important;
  }
  html body .faq-answer-inner {
    padding-left: 20px !important;
    padding-right: 20px !important;
    font-size: 0.98rem !important;
    line-height: 1.6 !important;
  }

  /* Closing call to action */
  html body .cta-final-card { padding: 40px 18px !important; border-radius: 24px !important; }
  html body .cta-final-content h2 {
    font-size: clamp(1.75rem, 1.35rem + 1.9vw, 2.15rem) !important;
    line-height: 1.1 !important;
    letter-spacing: -0.02em !important;
  }
  html body .cta-final-content .btn-premium-green {
    display: flex !important;
    justify-content: center;
    width: 100% !important;
    padding: 16px 12px !important;
    font-size: 0.98rem !important;
    white-space: nowrap;
    box-sizing: border-box;
  }

  /* Social row on the homepage: one card with three equal buttons. */
  html body .social-promo-wrap { padding-top: 28px !important; }
  html body .social-promo-wrap h3 {
    text-transform: none !important;
    letter-spacing: -0.01em !important;
    font-size: 1.15rem !important;
    color: var(--dv-forest) !important;
    text-align: left !important;
    margin-bottom: 12px !important;
  }
  html body .social-promo-wrap > div {
    display: grid !important;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 !important;
    padding: 12px 6px !important;
    background: var(--dv-card);
    border: 1px solid rgba(20, 37, 26, 0.08);
    border-radius: var(--dv-radius);
  }
  html body .social-promo-wrap > div > div { display: none !important; }
  html body .social-promo-wrap > div { width: 100%; max-width: none !important; margin: 0 !important; box-sizing: border-box; }
  html body .social-promo-wrap .social-hover-card { width: auto !important; }

  /* City pages */
  html body #degradation .reveal { padding: 0 !important; }
  html body #degradation p { text-align: left !important; font-size: 1.02rem !important; line-height: 1.65 !important; }
  html body .zones-wrapper { text-align: left !important; }
  html body .zones-cloud { justify-content: flex-start !important; }
  html body .service-block { border-radius: var(--dv-radius) !important; }

  /* Footer: nothing under 12 px, and legal links big enough to tap. */
  html body .f-title { font-size: 0.75rem !important; letter-spacing: 0.12em !important; }
  html body .f-contact-loc { font-size: 0.8rem !important; }
  html body .f-bottom p { font-size: 0.8rem !important; }
  html body .f-bottom-links { gap: 0 20px !important; }
  html body .f-bottom-link,
  html body .f-info-icon { font-size: 0.8rem !important; padding: 10px 0 !important; }
}

/* Small phones: the one-line buttons get a slightly smaller type size, and
   under 350 px (first iPhone SE) they may wrap rather than run off. */
@media (max-width: 380px) {
  html body main section[class^="hero"] .hero-btn-primary,
  html body .cta-final-content .btn-premium-green { font-size: 0.9rem !important; padding-left: 10px !important; padding-right: 10px !important; }
}
@media (max-width: 349px) {
  html body main section[class^="hero"] .hero-btn-primary,
  html body .cta-final-content .btn-premium-green { white-space: normal; }
}

/* Found by `node scripts/shots.mjs audit` (2026-09-23): the article
   before/after labels were 11.2 px, and at tablet width the contact page's
   e-mail button was set to one line and cut its own address. */
html body .article-ba-label { font-size: 0.75rem; }
@media (max-width: 768px) {
  html body main a[href^="mailto:"] { white-space: normal !important; overflow-wrap: anywhere; }
}

/* Early form, computer widths: the two halves of the card end at the same
   line. The text side ran further down than the form side, so the card
   looked lopsided and "Continuer" sat too high (Emile, 2026-09-24). The form
   becomes a panel as tall as the text column, with its button pinned to the
   bottom of the panel on every step. */
@media (min-width: 769px) {
  html body .dv-quick-card.form-box { align-items: stretch; }
  .dv-quick-form {
    display: flex;
    flex-direction: column;
    padding: 26px 28px 24px;
    background: var(--dv-stone);
    border: 1px solid var(--dv-line);
    border-radius: 20px;
  }
  .dv-quick-form .fs-steps { flex: 1; }
  .dv-quick-form .fs-choice-grid .fs-choice { min-height: 54px; }
  .dv-quick-form .fs-choice,
  .dv-quick-form .form-input { background: var(--dv-card); }
  .dv-quick-head { display: flex; flex-direction: column; }
}

/* ===================================================================
 * Presses (Emile, 2026-09-24: "make every click satisfying"). Every button
 * gives a little under the finger as it is pressed, within 0.1 s (NN/g: the
 * limit for feeling instant), and springs back on release. Wide rows (FAQ
 * questions) give less, small icon buttons give more. Hover effects stay on
 * devices that really hover.
 * =================================================================== */
html body .hero-btn-primary,
html body .btn-premium-green,
html body .btn-large,
html body .nav-btn-cta,
html body .nav-ref-btn,
html body .dv-bar a,
html body .dv-reviews-more a,
html body .contact-btn,
html body .service-link,
html body .mobile-menu-toggle,
html body .mobile-close-btn,
html body .faq-header,
html body .faq-pill,
html body .zone-badge {
  -webkit-tap-highlight-color: transparent;
  transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1), background-color 200ms ease, color 200ms ease, border-color 200ms ease, box-shadow 200ms ease, opacity 200ms ease !important;
}
html body .hero-btn-primary:active,
html body .btn-premium-green:active,
html body .btn-large:active,
html body .nav-btn-cta:active,
html body .nav-ref-btn:active,
html body .dv-bar a:active,
html body .dv-reviews-more a:active,
html body .contact-btn:active,
html body .faq-pill:active,
html body .zone-badge:active { transform: scale(0.97) !important; transition-duration: 90ms !important; }
html body .service-link:active { transform: translateX(2px) scale(0.98) !important; }
html body .faq-header:active { transform: scale(0.99) !important; transition-duration: 90ms !important; }
html body .mobile-menu-toggle:active,
html body .mobile-close-btn:active { transform: scale(0.9) !important; transition-duration: 90ms !important; }

/* Arriving at the form from a "Soumission gratuite" button: the card glows
   once, so the eye lands on it and the first question. */
@keyframes dv-arrive {
  0% { box-shadow: 0 30px 70px rgba(20, 37, 26, 0.16), 0 2px 6px rgba(20, 37, 26, 0.05), 0 0 0 0 rgba(76, 175, 80, 0.5); }
  100% { box-shadow: 0 30px 70px rgba(20, 37, 26, 0.16), 0 2px 6px rgba(20, 37, 26, 0.05), 0 0 0 16px rgba(76, 175, 80, 0); }
}
html body .dv-quick-card.dv-arrive { animation: dv-arrive 1100ms cubic-bezier(0.23, 1, 0.32, 1) 1; }

@media (prefers-reduced-motion: reduce) {
  html body .hero-btn-primary:active,
  html body .btn-premium-green:active,
  html body .btn-large:active,
  html body .nav-btn-cta:active,
  html body .nav-ref-btn:active,
  html body .dv-bar a:active,
  html body .dv-reviews-more a:active,
  html body .contact-btn:active,
  html body .service-link:active,
  html body .faq-header:active,
  html body .faq-pill:active,
  html body .zone-badge:active,
  html body .mobile-menu-toggle:active,
  html body .mobile-close-btn:active { transform: none !important; }
  html body .dv-quick-card.dv-arrive { animation: none; }
}

/* ===================================================================
 * Visual pass 2 (Emile, 2026-09-25: "go through the whole website again
 * visually and find spots that aren't appealing to the eye (too much going
 * on, not enough, boring colours, etc.)", "there is too much on the hero
 * section of homepage"). Every page looked at on phone and computer; the
 * wording itself is left for the copy phase.
 * =================================================================== */

/* Site chrome. The social top bar and the round call button already left
   phones; they leave computers too. The header shows the phone number and
   the quote button at all times, the social links sit in the footer, and
   each extra floating thing competes with the page (Baymard on floating
   widgets; the audit research: one floating element at most). */
html:root { --topbar-h: 0px; }
html body .topbar { display: none; }
html body .fab { display: none !important; }

/* Header over the photo, computer: the current page's link and the
   "Recevez 150 $ !" button were bright green on bright sky and leaves
   (about 2:1 on the about and before/after photos). White now, the green
   stays as the underline and the button's edge. */
@media (min-width: 769px) {
  html body .header:not(.scrolled) .nav-link { text-shadow: 0 1px 10px rgba(0, 0, 0, 0.35); }
  html body .header:not(.scrolled) .nav-link.active { color: #ffffff !important; }
  html body .header:not(.scrolled) .nav-ref-btn {
    color: #ffffff !important;
    background: rgba(20, 37, 26, 0.5) !important;
    border-color: rgba(76, 175, 80, 0.85) !important;
  }
}

/* One hero recipe on every page (Emile, 2026-09-25: "I need every page to
   have the same effect on the background ... when it's the same thing on
   every page, for example the final CTA or a hero section photo, we always
   put the same effects on them so that it stays coherent"). Measured that
   day: five recipes for the same thing (44 pages a flat 45 % black, about
   45 to 55 %, before/after 45 to 55 % plus a grey filter on the photo, FAQ
   50 %, and a shade added on top of all of them), and he found the darker
   before/after photo worse than the lighter one. Now every hero photo gets
   the same lighter veil, the header shade at the top (::before), a shade
   only right behind the words (::after: round behind centred words, from
   the left behind words on the left) and the same text shadow. The closing
   call to action was already the same on all 60 pages.
   `shots.mjs audit` still holds every hero's words to 4.5:1 (3:1 for large
   text) against the brightest tenth of the photo behind them. */
html body section[class^="hero"]:has(img) .hero-overlay:not(#dv) {
  background: rgba(6, 12, 8, 0.26) !important;
}
html body section[class^="hero"] img { filter: none !important; opacity: 1 !important; }
html body section[class^="hero"]:has(img) .hero-overlay::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 58% 60% at 50% 52%, rgba(6, 12, 8, 0.5), rgba(6, 12, 8, 0) 80%);
}
html body section.hero-asym .hero-overlay::after,
html body section.hero:not(.text-center):has(img) .hero-overlay::after {
  background: linear-gradient(to right, rgba(6, 12, 8, 0.55) 0, rgba(6, 12, 8, 0.3) 45%, rgba(6, 12, 8, 0) 72%);
}

html body section[class^="hero"] .dv-h1-sub,
html body section[class^="hero"] .hero-subtitle,
html body section[class^="hero"] .hero-desc,
html body section[class^="hero"] .container > p,
html body section[class^="hero"] .hero-col-main > p {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 14px rgba(0, 0, 0, 0.35);
}

/* Homepage hero: the extra two-line sentence left the hero (the smaller
   "Nettoyage et réparation" line is the one-line promise the research
   calls for: rating, headline, promise, button, then the form). The call
   link under the button reads as a sentence, not a shouted label. */
html body section[class^="hero"] .hero-link-sec {
  text-transform: none !important;
  letter-spacing: 0 !important;
  font-weight: 600;
  font-size: 0.98rem !important;
}

/* Heroes with no photo (contact, quote) were stretched to four fifths of a
   phone screen like the photo heroes, which left half a screen of empty
   dark green. They take their natural height. */
@media (max-width: 768px) {
  html body section.hero:not(:has(img)) { min-height: 0 !important; }
}

/* ===================================================================
 * Service pages
 * =================================================================== */
/* "Notre processus": the steps were long paragraphs in small type laid over
   darkened photos. The photo now sits on top of each card and the words on
   the card below it; the step number sits on the photo. The cards are not
   links, so they no longer lift on hover. */
html body .process-grid > .step-card[class*="step-card-"] {
  background-color: var(--dv-card) !important;
  background-blend-mode: normal !important;
  background-size: cover !important;
  background-position: center 35% !important;
  /* the photo stops inside the edge, or it shows through the 1 px border */
  background-clip: padding-box !important;
  border: 1px solid rgba(20, 37, 26, 0.08) !important;
  padding: 200px 26px 26px !important;
  min-height: 0 !important;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(20, 37, 26, 0.05), 0 10px 28px rgba(20, 37, 26, 0.07) !important;
}
html body .process-grid > .step-card[class*="step-card-"]:hover { transform: none; }
html body .process-grid > .step-card[class*="step-card-"]::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 176px;
  background: var(--dv-card);
  z-index: 0;
}
html body .process-grid > .step-card[class*="step-card-"] > * { position: relative; z-index: 1; }
html body .process-grid > .step-card[class*="step-card-"] .step-num {
  position: absolute !important;
  top: 16px;
  left: 16px;
  margin: 0 !important;
  padding: 8px 12px;
  border-radius: 10px;
  background: rgba(20, 37, 26, 0.85);
  color: #ffffff !important;
  font-size: 1.05rem !important;
  line-height: 1 !important;
  letter-spacing: 0.02em;
  opacity: 1 !important;
}
html body .process-grid > .step-card[class*="step-card-"] h3 { color: var(--dv-forest) !important; margin-bottom: 8px; }
html body .process-grid > .step-card[class*="step-card-"] p { color: var(--dv-body) !important; }
@media (max-width: 768px) {
  html body .process-grid > .step-card[class*="step-card-"] { padding: 164px 20px 22px !important; }
  html body .process-grid > .step-card[class*="step-card-"]::after { top: 140px; }
}

/* "Signes qu'il est temps...": seven signs were one long list of bold
   sentences. Each sign is now its own small card (Emile's rule since this
   morning: a set of parallel items gets an edge), two across on a computer,
   with a small green paver as the marker. */
html body section[id^="signes"] .reveal.d1 { max-width: 980px !important; }
html body section[id^="signes"] .reveal.d1 > p { max-width: 750px; margin-left: auto; margin-right: auto; }
html body section[id^="signes"] ul {
  list-style: none !important;
  padding-left: 0 !important;
  display: grid !important;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px !important;
  margin: 0 0 28px !important;
}
html body section[id^="signes"] ul li {
  position: relative;
  margin: 0 !important;
  padding: 16px 18px 16px 48px;
  background: var(--dv-card);
  border: 1px solid rgba(20, 37, 26, 0.08);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(20, 37, 26, 0.04), 0 6px 18px rgba(20, 37, 26, 0.05);
  font-size: 0.98rem;
  line-height: 1.5;
}
html body section[id^="signes"] ul li::before {
  content: '';
  position: absolute;
  left: 20px;
  top: 22px;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--dv-green);
  transform: rotate(45deg);
}
html body section[id^="signes"] ul li strong { color: var(--dv-forest); font-weight: 700; }
@media (max-width: 700px) {
  html body section[id^="signes"] ul { grid-template-columns: 1fr; }
}

/* "Zones desservies": the cities were a line of links in a sentence; they
   are now the same buttons as the city pages' "Nos autres zones desservies",
   in the light version for a stone band. Same links, same words. */
html body .zones-lead { max-width: 60ch; margin: 16px auto 0; color: var(--dv-body); font-size: 1.05rem; line-height: 1.6; }
html body .dv-zone-pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 28px;
}
html body .dv-zone-pills .zone-badge {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 12px 24px;
  border-radius: 999px;
  background: var(--dv-card);
  border: 1px solid rgba(20, 37, 26, 0.12);
  box-shadow: 0 1px 2px rgba(20, 37, 26, 0.05), 0 6px 16px rgba(20, 37, 26, 0.06);
  color: var(--dv-forest);
  font: 700 1rem/1 'Outfit', sans-serif;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  html body .dv-zone-pills .zone-badge:hover { border-color: var(--dv-green); color: var(--dv-green); }
}
@media (max-width: 768px) {
  html body .dv-zone-pills { justify-content: flex-start; }
  html body .zones-lead { margin-left: 0; text-align: left; }
}

/* ===================================================================
 * Other pages
 * =================================================================== */
/* Before/after: the two see-through boxes in the hero ("5.0 Noté 5 étoiles
   sur Google", "24h Réponse à votre soumission") stay: Emile, 2026-09-25,
   "it looked better before ... the little five star Google on my liquid
   glass" (hidden for a few hours that day, put back). */

/* About: the "Allez lire nos dizaines d'autres avis" pill sits in the same
   wrapper as the homepage's social row, which phones turn into three columns
   (above), so the pill was squeezed into a third of the width and read as a
   broken circle. Its wrapper stays a plain row, and the pill wraps as a
   rounded card. The long story paragraphs were centred; long text reads from
   one left edge. */
@media (max-width: 768px) {
  html body .social-promo-wrap > div:has(> .google-pill-badge) {
    display: flex !important;
    padding: 0 !important;
    background: none !important;
    border: 0 !important;
  }
  html body .about-text-content,
  html body .about-text-content p { text-align: left !important; }
  html body .google-pill-badge {
    display: flex !important;
    flex-wrap: wrap;
    width: 100%;
    box-sizing: border-box;
    border-radius: 18px !important;
    padding: 14px 18px !important;
    gap: 8px 12px !important;
    text-align: center;
  }
  html body .google-badge-text { flex: 1 1 auto; }
}

/* Prices, phone: the tilted see-through "0 $ Évaluation & visite" box took a
   third of the first screen. Same words, a compact flat card. */
@media (max-width: 768px) {
  html body .hero-visual {
    transform: none !important;
    padding: 16px 18px !important;
    border-radius: 18px !important;
    text-align: left !important;
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 16px;
    align-items: center;
  }
  html body .hero-visual > :first-child { font-size: 2.2rem !important; line-height: 1 !important; margin: 0 !important; grid-row: span 2; }
  html body .hero-visual > * { margin-top: 0 !important; margin-bottom: 0 !important; }
}

/* Quote page, "Pourquoi demander une soumission ?": three cards in three
   colours and two sizes (one white, one stone on stone, one gradient). One
   card colour, three across on a computer. */
html body .rassurance-card { background: var(--dv-card) !important; border: 1px solid rgba(20, 37, 26, 0.08) !important; }
@media (min-width: 900px) {
  html body .rassurance-grid { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
  html body .rassurance-card-1,
  html body .rassurance-card-2,
  html body .rassurance-card-3 { grid-column: auto !important; }
}

/* Referral page: the three step cards were 200 px wide in the middle of a
   wide band on a computer and inset 40 px on phones; the "conditions" link
   sat alone in a tall empty band. */
html body .steps-grid { max-width: 1080px !important; }
@media (max-width: 768px) {
  html body .steps-grid { padding: 0 !important; }
}
html body .conditions-section { padding: 28px 0 !important; }
/* Quote page hero, phone: "100 % gratuit", "Sans engagement", "Réponse en
   24h" took a line each; they sit side by side and wrap. */
@media (max-width: 768px) {
  html body section[class^="hero"] .hero-badges { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; gap: 8px !important; }
  html body section[class^="hero"] .hero-badge-item { padding: 7px 12px !important; font-size: 0.84rem !important; gap: 6px !important; }
}
/* "Ou appelez le 819 328-2129" under the hero button: the phone rules set it
   to 12.5 px capitals; it is a sentence now, so it gets reading size. */
@media (max-width: 768px) {
  html body main section[class^="hero"] .hero-btn-primary + .hero-link-sec,
  html body main section[class^="hero"] .hero-link-sec { font-size: 0.95rem !important; letter-spacing: 0 !important; opacity: 0.92; }
}
}

/* Hero photos on phones (Emile, 2026-09-25: "les photos de hero sections sur
   téléphone ... n'ont vraiment pas le bon format pour un téléphone").
   Measured: every hero photo is landscape (1376 x 768, the homepage
   2000 x 1000); a phone's tall hero keeps about a quarter of its width (26 to
   34 %), a slice from the middle, stretched about 3 times on a 3x screen.
   Until photos made for a phone exist (portrait, 1200 px wide or more), each
   photo gets its own phone framing, chosen by eye on the photo: the house and
   the paving instead of whatever sits in the middle. Framing only: the effect
   on every hero stays the same (one recipe, above). */
@media (max-width: 768px) {
  html body section[class^="hero"] img[src*="hero-accueil-pave-uni"] { object-position: 35% 50% !important; }
  html body section[class^="hero"] img[src*="hero-restauration-pave-uni"] { object-position: 67% 50% !important; }
  html body section[class^="hero"] img[src*="hero-nettoyage-pave-uni"] { object-position: 71% 50% !important; }
  html body section[class^="hero"] img[src*="hero-scellant-pave-uni"] { object-position: 29% 50% !important; }
  html body section[class^="hero"] img[src*="hero-nivelage-pave-uni"] { object-position: 54% 50% !important; }
  html body section[class^="hero"] img[src*="hero-pave-uni-gatineau"] { object-position: 67% 50% !important; }
  html body section[class^="hero"] img[src*="hero-pave-uni-hull"] { object-position: 50% 50% !important; }
  html body section[class^="hero"] img[src*="hero-pave-uni-aylmer"] { object-position: 82% 50% !important; }
  html body section[class^="hero"] img[src*="hero-pave-uni-buckingham"] { object-position: 73% 50% !important; }
  html body section[class^="hero"] img[src*="hero-pave-uni-masson-angers"] { object-position: 64% 50% !important; }
  html body section[class^="hero"] img[src*="hero-pave-uni-ottawa"] { object-position: 46% 50% !important; }
}

/* Phones: the hero photo whole at the top, the words under it on the forest
   green (Emile picked this on 2026-09-25, "pour l'instant je pense que B est
   le mieux", from the trial in pour-emile/29). The photos are landscape; set
   behind the words, a phone kept about a quarter of their width and
   stretched it about 3 times. In a frame as wide as the phone and 74 % as
   tall, the same 1376 px photo shows about three quarters of its width at
   about its own size. The same on every page with a hero photo (his rule:
   one effect for the same component). When portrait photos made for phones
   exist, each hero gets them through <picture> (the phone downloads only its
   own version) and this can go back to the photo behind the words. */
@media (max-width: 768px) {
  html body section[class^="hero"]:has(img.hero-bg):not(#dv) {
    background: var(--dv-forest) !important;
    padding-top: calc(min(74vw, 460px) + 20px) !important;
    min-height: 0 !important;
  }
  html body section[class^="hero"] .hero-bg-container:not(#dv),
  html body section[class^="hero"] > img.hero-bg:not(#dv) {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: auto !important;
    width: 100% !important;
    height: min(74vw, 460px) !important;
    overflow: hidden;
  }
  html body section[class^="hero"] .hero-bg-container img.hero-bg:not(#dv) {
    width: 100% !important;
    height: 100% !important;
    transform: none !important;
  }
  html body section[class^="hero"] img.hero-bg:not(#dv) { object-fit: cover; }
  html body section[class^="hero"]:has(img.hero-bg) .hero-overlay:not(#dv),
  html body section[class^="hero"] .hero-gradient-overlay:not(#dv) {
    top: 0 !important;
    bottom: auto !important;
    height: min(74vw, 460px) !important;
    background: linear-gradient(to bottom, rgba(6, 12, 8, 0.5) 0, rgba(6, 12, 8, 0) 32%, rgba(6, 12, 8, 0) 72%, var(--dv-forest) 100%) !important;
  }
  html body section[class^="hero"] .hero-overlay::after { display: none !important; }
}
/* The words under a hero headline start on the headline's left edge (the
   FAQ's sentence kept a centred block 30 px in from it on tablets). */
@media (max-width: 768px) {
  html body main section[class^="hero"] .container > p { margin-left: 0 !important; margin-right: 0 !important; }
}

/* ===================================================================
 * Button shine slides by transform (2026-09-25). It animated `left`, which
 * Chrome counts as a page jump on every frame: about 220 in 5 s on every
 * page, 0.05 to 0.06 of Google's 0.1 limit on phones, carried by every
 * visitor on top of the normal load. Same look, same 3 s loop. Stopped for
 * people who turn motion off. `audit:phone` fails on any animation that
 * moves the layout.
 * =================================================================== */
html body .nav-btn-cta:not(#dv)::after,
html body .btn-premium-green:not(#dv)::after,
html body .hero-btn-primary:not(#dv)::after {
  left: 0 !important;
  transform: translateX(-150%) skewX(-20deg);
  animation-name: dv-shine;
}
@keyframes dv-shine {
  from { transform: translateX(-150%) skewX(-20deg); }
  to { transform: translateX(150%) skewX(-20deg); }
}
@media (prefers-reduced-motion: reduce) {
  html body .nav-btn-cta:not(#dv)::after,
  html body .btn-premium-green:not(#dv)::after,
  html body .hero-btn-primary:not(#dv)::after { animation: none; visibility: hidden; }
}

/* ===================================================================
 * Phones: fewer tall boxes, more per screen (Emile, 2026-09-25: "one item
 * of width and it's long ... you can only see one box and it scrams up all
 * your screen"; what he likes: the homepage's four steps, all on one
 * screen). Four patterns, each for one kind of content:
 * - Swipe row, the next card peeking in, for sets of 3 to 12 parallel
 *   cards (reviews, services, reasons, photo steps, price factors, values).
 *   NN/g "Carousels on Mobile Devices": a half-visible item is the strongest
 *   cue that there is more; it must swipe; gutters at the edges; no
 *   auto-advance on phones. Dots under it are drawn by site.js.
 * - Grouped card: one card, rows separated by a hairline, for lists and
 *   steps (Apple's inset grouped list). One surface instead of a stack of
 *   separately shadowed boxes.
 * - Accordions stay for long answers (FAQ): NN/g "Accordions on Mobile".
 * - Short photo rows stay as they are (city services, homepage steps).
 * Phones only (up to 599 px, the phone gutter's breakpoint); tablets and
 * the computer are not touched. Every card's words stay in the page.
 * =================================================================== */
@media (max-width: 599px) {
  /* Swipe rows */
  html body .why-grid:not(#dv),
  html body .process-grid:has(> .step-card[class*="step-card-"]):not(#dv),
  html body .services-grid:not(#dv),
  html body .asymmetric-grid:not(#dv),
  html body .valeurs-grid:not(#dv),
  html body #testimonials-carousel-section .carousel-window:not(#dv) {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    gap: 12px !important;
    overflow-x: auto !important;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--dv-gutter);
    overscroll-behavior-x: contain;
    margin-inline: calc(-1 * var(--dv-gutter)) !important;
    padding: 4px var(--dv-gutter) 18px !important;
    max-width: none !important;
    width: auto !important;
    scrollbar-width: none;
    align-items: stretch !important;
    grid-template-columns: none !important;
  }
  html body .why-grid::-webkit-scrollbar,
  html body .process-grid::-webkit-scrollbar,
  html body .services-grid::-webkit-scrollbar,
  html body .asymmetric-grid::-webkit-scrollbar,
  html body .valeurs-grid::-webkit-scrollbar,
  html body #testimonials-carousel-section .carousel-window::-webkit-scrollbar { display: none; }
  html body .services-grid .service-side-stack { display: contents !important; }
  html body .why-grid > *,
  html body .process-grid:has(> .step-card[class*="step-card-"]) > *,
  html body .services-grid > .service-main,
  html body .services-grid .service-small-card,
  html body .asymmetric-grid > *,
  html body .valeurs-grid > * {
    flex: 0 0 min(84%, 320px) !important;
    width: auto !important;
    max-width: none !important;
    margin: 0 !important;
    scroll-snap-align: start;
    grid-column: auto !important;
    grid-row: auto !important;
  }
  /* Cards inside a row are on screen when their row is: no fade on each. */
  html body :is(.why-grid, .process-grid, .services-grid, .asymmetric-grid, .valeurs-grid) .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
  /* Reviews: back to a swipe row (Emile, 2026-09-25: "I preferred when it
     was like a carousel ... even on the phone"). The page script's arrows,
     dots and timer are set aside; all twelve reviews are in the row. */
  html body #testimonials-carousel-section .carousel-track {
    display: contents !important;
    transform: none !important;
  }
  html body #testimonials-carousel-section .carousel-slide,
  html body #testimonials-carousel-section .carousel-slide:nth-child(n + 4) {
    display: flex !important;
    flex: 0 0 min(84%, 320px) !important;
    padding: 0 !important;
    scroll-snap-align: start;
  }
  html body #testimonials-carousel-section .carousel-slide > .testimonial-card { width: 100%; }
  html body #testimonials-carousel-section .carousel-btn,
  html body #testimonials-carousel-section .carousel-dots { display: none !important; }
  html body #testimonials-carousel-section .carousel-container { padding: 0 !important; }

  /* Homepage services: the three smaller cards as tall as the featured one. */
  html body .services-grid .service-small-card { display: flex !important; flex-direction: column; justify-content: flex-end; min-height: 0 !important; }
  html body .services-grid > .service-main { min-height: 0 !important; }

  /* Grouped cards */
  html body .trust-row-steps:not(#dv),
  html body .inc-row:not(#dv),
  html body .rassurance-grid:not(#dv),
  html body section[id^="signes"] ul:not(#dv) {
    display: block !important;
    background: var(--dv-card) !important;
    border: 1px solid var(--dv-line) !important;
    border-radius: var(--dv-radius) !important;
    box-shadow: 0 1px 2px rgba(20, 37, 26, 0.04), 0 10px 26px rgba(20, 37, 26, 0.06) !important;
    overflow: hidden;
    padding: 0 !important;
  }
  html body .trust-row-steps > *,
  html body .inc-row > *,
  html body .rassurance-grid > *,
  html body section[id^="signes"] ul li {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    margin: 0 !important;
    transform: none !important;
    opacity: 1 !important;
  }
  html body .trust-row-steps > * + *,
  html body .inc-row > * + *,
  html body .rassurance-grid > * + *,
  html body section[id^="signes"] ul li + li { border-top: 1px solid var(--dv-line) !important; }
  html body section[id^="signes"] ul li { padding: 14px 16px 14px 42px !important; font-size: 0.95rem !important; }
  html body section[id^="signes"] ul li::before { left: 18px; top: 21px; }
  html body .inc-row > *,
  html body .rassurance-grid > * { padding: 18px !important; }

  /* Contact: the phone and email cards as two rows of one card, icon on the
     left (they were two 370 px boxes under the form). */
  html body .contact-grid:not(#dv) {
    display: block !important;
    background: var(--dv-card);
    border: 1px solid var(--dv-line);
    border-radius: var(--dv-radius);
    box-shadow: 0 1px 2px rgba(20, 37, 26, 0.04), 0 10px 26px rgba(20, 37, 26, 0.06);
    overflow: hidden;
  }
  html body .contact-grid > .contact-card:not(#dv) {
    display: grid !important;
    grid-template-columns: 48px minmax(0, 1fr);
    column-gap: 14px;
    align-items: center;
    text-align: left !important;
    min-width: 0 !important;
    padding: 18px !important;
    margin: 0 !important;
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
  html body .contact-grid > .contact-card + .contact-card { border-top: 1px solid var(--dv-line) !important; }
  html body .contact-grid .contact-icon-wrap { grid-row: 1 / span 3; align-self: start; width: 48px !important; height: 48px !important; margin: 0 !important; }
  html body .contact-grid .contact-icon-wrap svg { width: 22px; height: 22px; }
  html body .contact-grid .contact-label,
  html body .contact-grid .contact-value,
  html body .contact-grid .contact-card > p { grid-column: 2; margin: 0 !important; text-align: left !important; }
  html body .contact-grid .contact-value { font-size: 1.15rem !important; }
  html body .contact-grid .contact-value[href^="mailto"] { font-size: min(0.95rem, 4vw) !important; white-space: nowrap; }
  html body .contact-grid .contact-card > p { font-size: 0.88rem !important; }
  html body .contact-grid .contact-btn { grid-column: 1 / -1; margin: 14px 0 0 !important; width: 100%; min-height: 46px; }

  /* Before/after: both sliders on about one screen (were 437 px tall each). */
  html body .dv-ba-grid .ba-slider,
  html body .before-after-container .ba-slider { height: min(78vw, 360px) !important; }
}

/* Dots under a swipe row (site.js): small, not buttons; the peeking card is
   the real cue. */
.dv-dots { display: none; }
@media (max-width: 599px) {
  .dv-dots { display: flex; justify-content: center; gap: 6px; margin: 2px 0 0; }
  .dv-dots span { width: 6px; height: 6px; border-radius: 3px; background: rgba(20, 37, 26, 0.22); transition: width 200ms var(--dv-ease), background-color 200ms ease; }
  .dv-dots span.on { width: 18px; background: var(--dv-green); }
  .dv-dots-dark span { background: rgba(247, 243, 234, 0.35); }
  .dv-dots-dark span.on { background: var(--dv-bright); }
}

/* Three cards in one row on a computer (the sealer page's finish cards), instead of 2 + 1. */
@media (min-width: 1024px) {
  .why-grid.why-grid-3 { grid-template-columns: repeat(3, 1fr); }
}
