/**
 * SERSYS — Art direction layer (child theme).
 *
 * Loaded after the parent vendor CSS (ostech.css) and the parent theme.css.
 * Implements the official CDVI/SERSYS Brand Guidelines 2025 (see BRANDING.md):
 * CDVI blue focal color, silver/grey metallic gradients (50°), Verdana,
 * dark-grey #242424 typography, soft card radii. No dark "night" surfaces.
 */

:root {
  /* Brand palette — SERSYS Brand Guidelines 2025, p.8-9. */
  --sersys-grey: #B0B0B8;
  --sersys-text: #242424;
  --sersys-text-soft: #5A5A64;
  --sersys-silver-gradient: linear-gradient(50deg, #EEEEEE 0%, #D2D2D2 35%, #EEEEEE 65%, #BEBDBD 100%);
  --sersys-silver-gradient-alt: linear-gradient(50deg, #D1D1D1 0%, #EEEEEE 55%, #D2D2D2 100%);
  --sersys-radius: 14px;
  --sersys-shadow: 0 18px 40px -18px rgba(36, 36, 36, 0.25);

  /* Triangular mesh signature (guideline pp.1-13 corner motif) — inline SVG,
     CDVI blue at 3-8% opacity, layered as a watermark; no extra request. */
  --sersys-triangles: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='240' viewBox='0 0 480 240'%3E%3Cg fill='%2300457C'%3E%3Cpath d='M0 240l60-120 60 120z' opacity='.07'/%3E%3Cpath d='M120 240l60-120 60 120z' opacity='.04'/%3E%3Cpath d='M240 240l60-120 60 120z' opacity='.06'/%3E%3Cpath d='M360 240l60-120 60 120z' opacity='.03'/%3E%3Cpath d='M60 120l60 120 60-120z' opacity='.05'/%3E%3Cpath d='M180 120l60 120 60-120z' opacity='.08'/%3E%3Cpath d='M300 120l60 120 60-120z' opacity='.04'/%3E%3Cpath d='M60 120l60-120 60 120z' opacity='.04'/%3E%3Cpath d='M240 120l60-120 60 120z' opacity='.03'/%3E%3Cpath d='M120 0l60 120 60-120z' opacity='.05'/%3E%3C/g%3E%3C/svg%3E");

  /* Brand typeface is Verdana (system font) — the parent only emits these
     tokens for Google/uploaded fonts, so the child owns them. */
  --ostech-font: Verdana, Geneva, sans-serif;
  --ostech-heading-font: Verdana, Geneva, sans-serif;

  /* Align the vendor text tokens with the guideline typography colour. */
  --ostech-text-dark: #242424;
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* --------------------------------------------------------------
# Typography
#
# Verdana ships in 400/700 only and runs wide: cap weights at 700
# and rein in the tracking the previous art direction used.
-------------------------------------------------------------- */
.sec-title__tagline {
  letter-spacing: 0.12em;
  font-weight: 700;
}

.sec-title__title,
h1, h2, h3 {
  font-weight: 700;
}

/* Editorial blockquote: parent hardcodes an off-palette #1f4e8c. */
blockquote,
.wp-block-quote {
  color: var(--sersys-text);
}

/* --------------------------------------------------------------
# Buttons — industrial serious
-------------------------------------------------------------- */
.ostech-btn {
  border-radius: 6px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 13px;
  font-weight: 700;
}

/* --------------------------------------------------------------
# Slider + hero (both use .main-slider-three) — silver metallic
-------------------------------------------------------------- */
/* Scrim + guideline triangle watermark, anchored bottom-left like the
   guideline cover page. */
.main-slider-three__bg::before {
  background:
    var(--sersys-triangles) left bottom / 480px auto no-repeat,
    linear-gradient(
      50deg,
      rgba(238, 238, 238, 0.97) 0%,
      rgba(238, 238, 238, 0.92) 45%,
      rgba(210, 210, 210, 0.75) 75%,
      rgba(190, 189, 189, 0.6) 100%
    );
}

.main-slider-three__title {
  color: var(--ostech-base, #00457C);
  font-size: clamp(28px, 3.2vw, 46px);
  line-height: 1.16;
  font-weight: 700;
  margin-right: 0;
}

/* Keep highlighted words inline (vendor puts them on their own line). */
.main-slider-three__title span {
  display: inline;
  color: inherit;
}

.main-slider-three__title span svg {
  display: none;
}

/* CDVI blue scrim on top of the slide image (kept when the Ken Burns
   zoom was removed 2026-07-22 — no auto-zoom on image backgrounds). */
.main-slider-three__item {
  overflow: hidden;
}

.main-slider-three__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 69, 124, 0.35) 0%, rgba(0, 69, 124, 0) 45%);
  pointer-events: none;
}

/* No base opacity:0 here on purpose — the button must stay visible if the
   JS below never runs (blocked/slow script). The animation's own 'from'
   keyframe provides the transient dip, only when the class is toggled. */
.main-slider-three__link__btn.sersys-fade-in {
  animation: sersys-fade-in 280ms ease-out both;
  animation-delay: 80ms;
}

@keyframes sersys-fade-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .main-slider-three__link__btn {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
}

.main-slider-three__subtitle {
  color: var(--sersys-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 14px;
  font-weight: 700;
}

.main-slider-three__text {
  color: var(--sersys-text);
  max-width: 620px;
}

/* Hero right column rich text (certifications). */
.main-slider-three .main-slider-three__right,
.main-slider-three__item p {
  color: var(--sersys-text);
}

/* --------------------------------------------------------------
# "Dark" flexible sections — silver metallic gradient
#
# The vendor paints .rt-section--bg-dark with --ostech-secondary and
# --ostech-on-secondary, which the brand options now map to SERSYS grey
# and #242424. Swap the flat fill for the guideline gradient.
-------------------------------------------------------------- */
.rt-section--bg-dark {
  background:
    var(--sersys-triangles) right -120px top -80px / 420px auto no-repeat,
    var(--sersys-silver-gradient);
}

/* Inner vendor sections carry their own light background: neutralize it
   so the silver gradient shows through. */
.rt-section--bg-dark .service-two,
.rt-section--bg-dark .feature-one,
.rt-section--bg-dark .blog-three,
.rt-section--bg-dark .testimonial-three,
.rt-section--bg-dark .client-carousel {
  background: transparent;
}

/* --------------------------------------------------------------
# Projects showcase — always show imagery
-------------------------------------------------------------- */
.project-three__item {
  border-radius: var(--sersys-radius);
  overflow: hidden;
  padding: 96px 60px;
}

.project-three__item + .project-three__item {
  margin-top: 24px;
}

.project-three__item__bg {
  opacity: 1;
  visibility: visible;
}

/* CDVI blue scrim keeps the photo readable while staying on palette. */
.project-three__item__bg::after {
  background: linear-gradient(
    90deg,
    rgba(0, 69, 124, 0.92) 0%,
    rgba(0, 69, 124, 0.65) 55%,
    rgba(0, 69, 124, 0.3) 100%
  );
  z-index: -1;
}

.project-three__item__subtitle {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  border-radius: 4px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 12px;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

.project-three__item:hover .project-three__item__subtitle {
  background: #fff;
  color: var(--ostech-base, #00457C);
}

.project-three__item__link__btn {
  border-color: rgba(255, 255, 255, 0.4);
}

.project-three__item__link__btn__icon::before,
.project-three__item__link__btn__icon::after {
  background-color: rgba(255, 255, 255, 0.85);
}

/* --------------------------------------------------------------
# Feature cards (features_grid + subpages_list)
-------------------------------------------------------------- */
.feature-one__item {
  border-radius: var(--sersys-radius);
  overflow: hidden;
  filter: none;
  box-shadow: var(--sersys-shadow);
}

.feature-one__item__thumb img {
  aspect-ratio: 3 / 2;
  width: 100%;
  object-fit: cover;
}

/* Vendor hover paints the card in brand blue with dark text — force white. */
.feature-one__item:hover .feature-one__item__title,
.feature-one__item:hover .feature-one__item__title a,
.feature-one__item:hover .feature-one__item__text,
.feature-one__item:hover .feature-one__item__icon {
  color: var(--ostech-on-primary, #fff);
}

/* The vendor paints a flat 300px band behind the card tops
   (.feature-one::after, ostech.css:10792) with --ostech-secondary — since the
   rebrand that's SERSYS lavender-grey, a dirty slab with a hard edge cutting
   through the cards. The silver zebra + triangle watermark already carry the
   section: drop the band. */
.feature-one::after {
  display: none;
}

/* The vendor .feature-one (ostech.css:10690) only sets padding-top —
   cards sit glued to the section's bottom edge. Restore breathing room. */
.feature-one {
  padding-bottom: 90px;
}

@media (max-width: 991px) {
  .feature-one {
    padding-bottom: 70px;
  }
}

@media (max-width: 767px) {
  .feature-one {
    padding-bottom: 60px;
  }
}

/* --------------------------------------------------------------
# Client / certification logos
-------------------------------------------------------------- */
/* The vendor fades these logos to opacity:0.2 at rest (1 on hover) — its
   own hover-reveal idiom for a "b&w until interacted" strip. Force full
   colour permanently (no grayscale, no fade) and cap the render size so
   small source rasters don't pixelate at the vendor's larger max-height. */
.client-carousel-one .client-carousel__one__item img,
.client-carousel__one__item img {
  opacity: 1;
  filter: none;
  max-height: 48px;
}

.client-carousel-one .rt-tagline {
  display: block;
  text-align: center;
  margin-bottom: 20px;
  color: var(--ostech-base, #00457C);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

/* --------------------------------------------------------------
# Blog cards
-------------------------------------------------------------- */
.blog-card-three {
  border-radius: var(--sersys-radius);
  overflow: hidden;
  box-shadow: var(--sersys-shadow);
  background: #fff;
}

.blog-card-three__date {
  border-radius: 8px;
  color: #fff;
  padding: 10px 14px 12px;
}

.blog-card-three__date span {
  font-size: 24px;
}

/* --------------------------------------------------------------
# FAQ split — keep the product photo contained
-------------------------------------------------------------- */
.faqs-two__right img {
  max-height: 620px;
  width: auto;
  max-width: 100%;
  margin: 0 auto;
  display: block;
  object-fit: contain;
}

/* --------------------------------------------------------------
# CTA banner
-------------------------------------------------------------- */
.cta-three__content {
  border-radius: var(--sersys-radius);
}

/* --------------------------------------------------------------
# Tier comparison cards
-------------------------------------------------------------- */
.tier-comparison .tier-card,
.package-page .package-card {
  border-radius: var(--sersys-radius);
  overflow: hidden;
}

/* Flat at rest, no depth until hover — give the comparison cards real
   shadow presence and a hover/focus lift, matching the guideline's
   card shadow token used elsewhere (feature/blog/product cards). */
.package-page .package-card {
  box-shadow: var(--sersys-shadow);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.package-page .package-card:hover,
.package-page .package-card:focus-within {
  transform: translateY(-6px);
  box-shadow: 0 24px 48px -18px rgba(36, 36, 36, 0.32);
}

.package-page .package-card .ostech-btn:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 2px;
}

@media (max-width: 767px) {
  .package-page .package-card:hover,
  .package-page .package-card:focus-within {
    transform: translateY(-3px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .package-page .package-card,
  .client-carousel__one__item img {
    transition: none;
  }
}

/* --------------------------------------------------------------
# Language switcher (Polylang, child markup — no vendor CSS exists)
# Lives on the CDVI-blue topbar and the dark mobile off-canvas panel.
-------------------------------------------------------------- */
.lang-switcher {
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.lang-switcher--topbar {
  margin-left: 18px;
}

.lang-switcher__item a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 24px;
  padding: 0 8px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 4px;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1;
  transition: all 0.25s ease;
}

.lang-switcher__item a:hover {
  background: #fff;
  color: var(--ostech-base, #00457C);
  border-color: #fff;
}

/* Mobile nav variant sits on the dark off-canvas panel — same treatment. */
.lang-switcher--mobile {
  margin: 16px 0 0;
}

/* --------------------------------------------------------------
# Header sizing — cap the logo so the (sticky) header stays slim
#
# Brand Guidelines 2025 p.6: minimum clear space around the SERSYS logo
# = half its diameter, on all 4 sides (nothing enters that zone). At the
# previous 56px/44px caps the header only offered ~4-18px of breathing
# room (well under the 22-23px half-height threshold) — sizes below and
# the .main-header__inner padding-block further down restore it on all
# 4 sides at 1600/1280/mobile + the sticky clone. Measured with Playwright.
-------------------------------------------------------------- */
.main-header__logo {
  display: flex;
  align-items: center;
  gap: 24px;
}

/* SERSYS d'abord et dominant dans le lockup (marque du site), CDVI en
   endossement à sa droite : le filet passe donc à gauche du logo CDVI.

   Spécificité 0,2,0 requise : WooCommerce injecte `.woocommerce-page img
   { height: auto; max-width: 100% }` (0,1,1, chargé après ce fichier) qui
   écrasait le calage sur le catalogue et les fiches produit — le logo y
   était compressé par le conteneur flex au lieu de tenir sa hauteur fixe. */
.main-header .main-header__logo__cdvi {
  height: 34px;
  width: auto;
  max-width: none;
  margin-top: 8px;
  padding-left: 14px;
  border-left: 1px solid rgba(0, 69, 124, 0.2);
}

@media (max-width: 575px) {
  .main-header__logo__cdvi {
    display: none;
  }
}

.main-header__logo img {
  max-height: 50px;
  width: auto;
}

/* Même parade anti-WooCommerce que pour le logo CDVI ci-dessus : sans
   ceci, le logo SERSYS (taille naturelle > conteneur) est compressé par
   `max-width: 100%` sur les pages boutique. */
.main-header .main-header__logo img {
  max-width: none;
}

@media (max-width: 991px) {
  .main-header__logo img {
    max-height: 42px;
  }

  .main-header__logo {
    gap: 20px;
  }
}

.sticky-header--cloned .main-header__logo img {
  max-height: 42px;
}

.sticky-header--cloned .main-header__logo {
  gap: 20px;
}

/* Vertical clear space: the vendor sizes .main-header__inner off its
   tallest child (the nav — its own li padding varies by band) which left
   only ~4-18px above/below the logo. Pad the row explicitly so the 50px
   (42px sticky/mobile) logo gets >=25px (>=21px) top/bottom without
   ballooning the header past the ~100px/84px design ceiling. Values tuned
   per band against the nav's own natural height at that band (measured
   with Playwright — see e2e/_tmp_measure.mjs during the fitting pass). */
.main-header--three .main-header__inner {
  padding-block: 12px;
}

.sticky-header--cloned .main-header__inner {
  padding-block: 4px;
}

@media (min-width: 992px) and (max-width: 1599px) {
  .sticky-header--cloned .main-header__inner {
    padding-block: 10px;
  }
}

@media (max-width: 991px) {
  .main-header--three .main-header__inner {
    padding-block: 18px;
  }

  .sticky-header--cloned .main-header__inner {
    padding-block: 22px;
  }
}

/* The vendor hides the search toggler under 768px, leaving mobile users
   with no search access — bring the icon back next to the burger. */
@media (max-width: 767px) {
  .main-header--three button.search-toggler.main-header__right__info__item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* --------------------------------------------------------------
# Contrast repair — text on brand blue
#
# The vendor palette assumed a LIGHT primary (yellow #FFAA17) and pairs
# dark text (--ostech-secondary / --ostech-text-dark) with --ostech-base
# backgrounds, statically and on hover. With the deep CDVI blue as
# primary, every such pair becomes unreadable. Repaint them all with
# --ostech-on-primary. Covers unused vendor components too, so future
# layouts inherit correct contrast.
-------------------------------------------------------------- */

/* Header phone widget (blue box, dark text). */
.main-header--three .main-header__right__call__subtitle {
  color: rgba(255, 255, 255, 0.72);
}

.main-header--three .main-header__right__call__text {
  color: var(--ostech-on-primary, #fff);
}

/* Phone widget: bleed the blue box to the header's top/bottom edges.
   The vendor centers it in the flex row, so it floated inside the
   .main-header__inner padding-block set above, leaving a white band
   above and below (the ::before that carries the blue to the right edge
   is height:100% of the box, so it floated too). Stretching the box
   fills the flex line, and the negative margin-block eats the row
   padding — values mirror the padding-block of the "Vertical clear
   space" block above, band for band. The icon stays centered on the
   box's own align-items. */
.main-header--three .main-header__right {
  align-self: stretch;
}

.main-header--three .topbar-one__right__call {
  align-self: stretch;
  margin-block: -8px;
}

.sticky-header--cloned .topbar-one__right__call {
  margin-block: 0;
}

@media (min-width: 992px) and (max-width: 1599px) {
  .main-header--three .topbar-one__right__call {
    margin-block: -14px;
  }

  .sticky-header--cloned .topbar-one__right__call {
    margin-block: -7px;
  }
}

@media (max-width: 991px) {
  .main-header--three .topbar-one__right__call {
    margin-block: -20px;
  }

  .sticky-header--cloned .topbar-one__right__call {
    margin-block: -20px;
  }
}

/* Topbar info items: vendor grey reads poorly on the CDVI-blue topbar. */
.topbar-two__info__item a,
.topbar-two__info__item span,
.topbar-two__info__item__time {
  color: rgba(255, 255, 255, 0.85);
}

/* Topbar left segment: vendor paints it near-black — keep the whole
   topbar in the CDVI blue family (darker declination). */
.topbar-two__info,
.topbar-two__info::before,
.topbar-two__social,
.topbar-two__social::before {
  background: #00355F;
}

/* Dropdown submenu : le fill vendor instantané (fond base plein posé sur
   le <a> au hover) donnait un effet stroboscopique en balayant la liste —
   remplacé par un balayage scaleX porté par ::before (voir plus bas), donc
   le fond du <a> lui-même reste transparent. */
.main-menu .main-menu__list li ul li:hover > a {
  background-color: transparent;
  color: var(--ostech-on-primary, #fff);
}

/* Dropdown submenu, densité/lisibilité : le vendor pose 232px de large +
   labels uppercase + gros paddings — les 8 entrées Solutions wrappent sur
   3 lignes et le panneau (681px) dépasse un écran de laptop 13".
   → panneau plus large, casse mixte, rythme resserré, et garde-fou de
   hauteur (scroll) si un menu s'allonge encore. */
.main-menu .main-menu__list li ul {
  /* left:0 : aligne le bord du panneau sur le début du label parent
     (le vendor posait -25px, panneau flottant sans repère). width:max-content
     borné : élargit juste assez pour éviter les wraps à 1 seule entrée. */
  left: 0;
  min-width: 340px;
  width: max-content;
  max-width: 420px;
  padding: 10px 0;
  border-top: 3px solid var(--ostech-base, #00457C);
  /* Coins bas arrondis seulement (panneau accroché sous le header) ;
     ombre 2 couches : contact + portée. */
  border-radius: 0 0 8px 8px;
  box-shadow: 0 2px 6px rgba(0, 20, 45, 0.10), 0 18px 36px -12px rgba(0, 20, 45, 0.24);
  max-height: calc(100vh - 170px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* translateY au lieu du scaleY vendor (écrasait la scrollbar du garde-fou) ;
     délai à la fermeture seulement, pour tolérer le trajet diagonal vers le panneau. */
  transform: translateY(8px);
  transition: opacity 180ms ease 150ms, visibility 180ms ease 150ms, transform 200ms ease 150ms;
}
.main-menu .main-menu__list li:hover > ul {
  transform: translateY(0);
  transition-delay: 0ms;
}
/* Ouverture au clavier : le vendor n'ouvre qu'au :hover, donc le panneau
   (visibility:hidden) était inatteignable au Tab — WCAG 2.1.1. */
.main-menu .main-menu__list li:focus-within > ul {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  /* Ouverture instantanée : une tabulation rapide passait devant la
     transition de 180ms et sautait le panneau encore hidden. */
  transition: none;
}
.main-menu .main-menu__list li ul li {
  margin-bottom: 0;
}
.main-menu .main-menu__list li ul li > a {
  /* 13px vertical → cibles ~45px ; Verdana n'existe qu'en 400/700 → 400 assumé.
     position/z-index/overflow : socle du balayage ::before ci-dessous. */
  position: relative;
  z-index: 1;
  overflow: hidden;
  padding: 13px 24px;
  text-transform: none;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.4;
  color: #232A33;
  text-wrap: pretty;
  transition: color 160ms ease-out;
}
/* Filet 1px entre entrées : donne un rythme aux listes longues (Solutions, 8)
   et des ancres visuelles statiques pendant le balayage. */
.main-menu .main-menu__list li ul li + li > a {
  border-top: 1px solid rgba(0, 69, 124, 0.08);
}
/* Balayage : le fond base entre par la gauche au lieu d'un flash plein. */
.main-menu .main-menu__list li ul li > a::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--ostech-base, #00457C);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
}
.main-menu .main-menu__list li ul li:hover > a::before {
  transform: scaleX(1);
}
/* Focus clavier (aucun style focus vendor — WCAG 2.4.7) : anneau interne
   + fond clair, distinct du hover souris. */
.main-menu .main-menu__list li ul li > a:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: -2px;
  background-color: #EEF3F8;
}
/* Page courante : repère statique (texte base + point), sans le fill vendor. */
.main-menu .main-menu__list li ul li.current > a,
.main-menu .main-menu__list li ul li.current-menu-item > a {
  background-color: transparent;
  color: var(--ostech-base, #00457C);
  font-weight: 700;
}
.main-menu .main-menu__list li ul li.current > a::after,
.main-menu .main-menu__list li ul li.current-menu-item > a::after {
  content: '';
  position: absolute;
  right: 16px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ostech-base, #00457C);
  transform: translateY(-50%);
}
.main-menu .main-menu__list li ul li.current:hover > a,
.main-menu .main-menu__list li ul li.current-menu-item:hover > a {
  color: var(--ostech-on-primary, #fff);
}
.main-menu .main-menu__list li ul li.current:hover > a::after,
.main-menu .main-menu__list li ul li.current-menu-item:hover > a::after {
  background: var(--ostech-on-primary, #fff);
}
/* Affordance : chevron ▾ sur les labels qui ouvrent un sous-menu
   (le <a> parent est en display:flex align-items:center). */
.main-menu .main-menu__list > li.menu-item-has-children > a::after {
  content: '';
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  margin-left: 8px;
  margin-top: -4px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}

/* Services section: the vendor zeroes the title padding, gluing the
   heading to the carousel — restore breathing room. */
.service-two__left .sec-title {
  padding-bottom: 40px;
}

.service-two__right {
  margin-bottom: 24px;
}

@media (max-width: 767px) {
  .service-two__left .sec-title {
    padding-bottom: 24px;
  }
}

/* Services (méthodologie) card: hover fills content with base. */
.service-two__item:hover .service-two__item__content__title,
.service-two__item:hover .service-two__item__content__title a,
.service-two__item:hover .service-two__item__content__text,
.service-three__item:hover .service-three__item__title,
.service-three__item:hover .service-three__item__title a {
  color: var(--ostech-on-primary, #fff);
}

/* Tier comparison (package) card: hover repaints the head with base. */
.package-card:hover .package-card__head__title,
.package-card:hover .package-card__head__price,
.package-card:hover .package-card__head .sup,
.package-card:hover .package-card__head .sub,
.package-card:hover .package-card__head__month,
.package-card__head__top {
  color: var(--ostech-on-primary, #fff);
}

/* Shop sidebar search field (base-blue input, dark text/caret). */
.product__sidebar__search input[type='search'],
.product__sidebar__search input[type='text'] {
  color: var(--ostech-on-primary, #fff);
  caret-color: var(--ostech-on-primary, #fff);
}

.product__sidebar__search input::placeholder {
  color: rgba(255, 255, 255, 0.72);
}

/* Product card / detail buttons: hover fills with base. */
.product__item__link:hover,
.product__item__btn a:hover,
.product-details__buttons a:hover,
.ostech-btn--secondary:hover,
.cart-page__buttons .ostech-btn--secondary:hover {
  color: var(--ostech-on-primary, #fff);
}

/* Quote button on the product page: the vendor paints it with the
   near-black tier — use the focal blue, darker declination on hover. */
.product-details__buttons a,
.product-details__buttons a:last-child,
.product-action-buttons__btn--quote {
  background-color: var(--ostech-base, #00457C);
  color: var(--ostech-on-primary, #fff);
}

.product-details__buttons a:hover,
.product-details__buttons a:last-child:hover,
.product-action-buttons__btn--quote:hover {
  background-color: #00355F;
  color: var(--ostech-on-primary, #fff);
}

/* Static badges, date chips and icon circles painted with base. */
.blog-card__date,
.blog-card-two__date,
.blog-card__two__date,
.testimonials-one__item__quite,
.benefit-one__feature__icon,
.about-one__feature__item__icon__item,
.about-two__thumb__award,
.about-three__thumb__call__icon,
.faq-contact__inner__item__icon,
.team-card__content__hover__icon,
.why-choose-one__feature__item__link__btn,
.why-choose-two__inner__item__link__btn,
.main-header__right__icon,
.service-sidebar__contact-btn .ostech-btn,
.footer-widget__newsletter button[type='submit'] {
  color: var(--ostech-on-primary, #fff);
}

/* Hover states that fill an icon/pill with base. */
.why-choose-one__feature__item:hover .why-choose-one__feature__item__icon,
.why-choose-two__inner__item:hover .why-choose-two__inner__item__icon,
.why-choose-three__feature__top:hover .why-choose-three__feature__top__icon,
.about-two__feature__top:hover .about-two__feature__top__icon,
.about-three__feature__top:hover .about-three__feature__top__icon,
.service-card:hover .service-card__icon,
.service-card-two:hover .service-card-two__icon,
.service-one__item:hover .service-one__item__icon,
.testimonial-two__item:hover .testimonial-two__item__quite,
.footer-widget__contact__item:hover .footer-widget__contact__icon,
.main-footer__top__social a:hover,
.team-details__social a:hover,
.sidebar__tags a:hover,
.sidebar__comments__item:hover .sidebar__comments__icon,
.product-details__socials__item a:hover,
.project-details__box__social a:hover,
.testimonials-one .owl-nav .owl-prev span:hover,
.testimonials-one .owl-nav .owl-next span:hover,
.client-carousel-one .owl-theme .owl-nav button span:hover,
.price-page__inner__btn.active-btn,
.price-page__inner__btn:hover,
.pronation_widget ul a.active,
.pronation_widget ul a:hover,
.main-slider-one__link__btn:hover,
.why-choose-two__cta__link__btn:hover,
.project-one__content__btn:hover {
  color: var(--ostech-on-primary, #fff);
}

/* --------------------------------------------------------------
# Catalog (vitrine) product cards
-------------------------------------------------------------- */
/* Vendor capitalizes titles, which mangles product names (e-LOCK → E-LOCK). */
.product__item__title,
.product-details__title,
.page-header__title,
.related-products__title,
.product__categories ul li a {
  text-transform: none;
}

/* Vendor only adds margin-top to the related/upsells section on mobile
   (<=767px) — add breathing room above the "Produits similaires" title
   on desktop too. */
@media (min-width: 768px) {
  .related.products > h2,
  .upsells.products > h2 {
    margin-top: 40px;
  }
}

.product__item {
  border-radius: var(--sersys-radius);
  /* Depth at rest, not only on hover — vendor's larger .product__item:hover
     shadow (higher specificity) still takes over on hover/focus. */
  box-shadow: 0 10px 24px -14px rgba(36, 36, 36, 0.2);
  transition: box-shadow 0.3s ease;
}

.product__item:hover {
  box-shadow: var(--sersys-shadow);
}

/* Card CTA: quiet outline that fills with brand blue on hover. */
.product__item__link {
  background: transparent;
  border: 1px solid rgba(0, 69, 124, 0.35);
  color: var(--ostech-base, #00457C);
  border-radius: 6px;
}

/* --------------------------------------------------------------
# Product certification badges (EN 1627, A2P, NF...)
-------------------------------------------------------------- */
.product__item__img {
  position: relative;
}

.sersys-cert-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.sersys-cert-badges--card {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 2;
}

.sersys-cert-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(0, 69, 124, 0.25);
  border-radius: 999px;
  padding: 3px 10px 3px 3px;
  box-shadow: var(--sersys-shadow);
}

.sersys-cert-badge__icon {
  width: 22px;
  height: 22px;
  object-fit: contain;
  border-radius: 50%;
  background: #fff;
}

.sersys-cert-badge__label {
  color: var(--ostech-base, #00457C);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1;
}

/* Single product gallery: badges sit bottom-left over the main image. */
.woocommerce-product-gallery {
  position: relative;
}

.sersys-cert-badges--single {
  position: absolute;
  bottom: 14px;
  left: 14px;
  z-index: 2;
}

.sersys-cert-badges--single .sersys-cert-badge {
  background: rgba(255, 255, 255, 0.95);
}

/* --------------------------------------------------------------
# About pillars row — 2×2 grid
#
# The vendor lays the feature pillars out as one flex row with 44px
# borders/margins between items and 202px-wide texts: four pillars
# overflow the column (~730px of content for ~570px). Regrid 2×2 and
# lift the pale vendor text colour.
-------------------------------------------------------------- */
.about-two__feature {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px 28px;
  /* stretch explicite (le vendor pose align-items:center) : les items
     d'une même rangée — et leur filet gauche — font la même hauteur ;
     le texte reste collé au titre, sans min-height d'alignement sous
     les h3. */
  align-items: stretch;
}

/* Sans icône ni fond, les features sont des blocs de texte flottants :
   un filet bleu CDVI à gauche ancre chaque item et remplace les
   séparateurs vendor entre items (les deux règles car le sélecteur vendor
   :not(:first-of-type) est plus spécifique que la classe seule). */
.about-two__feature__item {
  border-left: 3px solid var(--ostech-base, #00457C);
  padding-left: 16px;
}

.about-two .about-two__feature__item:not(:first-of-type) {
  padding-left: 16px;
  border-left: 3px solid var(--ostech-base, #00457C);
  margin-left: 0;
}

.about-two__feature__item__text {
  max-width: none;
  color: var(--sersys-text);
  font-weight: 400;
}

/* Le chapô du bloc « à propos » (souvent un <ul>) : le vendor le pose en
   gris (#999B9F) et en 600, il doit se lire comme le reste du corps de
   texte — noir charte, graisse normale. La couleur cascade sur le ul/li. */
.about-two__top__text {
  color: var(--sersys-text);
  font-weight: 400;
}

/* Un seul mot (« Repositionnement », « environnemental ») peut être plus
   large que la demi-colonne : sans césure il traverse la ligne séparatrice
   (desktop) ou chevauche la colonne voisine (mobile). Le vendor met ces h3
   en 28px (taille quasi égale au h2 de section) dans une demi-colonne de
   ~246px : hiérarchie écrasée et césures forcées (« Conformité to-tale »).
   Recalés en 19px — sous-titre tertiaire, plus de césure sur les contenus
   réels ; break-word/hyphens gardés en filet de sécurité. */
.about-two__feature__item h3 {
  overflow-wrap: break-word;
  hyphens: auto;
  font-size: 19px;
  line-height: 1.4;
}

/* L'interligne vendor de 34px (2.125) est pensé pour de longs paragraphes,
   pas pour ces courtes descriptions : resserré à l'échelle de la carte. */
.about-two__feature__item p {
  line-height: 1.6;
  margin-bottom: 0;
}

/* Sous 576px la demi-colonne (~141px) reste illisible même césurée :
   empiler les features en 1 colonne. */
@media (max-width: 575px) {
  .about-two__feature {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------
# Footer — silver metallic
#
# The vendor paints the footer with --ostech-secondary (now SERSYS grey)
# but keeps light text designed for a dark surface: switch to the
# guideline gradient and repaint the text dark.
-------------------------------------------------------------- */
.main-footer {
  background:
    var(--sersys-triangles) right -100px bottom -60px / 420px auto no-repeat,
    var(--sersys-silver-gradient-alt);
  color: var(--sersys-text);
}

.main-footer__shape,
.main-footer__earth {
  display: none;
}

/* The parent paints every footer text white (".main-footer p, .main-footer a…",
   designed for a colored footer) — match its specificity to repaint dark. */
.main-footer,
.main-footer p,
.main-footer a,
.main-footer h1,
.main-footer h2,
.main-footer h3,
.main-footer h4 {
  color: var(--sersys-text);
}

.main-footer .footer-widget__title {
  color: var(--ostech-base, #00457C);
}

.main-footer .footer-widget__text,
.main-footer .footer-widget__links__item,
.main-footer .footer-widget__links__item a,
.main-footer .footer-widget__contact__text,
.main-footer .main-footer__copyright {
  color: var(--sersys-text-soft);
}

.main-footer__bottom {
  background: transparent;
  border-top: 1px solid rgba(36, 36, 36, 0.15);
}

/* CDVI co-branding (Brand Guidelines 2025, p.12): both logos on every
   design, SERSYS presented as a CDVI Group brand. */
.main-footer__bottom__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px 40px;
  padding-block: 20px;
}

/* Groupe de marque en bas à gauche : logo SERSYS puis logo CDVI, séparés par
   un filet — même construction que le logo du header. */
.main-footer__bottom__brand {
  display: flex;
  align-items: center;
  gap: 24px;
}

.main-footer__bottom__brand .main-footer__cobrand__logo {
  padding-left: 24px;
  border-left: 1px solid rgba(0, 69, 124, 0.2);
}

@media (max-width: 575px) {
  .main-footer__bottom__brand {
    gap: 16px;
  }

  .main-footer__bottom__brand .main-footer__cobrand__logo {
    padding-left: 16px;
  }
}

.main-footer__cobrand__text {
  color: var(--sersys-text-soft);
  font-size: 13px;
}

.main-footer__cobrand__logo img {
  height: 32px;
  width: auto;
  display: block;
}

.main-footer__bottom__logo img {
  height: 50px;
  width: auto;
  display: block;
}

/* Contact widget card: vendor paints it near-black — use the focal blue.
   (Keeps light text: these rules must stay AFTER the dark footer repaint.) */
.footer-widget--contact {
  background: var(--ostech-base, #00457C);
}

.main-footer .footer-widget--contact .footer-widget__title {
  color: var(--ostech-on-primary, #fff);
}

.main-footer .footer-widget--contact .footer-widget__contact__text,
.main-footer .footer-widget--contact .footer-widget__contact__item a {
  color: rgba(255, 255, 255, 0.85);
}

.footer-widget__contact__icon {
  background: var(--ostech-base, #00457C);
  color: var(--ostech-on-primary, #fff);
}

.footer-widget--contact .footer-widget__contact__icon {
  background: rgba(255, 255, 255, 0.15);
}

/* Newsletter: vendor styles a dark input for a dark footer. */
.footer-widget__newsletter input[type='email'] {
  background-color: #fff;
  border: 1px solid var(--sersys-grey);
  color: var(--sersys-text);
}

.footer-widget__newsletter input[type='email']::placeholder {
  color: var(--sersys-text-soft);
}

/* Social links now live in their own "Suivez-nous" footer column. Brand-blue
   circle / white glyph (the parent's dark chip clashed with the light footer);
   darkens on hover. */
.footer-widget--social .main-footer__top__social {
  margin-top: 6px;
  flex-wrap: wrap;
}

.main-footer__top__social a {
  background: var(--ostech-base, #00457C);
  color: #fff;
  box-shadow: 0 6px 14px -8px rgba(0, 69, 124, 0.55);
}

.main-footer__top__social a:hover {
  background: #013057;
  color: #fff;
}

/* --------------------------------------------------------------
# Secondary (ghost) button
#
# Default context is now light — outline in the focal blue. Inside
# blue CTA banners / brand sections, keep the white ghost variant.
-------------------------------------------------------------- */
.ostech-btn--secondary {
  background: transparent;
  border: 1px solid rgba(0, 69, 124, 0.5);
  color: var(--ostech-base, #00457C);
}

.ostech-btn--secondary:hover {
  border-color: var(--ostech-base, #00457C);
  background: var(--ostech-base, #00457C);
}

.cta-three .ostech-btn--secondary,
.rt-section--cta .ostech-btn--secondary,
.rt-section--bg-brand .ostech-btn--secondary {
  border-color: rgba(255, 255, 255, 0.6);
  color: #fff;
}

.cta-three .ostech-btn--secondary:hover,
.rt-section--cta .ostech-btn--secondary:hover,
.rt-section--bg-brand .ostech-btn--secondary:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

/* --------------------------------------------------------------
# Title + text — editorial statement (replaces the boxed v1)
-------------------------------------------------------------- */
.title-text-section {
  padding: 72px 0 48px;
}

.title-text-section .sec-title {
  padding-bottom: 24px;
}

.title-text-section .sec-title__title {
  color: var(--ostech-base, #00457C);
  font-size: clamp(26px, 2.6vw, 36px);
  line-height: 1.15;
  margin-bottom: 10px;
}

.title-text-section .sec-title__tagline {
  color: var(--sersys-text-soft);
  font-size: 13px;
}

/* The signature ::after bar below already marks this heading — the
   site-wide tagline mini-bar would double it up here. */
.title-text-section .sec-title__tagline::before {
  display: none;
}

/* Signature 50° accent bar under the heading block. */
.title-text-section .sec-title::after {
  content: '';
  display: block;
  width: 72px;
  height: 4px;
  margin-top: 18px;
  border-radius: 2px;
  background: linear-gradient(50deg, #00457C 0%, #00355F 55%, #BEBDBD 100%);
}

.title-text-section .entry-content {
  max-width: 72ch;
  font-size: 16px;
  line-height: 1.7;
  color: var(--sersys-text);
}

/* --------------------------------------------------------------
# Section rhythm — alternate silver panels by position
# (guard: never override an explicit bg_style from ACF — layouts that
# already carry a `rt-section--bg-*` modifier class are skipped;
# CTA layouts are skipped too: their inner panel carries its own
# full background, so the zebra only reads as orphan grey strips
# framing the blue box)
-------------------------------------------------------------- */
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]):not(.rt-section--cta):not(.rt-section--cta_split) {
  background: var(--sersys-silver-gradient-alt);
  padding: 40px 0;
}

/* The hero slider already sits on its own silver gradient — when the next
   section lands on an even index the two greys touch with no white
   breathing room. Neutralise the zebra on the section right after a hero.
   (Selector mirrors the zebra rule above so it ties its specificity and,
   coming later, wins the cascade.) */
.site-main > div.rt-section--hero + div.rt-section:nth-of-type(even):not([class*="--bg-"]):not(.rt-section--cta) {
  background: transparent;
  padding: 0;
}

.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .feature-one,
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .service-two,
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .client-carousel,
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .testimonial-three,
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .blog-three {
  background: transparent;
}

/* --------------------------------------------------------------
# Site-wide section-title signature
-------------------------------------------------------------- */
.sec-title__tagline {
  color: var(--ostech-base, #00457C);
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.sec-title__tagline::before {
  content: '';
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(50deg, #00457C 0%, #BEBDBD 100%);
  flex: none;
}

.sec-title__title {
  color: var(--ostech-base, #00457C);
  /* Vendor default is 40px (>=768px) — exceeds the 38px ceiling of the
     LOT 2 typographic scale pass, reading as a huge jump from the 14-16px
     menu / 16px body copy. Cap it site-wide. */
  font-size: clamp(24px, 2.4vw, 36px);
}

/* Keep the accent dot legible on brand-blue sections. The tagline/title
   text colour itself is already forced white by the vendor's own
   `.rt-section--bg-brand ... !important` rule (parent theme.css) — no need
   to repeat it here. */
.rt-section--bg-brand .sec-title__title {
  color: #fff;
}
.rt-section--bg-brand .sec-title__tagline::before {
  background: linear-gradient(50deg, #fff 0%, #BEBDBD 100%);
}

/* --------------------------------------------------------------
# Buttons — 50° gradient + lift
# (.ostech-btn--secondary keeps its own outline treatment above, and
# .product__item__link keeps its quiet catalog-card outline — both
# excluded here on purpose)
-------------------------------------------------------------- */
.ostech-btn:not(.ostech-btn--secondary):not(.product__item__link) {
  background: linear-gradient(50deg, #00457C 0%, #00355F 100%);
  color: var(--ostech-on-primary, #fff);
  box-shadow: 0 8px 18px -8px rgba(0, 69, 124, 0.5);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

/* Vendor wipes in --ostech-secondary via ::before/::after on hover; that
   token is ACF-mapped to SERSYS grey (light) elsewhere on this site, which
   would pair badly with the vendor's white hover text. Force the wipe to
   the CDVI dark blue so the swipe stays on-palette regardless of that
   mapping. */
.ostech-btn:not(.ostech-btn--secondary):not(.product__item__link)::before,
.ostech-btn:not(.ostech-btn--secondary):not(.product__item__link)::after {
  background-color: #00355F;
}

.ostech-btn:not(.ostech-btn--secondary):not(.product__item__link):hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 24px -8px rgba(0, 69, 124, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  .ostech-btn:not(.ostech-btn--secondary):not(.product__item__link),
  .ostech-btn:not(.ostech-btn--secondary):not(.product__item__link):hover {
    transform: none;
    transition: none;
  }
}

/* --------------------------------------------------------------
# Buttons on CDVI-blue split CTAs (.cta-split--brand)
#
# The vendor pairs both buttons in this layout with --ostech-secondary /
# --ostech-on-secondary, tokens mapped to SERSYS grey/dark here — dark text
# on a dark/blue fill. Repaint: white primary, ghost secondary.
-------------------------------------------------------------- */
.cta-split--brand .ostech-btn:not(.ostech-btn--secondary) {
  background: #fff;
  color: var(--ostech-base, #00457C);
  box-shadow: none;
}

.cta-split--brand .ostech-btn:not(.ostech-btn--secondary):hover {
  background: rgba(255, 255, 255, 0.88);
  color: var(--ostech-base, #00457C);
}

/* Neutralize the vendor's dark hover wipe (::before/::after, forced to
   #00355F above for the general case) — on this white button it would
   render the blue label unreadable at hover. */
.cta-split--brand .ostech-btn:not(.ostech-btn--secondary)::before,
.cta-split--brand .ostech-btn:not(.ostech-btn--secondary)::after {
  background-color: #fff;
}

.cta-split--brand .ostech-btn--secondary,
.cta-split--brand .ostech-btn--secondary:hover {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.65);
  color: #fff;
}

.cta-split--brand .ostech-btn--secondary:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

/* Title/paragraph on the CDVI-blue split CTA: same token confusion as the
   buttons above (--ostech-on-primary/--ostech-on-secondary mapped for a
   light beige vendor primary) reads as blue-on-blue on the deep CDVI blue
   fill. Force explicit white/near-white text. */
.cta-split--brand .cta-split__title {
  color: #fff;
}

.cta-split--brand .cta-split__text {
  color: rgba(255, 255, 255, 0.85);
}

/* --------------------------------------------------------------
# Inner-page headers — CDVI blue banner
# (vendor's only overlay is `.page-header::before`; title/breadcrumb sit
# in `.page-header .container`, already stacked above it via z-index: 10,
# and are already white via --ostech-white — no extra rule needed there)
-------------------------------------------------------------- */
.page-header::before {
  background: linear-gradient(50deg, rgba(0, 69, 124, 0.92) 0%, rgba(0, 69, 124, 0.72) 55%, rgba(0, 53, 95, 0.55) 100%);
}

/* --------------------------------------------------------------
# Cards — image zoom on hover
-------------------------------------------------------------- */
.feature-one__item__thumb {
  overflow: hidden;
}

.feature-one__item__thumb img {
  transition: transform 0.4s ease;
}

.feature-one__item:hover .feature-one__item__thumb img {
  transform: scale(1.05);
}

@media (prefers-reduced-motion: reduce) {
  .feature-one__item__thumb img { transition: none; }
  .feature-one__item:hover .feature-one__item__thumb img { transform: none; }
}

/* --------------------------------------------------------------
# Menu mobile — panneau blanc, à l'identique du header desktop
#
# Deux couches parentes peignent ce tiroir, et c'est la seconde qui décide :
#   1. cdvi-tmpl/assets/css/ostech.css — fond --ostech-secondary, texte,
#      filets, icônes et bouton de fermeture en --ostech-white ;
#   2. cdvi-tmpl/assets/css/theme.css (chargé APRÈS) — fond --ostech-base,
#      et `a.expanded` / `li.current > a` / le chevron en --ostech-on-primary.
# --ostech-base valant le bleu CDVI, le tiroir sortait en bleu plein : seul
# écran du site à ne pas suivre le header blanc, et contraire à la règle
# « pas de surfaces sombres » du guideline 2025.
#
# On repeint donc la surface en blanc, puis on rebascule en sombre TOUT ce que
# ces deux couches avaient éclairci pour le fond bleu (sinon : blanc sur
# blanc). Les sélecteurs ci-dessous égalent la spécificité du parent — c'est
# l'ordre de chargement (enfant après parent) qui les fait gagner.
-------------------------------------------------------------- */
.mobile-nav__content {
  background-color: #fff;
  /* Le tiroir se détachait du fond par sa couleur ; blanc sur blanc, il lui
     faut une ombre portée pour rester lisible comme surface distincte. */
  box-shadow: 0 0 40px rgba(36, 36, 36, 0.18);
}

.mobile-nav__close {
  color: var(--sersys-text);
}

.mobile-nav__content .main-menu__list li > a,
.mobile-nav__contact li,
.mobile-nav__social a {
  color: var(--sersys-text);
}

/* Filets de séparation : le vendor les tire en blanc à 10 % (invisibles sur
   blanc) — même valeur, encre inversée. */
.mobile-nav__content .main-menu__list ul,
.mobile-nav__content .main-menu__list li:not(:last-child) {
  border-color: rgba(36, 36, 36, 0.12);
}

/* Chevron des sous-menus : le parent le sert en --ostech-on-primary (blanc)
   sur fond transparent — invisible une fois le panneau blanc. Encre bleue,
   et pastille bleutée à l'état déplié pour marquer l'affordance. */
.mobile-nav__content .main-menu__list li a button {
  color: var(--ostech-base, #00457C);
}

.mobile-nav__content .main-menu__list li a button.expanded {
  background-color: rgba(0, 69, 124, 0.12);
  color: var(--ostech-base, #00457C);
}

/* Libellé de la rubrique dépliée : idem, blanc côté parent. */
.mobile-nav__content .main-menu__list li a.expanded {
  color: var(--ostech-base, #00457C);
}

/* Page courante : le parent la marque en blanc sur voile blanc à 14 % avec un
   liseré blanc — trois valeurs invisibles sur blanc. Même marquage, encre et
   voile bleus. */
.mobile-nav__content .main-menu__list li.current > a {
  color: var(--ostech-base, #00457C);
  background-color: rgba(0, 69, 124, 0.08);
  box-shadow: inset 3px 0 0 0 var(--ostech-base, #00457C);
}

/* Sélecteur de langue : la variante mobile héritait du traitement « sur fond
   bleu » (bordure et texte blancs) défini plus haut pour la topbar. */
.lang-switcher--mobile .lang-switcher__item a {
  border-color: rgba(0, 69, 124, 0.35);
  color: var(--ostech-base, #00457C);
}

.lang-switcher--mobile .lang-switcher__item a:hover {
  background: var(--ostech-base, #00457C);
  border-color: var(--ostech-base, #00457C);
  color: #fff;
}

/* Lockup SERSYS + endossement CDVI, aux mêmes dimensions qu'au header.
   Le markup ship width="155" sans cap CSS : le logo sortait en 96x101, plus
   du double du header. On borne donc par la HAUTEUR, comme le fait
   `.main-header__logo img` — c'est `width: auto` qui préserve le ratio (le
   cap en largeur seul laissait l'attribut width=155 piloter l'échelle).
   Le tiroir n'existe qu'en dessous de 992px : la référence est la taille que
   le header a à ces largeurs, soit 42px (SERSYS) et 34px (CDVI).
   `max-width: none` neutralise le `.woocommerce-page img { max-width: 100% }`
   de WooCommerce, comme au header. */
.mobile-nav__content .logo-box {
  margin-bottom: 24px;
  align-items: center;
}

.mobile-nav__content .logo-box a img {
  max-height: 42px;
  width: auto;
  max-width: none;
}

/* Même filet séparateur qu'au header (.main-header__logo__cdvi). */
.mobile-nav__content .logo-box .mobile-nav__logo__cdvi {
  height: 34px;
  width: auto;
  max-width: none;
  margin-left: 14px;
  padding-left: 14px;
  border-left: 1px solid rgba(0, 69, 124, 0.2);
}

/* Vendor fixes each row at height:46px (ostech.css .main-menu__list li > a):
   labels that wrap on two lines — the Solutions sectors at 390px — overflow
   their row and overlap the next one. Let rows grow instead. */
.mobile-nav__content .main-menu__list li > a {
  height: auto;
  min-height: 46px;
  padding-top: 8px;
  padding-bottom: 8px;
  line-height: 1.4;
}

/* --------------------------------------------------------------
# LOT 1 — Nav overflow on 13" laptops + search icon glued to "Contact"
#
# Vendor: .main-header--three .main-header__nav has margin-left only
# (no matching right-hand gap before .main-header__right); on ~1280-1440px
# viewports the flex row (logo + nav + right block) exceeds the container
# and .main-header__nav's own margin-right:auto collapses to 0, so the last
# menu item (Contact) touches .search-toggler. Give the search button its
# own left gap unconditionally, then shrink menu type/gaps + logo block in
# the squeezed 992-1599px band so everything fits with air to spare.
-------------------------------------------------------------- */
.main-header--three .search-toggler.main-header__right__info__item {
  margin-left: 18px;
}

@media (min-width: 992px) and (max-width: 1599px) {
  .main-header--three .main-menu .main-menu__list > li > a {
    font-size: 14px;
  }

  .main-header--three .main-menu .main-menu__list > li {
    padding-top: 20px;
    padding-bottom: 20px;
  }

  .main-header--three .main-menu .main-menu__list > li + li {
    /* 18px à l'origine (anti-overflow) ; le menu ne compte plus que 5 items,
       il reste >150px de marge avant le search-toggler à 1240px avec 32px. */
    margin-left: 32px;
  }

  /* Logo clear-space (Brand Guidelines p.6) still requires >=23px here —
     the 46px base logo size is unchanged in this band, only the menu
     shrinks, so the gap must stay at the base value (no more 10px). */
}

@media (min-width: 992px) and (max-width: 1399px) {
  /* Même spécificité 0,2,0 que la règle de base (parade WooCommerce). */
  .main-header .main-header__logo__cdvi {
    /* Pas plus bas : sous 32px la baseline « Security to Access » décroche. */
    height: 32px;
  }
}

/* Vendor default is a flat 16px at every width (no larger step above
   1600px) — cap it to 15px so it stays a hair below the 1280-1599 band's
   14px without matching the vendor's full 16px (LOT 2 typographic scale
   pass — the gap between menu (16) and body (16-17px via LOT 9) read as
   no hierarchy at all). */
@media (min-width: 1600px) {
  .main-header--three .main-menu .main-menu__list > li > a {
    font-size: 15px;
  }
}

/* --------------------------------------------------------------
# LOT 1bis — Header phone block clipped at the right edge
#
# The call block (a.topbar-one__right__call, fixed ~243px of icon + text)
# is the last item of the non-wrapping .main-header__inner flex row; when
# logo + menu + search don't leave it enough room it gets pushed past the
# viewport and clipped (measured right edge: 1280 at a 1280px viewport,
# 1779 at a 1600px viewport — the 1600 case is WORSE because the vendor
# menu type returns to 16px above 1599px). It only fully fits from ~1780px
# up. Fix: icon-only mode across the whole affected band — from 1231px
# (below that the vendor collapses the nav behind the burger and the block
# fits again) to 1799px. The tel: link is the <a> itself, so the round
# icon stays clickable; the text is sr-only-clipped (not display:none) so
# the link keeps its accessible name ("Appelez-nous 01 30 76 16 00").
# Topbar measured at 992/1100/1240/1280: never overflows — left untouched.
-------------------------------------------------------------- */
@media (min-width: 1231px) and (max-width: 1799px) {
  .main-header--three .main-header__right__call__content {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  /* Vendor pads 40px left for the icon+text pair; rebalance around the
     lone icon so it sits centred in the blue band. */
  .main-header--three .topbar-one__right__call {
    padding-left: 24px;
    padding-right: 6px;
  }
}

/* --------------------------------------------------------------
# LOT 2 — Inner-page banners too tall
#
# Vendor .page-header padding-top/bottom: 268/143 desktop, 250/140 <=991px,
# 200/100 <=767px. Excluded: .page-header--product, which already carries
# its own compact 68/43 padding for WooCommerce product pages.
-------------------------------------------------------------- */
.page-header:not(.page-header--product) {
  padding: 90px 0;
}

@media (max-width: 767px) {
  .page-header:not(.page-header--product) {
    padding: 60px 0;
  }
}

.page-header__title {
  font-size: clamp(26px, 2.6vw, 36px);
}

/* --------------------------------------------------------------
# LOT 3 — Inner-page "hero" flexible layout: double photo banner
#
# Inner pages already show a photo in .page-header above; the `hero`
# flexible layout (rt-section--hero > .main-slider-three) carries a SECOND
# full-bleed background image right under it, reading as two stacked
# banners — the client's #1 reported defect. Strip the photo, keep the
# content on the guideline silver panel.
-------------------------------------------------------------- */
.rt-section--hero .main-slider-three__bg {
  display: none;
}

.rt-section--hero .main-slider-three {
  background: var(--sersys-silver-gradient-alt);
}

.rt-section--hero .main-slider-three__item {
  padding: 96px 0 72px;
}

@media (max-width: 991px) {
  .rt-section--hero .main-slider-three__item {
    padding: 64px 0 48px;
  }
}

.rt-section--hero .main-slider-three__title {
  font-size: clamp(24px, 2.4vw, 34px);
}

.rt-section--hero .main-slider-three__title::after {
  content: '';
  display: block;
  width: 64px;
  height: 4px;
  margin-top: 16px;
  border-radius: 2px;
  background: linear-gradient(50deg, #00457C 0%, #00355F 55%, #BEBDBD 100%);
}

/* --------------------------------------------------------------
# LOT 4 — Fallback panel for sub-page cards with no image
#
# The `subpages_list` flexible layout's no-image branch
# (feature-one__item__thumb--placeholder) has NO vendor CSS at all —
# child override in template-parts/flexible/subpages_list.php swaps it
# for this branded panel (a CSS-only padlock mark, palette-only).
-------------------------------------------------------------- */
.feature-one__item__thumb--fallback {
  aspect-ratio: 3 / 2;
  background: var(--sersys-silver-gradient);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.feature-one__item__thumb--fallback::before {
  content: '';
  position: absolute;
  inset: -40% -20%;
  background: linear-gradient(50deg, rgba(0, 69, 124, 0.14) 0%, rgba(0, 69, 124, 0) 45%);
}

.sersys-thumb-fallback__mark {
  width: 56px;
  height: 56px;
  border: 3px solid rgba(0, 69, 124, 0.35);
  border-radius: 12px;
  position: relative;
}

.sersys-thumb-fallback__mark::before {
  content: '';
  position: absolute;
  top: -26px;
  left: 50%;
  transform: translateX(-50%);
  width: 34px;
  height: 44px;
  border: 3px solid rgba(0, 69, 124, 0.35);
  border-bottom: none;
  border-radius: 20px 20px 0 0;
}

/* --------------------------------------------------------------
# LOT 5 — "Méthodologie" carousel: text contrast + off-palette decoration
#
# The loop/autoplay/items-count fix for the broken carousel itself lives in
# the PHP override (template-parts/flexible/services.php), not here.
-------------------------------------------------------------- */
.service-two__item__content__text {
  color: rgba(255, 255, 255, 0.82);
}

/* Second, more severe manifestation of the same "broken carousel" report:
   .service-two__item__content is position:absolute, so when an item has no
   `image` sub-field (every /solutions/* "avantages" item on this site — the
   thumb markup is conditional in services.php) the parent .service-two__item
   has nothing left in normal flow and collapses to height:0 — the whole card
   renders invisible instead of just off-screen.

   This used to be patched with a blanket min-height:240px on
   .service-two__item, which fixed the collapse but then clipped the
   content itself: the absolutely-positioned block still sits pinned to
   `bottom:0`, so titles get cut at the top and body text gets cut at the
   bottom once the block's real height exceeds the floor. Fix the actual
   cause instead: for items with NO thumb, take the content out of
   absolute positioning so it drives the parent's height in normal flow.
   Items WITH a thumb (qui-sommes-nous) keep the vendor's absolute-over-
   image treatment untouched. */
.service-two__item--no-thumb .service-two__item__content {
  position: static;
  right: auto;
  padding: 24px;
}

/* Vendor pairs a near-black icon square with a base-blue glyph — both
   invisible-on-dark and off the blue card. White glyph on a translucent
   white circle instead. */
.service-two__item--no-thumb .service-two__item__content__icon {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 50%;
  width: 56px;
  min-width: 56px;
  max-width: 56px;
  height: 56px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.service-two__item--no-thumb .service-two__item__content__icon i {
  color: #fff;
  font-size: 24px;
}

/* Equal-height advantage tiles: stretch each owl cell and let the card
   fill it, so a shorter text no longer yields a shorter tile. */
.rt-section--services .owl-stage {
  display: flex;
}

.rt-section--services .owl-item {
  display: flex;
}

.rt-section--services .owl-item .service-two__item {
  width: 100%;
  height: 100%;
}

/* La tuile s'étire, mais le bloc bleu (__content, en flux normal pour les
   items --no-thumb) gardait sa hauteur naturelle : le remplir aussi. */
.rt-section--services .owl-item .service-two__item--no-thumb .service-two__item__content {
  height: 100%;
}

/* No CSS shape/pseudo-element carries the red/salmon accent seen behind
   the "méthodologie" cards on /qui-sommes-nous/ — ostech.css has no red
   hex, "salmon" or shape rule scoped to .service-two. The colour is baked
   directly into the uploaded step-icon rasters themselves
   (etude-et-conception-1.png, fabrication-et-vente-1.png, installation-1.png:
   a red circle + red glyph lines), which is site content, not theme CSS —
   out of scope to edit per the "never touch content" rule. Desaturate the
   icon on render instead so the off-palette red never reaches the page,
   without touching the uploaded file or any other imagery on the site. */
.service-two__item__thumb img {
  filter: grayscale(1);
}

/* --------------------------------------------------------------
# LOT 6 — CTA banner button unreadable (dark-blue-on-dark-blue)
#
# .cta-three__content resolves --ostech-base to the CDVI blue fill; its
# lone button is a plain .ostech-btn, which (see the buttons block above)
# also paints in CDVI blue — invisible against the matching background.
# Same white-primary / ghost-secondary treatment as .cta-split--brand.
-------------------------------------------------------------- */
.cta-three__content .ostech-btn:not(.ostech-btn--secondary) {
  background: #fff;
  color: var(--ostech-base, #00457C);
  box-shadow: none;
}

.cta-three__content .ostech-btn:not(.ostech-btn--secondary):hover {
  background: rgba(255, 255, 255, 0.88);
  color: var(--ostech-base, #00457C);
}

.cta-three__content .ostech-btn:not(.ostech-btn--secondary)::before,
.cta-three__content .ostech-btn:not(.ostech-btn--secondary)::after {
  background-color: #fff;
}

/* --------------------------------------------------------------
# LOT 7 — Bare bullet lists in editorial content
-------------------------------------------------------------- */
.entry-content ul:not([class]) {
  list-style: none;
  padding-left: 0;
  display: grid;
  gap: 10px;
}

.entry-content ul:not([class]) li {
  position: relative;
  padding-left: 30px;
}

.entry-content ul:not([class]) li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(0, 69, 124, 0.1);
}

.entry-content ul:not([class]) li::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 8px;
  width: 8px;
  height: 5px;
  border-left: 2px solid var(--ostech-base, #00457C);
  border-bottom: 2px solid var(--ostech-base, #00457C);
  transform: rotate(-45deg);
}

/* --------------------------------------------------------------
# LOT 8 — Contact page: info cards overlapping the form panel
#
# Vendor .contact-one__left carries margin-right:-30px, meant to cancel a
# Bootstrap gutter but on this build it reads as the info column
# encroaching on the form panel. Neutralize it and add an explicit gap;
# align the info cards to the top instead of stretching full height.
-------------------------------------------------------------- */
.contact-one__left {
  margin-right: 0;
}

/* column-gap removed: .col-lg-4 + .col-lg-8 already sum to exactly 100%
   of the row's flex-basis width (33.33% + 66.67%), so adding a 30px
   flex `column-gap` on top pushed the required row width past its
   container and forced the form column to wrap onto its own line below
   the info column at >=992px — the two columns rendered fully stacked
   instead of side by side (found while checking FIX D: this alone
   explained the imbalanced /contact/ layout). Bootstrap's own gutter
   (padding-based, cancelled at the row's outer edge by its negative
   margin) already spaces the two columns without needing an extra gap. */
.contact-one .row.gutter-y-30 {
  row-gap: 30px;
}

.contact-one__list {
  align-self: flex-start;
}

/* L'icône ronde (50×50, border-radius 50%) est un enfant flex de
   .contact-one__list__item : sans flex-shrink:0 elle se fait écraser en
   ovale dès que le texte du bloc est long (Adresse, Plan d'accès). */
.contact-one__list__icon {
  flex-shrink: 0;
}

/* 20px vendor trop massif face au reste de la page. */
.contact-one__list__action {
  font-size: 16px;
}

/* The WPForms title ("Contact Sersys") duplicates the section heading
   ("Parlons de votre projet") already shown just above it in
   .contact-one__top — scoped to this form only. */
.contact-one__form .wpforms-title {
  display: none;
}

/* --------------------------------------------------------------
# LOT 8bis — Contact page: form column half-empty at >=992px
#
# WPForms' own modern-theme CSS caps every field carrying its "medium"
# size (email, société, message — all default-sized in this form) to
# max-width:60% (.wpforms-container input.wpforms-field-medium, etc.),
# leaving the right ~40% of the col-lg-8 form column visibly empty.
# Let them use the full column width instead. Also close the vertical
# gap the vendor reserved for the WPForms title (padding-bottom:35px on
# .wpforms-head-container), which LOT 8 hides but whose spacing remained.
-------------------------------------------------------------- */
@media (min-width: 992px) {
  .contact-one__form .wpforms-field-medium {
    max-width: 100%;
  }

  .contact-one__right .sec-title {
    padding-bottom: 24px;
  }

  .contact-one__form .wpforms-head-container {
    padding-bottom: 0;
  }
}

/* --------------------------------------------------------------
# LOT 9 — Homepage hero: more presence
-------------------------------------------------------------- */
@media (min-width: 1200px) and (max-width: 1500px) {
  .main-slider-three--home .main-slider-three__item {
    padding-top: 200px;
    padding-bottom: 160px;
  }
}

.main-slider-three--home .main-slider-three__title::after {
  content: '';
  display: block;
  width: 88px;
  height: 5px;
  margin-top: 16px;
  border-radius: 2px;
  background: linear-gradient(50deg, #00457C 0%, #00355F 55%, #BEBDBD 100%);
}

.main-slider-three--home .main-slider-three__text {
  font-size: 16px;
  line-height: 1.7;
}

/* --------------------------------------------------------------
# LOT 10 — Text contrast on silver panels
#
# .feature-one__item__text and plain paragraphs inherit the vendor's light
# --ostech-text (#686A6F), too pale against the guideline silver panels
# (alternating .rt-section:nth-of-type(even) and .rt-section--bg-dark).
# Force the guideline dark text there; .sec-title__tagline is excluded on
# purpose (stays CDVI blue everywhere).
-------------------------------------------------------------- */
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) p:not(.sec-title__tagline),
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .feature-one__item__text,
.rt-section--bg-dark p:not(.sec-title__tagline),
.rt-section--bg-dark .feature-one__item__text {
  color: var(--sersys-text);
}

/* LOT 10 exception — the dark-text rule above must NEVER reach text that
   sits on a blue-filled component inside those same sections (its higher
   specificity was silently repainting them dark-on-blue). Every blue
   container keeps its light text. */
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .cta-split--brand .cta-split__text,
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .cta-split--brand .cta-split__text p,
.rt-section--bg-dark .cta-split--brand .cta-split__text,
.rt-section--bg-dark .cta-split--brand .cta-split__text p {
  color: rgba(255, 255, 255, 0.85);
}

/* Même exception pour les cartes features : le vendor passe la carte en bleu
   CDVI au survol, la description doit suivre en clair (le hover générique de
   la section "Feature cards" plus haut perd contre la spécificité LOT 10). */
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .feature-one__item:hover .feature-one__item__text,
.rt-section--bg-dark .feature-one__item:hover .feature-one__item__text {
  color: var(--ostech-on-primary, #fff);
}

.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) p.service-two__item__content__text,
.rt-section--bg-dark p.service-two__item__content__text {
  color: rgba(255, 255, 255, 0.82);
}

.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .cta-three__content p,
.rt-section--bg-dark .cta-three__content p,
.site-main > div.rt-section:nth-of-type(even):not([class*="--bg-"]) .project-three__item p,
.rt-section--bg-dark .project-three__item p {
  color: rgba(255, 255, 255, 0.9);
}

/* --------------------------------------------------------------
# LOT 11 — Catalog: product visuals at disparate scales + uneven cards
#
# Product photos are uploaded at whatever size the manufacturer supplied;
# the vendor only sets width:100%;height:auto on
# .product__item__img__item img, so a tall bloc-porte and a small
# accessory render at very different visual scales in the same grid.
# Give every image a fixed square box and letterbox it.
#
# Catch: .product__item__img__item is itself `display:flex;
# justify-content:center;align-items:center` in the vendor (a
# centre-without-stretching layout for photos smaller than the box). Its
# only child, the <a> wrapping the img, is therefore a flex item with the
# default flex-basis:auto — for any source image narrower than the box
# (every accessory/small-format photo here) that flex item shrinks to the
# image's own intrinsic width and never grows back out, so `width:100%`
# on the img resolves against that shrunk anchor instead of the visible
# box and the photo never fills it. Stretch the anchor to the box width
# so the img's percentage sizing has a container worth 100% of.
-------------------------------------------------------------- */
.product__item__img__item a {
  width: 100%;
}

.product__item__img__item img {
  aspect-ratio: 1 / 1;
  width: 100%;
  height: auto;
  object-fit: contain;
  background: #fff;
}

.product__item {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.product__item__content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

/* --------------------------------------------------------------
# LOT 12 — Card title "staircase" on same-row items
#
# .feature-one__item (subpages_list grid on /solutions/): plain block
# flow, title above thumb — a variable-length heading pushes the image
# down, so same-row thumbs misalign without a shared title zone.
# (Les piliers .about-two__feature sont traités dans le LOT About
# pillars : items grid étirés, texte collé au titre, pas de min-height.)
-------------------------------------------------------------- */
.feature-one__item__title {
  min-height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* --------------------------------------------------------------
# LOT 13 — Méthodologie carousel: icon circles cropped left/right
#
# Root cause is NOT the owl-stage clipping the track edges: measured at
# 1280px, every .service-two__item__thumb img box (with-thumb branch,
# vendor object-fit:cover) renders 100% inside its item — no overflow
# past the carousel bounds. The uploaded rasters themselves
# (etude-et-conception-1.png etc.) are tiny, near-square icons
# (~106x101px — see LOT 5 for why their baked-in colour is out of scope),
# stretched by `object-fit: cover` to fill a ~396x406px item box. Cover
# preserves the source aspect ratio and crops to fill — on a box taller
# than the source, that crop comes off the left/right, chopping the
# circle exactly as reported. Swap to `contain` so the whole icon shows
# (letterboxed) instead of being blown up and cropped; add wrap padding
# too so the track itself still gets breathing room from the section
# edges at first/last slide.
-------------------------------------------------------------- */
.service-two__item__thumb img {
  object-fit: contain;
}

/* Widened gutters: the vendor overlays .service-two__nav with inset:0 and
   only 20px of padding (parent theme.css), so the 50px round arrows land
   on the cards' text. Give the wrap real gutters and let the arrows live
   inside them, clear of the content at every viewport. */
.service-two__carousel-wrap {
  padding: 0 72px;
  box-sizing: border-box;
}

.service-two__nav {
  padding: 0;
}

@media (max-width: 575px) {
  .service-two__carousel-wrap {
    padding: 0 46px;
  }

  .service-two__nav__btn {
    width: 38px;
    height: 38px;
    font-size: 16px;
  }
}

/* --------------------------------------------------------------
# Homepage hero — responsive backgrounds + secondary CTA
#
# Both are fed by the child template-parts/homepage-slider.php override:
# each slide exposes its background size variants as custom properties
# (the parent inlined the full 1920px image for every viewport), and a
# second "Demander un devis" button rides next to the primary CTA.
# Scoped to --home so flexible-layout heroes keep the parent behaviour.
-------------------------------------------------------------- */
.main-slider-three--home .main-slider-three__bg {
  background-image: var(--sersys-hero-bg);
}

@media (max-width: 767px) {
  .main-slider-three--home .main-slider-three__bg {
    background-image: var(--sersys-hero-bg-sm, var(--sersys-hero-bg));
  }
}

@media (min-width: 768px) and (max-width: 1439px) {
  .main-slider-three--home .main-slider-three__bg {
    background-image: var(--sersys-hero-bg-md, var(--sersys-hero-bg));
  }
}

/* Style robintele (_components.scss) : pas de voile pleine largeur sur la
   photo — le scrim argenté ::before la rendait invisible. La lisibilité est
   portée par le voile clair du bloc contenu ci-dessous. Le filigrane
   triangles reste sur les panneaux argentés des pages internes. */
.main-slider-three--home .main-slider-three__bg::before {
  display: none;
}

/* Slide sans photo : on garde le panneau gradient argenté + triangles du
   guideline (le ::before générique plus haut) — seul le voile sur une vraie
   image est proscrit. */
.main-slider-three--home .main-slider-three__bg--no-image::before {
  display: block;
}

.main-slider-three--home .main-slider-three__content {
  background-color: rgba(var(--ostech-gray-rgb, 244, 245, 248), 0.75);
  padding: 25px 20px;
}

@media (min-width: 992px) {
  .main-slider-three--home .main-slider-three__content {
    padding: 35px 40px;
    max-width: 50vw;
  }
}

/* The secondary button reuses the existing .ostech-btn--secondary outline
   treatment (see the buttons block above) — only the layout is new here. */
.main-slider-three__link {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* ==============================================================
# QA design 16/07 — correctifs transverses (voir PLAN-AJUSTEMENTS-FRONT.md)
============================================================== */

/* The parent hides every <p> <br> under 576px (ostech.css:381-396) — meant
   for decorative headline breaks, but it concatenates real content lines
   (hotline hours on /support/, the publisher block on /mentions-legales/).
   Restore them inside the page content only; heading <br>s stay hidden. */
@media (max-width: 575px) {
  .site-main p br {
    display: inline;
  }
}

/* Feature cards — equal heights, thumbs pinned to the card bottom so the
   image row lines up whatever the title/text length. */
.feature-one__item {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.feature-one__item__thumb {
  margin-top: auto;
}

/* Product renders (features_grid) are cut-outs on white with wildly
   different aspect ratios — `cover` crops them into abstract close-ups.
   Show the whole product, letterboxed on white, inside the same 3:2 box.
   Sector-photo cards (subpages_list) keep the default cover crop. */
.rt-section--features_grid .feature-one__item__thumb {
  background: #fff;
}

.rt-section--features_grid .feature-one__item__thumb img {
  object-fit: contain;
  padding: 12px 16px;
}

/* Centre orphan cards on the last row of feature grids (3+1 / 3+2 rows
   previously left the stragglers glued to the left with a void beside). */
.feature-one .row {
  justify-content: center;
}

/* Blog archive cards — the mixed media (photos vs event banners) breaks
   the card rhythm; normalise every thumbnail to the same crop. */
.blog-card-two__image img {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
}

/* Page header (hero + breadcrumb) on mobile: long titles wrapped to three
   lines at the vendor size and blew the banner height up. */
@media (max-width: 575px) {
  .page-header__title {
    font-size: 26px;
    line-height: 1.25;
  }

  .ostech-breadcrumb {
    font-size: 12px;
  }
}

/* --------------------------------------------------------------
# QA design 16/07 — finitions mineures (2e passe)
-------------------------------------------------------------- */

/* Dots du carrousel services en mobile (activés par services.php sur les
   breakpoints 1-carte) — l'owl-theme vendor n'embarque aucun style ici. */
.service-two__carousel .owl-dots {
  text-align: center;
  margin-top: 18px;
}

.service-two__carousel .owl-dots .owl-dot span {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin: 0 5px;
  border-radius: 50%;
  background: #BEBDBD;
  transition: background 0.2s ease;
}

.service-two__carousel .owl-dots .owl-dot.active span {
  background: var(--ostech-base, #00457C);
}

/* Archive actualités : le vendor pose 120px de padding vertical
   (.blog-one--page, ostech.css) — un grand vide entre la pagination et le
   footer. On garde l'air en haut, on resserre le bas. */
.blog-one--page {
  padding-bottom: 40px;
}

/* Bande logos partenaires/certifications (home) : 80-120px de padding
   vendor + 40px de zébrage noyaient 4 petits logos dans le gris. */
.client-carousel {
  padding: 32px 0;
}

/* --------------------------------------------------------------
# LOT 14 — /support/ : vide entre Hotline et Documentation
#
# Séquence de layouts title_text -> about (unique à /support/ à date) :
# le padding-bottom du .title-text-section (48px) s'additionne au
# padding-top vendor du .about-two (160px), soit ~200px de blanc entre
# les deux textes. Resserrer uniquement quand les deux sections se
# suivent — les .about-two précédés d'un hero gardent leur respiration.
# NB : chaque layout est enveloppé par cdvi_render_flexible_content()
# dans un div.rt-section--<layout>, ce sont eux les siblings.
-------------------------------------------------------------- */
.rt-section--title_text + .rt-section--about .about-two {
  padding-top: 60px;
}

/* --------------------------------------------------------------
# LOT 15 — Cartes "avantages" (solutions) : typo surdimensionnée
#
# Le vendor calibre .service-two pour de grandes cartes-images
# (titre 24px, texte 16px/188%, icône 80px). Sur les tuiles
# "avantages" sans image des pages /solutions/* (4 par rangée,
# ~330px, Verdana très large), le titre mange la carte sur 2-3
# lignes et « Fonctionnement » déborde même du cadre : en flex
# (__top), le h3 refuse de rétrécir sous la largeur de son mot le
# plus long (min-width:auto). Scopé --no-thumb pour ne pas toucher
# le carrousel méthodologie avec images de /qui-sommes-nous/.
-------------------------------------------------------------- */
.service-two__item--no-thumb .service-two__item__content__title {
  font-size: 18px;
  line-height: 1.35;
  min-width: 0;
  overflow-wrap: break-word;
}

.service-two__item--no-thumb .service-two__item__content__text {
  font-size: 14px;
  line-height: 1.65;
}

.service-two__item--no-thumb .service-two__item__content__top {
  gap: 14px;
  margin-bottom: 14px;
}

.service-two__item--no-thumb .service-two__item__content__icon {
  width: 44px;
  min-width: 44px;
  max-width: 44px;
  height: 44px;
}

.service-two__item--no-thumb .service-two__item__content__icon i {
  font-size: 19px;
}

/* LOT 15 (suite) — passe DA :
   Flèches du carrousel : le vendor peint des disques gris translucides
   bordés blanc — quasi invisibles sur le fond gris clair de la
   section, seule affordance desktop (Owl ne rend aucun dot à ce
   breakpoint, config JS du parent). Blanc plein, glyphe bleu CDVI,
   ombre légère ; le hover bleu du vendor reste.
   (Pas de min-height d'alignement sous les titres : le texte reste collé
   au titre ; l'égalité de hauteur se fait au niveau des cartes, déjà
   étirées via .owl-stage flex + height:100% plus haut.) */
.service-two__nav__btn {
  background: #fff;
  color: var(--ostech-base, #00457C);
  border-color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}

.service-two__nav__btn:hover {
  color: #fff;
}

/* Dots mobiles : zone tactile élargie sans grossir le point. */
.service-two__carousel .owl-dots .owl-dot {
  padding: 8px 3px;
}

/* ============================================================
   Sidebar blog (articles) — harmonisation avec la sidebar catalogue
   (retours QA DA + front-end, 21/07)
   ============================================================ */

/* Mobile : le DOM met la sidebar en premier (single/home/archive) ;
   le contenu de l'article doit passer avant elle sous 992px. */
@media (max-width: 991.98px) {
  .blog-one .row > .col-lg-8 {
    order: -1;
  }
}

/* Focus clavier : le vendor annule le focus du champ recherche
   (box-shadow 0) et aucun lien de la sidebar n'a d'état visible. */
.product__sidebar__search input[type='text']:focus-visible,
.product__sidebar__search input[type='search']:focus-visible {
  outline: 2px solid var(--ostech-on-primary, #fff);
  outline-offset: -4px;
}
.product__categories ul li a:focus-visible,
.sidebar__tags a:focus-visible,
.sidebar__posts__title a:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 2px;
}

/* Hiérarchie des posts récents : le titre prime, la date (rendue
   après le titre par l'override child) redevient une métadonnée. */
.sidebar__posts__title {
  font-size: 15px;
  line-height: 1.35;
}
.sidebar__posts__meta,
.sidebar__posts__meta a {
  font-size: 13px;
}
.sidebar__posts__meta {
  margin-bottom: 0;
  margin-top: 6px;
}

/* Vignettes : radius Sersys, hover sobre (le vendor zoome à 130%
   avec rotation -15° + voile sombre — illisible à 70px). */
.sidebar__posts__image {
  border-radius: var(--sersys-radius);
}
.sidebar__posts__image::after {
  display: none;
}
.sidebar__posts__item:hover .sidebar__posts__image img {
  transform: scale(1.06);
}

/* Tags : chips cliquables en déclinaison du bleu de charte
   (le vendor les rend gris neutre, sans affordance). */
.sidebar__tags a {
  background: rgba(0, 69, 124, 0.06);
  color: var(--ostech-base, #00457C);
  border: 1px solid rgba(0, 69, 124, 0.25);
  border-radius: var(--sersys-radius);
  padding: 8px 14px;
}
.sidebar__tags a:hover {
  border-color: var(--ostech-base, #00457C);
}

/* Filet sous les titres de blocs : identique article/catalogue. */
.product__sidebar .product__categories__title {
  border-bottom: 1px solid var(--ostech-base, #00457C);
}

/* --------------------------------------------------------------
# Contact — carte des zones (template-contact.php)
#
# Carte statique 55 % à gauche, grille 2×2 des zones à droite ;
# empilé sous 992px (breakpoint lg de la grille vendor).
-------------------------------------------------------------- */
.contact-zones {
  padding-top: 60px;
  padding-bottom: 20px;
}

@media (min-width: 992px) {
  .contact-zones__row > .contact-zones__col--map {
    flex: 0 0 55%;
    max-width: 55%;
  }
  .contact-zones__row > .contact-zones__col--list {
    flex: 0 0 45%;
    max-width: 45%;
  }
}

.contact-zones__map {
  margin: 0;
}
.contact-zones__map--svg svg {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 auto;
}

/* Sous 992px la carte passe pleine largeur : la brider évite qu'un
   SVG soit étiré sur toute la largeur d'une tablette. */
@media (max-width: 991.98px) {
  .contact-zones__map--svg svg {
    max-width: 560px;
  }
}

.contact-zones__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

@media (max-width: 575.98px) {
  .contact-zones__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.contact-zones__zone {
  background: #fff;
  border: 1px solid rgba(0, 69, 124, 0.14);
  border-radius: var(--sersys-radius);
  box-shadow: var(--sersys-shadow);
  padding: 22px 20px;
}

.contact-zones__zone__title {
  color: var(--ostech-base, #00457C);
  font-size: 18px;
  line-height: 1.3;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ostech-base, #00457C);
}

.contact-zones__contact + .contact-zones__contact {
  margin-top: 14px;
}

.contact-zones__contact__role {
  font-weight: 700;
  font-size: 13px;
  line-height: 1.4;
  margin: 0 0 2px;
  color: var(--sersys-text, #242424);
}

.contact-zones__contact__line {
  font-size: 13px;
  line-height: 1.5;
  margin: 0;
  color: var(--sersys-text-soft, #5A5A64);
}

.contact-zones__contact__line a {
  color: var(--ostech-base, #00457C);
  word-break: break-word;
}
.contact-zones__contact__line a:hover,
.contact-zones__contact__line a:focus-visible {
  text-decoration: underline;
}
.contact-zones__contact__line a:focus-visible,
.contact-zones__zone__link a:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 2px;
}

/* La précision ("choix 1") est mise sur sa propre ligne : dans une colonne de
   ~200px elle repasse à la ligne toute seule et se lit comme un orphelin. */
.contact-zones__contact__note {
  display: block;
  color: var(--sersys-text-soft, #5A5A64);
}

/* Carte interactive (toggle Theme Options → Carte des secteurs) :
   survol/sélection → le secteur reste plein, le reste s'estompe, la fiche
   correspondante s'allume. L'opacité ne se bat pas avec les fills posés en
   attribut style par contact-zones.php. */
.contact-zones--interactive .contact-zones__map--svg path[data-sector] {
  cursor: pointer;
  transition: opacity 0.15s ease, filter 0.15s ease;
}
.contact-zones--interactive .contact-zones__map--svg path.cz-dim {
  opacity: 0.22;
}
/* Assombrit légèrement le secteur actif : nécessaire pour que le Grand Ouest
   (teinte la plus claire) se distingue aussi une fois le reste estompé. */
.contact-zones--interactive .contact-zones__map--svg path.cz-on {
  filter: brightness(0.9);
}
.contact-zones--interactive .contact-zones__zone {
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.contact-zones--interactive .contact-zones__zone.cz-active {
  border-color: var(--ostech-base, #00457C);
  box-shadow: 0 6px 18px rgba(0, 69, 124, 0.18);
}

.contact-zones__finder {
  margin-top: 18px;
}
.contact-zones__finder__label {
  display: block;
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 8px;
  color: var(--sersys-text, #242424);
}
.contact-zones__finder__select {
  font-family: inherit;
  font-size: 14px;
  padding: 9px 12px;
  min-width: 260px;
  max-width: 100%;
  border: 1px solid var(--ostech-secondary, #B0B0B8);
  border-radius: var(--sersys-radius);
  background: #fff;
  color: var(--sersys-text, #242424);
}
.contact-zones__finder__select:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 2px;
}
.contact-zones__finder__result {
  margin: 10px 0 0;
  min-height: 1.4em;
  font-size: 14px;
  font-weight: 700;
  color: var(--ostech-base, #00457C);
}

@media (prefers-reduced-motion: reduce) {
  .contact-zones--interactive .contact-zones__map--svg path[data-sector],
  .contact-zones--interactive .contact-zones__zone {
    transition: none;
  }
}

.contact-zones__zone__link {
  margin: 14px 0 0;
  font-size: 13px;
}
.contact-zones__zone__link a {
  color: var(--ostech-base, #00457C);
  text-decoration: underline;
}

/* ==========================================================================
   Réalisations (CPT) — archive + fiche
   Voir sersys/archive-realisation.php et single-realisation.php.
   ========================================================================== */

/* Chapeau : une ligne de contexte entre le bandeau et les filtres. */
.realisation-archive__lead {
  max-width: 640px;
  margin: 0 0 24px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--sersys-text-soft, #5A5A64);
}

/* --- Barre de filtres (Toutes / Sûreté / Sécurité) --- */
.realisation-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 40px;
}

.realisation-filter__btn {
  padding: 8px 22px;
  font-size: 14px;
  line-height: 1.4;
  border: 1px solid var(--ostech-base, #00457C);
  border-radius: 999px;
  background: transparent;
  color: var(--ostech-base, #00457C);
  cursor: pointer;
  transition: background-color .2s ease, color .2s ease;
}

.realisation-filter__btn:hover,
.realisation-filter__btn:focus-visible {
  background: var(--ostech-base, #00457C);
  color: #fff;
}

.realisation-filter__btn--active {
  background: var(--ostech-base, #00457C);
  color: #fff;
}

.realisation-filter__btn:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 2px;
}

/* --- Grille de cartes --- */
.realisation-card {
  height: 100%;
  overflow: hidden;
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .08);
  transition: transform .25s ease, box-shadow .25s ease;
}

/* Élévation au survol : la carte entière répond, pas seulement l'image. */
.realisation-card:hover,
.realisation-card:focus-within {
  transform: translateY(-4px);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .14);
}

/* Rejouer un léger fondu sur les cartes restantes après un filtrage
   (classe posée par le JS de l'archive). */
@keyframes sersys-realisation-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.realisation-item--in {
  animation: sersys-realisation-in .3s ease both;
}

@media (prefers-reduced-motion: reduce) {
  .realisation-item--in { animation: none; }
  .realisation-card,
  .realisation-card__image img { transition: none; }
}

.realisation-card__link {
  display: block;
  height: 100%;
  color: inherit;
  text-decoration: none;
}

.realisation-card__image {
  position: relative;
  overflow: hidden;
  /* Toutes les photos legacy n'ont pas le même ratio : on cadre pour que la
     grille reste régulière plutôt que de laisser des cartes dépareillées. */
  aspect-ratio: 391 / 240;
  background: var(--sersys-surface, #F2F4F7);
}

.realisation-card__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .4s ease;
}

.realisation-card__link:hover .realisation-card__image img,
.realisation-card__link:focus-visible .realisation-card__image img {
  transform: scale(1.05);
}

/* Pastille "lecture" sur les réalisations vidéo. Triangle en CSS : fa-play
   n'est pas dans le sous-ensemble FontAwesome du thème parent. */
.realisation-card__play {
  position: absolute;
  inset: 0;
  background: rgba(0, 69, 124, .35);
}

.realisation-card__play::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 56px;
  height: 56px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
}

.realisation-card__play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  /* Le triangle est optiquement décentré : on le décale d'un quart de sa
     largeur pour qu'il paraisse au milieu du disque. */
  transform: translate(-40%, -50%);
  border-style: solid;
  border-width: 11px 0 11px 18px;
  border-color: transparent transparent transparent var(--ostech-base, #00457C);
}

/* Chips de type sur l'image : même vocabulaire que les pills de filtre. */
.realisation-card__chips {
  position: absolute;
  top: 12px;
  left: 12px;
  display: flex;
  gap: 6px;
  z-index: 1;
}

.realisation-card__chip {
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ostech-base, #00457C);
  background: rgba(255, 255, 255, .92);
  border-radius: 999px;
}

.realisation-card__overlay {
  padding: 20px 24px 24px;
}

.realisation-card__title {
  margin: 0;
  font-size: 18px;
  line-height: 1.35;
  color: var(--ostech-black, #17181B);
  transition: color .2s ease;
}

.realisation-card__link:hover .realisation-card__title,
.realisation-card__link:focus-visible .realisation-card__title {
  color: var(--ostech-base, #00457C);
}

.realisation-card__link:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 3px;
}

.realisation-archive__empty {
  margin-top: 24px;
  font-weight: 600;
}

/* --- Fiche --- */

/* Le parent réserve 120px sous le bandeau : une fois le lien de retour placé
   dans ce vide, on resserre pour que le titre ne parte pas trop bas. */
.realisation-single {
  padding-top: 48px;
}

.realisation-details__back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 28px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ostech-base, #00457C);
  text-decoration: none;
}

.realisation-details__back:hover,
.realisation-details__back:focus-visible {
  color: var(--ostech-black, #17181B);
  text-decoration: underline;
}

.realisation-details__back:focus-visible {
  outline: 2px solid var(--ostech-base, #00457C);
  outline-offset: 3px;
}

.realisation-details__back i {
  font-size: 16px;
  line-height: 1;
}

.realisation-details__types {
  margin: 0 0 6px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ostech-base, #00457C);
}

.realisation-details__client {
  margin: 6px 0 0;
  font-weight: 600;
  color: var(--sersys-text-soft, #5A5A64);
}

.realisation-details__content {
  margin: 24px 0 32px;
}

/* Ratio 16/9 tenu sans JS : l'iframe oEmbed arrive avec ses width/height. */
.realisation-details__video__frame {
  position: relative;
  aspect-ratio: 16 / 9;
}

.realisation-details__video__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.realisation-details__gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
}

.realisation-details__gallery__item,
.realisation-details__image {
  margin: 0;
}

/* Image seule : ne JAMAIS agrandir au-delà de la taille native (les photos
   legacy sont parfois petites — 446px de large — et un portrait étiré pleine
   colonne devenait flou et haut de deux écrans), et plafonner la hauteur. */
.realisation-details__image {
  text-align: center;
}

.realisation-details__image img {
  max-width: 100%;
  width: auto;
  height: auto;
  max-height: min(70vh, 640px);
  border-radius: 6px;
}

/* Les photos legacy mélangent portraits (portes) et paysages : hauteur
   uniforme + `contain` pour garder des lignes régulières SANS recadrer une
   porte en deux. L'original reste accessible au clic. */
.realisation-details__gallery__item img {
  width: 100%;
  height: 280px;
  object-fit: contain;
  border-radius: 6px;
  background: var(--sersys-surface, #F2F4F7);
}

.realisation-details__gallery__item figcaption,
.realisation-details__image figcaption {
  margin-top: 8px;
  font-size: 13px;
  color: var(--sersys-text-soft, #5A5A64);
}

.realisation-details__footer {
  margin-top: 40px;
}
