/* ============================================================
   DAVICOM . page d'accueil v5
   REGLE DE CONTENU : tout le texte visible vient mot pour mot du
   site en production (extraction du 2026-08-14, content/pages/).
   DIRECTION VISUELLE, fixee par LC le 2026-08-14 :
     . plus aucune image enfermee dans une boite. Les produits sont
       detoures et flottent, poses par leur ombre.
     . les photos habillent : cretes de montagne tres pales sous les
       sections claires, sommets et ciel fondus dans les bandes
       sombres.
     . les divisions de section sont colorees et animees : bandes
       profondes ou l'image est melangee au fond et ou l'onde de la
       marque continue de courir.
   Mouvement etudie sur 21st.dev (Motion Footer 11714, Dynamic Wave
   Canvas 2517, Testimonials Marquee 19852, Vertical Cut Reveal
   18595) puis reecrit en vanilla : pas de React, pas de GSAP, pas
   de build. Environ 200 lignes de JS, degradation propre sans JS.
   ============================================================ */

@font-face{font-family:Raleway;font-style:normal;font-weight:400 700;font-display:swap;
  src:url(../fonts/raleway-400-700-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2122,U+2212}
@font-face{font-family:Raleway;font-style:normal;font-weight:400 700;font-display:swap;
  src:url(../fonts/raleway-400-700-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+1E00-1E9F,U+2020,U+20A0-20AB,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Roboto;font-style:normal;font-weight:300 700;font-display:swap;
  src:url(../fonts/roboto-300-700-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2122,U+2212}
@font-face{font-family:Roboto;font-style:normal;font-weight:300 700;font-display:swap;
  src:url(../fonts/roboto-300-700-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+1E00-1E9F,U+2020,U+20A0-20AB,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/ibm-plex-mono-400-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2122,U+2212}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;font-display:swap;
  src:url(../fonts/ibm-plex-mono-600-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2122,U+2212}
:root{
  /* hauteur du gabarit de la nav flottante : 18 (padding haut) + 68 (ilot) + 6 (bas).
     Le hero remonte de cette valeur et la reprend en padding, sinon la nav laisse
     une bande blanche au-dessus du degrade (bug vu par LC le 2026-08-15). */
  --nav-h:92px;
  --deepest:#002a3c; --navy:#003a52; --primary:#005b7d; --mid:#007aaa;
  /* Le survol d'un bouton plein va vers le FONCE. Le libelle blanc y passe de
     7,5:1 a 9,7:1 ; vers --mid il tomberait a 4,8:1, soit palir juste au moment
     ou on le vise. Regle posee par LC le 2026-08-16.
     🔴 Le jeton etait UTILISE par les 127 maquettes et DEFINI par aucune :
     `background:var(--primary-hover)` sans valeur est invalide au calcul, donc
     le fond retombait a `transparent` et le bouton blanc sur blanc disparaissait
     au survol. Constate par LC le 2026-08-20. */
  --primary-hover:#004a66;
  --signal:#00a8e0; --sky:#50b4dc; --pale:#bfe0ef;
  --white:#fff; --off-white:#f8fafb; --panel:#f0f4f7; --inset:#f3f6f9;
  --border:#dde6ec; --text:#1a2832; --muted:#5a7080;
  --deep-field:linear-gradient(155deg,#002a3c 0%,#003a52 48%,#00506e 100%);

  --font-display:Raleway,"Helvetica Neue",Arial,sans-serif;
  --font-body:Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-tech:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  --r-btn:10px; --r-bub:7px; --r-nav:18px; --r-tag:8px; --r-md:16px; --r-lg:22px;

  --amb-1:0 2px 6px rgba(0,42,60,.05);
  --amb-2:0 18px 40px -18px rgba(0,42,60,.16), 0 4px 12px -6px rgba(0,42,60,.08);
  --amb-3:0 40px 90px -28px rgba(0,42,60,.24), 0 10px 28px -12px rgba(0,42,60,.10);
  --amb-4:0 60px 140px -40px rgba(0,42,60,.32), 0 16px 40px -16px rgba(0,42,60,.12);
  --hairline:inset 0 0 0 1px rgba(0,42,60,.07);
  --gloss:inset 0 1px 1px rgba(255,255,255,.9);
  --focus:0 0 0 3px rgba(0,168,224,.34);
  /* l'ombre qui pose un objet detoure sans l'enfermer */
  --lift:drop-shadow(0 26px 34px rgba(0,42,60,.18)) drop-shadow(0 6px 10px rgba(0,42,60,.10));
  --lift-lg:drop-shadow(0 44px 58px rgba(0,42,60,.22)) drop-shadow(0 10px 16px rgba(0,42,60,.10));

  --ease:cubic-bezier(.32,.72,0,1);
  --t-fast:260ms; --t-base:460ms; --t-slow:820ms;

  --gut:clamp(20px,4vw,40px);
  --sec:clamp(84px,9.5vw,148px);
  --container:1240px;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--white);color:var(--text);
  font:400 17px/1.65 var(--font-body);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden}
img{max-width:100%;height:auto;display:block}
a{color:var(--primary);text-decoration:none}
:focus-visible{outline:none;box-shadow:var(--focus);border-radius:var(--r-btn)}
body::after{content:"";position:fixed;inset:0;z-index:60;pointer-events:none;opacity:.026;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}
h1,h2,h3,h4{font-family:var(--font-display);font-weight:600;color:var(--deepest);margin:0}
h1{font-size:clamp(2rem,3.6vw,3.25rem);line-height:1.05;letter-spacing:-.032em}
h2{font-size:clamp(1.875rem,3.3vw,3rem);line-height:1.06;letter-spacing:-.028em}
h3{font-size:clamp(1.1875rem,1.45vw,1.4375rem);line-height:1.22;letter-spacing:-.015em}
p{margin:0}
.wrap{width:min(100% - 2*var(--gut),var(--container));margin-inline:auto;position:relative;z-index:2}
.sec{padding-block:var(--sec);position:relative}
.stack>*+*{margin-top:var(--gut)}
.lede{font-size:clamp(1.0625rem,1.1vw,1.25rem);line-height:1.62;color:var(--muted);max-width:60ch}
.gauge{position:fixed;top:0;left:0;right:0;height:2px;z-index:70;pointer-events:none;
  background:linear-gradient(90deg,var(--primary),var(--signal));
  transform:scaleX(0);transform-origin:0 50%}
@supports (animation-timeline:scroll()){
  .gauge{animation:gauge linear both;animation-timeline:scroll(root)}
}
@keyframes gauge{to{transform:scaleX(1)}}
/* ---------- voix technique ---------- */
.mono{font-family:var(--font-tech);font-weight:600;font-size:11px;line-height:1;
  letter-spacing:.19em;text-transform:uppercase;color:var(--primary)}
.ref{display:flex;align-items:center;gap:14px;margin-bottom:26px}
.ref .dot{width:9px;height:9px;border-radius:2px;background:var(--signal);flex:none;
  box-shadow:0 0 0 5px rgba(0,168,224,.14)}
.ref .n{font-family:var(--font-tech);font-weight:600;font-size:15px;letter-spacing:.04em;
  color:var(--primary)}
.ref .rule{flex:0 0 auto;width:clamp(40px,6vw,86px);height:2px;border-radius:2px;
  background:var(--signal);opacity:.85}
.ref .lbl{font-family:var(--font-tech);font-weight:600;font-size:12px;letter-spacing:.19em;
  text-transform:uppercase;color:var(--primary)}
.on-dark .ref .n,.on-dark .ref .lbl{color:var(--sky)}
/* L'eyebrow du hero, degrade de badge a etiquette (LC, 2026-08-20 : « une
   grosse signature de Claude »). Plus de pastille teintee, plus de cadre, plus
   de point lumineux : un trait vertical cyan et un libelle. Le traque tombe de
   .17em a .1em, parce qu'un interlettrage large en capitales EST la signature.
   Le libelle reste, il porte une vraie metadonnee (« Davicom CORTEX Series »). */
.tag{display:inline-flex;align-items:center;gap:12px;padding:0;
  border-radius:0;background:none;box-shadow:none;white-space:nowrap;
  font:600 12px/1 var(--font-tech);letter-spacing:.1em;text-transform:uppercase;
  color:var(--primary)}
.tag i{font-style:normal;width:2px;height:15px;border-radius:1px;background:var(--signal)}
/* ---------- l'onde vivante ---------- */
.wv{display:block;width:100%;height:auto;overflow:visible}
.wv-sweep{opacity:0}
@media (prefers-reduced-motion:no-preference){
  .wv-sweep{opacity:1}
  .wv-sweep .band{animation:sweep 7s var(--ease) infinite}
}
@keyframes sweep{0%{transform:translateX(-520px)}62%{transform:translateX(1720px)}
  100%{transform:translateX(1720px)}}
/* ============================================================
   LES DECORS
   . la crete : une photo de montagne detouree, tres pale, posee
     sous une section claire. Elle habille sans rien enfermer.
   . la bande profonde : une division de section coloree ou la
     photo est melangee au fond plutot que collee dessus, et ou
     l'onde continue de courir.
   ============================================================ */
.ridge{position:absolute;left:0;right:0;bottom:0;z-index:0;pointer-events:none;
  opacity:.34;-webkit-mask-image:linear-gradient(180deg,transparent,#000 55%);
  mask-image:linear-gradient(180deg,transparent,#000 55%)}
.ridge img{width:100%}
.ridge-soft{opacity:.22}
.dark{position:relative;overflow:hidden;background:var(--deep-field);color:rgba(255,255,255,.78)}
.dark h2,.dark h3,.dark h4{color:#fff}
.dark .lede{color:rgba(255,255,255,.76)}
.dark .photo{position:absolute;inset:0;z-index:0;background-size:cover;
  background-position:72% 30%;opacity:.5;mix-blend-mode:luminosity;filter:saturate(.5)}
.dark .veil{position:absolute;inset:0;z-index:0;background:
  linear-gradient(180deg,rgba(0,32,46,.86) 0%,rgba(0,42,60,.62) 42%,rgba(0,32,46,.92) 100%)}
.dark .glow{position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(58% 84% at 82% 12%,rgba(0,168,224,.3),transparent 62%)}
.dark .flow{position:absolute;left:-6%;right:-6%;bottom:-14%;z-index:1;opacity:.55;
  pointer-events:none}
/* le reseau synaptique vivant (21st.dev InteractiveSynapseNetwork, porte en vanilla) */
.synapse{position:absolute;inset:0;z-index:1;pointer-events:none}
/* ---------- decors legers, une parcimonie de fond ----------
   Chaque section claire recoit UN decor discret, jamais le meme que sa
   voisine : lueur radiale, grille d'atelier ou crete. Le blanc reste la
   matiere, le decor est un souffle. */
.bg-glow::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(44% 54% at 84% 14%,rgba(0,168,224,.09),transparent 68%),
    radial-gradient(40% 50% at 4% 88%,rgba(191,224,239,.26),transparent 66%)}
.bg-glow-b::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(44% 54% at 10% 16%,rgba(0,168,224,.08),transparent 68%),
    radial-gradient(42% 52% at 94% 82%,rgba(191,224,239,.28),transparent 66%)}
/* ---------- navigation ---------- */
.nav-shell{position:sticky;top:0;z-index:50;padding-top:18px;padding-bottom:6px;
  pointer-events:none}
.nav{pointer-events:auto;isolation:isolate;position:relative;
  display:flex;align-items:center;gap:clamp(14px,2vw,30px);
  padding:9px 9px 9px 20px;border-radius:var(--r-nav);transform-origin:50% 0}
.nav::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  background:rgba(255,255,255,.74);
  backdrop-filter:saturate(180%) blur(20px);-webkit-backdrop-filter:saturate(180%) blur(20px);
  box-shadow:var(--amb-2),var(--hairline),var(--gloss);opacity:.62}
.nav .brand img{height:34px;width:auto}
.nav-links{display:flex;gap:clamp(14px,1.7vw,26px);margin-left:auto;align-items:center}
.nav-links>a,.has-menu>a{font:500 14px/1 var(--font-body);color:var(--text);white-space:nowrap;
  padding:9px 2px;position:relative}
.has-menu>a::after,.nav-links>a::after{content:"";position:absolute;left:0;right:0;bottom:2px;height:2px;
  border-radius:2px;background:var(--signal);transform:scaleX(0);transform-origin:left;
  transition:transform var(--t-base) var(--ease)}
.nav-links>a:hover::after,.nav-links>a[aria-current]::after,.has-menu>a:hover::after,.has-menu>a[aria-current]::after{transform:scaleX(1)}
.lang{display:flex;align-items:center;font:600 12px/1 var(--font-tech);letter-spacing:.1em;
  color:var(--muted)}
.lang a{color:inherit}
.lang a[aria-current]{color:var(--deepest);text-decoration:underline;text-decoration-color:var(--mid);text-decoration-thickness:2px;text-underline-offset:6px}
.lang a:hover{color:var(--primary-hover)}
.lang i{font-style:normal;margin-inline:7px;color:rgba(0,42,60,.22)}
@media (max-width:1080px){.nav-links>.has-menu{display:none}}
/* ---------- menus deroulants : l'arborescence du site ----------
   Panneaux en verre sous l'ilot, ouverts au survol ET au focus
   clavier (focus-within). CSS pur, aucun JS. Les intitules viennent
   mot pour mot de la navigation du site en production. */
.has-menu{position:relative}
.has-menu>a{display:inline-flex;align-items:center;gap:6px}
.has-menu .car{width:11px;height:11px;stroke:currentColor;stroke-width:1.8;fill:none;
  stroke-linecap:round;stroke-linejoin:round;opacity:.55;
  transition:transform var(--t-base) var(--ease)}
.has-menu:hover .car,.has-menu:focus-within .car{transform:rotate(180deg)}
.menu{display:block;position:absolute;top:100%;left:50%;transform:translateX(-50%);
  padding-top:14px;opacity:0;pointer-events:none;z-index:60;
  transition:opacity var(--t-fast) var(--ease)}
.has-menu:hover .menu,.has-menu:focus-within .menu{opacity:1;pointer-events:auto}
.menu-in{display:block;min-width:250px;border-radius:var(--r-md);padding:10px;
  background:rgba(255,255,255,.92);
  backdrop-filter:saturate(180%) blur(20px);-webkit-backdrop-filter:saturate(180%) blur(20px);
  box-shadow:var(--amb-3),var(--hairline),var(--gloss);
  transform:translateY(6px);transition:transform var(--t-base) var(--ease)}
.menu-h{display:block;margin:10px 12px 4px;font:600 9.5px/1 var(--font-tech);
  letter-spacing:.19em;text-transform:uppercase;color:var(--muted)}
.menu-in>.menu-h:first-child{margin-top:4px}
.menu-sub{padding-left:26px!important;position:relative}
/* le compte de references, discret, aligne a droite de l'entree */
.menu-n{font-style:normal;font-size:10.5px;color:var(--muted);margin-left:6px}
.menu a:hover .menu-n{color:var(--primary)}
.menu-sub::before{content:"";position:absolute;left:14px;top:50%;width:6px;height:1px;
  background:var(--border)}
.has-menu:hover .menu-in,.has-menu:focus-within .menu-in{transform:none}
.menu-in a{display:block;padding:9px 12px;border-radius:8px;white-space:nowrap;
  font:500 13.5px/1.3 var(--font-body);color:var(--text);position:relative;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.menu-in a:hover{background:rgba(0,91,125,.06);color:var(--primary)}
/* Les animations de connexion des sous-items, reprises du bloc « Explore Field
   Applications » de l'accueil (LC, 2026-08-21) : la meme barre cyan qui se
   deploie, les memes courbes. Le tiret des sous-items s'etire et s'allume. */
.menu-in a::after{content:"";position:absolute;left:2px;top:50%;width:3px;height:14px;
  border-radius:2px;background:var(--signal);transform:translateY(-50%) scaleY(0);
  transform-origin:50% 0;transition:transform var(--t-base) var(--ease)}
.menu-in a:hover::after{transform:translateY(-50%) scaleY(1)}
.menu-sub::after{display:none}
.menu-sub::before{transition:width var(--t-base) var(--ease),
  background var(--t-fast) var(--ease)}
.menu-in a.menu-sub:hover::before{width:16px;background:var(--signal)}
/* Le menu Produits a QUATRE colonnes (la generique en a deux : trois blocs y
   tombaient en 2+1, Services echouait sous les RTUs au lieu d'etre a droite). */
.menu-cols-p{grid-template-columns:repeat(4,minmax(0,max-content));gap:0 18px}
.menu-in a[aria-current]{color:var(--primary)}
.menu-in a[aria-current]::before{content:"";position:absolute;left:2px;top:50%;
  transform:translateY(-50%);width:3px;height:14px;border-radius:2px;background:var(--signal)}
.menu-k{display:block;padding:10px 12px 5px;
  font:600 9.5px/1 var(--font-tech);letter-spacing:.17em;text-transform:uppercase;
  color:var(--primary)}
.menu-cols{display:grid;grid-template-columns:1fr 1fr;gap:0 10px}
.menu-cols>span{display:block}
.menu-wide .menu-in{min-width:520px}
@supports (animation-timeline:scroll()){
  @media (prefers-reduced-motion:no-preference){
    .nav{animation:nav-tighten linear both;animation-timeline:scroll(root);animation-range:0 180px}
    .nav::before{animation:nav-glass linear both;animation-timeline:scroll(root);
      animation-range:0 180px}
  }
}
@keyframes nav-tighten{from{transform:none}to{transform:translateY(-5px) scale(.972)}}
@keyframes nav-glass{from{opacity:.62}to{opacity:1}}
/* ---------- boutons ---------- */
.btn{display:inline-flex;align-items:center;gap:12px;padding:9px 9px 9px 22px;
  border-radius:var(--r-btn);background:var(--primary);color:var(--white);border:0;cursor:pointer;
  font:600 14px/1 var(--font-body);letter-spacing:.01em;white-space:nowrap;
  box-shadow:var(--amb-2);
  transition:background var(--t-fast) var(--ease),box-shadow var(--t-base) var(--ease),
             transform var(--t-fast) var(--ease)}
.btn .bub{width:32px;height:32px;flex:none;border-radius:var(--r-bub);display:grid;
  place-items:center;background:rgba(255,255,255,.16);
  transition:transform var(--t-base) var(--ease),background var(--t-fast) var(--ease)}
.btn .bub svg{width:15px;height:15px;stroke:currentColor;stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.btn:hover{background:var(--primary-hover);color:var(--white);text-decoration:none;
  box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.5);transform:translateY(-2px)}
.btn:hover .bub{transform:translate(3px,-1px) scale(1.06);background:rgba(0,168,224,.34)}
.btn:active{transform:translateY(0) scale(.98)}
.btn-quiet{background:var(--white);color:var(--deepest);box-shadow:var(--amb-1),var(--hairline)}
.btn-quiet .bub{background:rgba(0,42,60,.055)}
.btn-quiet:hover{background:var(--white);color:var(--deepest);text-decoration:none;box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,91,125,.28)}
.btn-quiet:hover .bub{background:rgba(0,42,60,.10)}
.btn-lg{padding:11px 11px 11px 28px;font-size:15px}
.btn-lg .bub{width:38px;height:38px}
.btn-lg .bub svg{width:16px;height:16px}
.dark .btn-ghost{background:rgba(255,255,255,.12);color:#fff;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.28)}
.dark .btn-ghost:hover{background:rgba(255,255,255,.18);color:#fff;text-decoration:none}
.tlink{display:inline-flex;align-items:center;gap:9px;font:600 14px/1 var(--font-body);
  color:var(--primary)}
.tlink .bub{width:26px;height:26px;border-radius:6px;display:grid;place-items:center;
  background:rgba(0,91,125,.08);
  transition:transform var(--t-base) var(--ease),background var(--t-fast) var(--ease)}
.tlink .bub svg{width:12px;height:12px;stroke:currentColor;stroke-width:1.8;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.tlink:hover .bub{transform:translate(3px,-1px);background:rgba(0,91,125,.14)}
.dark .tlink{color:#fff}
.dark .tlink .bub{background:rgba(255,255,255,.14)}
.dark .tlink:hover .bub{background:rgba(0,168,224,.42)}
/* ---------- hero ---------- */
.hero{position:relative;overflow:hidden;
  margin-top:calc(-1 * var(--nav-h));
  padding-block:calc(var(--nav-h) + clamp(44px,5.6vw,84px)) clamp(60px,7vw,110px)}
.hero::before{content:"";position:absolute;inset:-24% -10% 6% -10%;pointer-events:none;z-index:0;
  background:
    radial-gradient(46% 52% at 78% 24%,rgba(0,168,224,.16),transparent 68%),
    radial-gradient(40% 46% at 6% 78%,rgba(0,91,125,.08),transparent 66%),
    radial-gradient(62% 40% at 50% 0%,rgba(191,224,239,.30),transparent 70%);
  filter:blur(6px)}
.hero-wave{position:absolute;left:-6%;right:-6%;top:16%;z-index:0;opacity:.5;pointer-events:none;
  -webkit-mask-image:radial-gradient(74% 92% at 74% 40%,#000 22%,transparent 74%);
  mask-image:radial-gradient(74% 92% at 74% 40%,#000 22%,transparent 74%)}
.mast{max-width:min(100%,1180px)}
.mast h1{margin-top:clamp(20px,2.2vw,32px)}
.mast h1 em{font-style:normal;
  background:linear-gradient(94deg,var(--deepest) 0%,var(--primary) 44%,var(--mid) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.lines .ln{display:block;overflow:hidden;padding-block:.08em;margin-block:-.08em}
@media (prefers-reduced-motion:no-preference){
  .lines .ln>span{display:block;animation:line-up 900ms var(--ease) both;
    animation-delay:calc(var(--i,0) * 120ms + 80ms)}
  .hero-say{animation:soft-in 900ms var(--ease) 430ms both}
  .hero-shot{animation:soft-in 1200ms var(--ease) 300ms both}
}
@keyframes line-up{from{transform:translateY(112%)}to{transform:none}}
@keyframes soft-in{from{opacity:0;transform:translateY(18px)}
                   to{opacity:1;transform:none}}
.hero-grid{display:grid;gap:clamp(24px,3vw,52px);align-items:center;
  margin-top:clamp(24px,2.6vw,38px);grid-template-columns:minmax(0,.96fr) minmax(0,1.04fr)}
@media (max-width:960px){.hero-grid{grid-template-columns:1fr}}
.hero-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:clamp(24px,2.6vw,34px)}
/* le montage flotte : aucune boite, seulement une ombre qui le pose */
.hero-shot img{width:100%;filter:var(--lift-lg)}
.hero-stamp{margin-top:16px;font:400 10px/1 var(--font-tech);letter-spacing:.19em;
  text-transform:uppercase;color:rgba(0,42,60,.36);text-align:center}
/* ---------- bande de preuve, division profonde ---------- */
.proof{padding-block:clamp(52px,6vw,92px)}
.proof-line{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px 30px}
.proof-line b{font:600 11px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--sky)}
.proof p{color:rgba(255,255,255,.8);font-size:clamp(1.0625rem,1.15vw,1.25rem);line-height:1.6;
  max-width:70ch;margin-top:18px}
.proof p strong{color:#fff;font-weight:600}
.names{display:flex;flex-wrap:wrap;gap:12px 30px;margin-top:26px}
.names span{font-family:var(--font-display);font-weight:600;font-size:17px;color:#fff;
  opacity:.92}
.count{display:flex;align-items:baseline;gap:10px;margin-left:auto}
.count .v{font-family:var(--font-display);font-weight:600;font-size:clamp(34px,3.4vw,46px);
  line-height:1;letter-spacing:-.03em;color:#fff}
.count .u{font:600 10px/1.4 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--sky);white-space:nowrap}
/* ---------- les RTU : tuiles visuelles aux zones normees ----------
   Regle de LC : les tuiles ont leur place ICI (les produits), et deux
   tuiles cote a cote partagent EXACTEMENT les memes proportions de
   zone image et de zone texte. La zone image est un ratio fixe, la
   zone texte une structure fixe : h3, une ligne, specs, lien au fond. */
.lead-tile{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  margin-top:clamp(30px,3.4vw,46px);border-radius:var(--r-lg);overflow:hidden;
  background:var(--white);box-shadow:var(--hairline),var(--amb-2);
  transition:box-shadow var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
.lead-tile:hover{transform:translateY(-4px);box-shadow:var(--hairline),var(--amb-3)}
@media (max-width:900px){.lead-tile{grid-template-columns:1fr}}
.lead-tile .pic{display:grid;place-items:center;aspect-ratio:16/9;
  background:linear-gradient(158deg,#f7fafc,#e9f0f5);padding:clamp(26px,3vw,48px)}
@media (max-width:900px){.lead-tile .pic{aspect-ratio:16/8}}
.lead-tile .pic img{max-width:min(100%,520px);max-height:100%;width:auto;object-fit:contain;
  filter:var(--lift);transition:transform var(--t-slow) var(--ease)}
.lead-tile:hover .pic img{transform:scale(1.03)}
.lead-tile .txt{padding:clamp(26px,3.2vw,50px);display:flex;flex-direction:column;gap:16px;
  justify-content:center}
.lead-tile .txt p,.unit .txt p{color:var(--muted);font-size:15.5px;line-height:1.6;
  max-width:46ch}
.duo{display:grid;gap:clamp(16px,1.8vw,24px);grid-template-columns:1fr 1fr;
  margin-top:clamp(20px,2.2vw,28px)}
@media (max-width:820px){.duo{grid-template-columns:1fr}}
.unit{display:flex;flex-direction:column;border-radius:var(--r-lg);overflow:hidden;
  background:var(--white);box-shadow:var(--hairline),var(--amb-2);
  transition:box-shadow var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
.unit:hover{transform:translateY(-4px);box-shadow:var(--hairline),var(--amb-3)}
/* la zone image : MEME ratio pour les deux tuiles, quel que soit le produit */
.unit .pic{display:grid;place-items:center;aspect-ratio:16/9;
  background:linear-gradient(158deg,#f7fafc,#e9f0f5);padding:clamp(22px,2.6vw,38px)}
.unit .pic img{max-width:min(100%,400px);max-height:100%;width:auto;object-fit:contain;
  filter:var(--lift);transition:transform var(--t-slow) var(--ease)}
.unit:hover .pic img{transform:scale(1.04)}
/* la zone texte : MEME padding, meme structure, lien cale au fond */
.unit .txt{padding:clamp(22px,2.6vw,32px);display:flex;flex-direction:column;gap:12px;flex:1}
.unit .txt .tlink{margin-top:auto;padding-top:6px}
.specs{display:flex;flex-wrap:wrap;gap:6px}
.specs span{font:600 10px/1 var(--font-tech);letter-spacing:.13em;text-transform:uppercase;
  color:var(--primary);padding:6px 9px;border-radius:6px;
  background:rgba(0,91,125,.06);box-shadow:inset 0 0 0 1px rgba(0,91,125,.14)}
.dark .specs span{color:#fff;background:rgba(255,255,255,.10);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.2)}
/* ---------- mosaic ---------- */
.split{display:grid;gap:clamp(30px,4vw,64px);align-items:center;
  grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr)}
@media (max-width:960px){.split{grid-template-columns:1fr}}
.split .pic img{width:100%;filter:var(--lift-lg)}
.mos-logo{height:48px;width:auto}
/* ---------- index des applications, section claire ---------- */
.apps{border-top:1px solid var(--border);margin-top:clamp(30px,3.4vw,48px)}
.apps a{display:grid;grid-template-columns:auto 1fr auto auto;align-items:center;
  gap:clamp(14px,2vw,28px);padding:clamp(14px,1.7vw,21px) clamp(8px,1.2vw,16px);
  border-bottom:1px solid var(--border);color:var(--deepest);position:relative;overflow:hidden;
  transition:background var(--t-fast) var(--ease)}
.apps a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--signal);transform:scaleY(0);transform-origin:50% 0;
  transition:transform var(--t-base) var(--ease)}
.apps a:hover{background:rgba(0,91,125,.04)}
.apps a:hover::before{transform:scaleY(1)}
.apps .n{font:600 12px/1 var(--font-tech);letter-spacing:.1em;color:var(--primary)}
.apps .t{font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.1875rem,1.7vw,1.625rem);letter-spacing:-.014em;
  transition:transform var(--t-base) var(--ease)}
.apps a:hover .t{transform:translateX(8px)}
.apps .m{font:400 10.5px/1 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);justify-self:end;margin-right:14px}
@media (max-width:760px){.apps .m{display:none}}
.apps .bub{width:30px;height:30px;flex:none;border-radius:7px;display:grid;place-items:center;
  background:rgba(0,91,125,.07);color:var(--primary);
  transition:transform var(--t-base) var(--ease),background var(--t-fast) var(--ease)}
.apps .bub svg{width:13px;height:13px;stroke:currentColor;stroke-width:1.8;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.apps a:hover .bub{transform:translate(3px,-1px);background:rgba(0,91,125,.13)}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .apps a{animation:wipe linear both;animation-timeline:view();animation-range:entry 0% entry 35%}
  }
}
/* l'apercu qui suit le curseur (pattern 21st.dev Project Showcase, porte en vanilla) */
.peek{position:fixed;left:0;top:0;z-index:40;width:310px;height:205px;pointer-events:none;
  border-radius:var(--r-md);overflow:hidden;box-shadow:var(--amb-3),var(--gloss);
  background:var(--panel);opacity:0;scale:.86;
  transition:opacity .32s var(--ease),scale .32s var(--ease)}
.peek.on{opacity:1;scale:1}
.peek img{width:100%;height:100%;object-fit:cover}
.peek .cap{position:absolute;left:12px;bottom:10px;
  font:600 9.5px/1 var(--font-tech);letter-spacing:.17em;text-transform:uppercase;
  color:#fff;text-shadow:0 1px 8px rgba(0,20,30,.8)}
@media (hover:none),(max-width:960px){.peek{display:none}}
@keyframes wipe{from{opacity:0;clip-path:inset(0 100% 0 0);transform:translateY(12px)}
  to{opacity:1;clip-path:inset(0 0 0 0);transform:none}}
/* ---------- industries ---------- */
.inds{display:grid;gap:clamp(12px,1.2vw,16px);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr))}
.ind{position:relative;display:block;overflow:hidden;border-radius:var(--r-lg);
  min-height:clamp(250px,27vw,330px);isolation:isolate}
.ind img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;
  transition:transform var(--t-slow) var(--ease)}
.ind::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(178deg,rgba(0,42,60,.04) 0%,rgba(0,42,60,.48) 50%,rgba(0,20,30,.90) 100%);
  transition:opacity var(--t-base) var(--ease)}
.ind:hover img{transform:scale(1.07)}
.ind:hover::after{opacity:.92}
.ind-in{position:absolute;inset:auto 0 0 0;padding:clamp(18px,2vw,26px);
  display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
.ind-in h3{color:var(--white);font-size:clamp(1rem,1.1vw,1.0625rem);line-height:1.28;
  text-shadow:0 1px 14px rgba(0,20,30,.6)}
.ind-in .k{display:block;margin-bottom:9px;font:600 10px/1 var(--font-tech);
  letter-spacing:.19em;text-transform:uppercase;color:var(--sky)}
.ind-in .bub{width:30px;height:30px;flex:none;border-radius:7px;display:grid;place-items:center;
  background:rgba(255,255,255,.16);backdrop-filter:blur(6px);color:#fff;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.26);
  transition:transform var(--t-base) var(--ease),background var(--t-fast) var(--ease)}
.ind-in .bub svg{width:13px;height:13px;stroke:currentColor;stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.ind:hover .ind-in .bub{transform:translate(3px,-2px);background:rgba(255,255,255,.28)}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .ind img{animation:take-color linear both;animation-timeline:view();
      animation-range:entry 4% cover 38%}
  }
}
@keyframes take-color{from{filter:saturate(.22) contrast(1.04)}to{filter:none}}
/* ---------- l'equipe et les raisons ---------- */
.team-grid{display:grid;gap:clamp(28px,3.4vw,56px);grid-template-columns:1.15fr 1fr;
  align-items:start}
@media (max-width:900px){.team-grid{grid-template-columns:1fr}}
.team-grid h2{font-size:clamp(1.5rem,2.4vw,2.25rem);line-height:1.18;max-width:22ch}
.why{display:grid;gap:clamp(20px,2.4vw,38px) clamp(24px,3vw,54px);
  grid-template-columns:repeat(3,minmax(0,1fr));margin-top:clamp(44px,5vw,76px)}
@media (max-width:900px){.why{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.why{grid-template-columns:1fr}}
.why article{position:relative;padding-top:22px;border-top:1px solid rgba(255,255,255,.18)}
.why article::before{content:"";position:absolute;top:-2px;left:0;width:38px;height:3px;
  border-radius:2px;background:var(--signal);transform-origin:0 50%;
  transition:transform var(--t-base) var(--ease)}
.why article:hover::before{transform:scaleX(2.4)}
.why h3{font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.125rem,1.5vw,1.4375rem);line-height:1.15;letter-spacing:.045em;
  text-transform:uppercase;color:#fff}
.why p{margin-top:12px;color:rgba(255,255,255,.74);font-size:15.5px;line-height:1.58;
  max-width:34ch}
/* ---------- temoignages ---------- */
.says{overflow:hidden;position:relative;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.row{display:flex;align-items:flex-start;gap:18px;width:max-content;padding-block:8px}
@media (prefers-reduced-motion:no-preference){
  .row{animation:slide 64s linear infinite}
  .row.rev{animation-direction:reverse}
  .says:hover .row{animation-play-state:paused}
}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.say{flex:0 0 clamp(280px,26vw,360px);display:flex;flex-direction:column;gap:14px;
  padding-top:18px;border-top:1px solid var(--border)}
.say q{quotes:none;font-family:var(--font-display);font-weight:500;font-size:16.5px;
  line-height:1.45;color:var(--deepest);letter-spacing:-.008em}
.say cite{font-style:normal;font:600 10px/1.5 var(--font-tech);letter-spacing:.19em;
  text-transform:uppercase;color:var(--muted)}
.say cite b{display:block;color:var(--primary);font-weight:600}
/* ---------- nouvelles ---------- */
.news{display:grid;gap:clamp(24px,3vw,48px);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,270px),1fr))}
.news article{display:flex;flex-direction:column;gap:14px;padding-top:20px;
  border-top:1px solid var(--border);position:relative}
.news article::before{content:"";position:absolute;top:-2px;left:0;width:34px;height:3px;
  border-radius:2px;background:var(--signal);transform-origin:0 50%;
  transition:transform var(--t-base) var(--ease)}
.news article:hover::before{transform:scaleX(2.2)}
.news .thumb{aspect-ratio:16/10;border-radius:var(--r-md);overflow:hidden;
  margin-bottom:8px;background:var(--panel);box-shadow:var(--hairline)}
.news .thumb img{width:100%;height:100%;object-fit:cover;object-position:center top;
  transition:transform var(--t-slow) var(--ease)}
.news article:hover .thumb img{transform:scale(1.05)}
.news .k{font:600 10px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--primary)}
.news h3{font-size:clamp(1.0625rem,1.2vw,1.1875rem);line-height:1.3}
.news p{color:var(--muted);font-size:15px;line-height:1.55}
.news .tlink{margin-top:auto}
/* ---------- les trois portes du contact : des TUILES ----------
   Regle de LC : les tuiles servent a mettre l'accent sur les call
   to action. Les portes sont les CTA de la page, elles portent donc
   la tuile blanche, le lisere cyan qui s'etend, et le lift au survol. */
.doors{display:grid;gap:clamp(16px,1.8vw,24px);margin-top:clamp(34px,3.8vw,54px);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr))}
.door{display:flex;flex-direction:column;gap:12px;
  padding:clamp(24px,2.6vw,34px);border-radius:var(--r-lg);
  background:var(--white);box-shadow:var(--hairline),var(--amb-1),var(--gloss);
  position:relative;overflow:hidden;
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.door::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;
  background:linear-gradient(90deg,var(--signal),rgba(0,168,224,0));
  transform:scaleX(.3);transform-origin:0 50%;
  transition:transform var(--t-base) var(--ease)}
.door:hover{transform:translateY(-4px);box-shadow:var(--hairline),var(--amb-2),var(--gloss)}
.door:hover::before{transform:scaleX(1)}
.door h3{font-size:1.1875rem}
.door p{color:var(--muted);font-size:15px;line-height:1.55}
.door .tlink{margin-top:auto;padding-top:8px}
/* ---------- coordonnees, dans le footer ---------- */
.foot-contact{position:relative;z-index:2;display:grid;gap:clamp(26px,3vw,44px);
  grid-template-columns:repeat(3,minmax(0,1fr));
  border-top:1px solid rgba(255,255,255,.10);padding-block:clamp(24px,2.8vw,38px)}
@media (max-width:820px){.foot-contact{grid-template-columns:1fr 1fr}}
.foot-contact a{display:block;padding:3px 0;color:#fff;font-size:16px;
  transition:color var(--t-fast) var(--ease)}
.foot-contact a:hover{color:var(--sky)}
.foot-contact .sub{color:rgba(255,255,255,.5);font-size:13px;margin-top:4px}
/* ---------- pied de page en rideau ---------- */
.foot-shell{position:relative;height:min(90vh,780px);
  clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}
.foot{position:fixed;bottom:0;left:0;width:100%;height:min(90vh,780px);
  display:flex;flex-direction:column;justify-content:space-between;overflow:hidden;
  background:var(--deepest);color:rgba(255,255,255,.72);font-size:14.5px}
@media (max-width:820px),(max-height:640px){
  .foot-shell{height:auto;clip-path:none}
  .foot{position:relative;height:auto}
}
.foot-photo{position:absolute;inset:0;background-size:cover;background-position:center 30%;
  opacity:.24;mix-blend-mode:luminosity;filter:saturate(.4)}
.foot-glow{position:absolute;left:50%;top:38%;width:120%;height:70%;
  transform:translate(-50%,-50%);pointer-events:none;filter:blur(60px);
  background:radial-gradient(closest-side,rgba(0,122,170,.42),transparent 72%)}
.foot-grid-bg{position:absolute;inset:0;pointer-events:none;
  background-image:
    repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 96px),
    repeating-linear-gradient(0deg,rgba(255,255,255,.04) 0 1px,transparent 1px 96px);
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 26%,#000 68%,transparent);
  mask-image:linear-gradient(180deg,transparent,#000 26%,#000 68%,transparent)}
.foot-wave{position:absolute;left:-10%;right:-10%;bottom:-6%;opacity:.42;pointer-events:none}
.foot-word{position:absolute;left:50%;bottom:-4%;transform:translateX(-50%);
  width:min(58vw,860px);pointer-events:none;user-select:none;opacity:.07;
  -webkit-mask-image:linear-gradient(180deg,#000,transparent 78%);
  mask-image:linear-gradient(180deg,#000,transparent 78%)}
.foot-word img{width:100%}
.foot-top{position:relative;z-index:2;padding-top:clamp(42px,5vw,76px)}
.foot-grid{display:grid;gap:clamp(26px,3vw,44px);grid-template-columns:1.6fr repeat(3,1fr)}
@media (max-width:820px){.foot-grid{grid-template-columns:1fr 1fr}}
.foot h4{margin:0 0 18px;color:var(--sky);font:600 10.5px/1 var(--font-tech);
  letter-spacing:.19em;text-transform:uppercase}
.foot-links a{color:rgba(255,255,255,.72);display:inline-block;padding:6px 0;position:relative;
  transition:color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.foot-links a::after{content:"";position:absolute;left:0;right:100%;bottom:4px;height:1px;
  background:var(--signal);transition:right var(--t-base) var(--ease)}
.foot-links a:hover{color:#fff;transform:translateX(4px)}
.foot-links a:hover::after{right:0}
.foot .brandline img{height:44px;width:auto;margin-bottom:20px}
.foot .brandline p{max-width:36ch;line-height:1.65}
.foot-mid{position:relative;z-index:2;display:flex;flex-wrap:wrap;gap:18px 40px;
  align-items:center;padding-block:clamp(22px,2.6vw,34px);
  border-top:1px solid rgba(255,255,255,.10)}
.foot-mid .stat{display:flex;align-items:baseline;gap:9px}
.foot-mid .stat b{font-family:var(--font-display);font-weight:600;font-size:24px;
  letter-spacing:-.02em;color:#fff}
.foot-mid .stat span{font:600 10px/1.4 var(--font-tech);letter-spacing:.19em;
  text-transform:uppercase;color:rgba(255,255,255,.5)}
.foot-base{position:relative;z-index:2;border-top:1px solid rgba(255,255,255,.10);
  padding-block:20px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  align-items:center;font:400 10.5px/1.6 var(--font-tech);letter-spacing:.14em;
  text-transform:uppercase;color:rgba(255,255,255,.44)}
.to-top{display:inline-flex;align-items:center;gap:10px;cursor:pointer;border:0;
  padding:9px 9px 9px 16px;border-radius:var(--r-btn);color:#fff;will-change:transform;
  background:rgba(255,255,255,.08);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);
  font:600 10.5px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  transition:background var(--t-fast) var(--ease)}
.to-top i{width:28px;height:28px;border-radius:var(--r-bub);display:grid;place-items:center;
  background:rgba(255,255,255,.10);
  transition:transform var(--t-base) var(--ease),background var(--t-fast) var(--ease)}
.to-top svg{width:14px;height:14px;stroke:currentColor;stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.to-top:hover{background:rgba(255,255,255,.13)}
.to-top:hover i{transform:translateY(-3px);background:rgba(0,168,224,.34)}
/* ---------- page CORTEX : blocs materiels ---------- */
.unit-views{display:grid;gap:clamp(14px,1.6vw,22px);grid-template-columns:1fr 1fr;
  align-items:center}
@media (max-width:820px){.unit-views{grid-template-columns:1fr}}
.unit-views img{width:100%;filter:var(--lift)}
.feat{display:grid;gap:14px clamp(20px,2.4vw,40px);grid-template-columns:1fr 1fr;
  margin-top:clamp(24px,2.6vw,36px)}
@media (max-width:760px){.feat{grid-template-columns:1fr}}
.feat div{border-top:1px solid var(--border);padding-top:12px}
.feat b{display:block;font:600 10.5px/1.5 var(--font-tech);letter-spacing:.16em;
  text-transform:uppercase;color:var(--primary)}
.feat p{margin-top:5px;color:var(--muted);font-size:14.5px;line-height:1.5}
/* ---------- vitrine spatiale des deux unites ----------
   Pattern 21st.dev Spatial Product Showcase (9679), porte en vanilla.
   Deux etats (CORTEX 360 / 320), dock a surface glissante en rectangles
   arrondis (jamais de pastille), lueur de fond qui suit l'etat actif,
   et un modal de specs en <dialog> natif qui mene a la brochure. */
.stage{display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
  gap:clamp(28px,3.6vw,64px);align-items:center;margin-top:clamp(36px,4vw,56px);
  position:relative}
@media (max-width:900px){.stage{grid-template-columns:1fr}}
.stage-viz{position:relative;display:grid;place-items:center;min-height:clamp(240px,30vw,380px)}
.stage-viz::before{content:"";position:absolute;inset:-8%;pointer-events:none;
  background:radial-gradient(52% 62% at 50% 46%,rgba(0,168,224,.16),transparent 70%);
  filter:blur(10px);transition:opacity var(--t-slow) var(--ease);opacity:1}
.stage[data-active="c320"] .stage-viz::before{
  background:radial-gradient(52% 62% at 50% 46%,rgba(0,91,125,.18),transparent 70%)}
.s-img{grid-area:1/1;width:100%;max-width:640px;filter:var(--lift);
  opacity:0;transform:translateX(-26px) scale(.96);pointer-events:none;
  transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease)}
.s-img.on{opacity:1;transform:none}
.stage-info{display:grid}
.s-pane{grid-area:1/1;opacity:0;transform:translateY(18px);pointer-events:none;
  transition:opacity var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
.s-pane.on{opacity:1;transform:none;pointer-events:auto}
.s-pane h3{font-size:clamp(1.75rem,2.6vw,2.375rem);margin-top:10px}
.s-pane .specs{margin-top:18px}
.s-pane .act{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px}
/* le dock : segments en rectangles arrondis, surface glissante */
.dock{position:relative;display:inline-flex;padding:5px;border-radius:12px;
  background:var(--white);box-shadow:var(--hairline),var(--amb-2);
  margin-top:clamp(28px,3.2vw,44px)}
.dock-pill{position:absolute;top:5px;bottom:5px;left:5px;width:calc(50% - 5px);
  border-radius:9px;background:var(--deep-field);
  transition:transform var(--t-base) var(--ease)}
.dock-btn{position:relative;z-index:1;border:0;background:none;cursor:pointer;
  padding:12px 26px;border-radius:9px;min-width:150px;
  font:600 13px/1 var(--font-body);color:var(--muted);
  transition:color var(--t-fast) var(--ease)}
.dock-btn.is-on{color:#fff}
/* le modal de specs */
dialog.specs{border:0;padding:0;border-radius:var(--r-lg);width:min(92vw,880px);
  max-height:86vh;box-shadow:var(--amb-4);background:var(--white);overflow:hidden}
dialog.specs:not([open]){display:none}
dialog.specs::backdrop{background:rgba(0,26,38,.55);backdrop-filter:blur(6px)}
.dlg-head{display:flex;align-items:center;gap:16px;justify-content:space-between;
  padding:clamp(20px,2.4vw,28px) clamp(22px,2.8vw,34px);
  border-bottom:1px solid var(--border)}
.dlg-head h3{font-size:1.3125rem}
.dlg-close{border:0;cursor:pointer;width:38px;height:38px;border-radius:var(--r-bub);
  display:grid;place-items:center;background:rgba(0,42,60,.06);color:var(--deepest);
  transition:background var(--t-fast) var(--ease)}
.dlg-close:hover{background:rgba(0,42,60,.12)}
.dlg-close svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.8;fill:none;
  stroke-linecap:round}
.dlg-body{padding:clamp(20px,2.4vw,30px) clamp(22px,2.8vw,34px);overflow:auto;
  max-height:calc(86vh - 180px)}
.dlg-body .unit-views{margin-bottom:6px}
.dlg-foot{display:flex;flex-wrap:wrap;align-items:center;gap:14px 24px;
  padding:clamp(18px,2vw,24px) clamp(22px,2.8vw,34px);
  border-top:1px solid var(--border);background:var(--off-white)}
.dlg-foot .mono{margin:0}
.dlg-foot .big{display:inline;font-family:var(--font-display);font-weight:600;
  font-size:1.1875rem;color:var(--deepest);text-transform:none;letter-spacing:-.015em;
  background:none;box-shadow:none;padding:0}
.dlg-foot .btn{margin-left:auto}
@media (max-width:700px){.dlg-foot .btn{margin-left:0}}
/* ---------- comparateur avant/apres (21st.dev 19250, porte en vanilla) ----
   Le curseur revele DavLink (2e gen) sur le workspace HTML5 (3e gen).
   Un input range invisible pilote --pos : clavier et tactile gratuits. */
.cmp-row{display:grid;grid-template-columns:minmax(0,.55fr) minmax(0,2fr) minmax(0,.55fr);
  gap:clamp(20px,2.6vw,44px);align-items:center;margin-top:clamp(34px,3.8vw,52px)}
@media (max-width:1000px){.cmp-row{grid-template-columns:1fr}}
.cmp-side h3{font-size:1.0625rem}
.cmp-side p{color:var(--muted);font-size:14px;line-height:1.6;margin-top:10px}
.cmp-side.r{text-align:left}
@media (min-width:1001px){.cmp-side.l{text-align:right}}
.cmp{position:relative;aspect-ratio:1600/840;border-radius:var(--r-md);overflow:hidden;
  box-shadow:var(--hairline),var(--amb-3);background:var(--panel);
  --pos:50%}
.cmp img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:left top}
.cmp .before{clip-path:inset(0 calc(100% - var(--pos)) 0 0)}
.cmp-bar{position:absolute;top:0;bottom:0;left:var(--pos);width:2px;margin-left:-1px;
  background:var(--signal);pointer-events:none}
.cmp-bar i{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:38px;height:38px;border-radius:10px;display:grid;place-items:center;
  background:var(--white);box-shadow:var(--amb-2),var(--hairline)}
.cmp-bar svg{width:18px;height:18px;stroke:var(--primary);stroke-width:1.8;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.cmp-range{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:ew-resize;
  margin:0;-webkit-appearance:none;appearance:none}
.cmp-tag{position:absolute;bottom:12px;font:600 9.5px/1 var(--font-tech);
  letter-spacing:.15em;text-transform:uppercase;color:#fff;padding:7px 10px;
  border-radius:7px;background:rgba(0,26,38,.62);backdrop-filter:blur(6px);pointer-events:none}
.cmp-tag.l{left:12px}
.cmp-tag.r{right:12px}
/* ---------- galerie de workspaces : defilement aimante ---------- */
.gal-head{display:flex;align-items:end;justify-content:space-between;gap:20px;
  margin-top:clamp(44px,5vw,72px)}
.gal-nav{display:flex;gap:8px}
.gal-btn{border:0;cursor:pointer;width:40px;height:40px;border-radius:var(--r-btn);
  display:grid;place-items:center;background:var(--white);color:var(--primary);
  box-shadow:var(--hairline),var(--amb-1);
  transition:box-shadow var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.gal-btn:hover{box-shadow:var(--hairline),var(--amb-2);transform:translateY(-2px)}
.gal-btn svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.8;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.gal{display:flex;align-items:flex-start;gap:clamp(14px,1.6vw,22px);
  overflow-x:auto;scroll-snap-type:x mandatory;
  padding:18px 4px 8px;margin-top:6px;scrollbar-width:none}
.gal::-webkit-scrollbar{display:none}
.gal figure{flex:0 0 auto;scroll-snap-align:center;margin:0;max-width:92vw}
.gal img{height:clamp(300px,34vw,480px);width:auto;max-width:100%;object-fit:contain;
  border-radius:var(--r-md);box-shadow:var(--hairline),var(--amb-2)}
.gal figcaption{margin-top:12px;font:600 10px/1.5 var(--font-tech);letter-spacing:.17em;
  text-transform:uppercase;color:var(--muted)}
/* ---------- vitrine de fonctions en scrollytelling ----------
   Pattern 21st.dev Scroll 01 (18041), porte en vanilla. Une feature
   a la fois au centre de l'attention : les etapes defilent a gauche,
   le visuel colle a droite et se remplace. Sans JS ou sous 900 px :
   chaque etape garde son visuel en flux, rien ne disparait. */
.show{margin-top:clamp(38px,4.4vw,60px)}
.step{padding-block:clamp(30px,4.5vh,54px)}
/* la version scrollytelling (grille + panneau colle) n'existe QUE via .js-show */
.js-show{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(30px,4.5vw,80px);align-items:start}
.step .k2{font:600 11px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--primary)}
.step h3{font-size:clamp(1.3125rem,1.9vw,1.75rem);margin-top:12px}
.step p{color:var(--muted);font-size:15.5px;line-height:1.62;margin-top:14px;max-width:54ch}
.step .fviz{margin-top:26px;display:grid;place-items:center}
.fviz img{width:100%;max-width:460px;
  filter:drop-shadow(0 18px 26px rgba(0,42,60,.14)) drop-shadow(0 4px 8px rgba(0,42,60,.08))}
.show-visual{display:none}
/* la version scrollytelling, activee par JS sur grand ecran */
.js-show .step{min-height:56vh;display:flex;flex-direction:column;justify-content:center;
  opacity:.34;transition:opacity var(--t-base) var(--ease)}
.js-show .step.is-on{opacity:1}
.js-show .step .fviz{display:none}
.js-show .show-visual{display:block;position:sticky;top:calc(50vh - 31vh);height:62vh}
.js-show .show-visual .viz{position:absolute;inset:0;display:grid;place-items:center;
  opacity:0;transform:translateY(16px) scale(.985);pointer-events:none;
  transition:opacity var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
.js-show .show-visual .viz.on{opacity:1;transform:none}
/* les six outils d'automatisation, en SVG natif */
.tools{display:grid;gap:clamp(12px,1.4vw,18px);grid-template-columns:repeat(3,1fr);width:100%}
@media (max-width:560px){.tools{grid-template-columns:repeat(2,1fr)}}
.tool{display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;
  padding:clamp(14px,1.6vw,20px) 8px}
.tool i{width:58px;height:58px;border-radius:12px;display:grid;place-items:center;
  background:rgba(0,168,224,.08);box-shadow:inset 0 0 0 1px rgba(0,168,224,.2)}
.tool svg{width:30px;height:30px;stroke:var(--primary);stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.tool span{font:600 10px/1.45 var(--font-tech);letter-spacing:.12em;text-transform:uppercase;
  color:var(--deepest)}
/* les quatre familles de capteurs, en SVG natif */
.cat-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,2.6vw,38px);width:100%;
  max-width:420px;margin-inline:auto}
.cat{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center}
.cat i{width:76px;height:76px;border-radius:14px;display:grid;place-items:center;
  background:rgba(0,168,224,.08);box-shadow:inset 0 0 0 1px rgba(0,168,224,.2)}
.cat svg{width:38px;height:38px;stroke:var(--primary);stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.cat span{font:600 10.5px/1.45 var(--font-tech);letter-spacing:.14em;text-transform:uppercase;
  color:var(--deepest)}
.cats{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.cats span{font:600 10.5px/1 var(--font-tech);letter-spacing:.14em;text-transform:uppercase;
  color:var(--primary);padding:8px 12px;border-radius:8px;
  background:rgba(0,91,125,.06);box-shadow:inset 0 0 0 1px rgba(0,91,125,.14)}
/* le diagramme de PINGs, en SVG natif */
.ping-svg{width:100%;max-width:480px}
.ping-svg text{font:600 9.5px "IBM Plex Mono",monospace;letter-spacing:.1em;fill:var(--muted)}
.ping-svg .node{fill:#fff;stroke:rgba(0,42,60,.22);stroke-width:1.2;rx:9}
.ping-svg .core{fill:#fff;stroke:var(--primary);stroke-width:1.6}
.ping-svg .lnk{stroke:rgba(0,122,170,.55);stroke-width:1.4;stroke-dasharray:3 5;fill:none}
.ping-svg .bad{stroke:#b04a4a}
.ping-svg .ok{stroke:var(--signal);stroke-width:1.8;fill:none;stroke-linecap:round}
.ping-svg .ko{stroke:#b04a4a;stroke-width:1.8;fill:none;stroke-linecap:round}
/* comparaison des generations */
.gen{display:grid;gap:clamp(16px,1.8vw,24px);grid-template-columns:1fr 1fr;
  margin-top:clamp(30px,3.4vw,46px)}
@media (max-width:760px){.gen{grid-template-columns:1fr}}
.gen article{padding:clamp(24px,2.6vw,34px);border-radius:var(--r-lg);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1);position:relative;overflow:hidden}
.gen article::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;
  background:linear-gradient(90deg,var(--signal),rgba(0,168,224,0))}
.gen h3{font-size:1.125rem}
.gen p{color:var(--muted);font-size:15px;line-height:1.6;margin-top:12px}
/* bande telephone */
.callrow{display:flex;flex-wrap:wrap;align-items:center;gap:18px clamp(24px,3vw,46px);
  padding:clamp(24px,2.6vw,36px) clamp(22px,2.6vw,38px);border-radius:var(--r-lg);
  background:var(--white);box-shadow:var(--hairline),var(--amb-2);
  margin-top:clamp(40px,4.6vw,64px)}
.callrow .big{font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.375rem,2.2vw,1.875rem);color:var(--deepest);letter-spacing:-.02em}
.callrow p{color:var(--muted);font-size:15.5px}
.callrow .btn{margin-left:auto}
@media (max-width:700px){.callrow .btn{margin-left:0}}
/* ---------- specificites MOSAIC ---------- */
.feats{display:grid;gap:clamp(22px,2.6vw,40px) clamp(26px,3vw,54px);
  grid-template-columns:repeat(2,minmax(0,1fr));margin-top:clamp(34px,3.8vw,52px)}
@media (max-width:820px){.feats{grid-template-columns:1fr}}
.feat-card{display:grid;grid-template-columns:64px 1fr;gap:20px;align-items:start;
  padding-top:22px;border-top:1px solid var(--border);position:relative}
.feat-card::before{content:"";position:absolute;top:-2px;left:0;width:38px;height:3px;
  border-radius:2px;background:var(--signal);transform-origin:0 50%;
  transition:transform var(--t-base) var(--ease)}
.feat-card:hover::before{transform:scaleX(2.2)}
.feat-card img{width:56px;height:auto}
.feat-card h3{font-size:1.125rem}
.feat-card p{margin-top:10px;color:var(--muted);font-size:15px;line-height:1.6}
.wide-viz{margin-top:clamp(30px,3.4vw,48px);display:grid;place-items:center}
.wide-viz img{width:100%;max-width:980px;filter:var(--lift)}
.rtu-trio{display:grid;gap:clamp(20px,2.4vw,34px);grid-template-columns:repeat(3,minmax(0,1fr));
  margin-top:clamp(34px,3.8vw,52px)}
@media (max-width:820px){.rtu-trio{grid-template-columns:1fr}}
.rtu-trio article{display:flex;flex-direction:column;gap:14px;text-align:center;height:100%}
.rtu-trio p{flex:1}
.rtu-trio .pic{display:grid;place-items:center;aspect-ratio:16/9}
.rtu-trio .pic img{max-width:min(100%,320px);max-height:100%;width:auto;object-fit:contain;
  filter:var(--lift);transition:transform var(--t-slow) var(--ease)}
.rtu-trio article:hover .pic img{transform:translateY(-5px) scale(1.02)}
.rtu-trio p{color:var(--muted);font-size:15px;line-height:1.6}
.rtu-trio .tlink{justify-content:center;margin-top:auto}
.why-rtu{display:grid;gap:18px clamp(26px,3vw,50px);grid-template-columns:repeat(2,minmax(0,1fr));
  margin-top:clamp(30px,3.4vw,46px)}
@media (max-width:820px){.why-rtu{grid-template-columns:1fr}}
.why-rtu article{padding-top:18px;border-top:1px solid rgba(255,255,255,.18)}
.why-rtu h3{font:600 11px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--sky)}
.why-rtu p{margin-top:12px;color:rgba(255,255,255,.74);font-size:15px;line-height:1.6}
/* ---------- specificites AXON ---------- */
dialog.video{border:0;padding:0;border-radius:var(--r-lg);width:min(92vw,1080px);
  background:#0b1a22;box-shadow:var(--amb-4);overflow:hidden}
dialog.video:not([open]){display:none}
dialog.video::backdrop{background:rgba(0,26,38,.72);backdrop-filter:blur(8px)}
.vid-head{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:14px 18px;background:#0b1a22}
.vid-head span{font:600 11px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--sky)}
.vid-head .dlg-close{background:rgba(255,255,255,.10);color:#fff}
.vid-head .dlg-close:hover{background:rgba(255,255,255,.18)}
.vid-box{position:relative;aspect-ratio:16/9;background:#000}
.vid-box iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.stage-viz .s-img{height:clamp(300px,34vw,460px);width:auto;max-width:100%}
.dock.dock-4 .dock-pill{width:calc(25% - 5px)}
.dock.dock-4 .dock-btn{min-width:118px;padding:12px 18px}
.views-2{display:grid;gap:clamp(18px,2.2vw,34px);grid-template-columns:1fr 1fr;
  align-items:center;margin-top:clamp(30px,3.4vw,46px)}
@media (max-width:820px){.views-2{grid-template-columns:1fr}}
.views-2 img{width:100%;filter:var(--lift)}
.views-2 figure{margin:0}
.views-2 figcaption{margin-top:14px;font:600 10px/1 var(--font-tech);letter-spacing:.17em;
  text-transform:uppercase;color:var(--muted);text-align:center}
.hw-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;
  margin-top:clamp(30px,3.4vw,44px)}
.hw-chips span{font:600 11px/1 var(--font-tech);letter-spacing:.14em;text-transform:uppercase;
  color:var(--primary);padding:11px 16px;border-radius:8px;background:var(--white);
  box-shadow:var(--hairline),var(--amb-1)}
.trio{display:grid;gap:clamp(20px,2.4vw,38px) clamp(24px,3vw,54px);
  grid-template-columns:repeat(3,minmax(0,1fr));margin-top:clamp(36px,4vw,56px)}
@media (max-width:900px){.trio{grid-template-columns:1fr}}
.trio article{position:relative;padding-top:20px;border-top:1px solid var(--border)}
.trio article::before{content:"";position:absolute;top:-2px;left:0;width:34px;height:3px;
  border-radius:2px;background:var(--signal)}
.trio .k2{font:600 10.5px/1.5 var(--font-tech);letter-spacing:.17em;text-transform:uppercase;
  color:var(--primary)}
.trio h3{font-size:1.125rem;margin-top:10px}
.trio p{margin-top:12px;color:var(--muted);font-size:15px;line-height:1.6}
.upsell{display:grid;gap:clamp(16px,1.8vw,24px);grid-template-columns:1fr 1fr;
  margin-top:clamp(34px,3.8vw,52px)}
@media (max-width:820px){.upsell{grid-template-columns:1fr}}
/* ---------- entrees ---------- */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .rev{animation:lift linear both;animation-timeline:view();animation-range:entry 0% entry 35%}
    .rev-stagger>*{animation:lift-soft linear both;animation-timeline:view();
      animation-range:entry 0% entry 30%}
    .rev-stagger>*:nth-child(2){animation-range:entry 3% entry 34%}
    .rev-stagger>*:nth-child(3){animation-range:entry 6% entry 38%}
    .rev-stagger>*:nth-child(4){animation-range:entry 9% entry 42%}
    .rev-stagger>*:nth-child(5){animation-range:entry 12% entry 46%}
    .rev-stagger>*:nth-child(6){animation-range:entry 15% entry 50%}
    .cut{animation:cut-up linear both;animation-timeline:view();animation-range:entry 0% entry 35%}
  }
}
@keyframes lift{from{opacity:0;transform:translateY(28px) scale(.995)}
  to{opacity:1;transform:none}}
@keyframes lift-soft{from{opacity:0;transform:translateY(30px)}
  to{opacity:1;transform:none}}
@keyframes cut-up{from{opacity:0;clip-path:inset(0 0 100% 0);transform:translateY(26px)}
  to{opacity:1;clip-path:inset(0 0 -12% 0);transform:none}}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important}
}
/* Un visuel detoure ne se pose pas dans une boite : sans ca, le degrade gris
   de .pic annule la transparence qu'on vient de gagner (LC, 2026-08-20). */
.pic.pic-cut{background:none;padding:0;aspect-ratio:auto}
.pic.pic-cut img{max-height:none;filter:drop-shadow(0 18px 26px rgba(0,42,60,.13))
  drop-shadow(0 4px 8px rgba(0,42,60,.07))}
/* ---------- prerequis systeme (page Mosaic) ----------
   Les trois roles serveur, puis un tableau qui alterne minimum et recommande.
   Le tableau defile dans sa propre boite : cinq colonnes ne tiennent pas sous
   700 px, et c'est la page qui ne doit jamais defiler lateralement. */
.roles-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,24px);margin-top:clamp(26px,3vw,38px)}
.role{padding:20px 22px;border-radius:var(--r-md);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1)}
.role-tag{display:block;font:600 11.5px/1 var(--font-tech);letter-spacing:.13em;
  text-transform:uppercase;color:var(--mid);margin-bottom:9px}
.role p{margin:0;color:var(--muted);font-size:14.5px;line-height:1.6}
@media (max-width:820px){.roles-3{grid-template-columns:1fr}}
.req-scroll{overflow-x:auto;margin-top:14px;border-radius:var(--r-md)}
.req-table{width:100%;border-collapse:collapse;background:var(--white);
  box-shadow:var(--hairline),var(--amb-1);border-radius:var(--r-md);overflow:hidden;
  font-size:14px;min-width:640px}
.req-table th,.req-table td{text-align:left;padding:11px 16px;
  border-top:1px solid var(--border);vertical-align:top}
.req-table thead th{border-top:0;background:var(--inset);
  font:600 10.5px/1.6 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--primary);white-space:nowrap}
.req-table tbody th{font-weight:600;color:var(--deepest);white-space:nowrap}
.req-table tbody th span{display:block;font:600 10.5px/1.6 var(--font-tech);
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.req-table tbody tr.rec{background:rgba(0,168,224,.045)}
.req-table td{color:var(--muted)}
/* le mot qui accompagne un bouton de configuration : il dit ce que le clic
   ouvre, sinon « Configure » demande au visiteur de parier */
.cta-hint{align-self:center;color:var(--muted);font-size:14px;line-height:1.5;max-width:44ch}
@media (max-width:700px){.cta-hint{align-self:flex-start}}
/* ---------- blocs communs aux pages Industries (2026-08-15) ---------- */
.feats-3{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:1040px){.feats-3{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:760px){.feats,.feats-3{grid-template-columns:1fr}}
.blist{margin-top:12px;padding-left:17px;font-size:15px;line-height:1.62}
.blist li+li{margin-top:9px}
/* deux colonnes de lecture : 3 a 5 paragraphes de suite se lisent mal en une
   colonne pleine largeur (mesure de ligne trop longue). */
.two-col{columns:2;column-gap:clamp(30px,3.6vw,60px);margin-top:clamp(20px,2.2vw,30px)}
.two-col .lede{max-width:none;break-inside:avoid;margin-bottom:16px}
.two-col .blist{max-width:none;break-inside:avoid;margin-bottom:16px}
.two-col h4.sub{break-inside:avoid;break-after:avoid}
@media (max-width:900px){.two-col{columns:1}}
/* la phrase de synthese, detachee */
.pull{margin-top:clamp(26px,3vw,40px);max-width:72ch;font-family:var(--font-display);
  font-weight:600;font-size:clamp(1.1875rem,1.7vw,1.5rem);line-height:1.36;
  color:var(--deepest);padding-left:clamp(16px,1.8vw,24px);
  border-left:2px solid var(--signal)}
/* trois piliers a puces : sur fond sombre par defaut, .light pour fond clair */
.pillars{display:grid;gap:clamp(26px,3vw,48px);margin-top:clamp(34px,4vw,56px);
  grid-template-columns:repeat(3,minmax(0,1fr))}
.pillars article{padding-top:18px;border-top:1px solid rgba(255,255,255,.22)}
.pillars h3{font-size:1.0625rem;line-height:1.3}
.pillars .blist{color:rgba(255,255,255,.78)}
.pillars.light article{border-top-color:var(--border)}
.pillars.light .blist{color:var(--muted)}
@media (max-width:900px){.pillars{grid-template-columns:1fr}}
/* la bande de logos : silhouettes tres inegales (400x131 a 1600x261), donc
   boite normee + contain + gris qui se leve au survol. Sans la boite, chaque
   logo rend a une echelle apparente differente (regle §5 du design system). */
.logos{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));
  gap:clamp(14px,1.8vw,30px);align-items:center;margin-top:clamp(30px,3.4vw,48px)}
.logos span{display:grid;place-items:center;height:clamp(52px,5.4vw,68px)}
/* piege : max-height:100% ne se resout pas dans une zone de grille (le pourcentage
   reste indefini) et les logos rendaient de 30 a 104 px de haut. Plafond absolu. */
.logos img{max-width:min(100%,150px);max-height:clamp(30px,3.2vw,42px);
  width:auto;height:auto;object-fit:contain;
  filter:grayscale(1);opacity:.62;
  transition:filter var(--t-base) var(--ease),opacity var(--t-base) var(--ease)}
.logos span:hover img{filter:none;opacity:1}
@media (max-width:900px){.logos{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* la bande a deux documents */
.pdf-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:clamp(18px,2.4vw,34px);margin-top:clamp(38px,4.4vw,60px);
  padding:clamp(22px,2.6vw,32px) clamp(24px,3vw,38px);border-radius:var(--r-md);
  background:var(--white);box-shadow:var(--hairline),var(--amb-2)}
.pdf-acts{display:flex;gap:12px;flex-wrap:wrap}
/* les titres des cartes « No problem » sont des questions : elles respirent plus */
.noprob .feat-card h3{font-size:1rem;line-height:1.34}
.noprob .feat-card>img{width:52px;height:52px;object-fit:contain}
/* ---------- gabarit des pages Field Application (vague 3) ---------- */
.body-copy{margin-top:clamp(20px,2.2vw,30px);max-width:76ch}
.body-copy .lede+.lede{margin-top:16px}
.body-copy .blist{margin-top:14px;max-width:72ch}
.on-dark .body-copy .lede{color:rgba(255,255,255,.80)}
.on-dark .body-copy .blist{color:rgba(255,255,255,.76)}
.on-dark h4.sub{color:var(--sky)}
.acts{display:flex;flex-wrap:wrap;gap:14px 22px;margin-top:clamp(18px,2vw,26px)}
h4.sub{margin-top:clamp(20px,2.2vw,28px);font:600 11px/1 var(--font-tech);letter-spacing:.19em;
  text-transform:uppercase;color:var(--primary)}
h4.sub+.lede{margin-top:12px}
.split .stack h3{font-size:clamp(1.1875rem,1.9vw,1.625rem);line-height:1.28}
.split .stack .lede+.lede{margin-top:14px}
#promise .wide-viz img,#promise-viz .wide-viz img{max-width:min(100%,720px)}
/* un portrait ne doit pas ecraser sa colonne : plafond en hauteur AUSSI, sinon
   une image 809x1600 rendait 1234 px de haut dans le hero (LC, 2026-08-16). */
.sec .split .pic img{max-width:min(100%,460px);max-height:440px;width:auto;height:auto;
  object-fit:contain;margin-inline:auto;display:block}
body.dv-axon-4aud .hero-shot img{max-height:340px;width:auto;margin-inline:auto}
/* un bloc sans visuel ne garde pas une colonne vide */
.split.solo{grid-template-columns:1fr}
.split.solo .stack{max-width:74ch;margin-inline:auto;text-align:left}
.split.solo .stack .lede{max-width:none}
/* la grille d'equipe : portraits normes, nom et role sous la photo */
.team{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(18px,2.2vw,32px);
  margin-top:clamp(30px,3.4vw,46px)}
.team figure{margin:0}
.team img{width:100%;aspect-ratio:3/4;object-fit:cover;object-position:center top;
  border-radius:var(--r-md);box-shadow:var(--hairline),var(--amb-2)}
.team figcaption{margin-top:12px;color:var(--muted);font-size:13.5px;line-height:1.5}
.team figcaption b{display:block;color:var(--deepest);font-weight:600;font-size:15px}
@media (max-width:1040px){.team{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.team{grid-template-columns:1fr}}
.door-lines{color:var(--muted);font-size:15px;line-height:1.7}
.views-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2vw,28px);
  margin-top:clamp(28px,3.2vw,44px)}
.views-3 figure{margin:0}
.views-3 img{width:100%;aspect-ratio:3/2;object-fit:cover;border-radius:var(--r-md);
  box-shadow:var(--hairline),var(--amb-2)}
@media (max-width:820px){.views-3{grid-template-columns:1fr}}
/* ---------- « il faut aussi ceci » : l'unite, puis ses pieces requises ----------
   Le DTPI se vend sans sondes (liste de prix : « Probes NOT included »). La page
   le disait dans un paragraphe, au milieu d'une galerie qui melangeait un
   capteur d'humidite et une sonde de batterie ; elle le MONTRE maintenant :
   l'interface a gauche, les trois longueurs a droite. (LC, 2026-08-21) */
.needs-row{display:grid;grid-template-columns:minmax(0,300px) auto minmax(0,1fr);
  gap:clamp(18px,2.4vw,34px);align-items:center;margin-top:clamp(26px,3vw,40px)}
.needs-unit,.needs-parts{display:grid;gap:10px}
.needs-unit{justify-items:center;text-align:center}
.needs-unit img{max-width:100%;max-height:230px;width:auto;height:auto;object-fit:contain;
  filter:var(--lift)}
.needs-tag{font:600 11.5px/1 var(--font-tech);letter-spacing:.12em;text-transform:uppercase;
  color:var(--mid)}
.needs-sku{font:600 15px/1.2 var(--font-tech);color:var(--primary)}
.needs-nm{font-size:14px;line-height:1.5;color:var(--muted);max-width:34ch}
.needs-arrow svg{width:30px;height:30px;stroke:var(--signal);stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.needs-list{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.needs-list li{display:grid;grid-template-columns:64px minmax(0,1fr);gap:14px;
  align-items:center;padding:12px 16px;border-radius:var(--r-md);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1)}
.needs-list img{width:100%;max-height:44px;height:auto;object-fit:contain}
.needs-list .sk{display:block;font:600 13px/1.2 var(--font-tech);letter-spacing:.03em;
  color:var(--primary)}
.needs-list .nm{display:block;margin-top:2px;font-size:13.5px;line-height:1.4;
  color:var(--muted)}
.needs-parts .btn{justify-self:start;margin-top:6px}
@media (max-width:860px){
  .needs-row{grid-template-columns:1fr}
  .needs-arrow{justify-self:center;transform:rotate(90deg)}
}
/* ---------- galerie produit ---------- */
/* La hauteur de scene vit dans UNE variable, lue par la scene ET par l'image.
   `max-height:100%` ne se resout pas sur une image posee en zone de grille (piege
   deja paye) : l'AXON-8D, en portrait, debordait de 111 px sous le cadre. */
.pgal{display:grid;gap:clamp(12px,1.4vw,18px);--pg-h:clamp(330px,40vw,520px)}
.pg-stage{position:relative;display:grid;place-items:center;overflow:hidden;
  /* HAUTEUR FIXE, pas un ratio. Les vues d'un meme produit vont de 4,20 (le rack,
     large et bas) a 0,51 (une sonde, en portrait) : aucun ratio unique ne les
     contient. Un cadre 16/10 rapetissait les schemas annotes au point de rendre
     leurs legendes illisibles (LC, 2026-08-16 : « le gabarit est trop petit en
     hauteur pour laisser voir l'image au complet »). Une hauteur fixe tient la
     mise en page et laisse chaque vue occuper toute la place disponible. */
  height:var(--pg-h);
  /* pas de boite : les visuels sont detoures et flottent, conformement au design
     system (« images jamais en boite sauf produits en tuile et CTA »). */
  border-radius:var(--r-md);background:transparent;
  outline:none}
.pg-stage:focus-visible{box-shadow:0 0 0 2px var(--signal)}
.pg-shot{grid-area:1/1;margin:0;width:100%;height:100%;display:grid;place-items:center;
  opacity:0;transform:scale(.985);pointer-events:none;
  transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease)}
.pg-shot.on{opacity:1;transform:none}
.pg-shot img{max-width:100%;max-height:var(--pg-h);width:auto;height:auto;object-fit:contain;
  filter:var(--lift-lg)}
/* Pas de zoom au survol : retire le 2026-08-21 a la demande de LC. */
.pg-thumbs{display:flex;flex-wrap:wrap;gap:10px}
.pg-thumbs:empty,.pgal:has(.pg-thumb:only-child) .pg-thumbs{display:none}
.pg-thumb{flex:0 0 auto;width:clamp(58px,6vw,74px);aspect-ratio:1;padding:6px;border:0;
  cursor:pointer;border-radius:10px;background:var(--panel);
  box-shadow:inset 0 0 0 1px var(--border);position:relative;overflow:hidden;
  transition:background var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.pg-thumb::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;
  background:var(--signal);transform:scaleX(0);transform-origin:0 50%;
  transition:transform var(--t-base) var(--ease)}
.pg-thumb.on::before{transform:scaleX(1)}
.pg-thumb:hover{transform:translateY(-2px);background:var(--white)}
.pg-thumb.on{background:var(--white);box-shadow:var(--hairline),var(--amb-1)}
.pg-thumb img{width:100%;height:100%;object-fit:contain}
/* sans JS : toutes les vues restent visibles, rien ne se cache derriere un etat */
.no-js .pg-stage{height:auto;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,180px),1fr));gap:10px;padding:10px}
.no-js .pg-shot{opacity:1;transform:none;position:static}
.no-js .pg-thumbs{display:none}
@media (max-width:900px){.pgal{--pg-h:clamp(280px,58vw,420px)}}
/* ---------- le bloc produit ---------- */
.pcard{display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr);
  gap:clamp(28px,3.4vw,60px);align-items:center;margin-top:clamp(10px,1.4vw,22px)}
.pcard,.pcard-info{position:relative;z-index:2}
/* l'onde accompagne l'unite a gauche : centrer son masque sur la colonne du
   produit, sinon ses traits traversent le lede et les specifications. */
.hero:has(.pcard) .hero-wave{-webkit-mask-image:radial-gradient(64% 86% at 30% 44%,#000 20%,transparent 72%);
  mask-image:radial-gradient(64% 86% at 30% 44%,#000 20%,transparent 72%);opacity:.42}
.pcard-info>*+*{margin-top:clamp(14px,1.6vw,20px)}
.pcard-info h1{font-size:clamp(2rem,3.6vw,3rem);line-height:1.06}
.pcard-info .lede{max-width:52ch}
.pcard-key{margin-top:clamp(18px,2vw,26px);max-width:none}
.pcard-key .spec-row{padding:10px 0}
.pcard-back{margin-top:clamp(16px,1.8vw,22px)}
@media (max-width:960px){.pcard{grid-template-columns:1fr}}
/* les onglets : un seul endroit pour le detail */
.ptabs{margin-top:clamp(6px,1vw,14px)}
/* le detail a gauche, la colonne de documents a droite, centree en hauteur en
   face du contenu (LC, 2026-08-16) */
.ptabs{display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(26px,3.4vw,58px);align-items:center}
.ptab-dl{display:flex;flex-direction:column;align-items:stretch;gap:10px;
  min-width:clamp(200px,17vw,246px)}
.ptab-dl .btn{justify-content:space-between;padding:12px 12px 12px 20px;font-size:13.5px}
.ptab-dl .bub{width:30px;height:30px}
@media (max-width:900px){.ptabs{grid-template-columns:1fr}
  .ptab-dl{flex-direction:row;flex-wrap:wrap;min-width:0}}
.ptab-bar{display:flex;flex-wrap:wrap;gap:6px;padding:5px;border-radius:12px;
  background:var(--white);box-shadow:var(--hairline),var(--amb-1);width:fit-content}
.ptab{border:0;cursor:pointer;background:none;border-radius:9px;padding:11px 20px;
  font:600 13px/1 var(--font-body);color:var(--muted);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.ptab:hover{color:var(--deepest)}
.ptab.on{background:var(--deep-field);color:#fff}
.ptab-panel{display:none;margin-top:clamp(24px,2.8vw,38px)}
.ptab-panel.on{display:block}
/* le tableau de specifications */
.specs-table{margin:clamp(20px,2.4vw,34px) 0 0;display:grid;gap:0;max-width:74ch}
.spec-row{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:18px;
  padding:14px 0;border-top:1px solid var(--border)}
.spec-row:last-child{border-bottom:1px solid var(--border)}
.spec-row dt{margin:0;font:600 10.5px/1.6 var(--font-tech);letter-spacing:.17em;
  text-transform:uppercase;color:var(--primary)}
.spec-row dd{margin:0;color:var(--deepest);font-size:15.5px;line-height:1.6}
@media (max-width:700px){.spec-row{grid-template-columns:1fr;gap:4px}}
/* Un visuel detoure ne se pose pas dans une boite : le degrade gris de .pic
   annulerait la transparence (LC, 2026-08-20). */
.pic.pic-cut{background:none;padding:0;aspect-ratio:auto}
/* ---------- catalogue : plateformes ---------- */
.pl-wrap{display:grid;gap:clamp(30px,3.4vw,48px);margin-top:clamp(22px,2.6vw,34px)}
.pl-h{font:600 10.5px/1 var(--font-tech);letter-spacing:.18em;text-transform:uppercase;
  color:var(--primary);margin:0 0 14px}
.pl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,232px),1fr));
  gap:clamp(12px,1.4vw,18px)}
.pl-card{display:grid;gap:8px;padding:18px;border-radius:var(--r-md);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1);text-decoration:none;color:var(--deepest);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.pl-card:hover{transform:translateY(-3px);box-shadow:var(--hairline),var(--amb-2)}
.pl-pic{display:grid;place-items:center;height:104px}
.pl-pic img{max-width:92%;max-height:104px;width:auto;height:auto;object-fit:contain}
.pl-name{font-weight:600;font-size:15px}
.pl-line{color:var(--muted);font-size:13px;line-height:1.55}
.pl-card .bub{width:28px;height:28px;border-radius:var(--r-bub);display:grid;
  place-items:center;background:rgba(0,42,60,.055);justify-self:start;
  transition:background var(--t-fast) var(--ease)}
/* hors d'un .btn, l'icone n'herite pas du trait : sans ca la fleche se rend
   en aplat noir. */
.pl-card .bub svg{width:14px;height:14px;stroke:currentColor;stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.pl-card:hover .bub{background:rgba(0,168,224,.16)}
/* ---------- catalogue : la grille filtrable ---------- */
.ct-bar{display:flex;flex-wrap:wrap;gap:8px;margin:clamp(20px,2.4vw,30px) 0 0}
.ct-chip{border:0;cursor:pointer;border-radius:10px;padding:10px 16px;background:var(--white);
  box-shadow:var(--hairline);color:var(--deepest);font:600 13px/1 var(--font-body);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease)}
.ct-chip i{font-style:normal;font-size:11px;color:var(--muted);margin-left:5px}
.ct-chip:hover{box-shadow:var(--hairline),var(--amb-1)}
.ct-chip.on{background:var(--deep-field);color:#fff;box-shadow:var(--amb-2)}
.ct-chip.on i{color:rgba(255,255,255,.7)}
.ct-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,224px),1fr));
  gap:clamp(12px,1.4vw,18px);margin-top:clamp(20px,2.4vw,30px)}
.ct-card{display:grid;gap:7px;align-content:start;padding:16px;border-radius:var(--r-md);
  background:var(--white);box-shadow:var(--hairline),var(--amb-1)}
.ct-card[hidden]{display:none}
.ct-pic{display:grid;place-items:center;height:118px}
.ct-pic img{max-width:88%;max-height:118px;width:auto;height:auto;object-fit:contain}
.ct-name{margin:0;font-size:14.5px;font-weight:600;line-height:1.35}
.ct-line{margin:0;color:var(--muted);font-size:12.5px;line-height:1.55}
.ct-sku{font:600 10px/1 var(--font-tech);letter-spacing:.14em;text-transform:uppercase;
  color:var(--primary)}
/* ---------- nouvelles : l'index ---------- */
.nw-bar{display:flex;flex-wrap:wrap;align-items:end;justify-content:space-between;
  gap:clamp(14px,1.8vw,24px);margin-top:clamp(20px,2.4vw,30px)}
.nw-year{display:grid;gap:6px}
.nw-year span{font:600 10px/1 var(--font-tech);letter-spacing:.17em;text-transform:uppercase;
  color:var(--muted)}
.nw-year select{border:0;border-radius:10px;padding:11px 14px;background:var(--white);
  box-shadow:var(--hairline);font:600 13px/1 var(--font-body);color:var(--deepest);cursor:pointer}
.nw-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,296px),1fr));
  gap:clamp(14px,1.6vw,20px);margin-top:clamp(22px,2.6vw,32px)}
.nw-card{display:grid;gap:10px;align-content:start;padding:16px;border-radius:var(--r-md);
  background:var(--white);box-shadow:var(--hairline),var(--amb-1);text-decoration:none;
  color:var(--deepest);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.nw-card:hover{transform:translateY(-3px);box-shadow:var(--hairline),var(--amb-2)}
.nw-card[hidden]{display:none}
.nw-pic{display:block;overflow:hidden;border-radius:10px;background:var(--inset);
  aspect-ratio:16/10}
.nw-pic img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform var(--t-slow) var(--ease)}
.nw-card:hover .nw-pic img{transform:scale(1.03)}
.nw-meta{display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  font:600 10px/1 var(--font-tech);letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted)}
.nw-cat{color:var(--primary)}
.nw-title{font-weight:600;font-size:16px;line-height:1.35}
.nw-lede{color:var(--muted);font-size:13.5px;line-height:1.6}
.nw-card .bub{width:28px;height:28px;border-radius:var(--r-bub);display:grid;place-items:center;
  background:rgba(0,42,60,.055);justify-self:start;
  transition:background var(--t-fast) var(--ease)}
.nw-card .bub svg{width:14px;height:14px;stroke:currentColor;stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.nw-card:hover .bub{background:rgba(0,168,224,.16)}
/* la plus recente tient deux colonnes et met son image en avant */
.nw-lead{grid-column:span 2}
.nw-lead .nw-pic{aspect-ratio:2/1}
.nw-lead .nw-title{font-size:clamp(1.25rem,2vw,1.7rem);line-height:1.2}
.nw-lead .nw-lede{font-size:15px}
@media (max-width:700px){.nw-lead{grid-column:span 1}}
/* ---------- nouvelles : la barre laterale de l'article ---------- */
.po-wrap{display:grid;grid-template-columns:minmax(0,1fr) clamp(250px,22vw,306px);
  gap:clamp(28px,4vw,72px);align-items:start}
.po-side{display:grid;gap:clamp(18px,2vw,26px);position:sticky;top:calc(var(--nav-h) + 22px)}
.sd-block{display:grid;gap:4px}
.sd-h{margin:0 0 10px;font:600 10px/1 var(--font-tech);letter-spacing:.18em;
  text-transform:uppercase;color:var(--primary)}
.sd-item{display:grid;gap:3px;padding:11px 0;text-decoration:none;color:var(--deepest);
  border-top:1px solid var(--border);transition:color var(--t-fast) var(--ease)}
.sd-item:first-of-type{border-top:0;padding-top:0}
.sd-item:hover{color:var(--primary)}
.sd-date{font:600 9.5px/1 var(--font-tech);letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted)}
.sd-t{font-size:13.5px;line-height:1.45;font-weight:500}
.sd-topic{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 0;text-decoration:none;color:var(--deepest);font-size:13.5px;
  border-top:1px solid var(--border);transition:color var(--t-fast) var(--ease)}
.sd-topic:first-of-type{border-top:0;padding-top:0}
.sd-topic:hover{color:var(--primary)}
.sd-topic i{font-style:normal;font-size:11px;color:var(--muted)}
.sd-cta{padding:clamp(18px,2vw,24px);border-radius:var(--r-md);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1);display:grid;gap:8px;justify-items:start}
.sd-cta-t{margin:0;font-weight:600;font-size:15px}
.sd-cta-l{margin:0 0 6px;color:var(--muted);font-size:13px;line-height:1.55}
@media (max-width:900px){.po-wrap{grid-template-columns:1fr}
  .po-side{position:static}}
/* ---------- nouvelles : un article ---------- */
.po-hero h1{font-size:clamp(1.9rem,3.4vw,2.9rem);line-height:1.08;max-width:20ch}
.po-back{margin-bottom:clamp(14px,1.6vw,20px)}
.po-date{margin-top:clamp(12px,1.4vw,18px);font:600 10.5px/1 var(--font-tech);
  letter-spacing:.17em;text-transform:uppercase;color:var(--muted)}
.po-body{max-width:74ch}
.po-body p{margin:0 0 1.15em}
.po-body h2{font-size:clamp(1.25rem,1.9vw,1.55rem);margin:1.8em 0 .6em}
.po-body h3{font-size:clamp(1.08rem,1.5vw,1.25rem);margin:1.5em 0 .5em}
.po-body ul,.po-body ol{margin:0 0 1.15em;padding-left:1.25em}
.po-body li{margin:0 0 .45em}
.po-body a{color:var(--primary);text-underline-offset:3px}
.po-body a:hover{color:var(--primary-hover)}
.po-body img{max-width:100%;height:auto;border-radius:var(--r-md);margin:1.4em 0;
  box-shadow:var(--hairline),var(--amb-1)}
.po-body blockquote{margin:1.6em 0;padding:2px 0 2px 20px;border-left:2px solid var(--signal);
  color:var(--deepest)}
.po-body + .po-back{margin-top:clamp(30px,3.4vw,46px)}
/* ---------- carte des representants ---------- */
.repmap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.86fr);
  gap:clamp(24px,3vw,48px);align-items:start;margin-top:clamp(30px,3.4vw,48px)}
.rm-row{display:flex;gap:5px;margin-bottom:5px}
.rm-cell,.rm-gap{width:100%;aspect-ratio:1;border-radius:7px;flex:1 1 0;min-width:26px}
.rm-gap{visibility:hidden}
/* Les tuiles se distinguent par la COULEUR, jamais par l'effacement : une opacite
   a .34 rendait les etats non selectionnes illisibles (LC, 2026-08-16). */
.rm-cell{border:0;cursor:pointer;background:var(--panel);color:var(--primary);
  box-shadow:inset 0 0 0 1px var(--border);
  font:600 10.5px/1 var(--font-tech);letter-spacing:.04em;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.rm-cell:hover{transform:translateY(-2px);background:var(--inset);color:var(--deepest)}
.rm-cell.lit{background:var(--deep-field);color:#fff;box-shadow:none}
.rm-cell.dim{opacity:1;background:var(--panel);color:var(--primary)}
.rm-cell:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
.rm-side{position:relative;min-height:340px}
.rm-panel{display:none;gap:18px;padding-top:20px;border-top:2px solid var(--signal)}
.rm-panel.on{display:grid;grid-template-columns:minmax(0,150px) minmax(0,1fr)}
.rm-mark{display:grid;place-items:center;min-height:60px}
.rm-mark img{max-width:100%;max-height:76px;width:auto;height:auto;object-fit:contain}
.rm-panel h3{font-size:1.125rem;line-height:1.3}
.rm-addr{margin-top:10px;color:var(--muted);font-size:14px;line-height:1.6}
.rm-contact{list-style:none;padding:0;margin:14px 0 0;font-size:14px;line-height:1.7}
.rm-contact span{display:inline-block;min-width:96px;color:var(--muted);
  font:600 10px/1.7 var(--font-tech);letter-spacing:.16em;text-transform:uppercase}
.rm-terr{margin-top:14px;font-size:14px;line-height:1.6;color:var(--deepest)}
.rm-terr span{display:block;color:var(--primary);
  font:600 10px/1.7 var(--font-tech);letter-spacing:.16em;text-transform:uppercase}
.rm-panel .tlink{margin-top:16px}
.rm-legend{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:clamp(22px,2.6vw,34px)}
.rm-key{border:0;background:none;cursor:pointer;display:inline-flex;align-items:center;gap:8px;
  padding:6px 0;color:var(--muted);font-size:13px}
.rm-key i{width:11px;height:11px;border-radius:3px;background:var(--panel)}
.rm-key.on{color:var(--deepest)}
.rm-key.on i{background:var(--deep-field)}
@media (max-width:960px){.repmap{grid-template-columns:1fr}
  .rm-panel.on{grid-template-columns:1fr}.rm-cell{font-size:9px}}
/* le hero sans montage produit : la colonne de texte respire sur toute la mesure */
.hero-grid:not(:has(.hero-shot)){grid-template-columns:minmax(0,1fr)}
.hero-grid:not(:has(.hero-shot)) .hero-say .lede{max-width:64ch}
@media (max-width:960px){.split{grid-template-columns:1fr}.split.flip .pic{order:0}}
/* ---------- ajouts de la page BDA & DAS Monitoring ---------- */
.split.brochure-row{margin-top:clamp(40px,4.6vw,64px);align-items:center;
  grid-template-columns:minmax(0,260px) minmax(0,1fr)}
.brochure-row .pic img{max-width:min(100%,250px);width:auto;margin-inline:auto;display:block}
.split.flip .pic{order:-1}
.pkg-row{align-items:center;margin-top:clamp(32px,3.6vw,50px)}
.pkg-badges{display:flex;flex-wrap:wrap;align-items:center;gap:clamp(12px,1.6vw,22px);
  margin-top:clamp(18px,2vw,26px)}
.pkg-badges img{width:clamp(62px,6.4vw,84px);height:auto}
.note{margin-top:clamp(28px,3vw,42px);color:var(--muted);font-size:14px;line-height:1.6;
  max-width:80ch}
.fviz .views-2{grid-template-columns:1fr;gap:14px}
@media (max-width:900px){
  .split{grid-template-columns:1fr}
  .split.flip .pic{order:0}
  .feats{grid-template-columns:1fr}
}
/* -- echelle des visuels : aucun raster ne depasse son texte (LC 2026-08-15) -- */
/* le diagramme NOC est natif en 861 px : le plafond de 980 px l'agrandissait au-dela
   de sa resolution, d'ou le rendu mou et surdimensionne. */
body.dv-bda-das .wide-viz img{max-width:min(100%,740px)}
#offer .split .pic img{max-width:min(100%,540px);margin-inline:auto;display:block}
#offer .brochure-row .pic img{max-width:min(100%,250px)}
#packages .split .pic img{max-width:min(100%,520px);margin-inline:auto;display:block}
#no-snmp .split .pic img{max-width:min(100%,460px);margin-inline:auto;display:block}
body.dv-bda-das .fviz img{max-width:min(100%,300px)}
.fviz .views-2 img{max-width:100%}
/* le moteur de scrollytelling clone le .fviz dans le panneau collant : les regles
   .fviz ne suivent pas le clone, il faut re-plafonner cote panneau (les icones
   rendaient a leur taille native, jusqu'a 544 px). */
.js-show .show-visual .viz img{max-width:min(100%,300px);max-height:54vh;width:auto;
  height:auto;margin-inline:auto;display:block}
.js-show .show-visual .viz .views-2{width:100%}
.js-show .show-visual .viz .views-2 img{max-width:100%}
/* ============================================================
   DAVICOM . le localisateur de revendeurs
   Vocabulaire : celui du design system web (v1.1.0). Blanc et
   aere, cyan graphique seulement, rectangles a 10 px, jamais de
   pastille. Le module emprunte la voix d'instrument des autres
   pages : libelles en mono, compteurs a droite, rail de cote.

   REGLE DE DONNEES : rien de ce que ce CSS habille ne contient
   de courriel de dealer, et la rue n'apparait que dans la fiche
   ouverte une par une. Voir davicom-dealers.php.
   ============================================================ */

.dlf{margin-top:clamp(26px,3vw,42px)}
/* ---------- la console de filtres ---------- */
.dlf-console{background:var(--white);border:1px solid var(--border);
  border-radius:var(--r-lg);padding:clamp(18px,2.2vw,28px);box-shadow:var(--lift)}
.dlf-legend{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  margin-bottom:12px}
.dlf-legend .mono{color:var(--primary)}
.dlf-legend .dlf-count{font:600 12px/1 var(--font-tech);color:var(--muted);
  letter-spacing:.04em}
/* Le rail des regions. Des rectangles, pas des pastilles : la regle de LC
   s'applique aux boutons de filtre comme au reste. */
.dlf-regions{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;
  border:0;padding:0;margin:0}
.dlf-regions button{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:11px 13px;border:1px solid var(--border);border-radius:10px;
  background:var(--white);color:var(--deepest);cursor:pointer;text-align:left;
  font:600 14px/1.2 var(--font-body);
  transition:border-color var(--t-fast) var(--ease),background var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease)}
/* Le libelle est un `span` explicite, pas un noeud texte nu. Un noeud texte
   dans un conteneur flex devient un « element anonyme » : il occupe bien sa
   boite au calcul, mais son rendu depend du navigateur et de la cascade
   environnante, et ici il ne se peignait pas alors que sa geometrie etait
   juste (mesure : x=63, largeur 51,3 px, couleur #002a3c, opacite 1). Un
   element reel supprime toute la classe de probleme, et permet en prime de
   tronquer proprement « Latin America » dans un bouton etroit. */
.dlf-regions button span{flex:1 1 auto;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.dlf-regions button i{flex:none;font:600 11px/1 var(--font-tech);font-style:normal;
  color:var(--muted);letter-spacing:.04em}
.dlf-regions button:hover{border-color:var(--primary);transform:translateY(-1px)}
/* Le survol va vers le fonce, jamais vers le clair. */
.dlf-regions button[aria-pressed="true"]{background:var(--primary);border-color:var(--primary);
  color:var(--white)}
.dlf-regions button[aria-pressed="true"] i{color:rgba(255,255,255,.72)}
.dlf-regions button[aria-pressed="true"]:hover{background:var(--primary-hover);
  border-color:var(--primary-hover)}
.dlf-regions button:focus-visible{outline:var(--focus)}
/* Une region sans dealer publie ne se clique pas : proposer un filtre qui ne
   rend rien est une promesse cassee. */
.dlf-regions button[disabled]{opacity:.42;cursor:not-allowed}
.dlf-regions button[disabled]:hover{transform:none;border-color:var(--border)}
.dlf-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) auto;gap:12px;
  align-items:end;margin-top:16px;padding-top:16px;border-top:1px solid var(--border)}
.dlf-row label{display:block}
.dlf-row .mono{display:block;margin-bottom:7px;color:var(--primary)}
.dlf-row select,.dlf-row input{width:100%;padding:10px 12px;border:1px solid var(--border);
  border-radius:10px;background:var(--white);color:var(--deepest);
  font:400 15px/1.3 var(--font-body)}
.dlf-row select:focus-visible,.dlf-row input:focus-visible{outline:var(--focus)}
.dlf-clear{padding:10px 16px;border:1px solid var(--border);border-radius:10px;
  background:var(--white);color:var(--muted);cursor:pointer;
  font:600 13px/1.3 var(--font-body);white-space:nowrap;
  transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.dlf-clear:hover{color:var(--deepest);border-color:var(--primary)}
/* ---------- l'etat de depart et les etats vides ---------- */
.dlf-out{margin-top:clamp(20px,2.4vw,32px);min-height:180px}
.dlf-note{display:flex;gap:14px;align-items:flex-start;padding:clamp(20px,2.4vw,30px);
  border:1px dashed var(--border);border-radius:var(--r-lg);background:var(--off-white)}
.dlf-note svg{flex:none;width:22px;height:22px;stroke:var(--signal);stroke-width:1.7;
  fill:none;margin-top:2px}
.dlf-note p{margin:0;color:var(--muted);font-size:15px;line-height:1.6;max-width:62ch}
.dlf-note strong{color:var(--deepest)}
/* ---------- les cartes de resultat ---------- */
.dlf-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.6vw,20px)}
.dlf-card{display:flex;flex-direction:column;gap:9px;padding:clamp(18px,2vw,22px);
  background:var(--white);border:1px solid var(--border);border-radius:var(--r-lg);
  transition:border-color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease)}
.dlf-card:hover{border-color:var(--primary);transform:translateY(-2px);box-shadow:var(--lift)}
.dlf-card h3{font:600 1.0625rem/1.32 var(--font-display);color:var(--deepest);margin:0}
.dlf-where{font:400 14px/1.5 var(--font-body);color:var(--muted)}
.dlf-tag{align-self:flex-start;padding:4px 9px;border-radius:6px;background:var(--off-white);
  border:1px solid var(--border);font:600 11px/1.25 var(--font-tech);color:var(--primary);
  letter-spacing:.03em}
.dlf-links{display:flex;flex-wrap:wrap;gap:8px 16px;margin-top:auto;padding-top:11px;
  border-top:1px solid var(--border)}
.dlf-links a,.dlf-links button{font:600 13px/1.3 var(--font-body);color:var(--primary);
  background:none;border:0;padding:0;cursor:pointer;text-decoration:none;
  border-bottom:1px solid transparent;transition:border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease)}
.dlf-links a:hover,.dlf-links button:hover{color:var(--primary-hover);
  border-bottom-color:currentColor}
.dlf-links a:focus-visible,.dlf-links button:focus-visible{outline:var(--focus)}
/* ---------- la pagination ---------- */
.dlf-more{display:flex;align-items:center;justify-content:center;gap:16px;
  margin-top:clamp(20px,2.4vw,30px)}
.dlf-more button{padding:10px 20px;border:1px solid var(--border);border-radius:10px;
  background:var(--white);color:var(--deepest);cursor:pointer;
  font:600 14px/1.3 var(--font-body);
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.dlf-more button:hover:not([disabled]){border-color:var(--primary);color:var(--primary)}
.dlf-more button[disabled]{opacity:.4;cursor:not-allowed}
.dlf-more span{font:600 12px/1 var(--font-tech);color:var(--muted);letter-spacing:.04em}
/* ---------- la fiche ouverte et le relais de contact ---------- */
.dlf-dlg{border:0;padding:0;border-radius:var(--r-lg);max-width:min(92vw,560px);width:100%;
  background:var(--white);box-shadow:var(--lift-lg);color:var(--deepest)}
.dlf-dlg::backdrop{background:rgba(0,32,46,.52)}
.dlf-dlg-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  padding:22px 24px 0}
.dlf-dlg-head h3{margin:0;font:600 1.1875rem/1.3 var(--font-display)}
.dlf-dlg-head .dlf-where{margin-top:5px}
.dlf-dlg-body{padding:18px 24px 24px}
.dlf-dlg form{display:grid;gap:12px;margin-top:14px}
.dlf-dlg .dlf-two{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.dlf-dlg label{display:block}
.dlf-dlg .mono{display:block;margin-bottom:6px;color:var(--primary)}
.dlf-dlg input,.dlf-dlg textarea{width:100%;padding:10px 12px;border:1px solid var(--border);
  border-radius:10px;font:400 15px/1.4 var(--font-body);color:var(--deepest);
  background:var(--white)}
.dlf-dlg textarea{min-height:104px;resize:vertical}
.dlf-dlg input:focus-visible,.dlf-dlg textarea:focus-visible{outline:var(--focus)}
/* Le pot de miel. Masque a l'oeil et au lecteur d'ecran, visible pour un robot
   qui remplit tout ce qu'il trouve. `display:none` serait ignore par certains :
   on le sort du flux au lieu de le retirer. */
.dlf-hp{position:absolute!important;left:-9999px!important;width:1px!important;
  height:1px!important;overflow:hidden!important}
.dlf-dlg .dlf-send{justify-self:start;padding:11px 22px;border:0;border-radius:10px;
  background:var(--primary);color:var(--white);cursor:pointer;
  font:600 15px/1.3 var(--font-body);
  transition:background var(--t-fast) var(--ease)}
.dlf-dlg .dlf-send:hover{background:var(--primary-hover)}
.dlf-dlg .dlf-send[disabled]{opacity:.55;cursor:progress}
.dlf-msg{margin:0;font:400 14px/1.6 var(--font-body)}
.dlf-msg.ok{color:#1a7f4b}
.dlf-msg.err{color:#9b2c2c}
.dlf-close{flex:none;width:32px;height:32px;border:1px solid var(--border);border-radius:8px;
  background:var(--white);cursor:pointer;display:grid;place-items:center}
.dlf-close svg{width:14px;height:14px;stroke:var(--deepest);stroke-width:1.9;fill:none}
.dlf-close:hover{border-color:var(--primary)}
/* ---------- replis ---------- */
@media (max-width:1040px){
  .dlf-regions{grid-template-columns:repeat(3,minmax(0,1fr))}
  .dlf-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dlf-row{grid-template-columns:1fr 1fr;}
  .dlf-clear{grid-column:1/-1;justify-self:start}
}
@media (max-width:680px){
  .dlf-regions{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dlf-grid{grid-template-columns:1fr}
  .dlf-row{grid-template-columns:1fr}
  .dlf-dlg .dlf-two{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  .dlf-card,.dlf-regions button{transition:none}
  .dlf-card:hover,.dlf-regions button:hover{transform:none}
}
/* ---------- le formulaire de candidature dealer ---------- */
.dva{margin-top:clamp(26px,3vw,42px);display:grid;gap:clamp(18px,2.2vw,28px);
  max-width:900px}
.dva-set{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--white);
  padding:clamp(18px,2.2vw,26px);box-shadow:var(--lift)}
.dva-set legend{padding:0 10px;color:var(--primary)}
.dva-two{display:grid;grid-template-columns:1fr 1fr;gap:14px}
/* L'espacement se pose entre FRERES, quels qu'ils soient : `.dva-two+.dva-two`
   seul laissait « Tell us about yourself » colle a la rangee courriel/telephone,
   parce qu'un `label` pleine largeur n'est pas un `.dva-two`. */
.dva-set > * + *{margin-top:14px}
.dva-set > legend + *{margin-top:0}
.dva label{display:block}
.dva-lbl{display:block;margin-bottom:6px;font:600 13px/1.3 var(--font-body);
  color:var(--deepest)}
.dva-lbl em{font-style:normal;color:var(--signal)}
.dva input,.dva select,.dva textarea{width:100%;padding:10px 12px;border:1px solid var(--border);
  border-radius:10px;background:var(--white);color:var(--deepest);
  font:400 15px/1.4 var(--font-body)}
.dva textarea{resize:vertical;min-height:118px}
.dva input:focus-visible,.dva select:focus-visible,.dva textarea:focus-visible{
  outline:var(--focus)}
.dva-checks{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px}
.dva-check{display:flex;align-items:center;gap:9px;padding:9px 11px;border:1px solid var(--border);
  border-radius:10px;cursor:pointer;font:400 14px/1.3 var(--font-body);
  transition:border-color var(--t-fast) var(--ease)}
.dva-check:hover{border-color:var(--primary)}
.dva-check input{width:auto;padding:0;flex:none}
.dva-check span{color:var(--deepest)}
.dva-foot{display:flex;flex-wrap:wrap;align-items:center;gap:18px}
.dva-fine{margin:0;font:400 13px/1.6 var(--font-body);color:var(--muted)}
.dva-fine a{color:var(--primary)}
@media (max-width:900px){
  .dva-two{grid-template-columns:1fr}
  .dva-checks{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:600px){.dva-checks{grid-template-columns:1fr}}
/* Un libelle de champ visuellement masque mais lu par les lecteurs d'ecran.
   `display:none` le retirerait aussi de l'arbre d'accessibilite. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* ---------- ajouts propres a Broadcast ---------- */
body.dv-broadcast .hero-shot img{border-radius:var(--r-md)}
#how .wide-viz img{max-width:min(100%,700px)}
/* les deux appareils broadcast : deux blocs, pas trois cartes egales */
.gear{display:grid;gap:clamp(30px,3.6vw,62px);margin-top:clamp(34px,4vw,56px);
  grid-template-columns:repeat(2,minmax(0,1fr))}
.gear article{display:flex;flex-direction:column;gap:14px;padding-top:20px;
  border-top:2px solid var(--signal)}
.gear .k2{font:600 11px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--primary)}
.gear h3{font-size:clamp(1.125rem,1.5vw,1.3125rem);line-height:1.3}
.gear p{color:var(--muted);font-size:15px;line-height:1.64}
.gear .specs{margin-top:4px}
.gear .tlink{margin-top:auto;align-self:flex-start}
@media (max-width:900px){.gear{grid-template-columns:1fr}}
/* ---------- vignette video (company-overview) ----------
   Une carte, pas une boite : coins arrondis, ombre ambiante, et un badge de
   lecture en rectangle arrondi, jamais une pastille. Le survol fonce le badge,
   il ne l'eclaircit pas (regle du design system sur les etats de survol). */
.vposter{position:relative;display:block;border-radius:var(--r-md);overflow:hidden;
  box-shadow:var(--hairline),var(--amb-3);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.vposter:hover{transform:translateY(-3px);box-shadow:var(--hairline),var(--amb-4)}
.vposter img{display:block;width:100%;height:auto;filter:none}
/* Le badge se pose dans un coin, jamais au centre : au centre il masquait le
   mot-symbole, et le mot-symbole ne se defigure pas (regle de marque). */
.vplay{position:absolute;left:22px;bottom:22px;
  width:58px;height:58px;border-radius:14px;display:grid;place-items:center;
  background:var(--primary);box-shadow:var(--amb-2);
  transition:background var(--t-fast) var(--ease)}
.vposter:hover .vplay{background:#004a66}
.vplay svg{width:26px;height:26px;fill:#fff;stroke:none;margin-left:3px}
.vposter:focus-visible{outline:2px solid var(--primary);outline-offset:4px}
/* en gris sur la crete pale, le stamp disparaissait */
.hero-shot .hero-stamp{color:var(--primary)}
/* Pas de zoom au survol. LC, 2026-08-21 : « ca fait juste gosser ». Une capture de
   workspace se lit en entier ; l'agrandir sous le curseur bouge l'image pendant qu'on
   la lit et n'aide personne. Les vignettes changent de vue, c'est tout. */
.pg-thumbs{display:flex;flex-wrap:wrap;gap:10px}
/* la photo du service de configuration : un rectangle plein prend le rayon des
   grandes surfaces du site, sinon ses angles vifs jurent avec le reste
   (LC, 2026-08-21) */
.hero-shot.shot-photo img,.pic.pic-photo img{border-radius:var(--r-lg)}
.team-grid{display:grid;gap:clamp(28px,3.4vw,56px);grid-template-columns:1.15fr 1fr;
  align-items:start}
.synapse{position:absolute;inset:0;z-index:1;pointer-events:none}
/* la galerie occupe seule la largeur de lecture : plafonnee et centree */
#examples .pgal{max-width:980px}
/* =====================================================================
   Formulaires Davicom : devis a etapes, configurateur, contact general.
   Source unique : scripts/forms.css, injecte par make-forms.py.
   Regles suivies : boutons 10px jamais pastille, hover vers le fonce,
   label AU-DESSUS du champ, erreur SOUS le champ, mono pour les references.
   Mecanique portee de 21st.dev « Wizard Steps » (id 23576) : rail cliquable
   borne au pas le plus loin atteint, transitions orientees par la direction,
   navigation clavier, bouton d'avance a largeur figee.
   ===================================================================== */
.dvf{--err:#9b2c2c;--ok:#12694a}
/* la coquille n'a pas de classe d'accessibilite : elle vit ici */
body.dv-contact-us .dvf .sr-only,body.dv-contact-us .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* ---------- champs ---------- */
.dvf-field{display:block;margin-top:16px}
.dvf-field>label,.dvf-legend{display:block;font:600 12px/1.2 var(--font-tech);
  letter-spacing:.06em;text-transform:uppercase;color:var(--primary);margin-bottom:9px}
.dvf-field .req{color:var(--mid)}
.dvf-field input[type=text],.dvf-field input[type=email],.dvf-field input[type=tel],
.dvf-field input[type=number],.dvf-field select,.dvf-field textarea{
  width:100%;padding:12px 14px;border-radius:var(--r-btn);border:1px solid var(--border);
  background:var(--white);color:var(--text);font:400 16px/1.45 var(--font-body);
  box-shadow:var(--gloss);
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.dvf-field textarea{min-height:118px;resize:vertical}
/* le texte indicatif passe l'AA lui aussi : #8ea3b0 sur blanc plafonnait a 2,7:1.
   Le libelle vit au-dessus du champ, mais un indicatif illisible reste un defaut. */
.dvf-field input::placeholder,.dvf-field textarea::placeholder{color:var(--muted);opacity:1}
.dvf-field input:focus,.dvf-field select:focus,.dvf-field textarea:focus{
  outline:none;border-color:var(--mid);box-shadow:var(--focus)}
.dvf-field .hint{display:block;margin-top:6px;font-size:13px;color:var(--muted)}
.dvf-err{display:none;margin-top:6px;font:500 13px/1.4 var(--font-body);color:var(--err)}
.dvf-field.bad input,.dvf-field.bad select,.dvf-field.bad textarea{border-color:var(--err)}
.dvf-field.bad .dvf-err{display:block}
.dvf-row{display:grid;gap:0 clamp(14px,1.6vw,22px);grid-template-columns:1fr 1fr}
.dvf-row3{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:900px){.dvf-row3{grid-template-columns:1fr 1fr}}
@media (max-width:680px){.dvf-row,.dvf-row3{grid-template-columns:1fr}}
.dvf-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* ---------- puces de choix (application, objet, delai) ---------- */
/* Le choix d'objet est une question a part, pas un champ de plus : il respire
   au-dessus et au-dessous, sinon la rangee de puces se colle au libelle du champ
   suivant (defaut vu par LC le 2026-08-20). */
.dvf-topic{margin-bottom:clamp(26px,3vw,36px)}
.dvf-topic .dvf-legend{margin-bottom:12px}
.dvf-chips{display:flex;flex-wrap:wrap;gap:10px}
.dvf-chips input{position:absolute;opacity:0;pointer-events:none}
.dvf-chips label{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  padding:10px 16px;border-radius:var(--r-tag);background:var(--inset);
  font:500 14px/1 var(--font-body);color:var(--primary);
  box-shadow:inset 0 0 0 1px var(--border);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease)}
/* Meme piege que les rangees du catalogue : `display:inline-flex` bat le style
   navigateur de [hidden], donc filtrer les puces ne cacherait rien sans ceci. */
.dvf-chips label[hidden]{display:none}
.q-scope{color:var(--mid);font-weight:500}
.dvf-chips label:hover{background:#e7eef3}
.dvf-chips input:checked+label{background:var(--primary);color:var(--white);
  box-shadow:inset 0 0 0 1px var(--primary)}
.dvf-chips input:focus-visible+label{box-shadow:var(--focus),inset 0 0 0 1px var(--mid)}
/* ---------- le rail d'etapes ---------- */
.q-rail{display:flex;align-items:center;gap:10px;list-style:none;padding:0;margin:0 0 26px}
.q-rail li{display:flex;align-items:center;gap:10px;flex:1 1 0}
.q-rail li:last-child{flex:0 0 auto}
.q-step{display:inline-flex;align-items:center;gap:10px;border:0;background:none;padding:0;
  cursor:default;font:inherit;color:inherit;border-radius:var(--r-tag)}
.q-rail li[data-done] .q-step,.q-rail li[data-here] .q-step{cursor:pointer}
.q-step .num{width:30px;height:30px;flex:none;border-radius:var(--r-tag);display:grid;
  place-items:center;background:var(--white);color:var(--muted);
  font:600 13px/1 var(--font-tech);box-shadow:inset 0 0 0 1px var(--border),var(--amb-1);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.q-step .lbl{font:600 13px/1 var(--font-body);color:var(--muted);white-space:nowrap;
  transition:color var(--t-fast) var(--ease)}
li[data-here] .q-step .num{background:var(--white);color:var(--primary);transform:scale(1.06);
  box-shadow:inset 0 0 0 2px var(--signal),0 0 0 5px rgba(0,168,224,.14)}
li[data-here] .q-step .lbl{color:var(--deepest)}
li[data-done] .q-step .num{background:var(--primary);color:var(--white);
  box-shadow:inset 0 0 0 1px var(--primary)}
li[data-done] .q-step .lbl{color:var(--primary)}
.q-step:focus-visible{outline:none;box-shadow:var(--focus)}
.q-step .num svg{width:14px;height:14px;stroke:currentColor;stroke-width:2.4;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.q-link{flex:1 1 auto;height:3px;border-radius:2px;background:var(--border);overflow:hidden}
.q-link i{display:block;height:100%;width:100%;transform-origin:left;transform:scaleX(0);
  background:var(--signal);transition:transform var(--t-base) var(--ease)}
li[data-done] .q-link i{transform:scaleX(1)}
@media (max-width:760px){.q-rail .lbl{display:none}.q-rail li{flex:1 1 0}}
/* ---------- les panneaux ----------
   Sans JavaScript la page est complete : tous les panneaux sont ouverts et le
   formulaire poste en natif. Le moteur ne fait qu'ameliorer (regle « no-JS
   fallback » du registre des pieges). */
.q-panel{display:block;margin-top:30px}
.dvf[data-js] .q-panel{display:none;margin-top:0}
.dvf[data-js] .q-panel[data-on]{display:block}
.q-anim{animation:q-in var(--t-base) var(--ease) both}
@keyframes q-in{from{opacity:0;transform:translateX(var(--q-dx,22px))}
                to{opacity:1;transform:none}}
.q-head{margin-bottom:6px;font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.25rem,1.7vw,1.5rem);line-height:1.28;color:var(--deepest)}
.q-sub{font-size:15px;line-height:1.6;color:var(--muted);max-width:62ch}
/* ---------- la porte du depart ----------
   Deux cartes, pas deux onglets. Un onglet dit « regarde ailleurs », une carte
   dit « choisis ». C'est la seule decision de l'etape, elle doit se voir. */
.q-doors{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(14px,1.8vw,22px);margin-top:clamp(22px,2.6vw,32px)}
@media (max-width:760px){.q-doors{grid-template-columns:1fr}}
.q-door{display:flex;flex-direction:column;gap:9px;text-align:left;cursor:pointer;border:0;
  padding:clamp(20px,2.4vw,28px);border-radius:var(--r-lg);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.q-door:hover{transform:translateY(-3px);box-shadow:var(--hairline),var(--amb-2)}
.q-door:focus-visible{outline:none;box-shadow:var(--focus),var(--hairline)}
.q-door[data-on]{box-shadow:inset 0 0 0 2px var(--signal),var(--amb-2)}
.q-dh{font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.0625rem,1.4vw,1.25rem);line-height:1.3;color:var(--deepest)}
.q-dd{font-size:14.5px;line-height:1.6;color:var(--muted)}
.q-door .tlink{margin-top:4px}
.q-doors[data-bad] .q-door{box-shadow:inset 0 0 0 1px rgba(155,44,44,.4),var(--amb-1)}
/* ---------- etape 2 : les produits, sur un seul ecran ----------
   Les plateformes et le catalogue ne sont plus derriere des onglets : ils se
   suivent. Un intertitre discret separe les deux, sans faire croire a un choix
   exclusif. */
/* 🔴 PAS `.q-block + .q-block`. Le panneau NEURO s'intercale entre les deux
   blocs, et **meme cache** il rompt l'adjacence : la marge ne s'appliquait
   jamais et l'intertitre se collait aux tuiles (defaut vu par LC le
   2026-08-20 : « c'est tout colle »). On espace chaque bloc sauf le premier,
   ce qui ne depend plus de ce qui se glisse entre eux. */
.q-block{margin-top:clamp(42px,4.8vw,68px)}
/* le premier bloc respire aussi : colle au paragraphe d'intro, l'intertitre
   « PLATFORMS » se lisait comme la fin de la phrase */
.q-block:first-child{margin-top:clamp(28px,3.2vw,40px)}
.q-bh{display:flex;align-items:center;gap:14px;margin:0 0 22px;
  font:600 12px/1.2 var(--font-tech);letter-spacing:.06em;text-transform:uppercase;
  color:var(--primary)}
.q-bh::after{content:"";flex:1;height:1px;background:var(--border)}
.q-panel.bad .dvf-err{display:block}
/* ---------- etape 2 : le choix des produits ---------- */
/* Les onglets de l'etape 1 sont partis avec la refonte du flot : une porte a
   deux cartes les remplace. Leurs regles sont retirees plutot que gardees au
   cas ou : du CSS sans markup ment sur ce que la page contient. */

.q-pick{display:grid;grid-template-columns:1fr;gap:clamp(20px,2.4vw,34px);align-items:start}
.dvf[data-js] .q-pick{grid-template-columns:minmax(0,1fr) 342px}
/* en une colonne, la configuration passe AU-DESSUS du catalogue : sinon elle
   se retrouve sous une liste qui defile et on choisit a l'aveugle. */
@media (max-width:1040px){.dvf[data-js] .q-pick{grid-template-columns:1fr}
  /* il passe au-dessus de la liste, mais il **reste colle** : c'est en dessous
     de 1040 px qu'on defile le plus longtemps, donc la qu'un panier statique
     disparait le plus vite. */
  .dvf[data-js] .q-sum{order:-1;position:sticky;top:calc(var(--nav-h) + 8px);z-index:3}
  .dvf[data-js] .q-lines{max-height:26vh}}
/* les tuiles de plateforme : zone image a ratio fixe, exception « produits » */
/* huit tuiles, quatre colonnes : la grille est pleine aux deux rangees, et le
   repli 2 puis 1 colonne reste plein lui aussi (piege « arite de grille »). */
/* 🔴 Pas de nombre de colonnes ecrit en dur. Le compte de plateformes bouge :
   huit, puis neuf avec MOSAIC, puis huit de nouveau dans la meme journee. Une
   grille de quatre colonnes nourrie de neuf tuiles rend 4/4/1, et le registre du
   design system a une ligne la-dessus (« arite de grille »).
   `auto-fill` remplit ce qu'il peut et laisse la place libre a droite quand le
   compte ne tombe pas juste, au lieu d'etirer une tuile solitaire sur toute la
   largeur. C'est deja le motif du catalogue produit (`.pl-grid`), donc la page
   parle la meme langue que le reste du site. */
.q-plats{display:grid;gap:clamp(12px,1.4vw,18px);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,224px),1fr))}
@media (max-width:560px){.q-plats{grid-template-columns:1fr}}
.q-plat{display:flex;flex-direction:column;text-align:left;cursor:pointer;border:0;
  padding:0;overflow:hidden;border-radius:var(--r-md);background:var(--white);
  box-shadow:var(--hairline),var(--amb-1);
  transition:box-shadow var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
.q-plat:hover{transform:translateY(-3px);box-shadow:var(--hairline),var(--amb-2)}
.q-plat:focus-visible{outline:none;box-shadow:var(--focus),var(--hairline)}
/* Zone image a hauteur FIXE, pas un ratio : `max-height:100%` ne se resout pas
   dans une zone de grille (piege du registre, paye sur la bande de logos), et
   les silhouettes sont tres inegales (CORTEX en 19 pouces, AXON en boitier
   vertical). Boite fixe + `contain` = une seule echelle apparente. */
.q-plat .pic{height:128px;display:grid;place-items:center;background:var(--inset);
  padding:12px}
.q-plat .pic img{max-width:100%;max-height:104px;width:auto;height:auto;object-fit:contain}
.q-plat .tx{padding:13px 15px 15px;display:flex;flex-direction:column;gap:5px}
.q-plat .nm{font:600 14px/1.3 var(--font-body);color:var(--deepest)}
.q-plat .sk{font:500 12px/1 var(--font-tech);letter-spacing:.04em;color:var(--mid)}
.q-plat[data-in] .sk{color:var(--ok)}
.q-plat[data-in]{box-shadow:inset 0 0 0 2px var(--signal),var(--amb-2)}
/* la recherche et les rangees du catalogue */
/* Le champ de recherche est la porte d'entree des 132 references : il se voit.
   (LC, 2026-08-20 : « que la recherche de produit soit un petit peu plus grosse,
   le champ, pour qu'on puisse bien le voir ».) */
.q-search{position:relative;margin-bottom:20px}
/* 🔴 `width:100%` explicite. Ce champ ne vit PAS dans un `.dvf-field` : il
   n'heritait donc d'aucune largeur et rendait a sa taille par defaut, environ
   200 px, le texte indicatif coupe en plein mot. Grossir la hauteur sans
   donner la largeur ne reglait rien. */
.q-search input{width:100%;padding:16px 18px 16px 52px;font-size:17px;
  border-radius:12px;border:1px solid var(--border);background:var(--white);
  color:var(--text);font-family:var(--font-body);
  box-shadow:var(--gloss),var(--amb-1);
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.q-search input:focus{outline:none;border-color:var(--mid);box-shadow:var(--focus)}
.q-search input::placeholder{font-size:16px}
.q-search svg{position:absolute;left:19px;top:50%;transform:translateY(-50%);
  width:19px;height:19px;stroke:var(--primary);stroke-width:1.9;fill:none;
  stroke-linecap:round;pointer-events:none}
.q-search input:focus+*,.q-search input:focus~svg{stroke:var(--mid)}
.q-secs{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:22px}
.q-secs button{border:0;cursor:pointer;padding:7px 12px;border-radius:var(--r-tag);
  background:var(--inset);color:var(--primary);font:500 13px/1 var(--font-body);
  box-shadow:inset 0 0 0 1px var(--border);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.q-secs button[aria-pressed=true]{background:var(--primary);color:var(--white);
  box-shadow:inset 0 0 0 1px var(--primary)}
.q-secs button:focus-visible{outline:none;box-shadow:var(--focus)}
.q-list{max-height:min(58vh,540px);overflow:auto;overscroll-behavior:contain;
  border-radius:var(--r-md);background:var(--white);box-shadow:var(--hairline)}
/* Une vignette, la reference, le bouton. La colonne de la vignette existe meme
   quand la piece n'en a pas (les licences logicielles n'ont pas de photo) :
   sinon la colonne de texte se decale d'une ligne a l'autre.
   Pas de cadre derriere l'image : ce sont des detourages sur transparence, ils
   se posent comme dans le reste du site, ils ne s'enferment pas. */
/* `content-visibility` a ete retire : il avait ete pose pour une cause qui
   s'est revelee fausse (le navigateur etait tue par un `pkill` trop large, pas
   par la page), et sa hauteur reservee mentait — les descriptions font souvent
   trois lignes, pas 74 px, ce qui faisait sauter le defilement. La page est
   mesuree stable sans lui. */
.q-item{display:grid;grid-template-columns:78px minmax(0,1fr) auto;gap:15px;
  align-items:center;padding:15px;border-top:1px solid var(--border)}
/* La case est LARGE et basse : les RTU sont des chassis 19 pouces, les capteurs
   des boitiers verticaux. Une case carree ecrasait les premiers a la hauteur des
   seconds. Le plafond de hauteur garde malgre tout une seule echelle apparente. */
.q-thumb{width:78px;height:48px;display:grid;place-items:center}
/* 🔴 Pas de `filter` ici. Le design system pose les detourages avec un
   `drop-shadow`, et c'est juste pour un visuel de hero. Repete sur **109
   vignettes dans un conteneur qui defile**, le meme effet force le navigateur a
   rasteriser chaque rangee dans son propre calque, a chaque defilement. Le mode
   sans affichage ne compose pas de calques : il ne peut pas voir ce cout. */
.q-thumb img{max-width:100%;max-height:48px;width:auto;height:auto;object-fit:contain}
@media (max-width:520px){.q-item{grid-template-columns:52px minmax(0,1fr) auto;gap:11px}
  .q-thumb{width:52px;height:38px}.q-thumb img{max-height:38px}}
/* `display:grid` bat le style navigateur de [hidden] : sans cette ligne, filtrer
   ne cacherait rien. Et c'est `:first-child` qui devient faux quand des rangees
   sont cachees, d'ou le trait du haut sur la premiere rangee VISIBLE. */
.q-item[hidden]{display:none}
.q-item:first-child{border-top:0}
.q-item .sk{font:600 12.5px/1.2 var(--font-tech);letter-spacing:.03em;color:var(--primary)}
.q-item .ds{display:block;margin-top:3px;font-size:13.5px;line-height:1.45;color:var(--muted)}
.q-item[data-in]{background:rgba(0,168,224,.05)}
.q-add{display:inline-flex;align-items:center;gap:7px;border:0;cursor:pointer;
  padding:8px 13px;border-radius:var(--r-btn);background:var(--inset);color:var(--primary);
  font:600 13px/1 var(--font-body);box-shadow:inset 0 0 0 1px var(--border);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.q-add:hover{background:var(--primary);color:var(--white)}
.q-add:focus-visible{outline:none;box-shadow:var(--focus)}
.q-empty{padding:28px 16px;text-align:center;color:var(--muted);font-size:14px}
/* ---------- le configurateur NEURO ----------
   Il n'apparait que si un chassis NEURO est dans la configuration. Trois
   contraintes, toutes ecrites : 5 emplacements, au plus 2 cartes relais, au
   moins 1 carte avec la base. Le compteur d'emplacements est la piece maitresse :
   il dit a tout moment ce qu'il reste, au lieu de refuser apres coup. */
.q-neuro{margin-top:20px;border-radius:var(--r-md);background:var(--white);
  box-shadow:inset 0 0 0 2px rgba(0,168,224,.34),var(--amb-1);overflow:hidden}
.q-neuro[hidden]{display:none}
.q-nhead{display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  padding:14px 18px 12px;border-bottom:1px solid var(--border)}
.q-nhead h4{font:600 12px/1.2 var(--font-tech);letter-spacing:.06em;text-transform:uppercase;
  color:var(--primary);margin:0}
/* la bascule « tous pareils / chacun le sien », dans le meme langage que les
   portes de l'etape 1 : un rail clair, l'onglet actif en blanc detache */
.q-nmode{margin-left:auto;display:inline-flex;gap:5px;padding:4px;border-radius:11px;
  background:var(--inset);box-shadow:var(--hairline)}
.q-nmode button{border:0;cursor:pointer;padding:7px 13px;border-radius:var(--r-tag);
  background:transparent;color:var(--primary);font:600 12.5px/1 var(--font-body);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.q-nmode button[aria-pressed=true]{background:var(--white);color:var(--deepest);
  box-shadow:var(--amb-1),var(--hairline)}
.q-nmode button:focus-visible{outline:none;box-shadow:var(--focus)}
/* une tuile par chassis. En dessous de deux, la grille n'a rien a arranger. */
.q-ntiles.multi{display:grid;gap:14px;padding:14px 18px;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,270px),1fr))}
.q-ntiles.multi .q-ntile{border-radius:var(--r-md);background:var(--inset);
  box-shadow:var(--hairline);padding-bottom:6px}
.q-ntiles.multi .q-ncard{padding-left:14px;padding-right:14px;border-top-color:rgba(0,42,60,.09)}
.q-ntiles.multi .q-ntile.empty{box-shadow:inset 0 0 0 1px rgba(155,44,44,.35)}
.q-nth{display:flex;align-items:baseline;gap:10px;padding:12px 18px 8px}
.q-ntiles.multi .q-nth{padding:11px 14px 7px}
.q-nth h5{margin:0;font:600 13px/1.2 var(--font-body);color:var(--deepest)}
.q-slots{margin-left:auto;font:600 13px/1 var(--font-tech);color:var(--deepest)}
.q-slots b{color:var(--mid)}
.q-slots.full b{color:var(--err)}
.q-ncard{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:center;
  padding:11px 18px;border-top:1px solid var(--border)}
/* la vignette de la carte : meme boite que la liste du catalogue, un peu plus
   basse pour la densite du configurateur */
.q-ncard .q-thumb{width:64px;height:40px}
.q-ncard .q-thumb img{max-height:40px}
.q-ncard:first-of-type{border-top:0}
/* le total d'une carte se lit ici, il se regle dans le configurateur */
.q-qfix{font:600 13px/1 var(--font-tech);color:var(--muted);padding:0 4px}
.q-ncard .sk{font:600 12.5px/1.2 var(--font-tech);letter-spacing:.03em;color:var(--primary)}
.q-ncard .nm{display:block;margin-top:3px;font-size:13.5px;line-height:1.4;color:var(--muted)}
/* la rangee du compte d'unites du panneau MOSAIC : un champ numerique, pas des
   boutons — un reseau se compte en dizaines ou en centaines */
.q-mdevin{display:flex;align-items:center;gap:8px}
.q-mdevin input{width:96px;padding:9px 10px;border:1px solid var(--border-strong);
  border-radius:8px;font:600 15px/1 var(--font-tech);color:var(--deepest);
  background:var(--white);text-align:right}
.q-mdevin input:focus{outline:none;border-color:var(--mid);box-shadow:var(--focus)}
.q-mdevin span{font:600 12px/1 var(--font-tech);color:var(--muted)}
.q-ncard .cap{display:block;margin-top:3px;font:500 12px/1.3 var(--font-body);color:var(--mid)}
.q-qty button[disabled]{opacity:.34;cursor:not-allowed}
.q-qty button[disabled]:hover{background:none}
.q-nnote{padding:12px 18px;font-size:13px;line-height:1.5;color:var(--muted);
  background:var(--inset)}
.q-nnote.bad{color:var(--err);background:#fdf2f2}
.q-nfix{display:inline-flex;align-items:center;gap:7px;border:0;cursor:pointer;margin-left:8px;
  padding:6px 11px;border-radius:var(--r-tag);background:var(--primary);color:var(--white);
  font:600 12.5px/1 var(--font-body)}
.q-nfix:hover{background:var(--primary-hover)}
.q-nfix:focus-visible{outline:none;box-shadow:var(--focus)}
/* le panneau « votre configuration » */
.q-sum{position:sticky;top:calc(var(--nav-h) + 12px);border-radius:var(--r-lg);
  background:var(--white);box-shadow:var(--hairline),var(--amb-2);overflow:hidden}
/* L'entete du panneau : c'est le panier, il doit se reconnaitre sans etre lu.
   Un bandeau de marque, l'icone du document de devis, et le compte a droite. */
.q-sum-h{display:flex;align-items:center;gap:10px;padding:13px 16px;
  background:linear-gradient(180deg,var(--inset),var(--white));
  border-bottom:1px solid var(--border)}
.q-sum-ico{width:30px;height:30px;flex:none;border-radius:var(--r-bub);display:grid;
  place-items:center;background:rgba(0,91,125,.09)}
.q-sum-ico svg{width:17px;height:17px;stroke:var(--primary);stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.q-sum h3{margin:0;padding:0;font:600 12px/1.2 var(--font-tech);letter-spacing:.06em;
  text-transform:uppercase;color:var(--primary)}
/* le compte ne s'affiche qu'une fois qu'il y a quelque chose a compter :
   un « 0 » permanent est du bruit, pas une information */
.q-badge{margin-left:auto;min-width:24px;height:24px;padding:0 7px;border-radius:var(--r-tag);
  display:grid;place-items:center;background:var(--signal);color:#fff;
  font:600 12px/1 var(--font-tech)}
.q-badge[hidden]{display:none}
/* Le bouton d'avancement vit DANS le panier : c'est la que le geste se termine.
   LC, 2026-08-21. Il ne parait qu'a l'etape des produits, ou le panier existe ;
   la barre du bas garde Back et la mention de prix, et son propre Next
   s'efface pour qu'il n'y en ait jamais deux a l'ecran. */
.q-sum-next{display:none;width:calc(100% - 32px);margin:14px 16px 16px;
  justify-content:space-between;padding:12px 12px 12px 20px}
.dvf[data-at="1"] .q-sum-next{display:inline-flex}
.dvf[data-at="1"] .q-acts .q-next{display:none}
.q-sum .cnt{padding:12px 18px 0;font-size:13px;color:var(--muted)}
.q-sum .cnt:last-child{padding-bottom:14px}
.q-lines{list-style:none;margin:0;padding:0;max-height:44vh;overflow:auto;
  overscroll-behavior:contain}
.q-line{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:center;
  padding:11px 18px;border-top:1px solid var(--border)}
.q-line .sk{font:600 12.5px/1.2 var(--font-tech);letter-spacing:.03em;color:var(--deepest)}
.q-line .ds{display:block;margin-top:2px;font-size:12.5px;line-height:1.4;color:var(--muted)}
.q-qty{display:inline-flex;align-items:center;gap:2px;border-radius:var(--r-tag);
  background:var(--inset);box-shadow:inset 0 0 0 1px var(--border)}
.q-qty button{width:28px;height:28px;border:0;background:none;cursor:pointer;
  color:var(--primary);font:600 15px/1 var(--font-body);border-radius:var(--r-tag)}
.q-qty button:hover{background:#e7eef3}
.q-qty button:focus-visible{outline:none;box-shadow:var(--focus)}
.q-qty output{min-width:26px;text-align:center;font:600 13px/1 var(--font-tech);
  color:var(--deepest)}
.q-none{padding:22px 18px;font-size:13.5px;line-height:1.55;color:var(--muted)}
/* ---------- le recapitulatif de l'etape 3 ---------- */
.q-recap{margin-top:20px;border-radius:var(--r-md);background:var(--inset);
  box-shadow:var(--hairline);padding:16px 18px}
.q-recap h4{font:600 12px/1.2 var(--font-tech);letter-spacing:.06em;text-transform:uppercase;
  color:var(--primary);margin-bottom:9px}
.q-recap ul{list-style:none;margin:0;padding:0;font-size:13.5px;line-height:1.7;
  color:var(--text)}
.q-recap .sk{font-family:var(--font-tech);font-weight:600;color:var(--primary)}
.q-recap .edit{margin-top:10px}
/* ---------- barre d'action ---------- */
.q-acts{display:flex;align-items:center;gap:12px;margin-top:26px;flex-wrap:wrap}
.q-acts .q-back{background:var(--white);color:var(--primary);
  box-shadow:var(--hairline),var(--amb-1);padding-left:22px;padding-right:22px}
.q-acts .q-back:hover{background:var(--inset);color:var(--deepest)}
.q-acts .grow{margin-left:auto}
.q-next{position:relative;display:inline-grid;place-items:center}
.q-next .a,.q-next .b{grid-area:1/1;display:inline-flex;align-items:center;gap:12px;
  transition:opacity var(--t-fast) var(--ease)}
.q-next .ghost{grid-area:1/1;visibility:hidden}
.q-note{flex:1 1 22ch;max-width:46ch;margin:0;font-size:13px;line-height:1.5;
  color:var(--muted)}
@media (max-width:680px){.q-note{flex-basis:100%;order:1}}
/* ---------- etat d'envoi et de succes ---------- */
.dvf-busy{pointer-events:none;opacity:.62}
/* Cloudflare Turnstile. En `interaction-only` le widget ne se montre que si un
   defi est reellement necessaire : le conteneur reste a hauteur nulle le reste
   du temps, donc aucune marge fantome sous le formulaire. On ne lui donne
   qu'un centrage et une borne de largeur . jamais de boite ni de bordure : ce
   n'est pas un champ du formulaire. */
.dvf-ts{display:flex;justify-content:center}
.dvf-ts iframe{max-width:100%}
.dvf-sent{display:none;border-radius:var(--r-lg);background:var(--white);
  box-shadow:var(--hairline),var(--amb-2);padding:clamp(26px,3.2vw,40px)}
.dvf-sent[data-on]{display:block}
.dvf-sent h3{font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.25rem,1.8vw,1.6rem);line-height:1.24;color:var(--deepest)}
.dvf-sent p{margin-top:10px;font-size:15px;line-height:1.62;color:var(--muted);max-width:60ch}
.dvf-sent .ref-id{font-family:var(--font-tech);font-weight:600;color:var(--primary)}
.dvf-fail{display:none;margin-top:16px;padding:13px 16px;border-radius:var(--r-btn);
  background:#fdf2f2;color:var(--err);font-size:14px;line-height:1.5;
  box-shadow:inset 0 0 0 1px rgba(155,44,44,.22)}
.dvf-fail[data-on]{display:block}
/* ---------- le contact general ---------- */
.cf{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,320px);
  gap:clamp(24px,3vw,52px);align-items:start;margin-top:clamp(26px,3vw,40px)}
@media (max-width:900px){.cf{grid-template-columns:1fr}}
.cf-form{border-radius:var(--r-lg);background:var(--white);
  box-shadow:var(--hairline),var(--amb-2);padding:clamp(22px,2.6vw,34px)}
.cf-form .dvf-field:first-of-type{margin-top:0}
.cf-aside{font-size:14.5px;line-height:1.68;color:var(--muted)}
.cf-aside dt{font:600 12px/1.2 var(--font-tech);letter-spacing:.06em;text-transform:uppercase;
  color:var(--primary);margin-top:18px}
.cf-aside dt:first-child{margin-top:0}
.cf-aside dd{margin:5px 0 0}
.cf-aside a{color:var(--primary);font-weight:500}
/* ---------- ce qui n'existe qu'avec le moteur ---------- */
.q-rail,.q-acts,.q-sum{display:none}
.dvf[data-js] .q-rail{display:flex}
.dvf[data-js] .q-acts{display:flex}
.dvf[data-js] .q-sum{display:block}
.dvf[data-js] .q-nojs{display:none}
.dvf[data-js] .q-list{max-height:min(58vh,540px)}
.q-list{max-height:none}
@media (prefers-reduced-motion:reduce){
  .q-anim{animation:none}
  .q-plat:hover{transform:none}
  .q-link i{transition:none}
}
/* ================================================================
   LE PANNEAU D'AIDE DU HERO (2026-08-20)
   LC : « des call to action dans le request a quote [...] dans
   l'espace blanc a droite du hero [...] mettre aussi le numero de
   telephone et email accessible ».
   Le hero du devis etait une colonne de texte et une moitie droite
   vide. Elle porte maintenant la sortie de secours : parler a
   quelqu'un, ou joindre les ventes directement.
   ================================================================ */
.hero-aside{padding:clamp(24px,2.4vw,32px);border-radius:var(--r-lg);
  background:var(--white);box-shadow:var(--hairline),var(--amb-2),var(--gloss);
  position:relative;overflow:hidden}
/* le filet de marque sur la tranche haute, comme le cadre de reservation */
.hero-aside::before{content:"";position:absolute;inset:0 0 auto 0;height:2px;
  background:linear-gradient(90deg,var(--primary),var(--signal) 62%,var(--pale))}
.hero-aside .k2{font:600 11px/1 var(--font-tech);letter-spacing:.19em;
  text-transform:uppercase;color:var(--primary)}
.hero-aside>p.say{margin-top:12px;color:var(--muted);font-size:15px;line-height:1.6;
  max-width:38ch}
.hero-aside .hero-cta{margin-top:clamp(18px,1.8vw,22px)}
.hero-aside .btn{flex:1 1 auto;justify-content:center}
/* les deux moyens de joindre quelqu'un, chacun cliquable en entier */
.reach{display:grid;gap:10px;margin-top:clamp(20px,2vw,26px);
  padding-top:clamp(18px,1.8vw,22px);border-top:1px solid var(--border)}
.reach a{display:grid;grid-template-columns:34px minmax(0,1fr);gap:0 14px;
  align-items:center;padding:10px 12px;margin:-10px -12px;border-radius:var(--r-btn);
  text-decoration:none;color:inherit;
  transition:background var(--t-fast) var(--ease)}
.reach a:hover,.reach a:focus-visible{background:var(--inset)}
.reach a:focus-visible{outline:none;box-shadow:var(--focus)}
.reach svg{grid-row:span 2;width:34px;height:34px;padding:8px;border-radius:10px;
  background:var(--inset);color:var(--primary);fill:none;stroke:currentColor;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.reach b{font:600 11px/1 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted)}
.reach span{margin-top:3px;font-family:var(--font-display);font-weight:600;
  font-size:clamp(.9375rem,1.1vw,1.0625rem);color:var(--deepest);
  overflow-wrap:anywhere}
.reach a:hover span{color:var(--primary)}
.reach i{grid-column:2;font-style:normal;font-size:13px;color:var(--muted);margin-top:2px}
@media (max-width:900px){
  .hero-aside{margin-top:clamp(26px,3vw,36px)}
  .hero-aside .btn{flex:1 1 100%}
}
/* Le hero du devis met le titre DANS la colonne de gauche : sinon le h1 court
   sur toute la largeur, la colonne gauche ne porte plus qu'une phrase et le
   panneau de droite ecrase la page. Aligne en haut, pas au centre : une carte
   haute ne doit pas faire flotter le titre au milieu du vide. */
.hero-grid-help{align-items:start;grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr)}
.hero-grid-help .lede{margin-top:clamp(16px,1.6vw,22px)}
.hero-grid-help .hero-aside{justify-self:end;width:min(100%,470px)}
@media (max-width:900px){
  .hero-grid-help{grid-template-columns:1fr}
  .hero-grid-help .hero-aside{justify-self:stretch;width:100%}
}
body.dv-cortex-series .cmp{position:relative;aspect-ratio:1600/912;border-radius:var(--r-md);overflow:hidden;
  box-shadow:var(--hairline),var(--amb-3);background:var(--panel);
  --pos:50%}
.gal figcaption a{color:inherit;text-decoration:none;border-bottom:1px solid var(--border)}
.gal figcaption a:hover{color:var(--primary);border-color:var(--primary)}
/* la grille des deux unites voisines, portee des pages AXON et NEURO */
.upsell{display:grid;gap:clamp(16px,1.8vw,24px);grid-template-columns:1fr 1fr;
  margin-top:clamp(34px,3.8vw,52px)}
/* ---------- la scene des deux unites, a sa vraie taille ----------
   🔴 Defaut visible signale par LC le 2026-08-21 : sur cette page en blocs,
   l'unite s'affichait enorme ET deformee.

   Cette maquette dimensionne son image par la LARGEUR (`.s-img{width:100%;
   max-width:640px}`) : le CORTEX 360 est un ruban de ratio 4,04, il doit
   s'etaler, pas monter. Les 53 autres maquettes portent une regle plus
   specifique, `.stage-viz .s-img{height:clamp(300px,34vw,460px);width:auto}`,
   qui dimensionne par la HAUTEUR . et cette page ne l'a jamais eue.

   Sur un gabarit classique, chaque page ne sert que son propre CSS : la regle
   des autres n'existait pas et tout allait bien. **La feuille partagee des
   pages en blocs est l'union de toutes les maquettes** : la regle des autres
   est arrivee ici, a specificite superieure, et a impose 460 px de haut. La
   largeur restant plafonnee par la colonne, l'image s'est trouvee etiree
   a 640 x 460 au lieu de 640 x 158.

   On rend donc a cette page sa regle, bornee a elle. */
body.dv-cortex-series .stage-viz .s-img{
  height:auto;width:100%;max-width:640px;
}
body.dv-ef-johnson-atlas-p25-monitoring .pg-shot img{max-width:100%;max-height:var(--pg-h);width:auto;height:auto;object-fit:contain;
  filter:var(--lift-lg);
  transition:transform var(--t-slow) var(--ease)}
/* ---------- pages d'integration prouvee ----------
   Trois pieces neuves seulement : la capture de preuve avec sa legende, la
   liste de questions, et la rangee des autres integrations. Tout le reste
   (ref, cut, lede, feat, pl-card) vient du vocabulaire des pages existantes. */
.itg-hero-shot img{width:100%;height:auto;border-radius:var(--r-md);
  box-shadow:var(--hairline),var(--amb-3)}
/* le stamp se pose sur la crete pale du hero : en gris il disparaissait */
.itg-hero-shot .hero-stamp{color:var(--primary)}
.itg-cap{margin-top:10px;max-width:62ch;color:var(--muted);font-size:12.5px;line-height:1.6}
/* sur fond sombre, le mono passe au ciel et le corps s'eclaircit : le teal
   de la version claire disparait dans le deep field. */
.dark .feat b{color:var(--sky)}
.dark .feat p{color:rgba(255,255,255,.74)}
.dark .itg-shot figcaption{color:rgba(255,255,255,.66)}
.dark .itg-shot img{box-shadow:0 30px 70px -24px rgba(0,20,30,.7)}
.dark .faq-i{border-color:rgba(255,255,255,.16)}
.itg-shot img{max-width:1040px;border-radius:var(--r-md);
  box-shadow:var(--hairline),var(--amb-3);filter:none}
.itg-shot figcaption{margin:16px auto 0;max-width:74ch;color:var(--muted);
  font-size:13.5px;line-height:1.6;text-align:center}
/* deux paragraphes de suite se touchaient : .lede n'a pas de marge basse,
   les gabarits existants n'en enchainent jamais deux. */
.sec .cut + .lede{margin-top:clamp(16px,1.8vw,24px)}
.sec .lede + .lede{margin-top:clamp(14px,1.5vw,20px)}
/* les pieces communes des schemas de systemes : la carte, sa marque, le
   trait, la fleche, la validation croisee. (Retirees par erreur en reecrivant
   le bloc .sy : les cartes perdaient leur fond et les logos leur gabarit.) */
.ly-node{--ly-pad:clamp(18px,2vw,24px);position:relative;display:grid;gap:11px;
  align-content:start;padding:var(--ly-pad);border-radius:16px;background:#fff;
  box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,42,60,.07)}
/* l'ecran du produit, bord a bord en tete de carte : il annule le pad et
   reprend le rayon exterieur moins rien (il touche les aretes) */
.ly-shot{display:block;margin:calc(-1 * var(--ly-pad)) calc(-1 * var(--ly-pad)) 6px;
  border-radius:16px 16px 0 0;overflow:hidden}
.ly-shot img{display:block;width:100%;height:auto}
.ly-hub::before{content:"";position:absolute;z-index:1;left:0;right:0;
  top:0;height:2px;border-radius:0 0 2px 2px;
  background:linear-gradient(90deg,var(--signal),rgba(0,168,224,.25))}
.ly-mark{display:block;height:38px}
.ly-logo img{height:100%;width:auto;max-width:78%;object-fit:contain;object-position:left center}
.ly-unit{height:44px}
.ly-unit img{height:auto;width:min(100%,196px);
  filter:drop-shadow(0 10px 14px rgba(0,42,60,.18))}
.ly-n{margin:0;font-family:var(--font-display);font-weight:600;letter-spacing:-.015em;
  font-size:clamp(1.0625rem,1.3vw,1.25rem);line-height:1.12;color:var(--deepest)}
.ly-role{margin:0;font:500 13.5px/1.55 var(--font-body);color:var(--muted)}
.ly-wire{position:relative;display:grid;align-content:center;justify-items:center;gap:7px;
  padding:0 6px}
.ly-line{position:relative;display:block;width:100%;height:2px;border-radius:2px;overflow:visible;
  background:linear-gradient(90deg,rgba(0,91,125,.26),rgba(0,168,224,.6))}
.ly-line::after{content:"";position:absolute;right:0;top:50%;width:7px;height:7px;
  border-top:1.8px solid var(--signal);border-right:1.8px solid var(--signal);
  transform:translate(1px,-50%) rotate(45deg)}
.ly-line i{position:absolute;top:-2px;bottom:-2px;left:0;width:22%;border-radius:3px;
  background:linear-gradient(90deg,transparent,rgba(0,168,224,.85),transparent)}
.ly-back{background:linear-gradient(90deg,rgba(0,168,224,.6),rgba(0,91,125,.26))}
.ly-back::after{right:auto;left:0;border-top:none;border-right:none;
  border-bottom:1.8px solid var(--signal);border-left:1.8px solid var(--signal);
  transform:translate(-1px,-50%) rotate(45deg)}
.ly-back i{left:auto;right:0}
.ly-lbl{font:600 9.5px/1.3 var(--font-tech);letter-spacing:.13em;text-transform:uppercase;
  color:var(--primary);text-align:center}
.ly-lbl-back{color:var(--mid)}
.ly-cross{display:flex;align-items:center;gap:14px;padding:14px 0 14px 30px}
.ly-vline{position:relative;flex:none;width:2px;align-self:stretch;min-height:44px;border-radius:2px;
  background:linear-gradient(180deg,rgba(0,168,224,.6),rgba(0,91,125,.22))}
.ly-vline::before{content:"";position:absolute;left:50%;top:0;width:7px;height:7px;
  border-top:1.8px solid var(--signal);border-left:1.8px solid var(--signal);
  transform:translate(-50%,-1px) rotate(45deg)}
.ly-cross-lbl{margin:0;font:500 12.5px/1.5 var(--font-body);color:var(--muted);max-width:34ch}
@media (prefers-reduced-motion:no-preference){
  .ly-line i{animation:ly-run 5.2s linear infinite}
  .sy-w2 .ly-line i{animation-delay:.7s}
  .ly-back i{animation-name:ly-run-back;animation-delay:2.6s}
}
@keyframes ly-run{0%{transform:translateX(0);opacity:0} 8%{opacity:1}
  86%{opacity:1} 100%{transform:translateX(355%);opacity:0}}
@keyframes ly-run-back{0%{transform:translateX(0);opacity:0} 8%{opacity:1}
  86%{opacity:1} 100%{transform:translateX(-355%);opacity:0}}
/* ---------- deux couches, et le site montre ce qu'il contient ----------
   Cinq colonnes, trois rangees, zones nommees : ATLAS en haut a gauche, le
   site en dessous avec ses sous-systemes, l'unite au centre, la console a
   droite sur toute la hauteur. Chaque trait est donc horizontal, vertical, ou
   un faisceau a coordonnees fixes calees sur la hauteur d'une ligne : rien
   n'est pose a la main. Meme mecanique que le schema de l'accueil, parce que
   c'est la meme histoire : des equipements qui convergent vers une unite. */
.sy{margin-top:clamp(30px,3.4vw,46px)}
/* Le rail : la colonne verticale ou TOUT aboutit. LC, 2026-08-24 : « ce qui
   me gosse c'est les fleches qui arrivent dans le vide ». La trap d'ATLAS y
   entre, les echanges du CORTEX y entrent, et le rail entre dans l'ecran de
   la console par le taquet du milieu. Ses deux bouts fondent en transparence :
   c'est un bus, pas une bordure. */
.sy-stage{--sy-rh:54px;--sy-rg:8px;--sy-fan:100px;--sy-over:16px;
  --sy-rail:28px;--sy-hubgap:clamp(10px,1.4vw,20px);
  display:grid;align-items:stretch;
  grid-template-columns:minmax(0,1.12fr) var(--sy-fan) 208px clamp(96px,10vw,130px) var(--sy-rail) minmax(0,.86fr);
  grid-template-areas:"atlas w1 w1 w1 rail hub" "x . . . rail hub" "site fan cortex w2 rail hub";gap:18px 0}
.sy-rail{grid-area:rail;position:relative}
.sy-rail::before{content:"";position:absolute;left:50%;top:0;bottom:0;width:2px;
  transform:translateX(-50%);border-radius:2px;
  background:linear-gradient(180deg,transparent,rgba(0,168,224,.55) 14%,rgba(0,168,224,.55) 86%,transparent)}
.sy-rail-lbl{position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%) rotate(180deg);writing-mode:vertical-rl;
  font:600 9px/1 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--mid);background:var(--off-white);padding:10px 1px;white-space:nowrap}
/* les fils vont jusqu'au rail : ils debordent de leur cellule pour le toucher */
.sy-w1 .ly-line,.sy-w2 .ly-line{margin-right:calc(-1 * var(--sy-rail) / 2)}
.sy-atlas{grid-area:atlas}
.sy-site{grid-area:site;position:relative}
.sy-cortex{grid-area:cortex;align-self:center;text-align:center}
.sy-w1{grid-area:w1}
.sy-w2{grid-area:w2}
.sy .ly-cross{grid-area:x}
/* La console : un ecran qui flotte, pose par son ombre, et le panneau
   d'alarmes qui deborde en bas a gauche — le langage de l'accueil (LC :
   la carte blanche etiree « pas vraiment beau non plus »). Le pied porte le
   logo et la phrase de role. */
.sy-hubx{grid-area:hub;align-self:center;margin-left:var(--sy-hubgap);
  display:grid;gap:0}
.sy-shot{position:relative}
.sy-shot::before{content:"";position:absolute;right:100%;top:50%;height:2px;
  width:calc(var(--sy-hubgap) + var(--sy-rail) / 2);
  background:linear-gradient(90deg,rgba(0,168,224,.55),rgba(0,91,125,.3))}
.sy-shot::after{content:"";position:absolute;left:-1px;top:50%;width:7px;height:7px;
  border-top:1.8px solid var(--signal);border-right:1.8px solid var(--signal);
  transform:translate(-100%,-50%) rotate(45deg)}
.sy-shot > img{display:block;width:100%;height:auto;border-radius:10px;
  filter:drop-shadow(0 26px 34px rgba(0,42,60,.20)) drop-shadow(0 6px 10px rgba(0,42,60,.10))}
.sy-abox{position:absolute;left:-16px;bottom:-46px;width:min(90%,296px);
  padding:13px 15px;border-radius:12px;background:rgba(255,255,255,.97);
  box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,91,125,.10)}
.sy-abox .k{display:block;margin-bottom:9px;font:600 9.5px/1 var(--font-tech);
  letter-spacing:.16em;text-transform:uppercase;color:var(--primary)}
.sy-alist{list-style:none;margin:0;padding:0;display:grid;gap:5px}
.sy-alist li{display:grid;grid-template-columns:8px 1fr;align-items:center;gap:10px}
.sy-alist i{width:8px;height:8px;border-radius:50%;background:#d64545;font-style:normal;
  box-shadow:0 0 0 3px rgba(214,69,69,.14)}
.sy-alist span{font:500 12.5px/1.35 var(--font-body);color:var(--text)}
.sy-hub-cap{display:flex;align-items:center;gap:13px;margin:62px 0 0}
.sy-hub-cap .ly-mark{height:26px;flex:none}
.sy-hub-cap .ly-logo img{height:100%;width:auto;max-width:none}
.sy-hub-cap span{font:500 13px/1.5 var(--font-body);color:var(--muted)}
@media (max-width:1080px){
  .sy-hubx{margin-left:0;margin-top:18px}
  .sy-abox{position:static;width:auto;margin-top:14px;
    box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,91,125,.10)}
  .sy-hub-cap{margin-top:18px}
}
/* La console s'etire sur toute la hauteur de la scene (LC, 2026-08-24 :
   « the height of the mosaic tuile isn't enough ») : centree, elle flottait
   dans une colonne aussi haute que les cinq lignes du site. C'est l'ecran qui
   absorbe la hauteur (rangee 1fr, image en cover calee a gauche pour garder la
   liste des appareils et la carte), le texte garde la sienne. */
.sy .ly-hub{grid-area:hub;align-self:stretch;margin-left:clamp(6px,1vw,14px);
  grid-template-rows:minmax(220px,1fr) auto auto auto}
.sy .ly-hub .ly-shot{position:relative;min-height:220px}
.sy .ly-hub .ly-shot img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:30% center}
/* 30 % et pas « left » : a gauche pure on ne cadre que la liste sombre des
   appareils ; a 30 % on garde son bord, les epingles de la carte et les
   colonnes de gauche de la table d'alarmes. Juge sur la page rendue. */
.sy-kick{margin:0 0 12px;font:600 11px/1 var(--font-tech);letter-spacing:.19em;
  text-transform:uppercase;color:var(--mid)}
.sy-rows{list-style:none;margin:0;padding:0;display:grid;gap:var(--sy-rg)}
.sy-row{height:var(--sy-rh);display:grid;grid-template-columns:1fr auto 9px;
  align-items:center;gap:13px;border-bottom:1px solid rgba(0,91,125,.10)}
.sy-row:last-child{border-bottom:0}
.sy-row .t{font:500 15px/1.25 var(--font-body);color:var(--text)}
.sy-row .w{justify-self:end;font:600 10px/1 var(--font-tech);letter-spacing:.13em;
  text-transform:uppercase;color:var(--primary);padding:6px 9px;border-radius:6px;
  background:rgba(0,91,125,.06);box-shadow:inset 0 0 0 1px rgba(0,91,125,.14)}
.sy-row .p{width:9px;height:9px;border-radius:2px;background:var(--signal);
  box-shadow:0 0 0 4px rgba(0,168,224,.13)}
/* le faisceau part du bord droit des lignes et mord sur la colonne de l'unite */
.sy-fan{position:absolute;left:100%;bottom:0;width:calc(var(--sy-fan) + var(--sy-over));
  height:var(--sy-h);overflow:visible;pointer-events:none}
.sy-spark{opacity:0}
.sy-cortex .ly-mark{height:52px;display:grid;place-items:center}
.sy-cortex .ly-unit img{width:min(100%,200px)}
.sy-cortex .ly-role{max-width:30ch;margin-inline:auto}
.sy-notes{list-style:none;margin:clamp(26px,3vw,38px) 0 0;padding:0;display:grid;gap:12px 34px;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
.sy-notes li{font:500 13px/1.55 var(--font-body);color:var(--muted);
  padding-top:12px;border-top:1px solid rgba(0,91,125,.12)}
.sy-notes b{display:block;margin-bottom:5px;font:600 9.5px/1 var(--font-tech);
  letter-spacing:.14em;text-transform:uppercase;color:var(--primary)}
@media (prefers-reduced-motion:no-preference){
  .sy-spark{animation:fl-spark 7.6s linear infinite;animation-delay:var(--d,0s)}
}
@keyframes fl-spark{0%{offset-distance:0%;opacity:0}
  4%{opacity:1} 21%{offset-distance:100%;opacity:1}
  25%{offset-distance:100%;opacity:0} 100%{offset-distance:100%;opacity:0}}
.on-dark .sy-kick{color:var(--pale)}
.on-dark .sy-row{border-bottom-color:rgba(255,255,255,.16)}
.on-dark .sy-row .t{color:#fff}
.on-dark .sy-row .w{color:#fff;background:rgba(255,255,255,.10);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.22)}
.on-dark .sy-notes li{color:rgba(255,255,255,.72);border-top-color:rgba(255,255,255,.18)}
.on-dark .sy-notes b{color:var(--sky)}
@media (max-width:1080px){
  .sy-stage{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"atlas" "w1" "x" "site" "fan" "cortex" "w2" "rail" "hub"}
  .sy-fan,.sy-rail{display:none}
  .sy-shot::before,.sy-shot::after{display:none}
  .sy-w1 .ly-line,.sy-w2 .ly-line{margin-right:0}
  .sy-row{grid-template-columns:1fr auto}
  .sy-row .p{display:none}
  .sy .ly-hub{margin:18px 0 0}
  .sy-cortex{text-align:left;margin-top:18px}
  .sy-cortex .ly-role{margin-inline:0}
  .sy .ly-wire{padding:16px 0 0}
}
/* Sur une bande sombre, les cartes restent blanches (elles se posent comme des
   objets sur une console) mais tout le reste doit changer de valeur : la voix
   technique passe au ciel, le texte hors carte au blanc attenue. Sans ca les
   libelles des liens etaient invisibles. */
.on-dark .ly-lbl{color:var(--sky)}
.on-dark .ly-lbl-back{color:rgba(191,224,239,.82)}
.on-dark .ly-cross-lbl{color:rgba(255,255,255,.76)}
.on-dark .ly-line{background:linear-gradient(90deg,rgba(191,224,239,.32),rgba(0,168,224,.85))}
.on-dark .ly-back{background:linear-gradient(90deg,rgba(0,168,224,.85),rgba(191,224,239,.32))}
.on-dark .ly-vline{background:linear-gradient(180deg,rgba(0,168,224,.85),rgba(191,224,239,.3))}
.on-dark .ly-node{box-shadow:var(--amb-4),inset 0 0 0 1px rgba(255,255,255,.14)}
/* Deux paragraphes cote a cote plutot qu'empiles : la section occupe sa
   largeur, et la hauteur du mur de texte est divisee par deux. */
.sec-2col{display:grid;gap:clamp(20px,3vw,48px);grid-template-columns:repeat(2,minmax(0,1fr));
  margin-top:clamp(16px,1.8vw,24px)}
.sec-2col .lede{max-width:58ch}
@media (max-width:900px){.sec-2col{grid-template-columns:minmax(0,1fr)}}
/* ---------- la FAQ, en deux colonnes qui se repondent ----------
   Le titre tient sa colonne et **reste en vue pendant qu'on lit** (sticky) :
   c'est ce qui fait que les deux moities se parlent au lieu de se suivre. Les
   questions occupent l'autre. Ouverture sans JS, `<details>` natif : le clavier
   marche, et les reponses restent dans le document. */
.fq-grid{display:grid;gap:clamp(26px,3.6vw,64px);align-items:start;
  grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr)}
.fq-head{position:sticky;top:clamp(96px,12vh,132px)}
.fq-head h2{max-width:14ch}
.fq{display:grid;gap:0}
.fq-i{border-bottom:1px solid var(--border)}
.fq-i:first-child{border-top:1px solid var(--border)}
.fq-i summary{display:flex;align-items:flex-start;gap:13px;cursor:pointer;list-style:none;
  padding:clamp(18px,2vw,24px) 0;
  font-family:var(--font-display);font-weight:600;font-size:1.0625rem;line-height:1.28;
  letter-spacing:-.012em;color:var(--deepest);
  transition:color var(--t-fast) var(--ease)}
.fq-i summary::-webkit-details-marker{display:none}
.fq-i summary:hover{color:var(--primary-hover)}
.fq-i summary:focus-visible{outline:none;box-shadow:var(--focus);border-radius:var(--r-btn)}
.fq-c{width:17px;height:17px;flex:none;margin-top:3px;fill:none;stroke:var(--mid);
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;
  transition:transform var(--t-base) var(--ease)}
.fq-i[open] .fq-c{transform:rotate(90deg)}
.fq-a{padding:0 0 clamp(20px,2.2vw,26px) 30px}
.fq-a p{margin:0;max-width:72ch;color:var(--muted);font-size:15px;line-height:1.62}
@media (prefers-reduced-motion:no-preference){
  /* l'ouverture d'un `<details>` passe de `display:none` a visible : sans
     `@starting-style` il n'y a rien a interpoler. La ou ce n'est pas supporte,
     la reponse apparait d'un coup, ce qui reste correct. */
  .fq-i[open] .fq-a{animation:fq-open 320ms var(--ease) both}
}
@keyframes fq-open{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
@media (max-width:900px){
  .fq-grid{grid-template-columns:minmax(0,1fr)}
  .fq-head{position:static}
  .fq-head h2{max-width:22ch}
}
.faq{display:grid;gap:0;margin-top:clamp(26px,3vw,40px)}
.faq-i{padding:clamp(22px,2.4vw,30px) 0;border-top:1px solid var(--border)}
.faq-i:last-child{border-bottom:1px solid var(--border)}
.faq-i h3{font-size:1.0625rem;max-width:52ch}
.faq-i p{margin-top:10px;color:var(--muted);font-size:15px;line-height:1.62;max-width:78ch}
.hero-partner{display:flex;align-items:center;gap:16px;margin-top:clamp(24px,2.6vw,32px)}
.hero-partner .mono{margin:0;color:var(--primary)}
.hero-partner img{height:38px;width:auto;object-fit:contain}
/* ---------- la scene Mosaic : trois ecrans composes ----------
   Une vue d'ensemble ne dit pas ce qu'on fait d'elle. La liste d'alarmes se
   pose au-dessus, la tendance a droite, chacune avec son ombre : on lit la
   profondeur avant de lire le detail. Sous 900 px la scene se remet a plat,
   dans l'ordre de lecture. */
.mos-stage{position:relative;margin-top:clamp(44px,5vw,72px);padding:5% 8% 0 0}
.mos-stage figure{margin:0}
.mos-stage img{width:100%;height:auto;display:block;border-radius:var(--r-md);
  box-shadow:var(--hairline),var(--amb-3)}
.mos-big{width:84%}
.mos-a{position:absolute;top:0;right:0;width:52%}
.mos-a img{box-shadow:var(--hairline),var(--amb-4)}
.mos-b{position:absolute;right:0;bottom:6%;width:34%}
.mos-b img{box-shadow:var(--hairline),var(--amb-4)}
.mos-cap{margin:22px 0 0;max-width:74ch;color:var(--muted);font-size:13.5px;line-height:1.6}
.dark .mos-cap{color:rgba(255,255,255,.66)}
@media (max-width:900px){
  .mos-stage{padding:0}
  .mos-big,.mos-a,.mos-b{position:static;width:100%}
  .mos-a,.mos-b{margin-top:16px}
}
.itg-fig{margin-top:clamp(26px,3vw,38px)}
/* Un schema n'a pas de rectangle a lui : pas de cadre, pas d'ombre, il repose
   a plat sur le fond de la section. `.itg-shot` reste le traitement des
   captures d'ecran, qui elles ont bien un bord. */
.itg-shot.itg-flat img{border-radius:0;box-shadow:none;filter:none;background:none}
.itg-wide img{max-width:100%}
.views-2.itg-fig img{border-radius:var(--r-md);box-shadow:var(--hairline),var(--amb-2);
  filter:none;aspect-ratio:16/9;object-fit:cover}
.views-2.itg-fig .itg-contain img{object-fit:contain;background:#0d293a}
.views-2.itg-fig figcaption{text-transform:none;letter-spacing:0;font:400 13px/1.55 var(--font-body);
  color:var(--muted);text-align:left}
.itg-fig img{max-width:880px}
.itg-more{margin-top:clamp(22px,2.6vw,34px)}
.itg-more .pl-pic{height:70px}
.itg-more .pl-pic img{max-height:44px;max-width:78%}
/* ---------- le bloc de reponse ----------
   Il tenait sur une colonne, donc la moitie droite de la section restait vide
   et la section suivante recommencait par un titre et un paragraphe : deux
   murs de texte de suite. La question tient maintenant sa colonne, la reponse
   la sienne, et la section prend le fond voile pour se detacher de la blanche
   qui la suit. Le surtitre est le meme filet cyan que le hero. */
.ans-grid{display:grid;gap:clamp(24px,3.2vw,56px);align-items:start;
  grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr)}
.ans-grid .tag{margin:0 0 clamp(16px,1.8vw,22px)}
.ans-grid h2{max-width:22ch}
.ans-grid .lede{max-width:64ch}
@media (max-width:900px){
  .ans-grid{grid-template-columns:minmax(0,1fr)}
  .ans-grid h2{max-width:26ch}
}
/* ---------- la chaine d'un systeme ----------
   Meme langage que le schema de l'accueil : des cartes de lieu, la voix
   technique en mono, un fil ou la lumiere court. La difference est le propos :
   l'accueil fait varier le contexte pour dire « ca va partout », une page de
   compatibilite prouvee a un contexte fixe et montre SA topologie.
   Toute la geometrie descend d'un jeton, l'ecart entre colonnes : les prises du
   lien sont posees sur la MEME grille que les cartes, donc elles tombent sous
   leur lieu quel que soit le nombre de lieux, et le trait s'arrete pile au
   centre de la premiere et de la derniere (une demi-colonne de marge). */
.chn{--chn-g:clamp(18px,2.4vw,34px);margin-top:clamp(30px,3.4vw,46px)}
.chn-sites,.chn-taps{display:grid;gap:var(--chn-g);
  grid-template-columns:repeat(var(--chn-n),minmax(0,1fr))}
.chn-site{display:grid;gap:12px;align-content:start}
.chn-card{display:block;position:relative;height:clamp(112px,11vw,148px);border-radius:14px;
  overflow:hidden;box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,42,60,.06)}
.chn-card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:saturate(.6)}
.chn-card::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,42,60,.06) 0%,rgba(0,42,60,.34) 46%,rgba(0,42,60,.78) 100%)}
.chn-n{position:absolute;left:16px;right:16px;bottom:13px;z-index:1;color:#fff;
  font-family:var(--font-display);font-weight:600;letter-spacing:-.015em;
  font-size:clamp(1rem,1.25vw,1.1875rem);line-height:1.1}
.chn-unit{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0;
  font:600 10px/1 var(--font-tech);letter-spacing:.13em;text-transform:uppercase;
  color:var(--primary)}
.chn-unit b{font:600 9.5px/1 var(--font-tech);letter-spacing:.13em;color:#fff;
  padding:5px 8px;border-radius:6px;background:var(--primary)}
.chn-role{margin:0;font:500 13.5px/1.55 var(--font-body);color:var(--muted)}
/* le lien : une demi-colonne de marge de chaque cote, donc le trait part du
   centre de la premiere prise et s'arrete au centre de la derniere */
.chn-link{position:relative;margin-top:clamp(20px,2.2vw,28px);height:12px}
.chn-line{position:absolute;top:5px;left:0;right:0;height:2px;border-radius:2px;overflow:hidden;
  margin-inline:calc((100% - (var(--chn-n) - 1) * var(--chn-g)) / (var(--chn-n) * 2));
  background:linear-gradient(90deg,rgba(0,91,125,.28),rgba(0,168,224,.55),rgba(0,91,125,.28))}
.chn-run{position:absolute;inset:0;width:18%;
  background:linear-gradient(90deg,transparent,#00a8e0,transparent)}
.chn-taps{position:absolute;inset:0}
.chn-tap{display:grid;place-items:center}
.chn-tap i{width:11px;height:11px;border-radius:3px;background:var(--signal);
  box-shadow:0 0 0 4px rgba(0,168,224,.14)}
.chn-lbl{margin:16px 0 0;text-align:center;font:600 11px/1 var(--font-tech);
  letter-spacing:.19em;text-transform:uppercase;color:var(--primary)}
.chn-cap{margin:14px auto 0;max-width:74ch;text-align:center;
  font:500 13.5px/1.6 var(--font-body);color:var(--muted)}
.chn-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:7px;margin-top:18px}
.chn-chips span{font:600 10px/1 var(--font-tech);letter-spacing:.13em;text-transform:uppercase;
  color:var(--primary);padding:9px 12px;border-radius:8px;background:#fff;
  box-shadow:var(--amb-1),inset 0 0 0 1px rgba(0,91,125,.14)}
@media (prefers-reduced-motion:no-preference){
  .chn-run{animation:chn-run 4.6s linear infinite}
}
/* la course se compte en pourcentage de la lueur elle-meme : elle fait 18 %
   du trait, donc traverser les 82 % restants vaut 455 % de sa propre largeur */
@keyframes chn-run{0%{transform:translateX(0);opacity:0}
  6%{opacity:1} 88%{opacity:1} 100%{transform:translateX(455%);opacity:0}}
@media (max-width:820px){
  .chn-sites{grid-template-columns:minmax(0,1fr)}
  .chn-link{display:none}
  .chn-site+.chn-site{margin-top:clamp(22px,3vw,30px)}
  .chn-lbl,.chn-cap,.chn-chips{text-align:left;justify-content:flex-start}
  .chn-cap{margin-inline:0}
}
/* ---------- ajouts de la page Fire Station Alerting System ---------- */
.feats-3{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:900px){.feats{grid-template-columns:1fr}.feats-3{grid-template-columns:1fr}}
body.dv-fire-station .blist{margin-top:10px;padding-left:17px;color:var(--muted);font-size:15px;line-height:1.6}
body.dv-fire-station .blist li+li{margin-top:8px}
.partner-mark{width:min(100%,215px);height:auto;filter:var(--lift)}
.split.brochure-row{margin-top:clamp(40px,4.6vw,64px);align-items:center;
  grid-template-columns:minmax(0,260px) minmax(0,1fr)}
.rtu-trio.modules .pic{aspect-ratio:3/4;place-items:center}
.rtu-trio.modules .pic img{max-width:min(100%,170px)}
.rtu-trio.modules article{text-align:left}
@media (max-width:900px){.split{grid-template-columns:1fr}.rtu-trio{grid-template-columns:1fr}}
/* -- echelle des visuels : aucun raster ne depasse son texte (LC 2026-08-15) -- */
/* les pictogrammes de fonction ont des silhouettes tres differentes (350x463,
   120x96, 606x400, 481x513) : boite carree fixe + contain, sinon ils rendent a
   quatre echelles apparentes differentes. */
.feats .feat-card>img{width:56px;height:56px;object-fit:contain;object-position:center}
body.dv-fire-station .wide-viz img{max-width:min(100%,840px)}
#core-unit .split .pic img{max-width:min(100%,520px);margin-inline:auto;display:block}
#targa .split .pic img{max-width:min(100%,560px);margin-inline:auto;display:block}
/* -- 02 . le rail de procede, natif -------------------------------------------
   remplace le portrait 1418x1600 dont toute la typographie etait cuite dans le
   raster (et qui ecrasait sa colonne de texte). Meme contenu, mot pour mot. */
.flow{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  gap:clamp(14px,1.6vw,26px);margin-top:clamp(36px,4vw,56px);position:relative}
.flow::before{content:"";position:absolute;top:21px;left:6%;right:6%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(0,168,224,.5) 12%,
    rgba(0,168,224,.5) 88%,transparent)}
.flow article{position:relative}
.flow .n{position:relative;display:grid;place-items:center;width:44px;height:44px;
  border-radius:12px;background:var(--white);box-shadow:var(--hairline),var(--amb-2);
  font:600 12px/1 var(--font-tech);letter-spacing:.08em;color:var(--primary)}
.flow h3{margin-top:16px;font-size:1.0625rem;line-height:1.3}
.flow p{margin-top:9px;color:var(--muted);font-size:14px;line-height:1.6}
@media (max-width:1040px){.flow{grid-template-columns:repeat(3,minmax(0,1fr));
  row-gap:clamp(24px,3vw,36px)}.flow::before{display:none}}
@media (max-width:640px){.flow{grid-template-columns:1fr}}
/* la bande cas d'usage : une porte, pas une demi-section vide */
.usecase{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:clamp(18px,2.4vw,34px);margin-top:clamp(40px,4.6vw,62px);
  padding:clamp(22px,2.6vw,32px) clamp(24px,3vw,38px);border-radius:var(--r-md);
  background:var(--white);box-shadow:var(--hairline),var(--amb-2)}
/* -- 03 . vitrine spatiale des trois deploiements ------------------------------
   pattern 21st.dev Spatial Product Showcase (9679), deja porte sur la page AXON :
   une scene, un dock a surface glissante, le visuel et le panneau se croisent.
   Les diagrammes sont larges : la scene penche en faveur du visuel. */
.stage.deploy{grid-template-columns:minmax(0,1.52fr) minmax(0,.88fr);
  margin-top:clamp(34px,3.8vw,52px)}
.stage.deploy .stage-viz{min-height:clamp(260px,26vw,400px)}
.stage.deploy .s-img{height:auto;width:100%;max-width:100%}
.s-pane .k2{font:600 11px/1 var(--font-tech);letter-spacing:.19em;text-transform:uppercase;
  color:var(--primary)}
.s-pane p{margin-top:14px;color:var(--muted);font-size:15px;line-height:1.62;max-width:44ch}
.dock.dock-3 .dock-pill{width:calc(33.3333% - 3.4px)}
.dock.dock-3 .dock-btn{min-width:142px;padding:12px 20px}
@media (max-width:900px){
  .stage.deploy{grid-template-columns:1fr}
  .dock.dock-3{display:flex;width:100%}
  .dock.dock-3 .dock-btn{min-width:0;flex:1;padding:12px 10px;font-size:12px}
}
/* ---------- la chaine d'evenements d'une caserne ----------
   Une ligne de temps, pas une topologie : ce que vend ce systeme est un delai,
   donc la forme doit etre le temps qui passe. Surface en langage
   d'intervention, detail technique au clic. Radios cachees, aucun JS.
   Les jetons de geometrie vivent sur la scene, jamais sur la piece. */
.fc{--fc-n:6;position:relative;margin-top:clamp(30px,3.4vw,46px)}
.fc-in{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;margin:0}
.fc-beats{display:grid;gap:0;grid-template-columns:repeat(var(--fc-n),minmax(0,1fr));
  position:relative;z-index:1}
/* le fil du temps passe DERRIERE les pastilles, d'une demi-colonne a l'autre */
.fc-line{position:absolute;left:0;right:0;top:34px;height:2px;border-radius:2px;z-index:0;
  margin-inline:calc(100% / var(--fc-n) / 2);
  background:linear-gradient(90deg,rgba(0,91,125,.22),rgba(0,168,224,.55))}
/* 🔴 `align-content:start` obligatoire. Les six tuiles sont etirees a la meme
   hauteur par la grille exterieure ; dans chacune, `align-content` vaut
   `stretch` par defaut et **repartit le surplus ENTRE les lignes**. Les tuiles
   au texte court ecartaient donc leurs elements davantage, et les titres se
   retrouvaient a des hauteurs differentes (mesure : 10 px d'ecart). Le surplus
   doit rester en bas, pas se glisser dans les interlignes. */
.fc-b{display:grid;align-content:start;justify-items:center;text-align:center;gap:9px;
  cursor:pointer;padding:0 clamp(6px,.7vw,12px)}
.fc-ic{width:68px;height:68px;display:grid;place-items:center;border-radius:50%;background:#fff;
  box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,42,60,.08);
  transition:box-shadow var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.fc-ic svg{width:26px;height:26px;fill:none;stroke:var(--primary);stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;transition:stroke var(--t-fast) var(--ease)}
.fc-b:hover .fc-ic{transform:translateY(-3px);
  box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,91,125,.26)}
/* hauteur FIXE, pas `min-height` : deux temps sur six portent une valeur, et
   une boite qui se dimensionne sur son contenu faisait demarrer les titres a
   des hauteurs differentes. Ici la ligne de base est la meme pour les six,
   qu'il y ait un chiffre ou non. */
.fc-t{height:18px;line-height:18px;font:600 10px/18px var(--font-tech);letter-spacing:.14em;
  text-transform:uppercase;color:var(--mid)}
.fc-n{font-family:var(--font-display);font-weight:600;letter-spacing:-.012em;
  font-size:clamp(.9375rem,1.05vw,1.0625rem);line-height:1.2;color:var(--deepest)}
.fc-s{font:500 12.5px/1.5 var(--font-body);color:var(--muted);max-width:24ch}
/* le temps choisi : la pastille se remplit, le reste reste lisible */
.fc-p{display:none}
.fc-panels{margin-top:clamp(26px,3vw,38px);padding-top:clamp(22px,2.6vw,30px);
  border-top:1px solid rgba(0,91,125,.14)}
.fc-p h3{margin:6px 0 0;font-size:clamp(1.125rem,1.5vw,1.4375rem);max-width:22ch}
.fc-p p{margin:14px 0 0;max-width:58ch;font:400 15px/1.62 var(--font-body);color:var(--muted)}
/* le panneau : ce qui se dit a gauche, ce qui se voit a droite */
.fc-p{grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);gap:clamp(26px,3.4vw,58px);
  align-items:start}
.fc-say{min-width:0}
.fc-viz{min-width:0;display:grid;gap:14px;align-content:start}
/* les cellules : la primitive du site, une boite claire, un nom, un etat */
.fc-cells{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:10px}
.fc-c{position:relative;flex:1 1 auto;min-width:132px;display:grid;gap:6px;
  padding:14px 16px;border-radius:12px;background:#fff;
  box-shadow:var(--amb-1),inset 0 0 0 1px rgba(0,42,60,.08)}
.fc-cn{font:500 13.5px/1.35 var(--font-body);color:var(--text)}
.fc-cs{font:600 9.5px/1 var(--font-tech);letter-spacing:.14em;text-transform:uppercase;
  color:var(--primary)}
.fc-c-on{box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,168,224,.45)}
.fc-c-on .fc-cs{color:var(--primary)}
/* « eteint » s'attenue par sa COULEUR, pas par son opacite : une opacite
   effacerait le libelle autant que le fond et l'etat deviendrait illisible. */
.fc-c-off{background:var(--inset);box-shadow:inset 0 0 0 1px rgba(0,91,125,.12)}
.fc-c-off .fc-cn{color:var(--muted)}
.fc-c-off .fc-cs{color:var(--muted)}
/* la fleche entre deux cellules, quand l'ordre compte */
.fc-flow .fc-c + .fc-c::before{content:"";position:absolute;left:-10px;top:50%;width:10px;height:2px;
  background:rgba(0,168,224,.5)}
.fc-flow .fc-c + .fc-c::after{content:"";position:absolute;left:-4px;top:50%;width:6px;height:6px;
  border-top:1.7px solid var(--signal);border-right:1.7px solid var(--signal);
  transform:translate(-50%,-50%) rotate(45deg)}
.fc-into{margin:0;padding-left:22px;position:relative;
  font:500 13.5px/1.4 var(--font-body);color:var(--text)}
.fc-into::before{content:"";position:absolute;left:4px;top:2px;width:2px;bottom:2px;
  border-radius:2px;background:linear-gradient(180deg,rgba(0,168,224,.6),rgba(0,91,125,.24))}
.fc-into span{display:inline-block;padding:9px 14px;border-radius:10px;background:#fff;
  box-shadow:var(--amb-1),inset 0 0 0 1px rgba(0,168,224,.34)}
.fc-vfoot{margin:0;font:500 12.5px/1.5 var(--font-body);color:var(--muted)}
.fc-shot{margin:0}
.fc-shot img{width:100%;height:auto;
  filter:drop-shadow(0 22px 30px rgba(0,42,60,.18)) drop-shadow(0 5px 9px rgba(0,42,60,.10))}
.fc-shot figcaption{margin-top:14px;font:400 13px/1.55 var(--font-body);color:var(--muted);
  max-width:52ch}
.fc-who{margin:0;font:600 10px/1 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--primary)}
@media (max-width:900px){
  .fc-p{grid-template-columns:minmax(0,1fr)}
  .fc-beats{grid-template-columns:repeat(2,minmax(0,1fr));gap:26px 0}
  .fc-line{display:none}
  .fc-s{display:none}
}
@media (max-width:520px){.fc-beats{grid-template-columns:minmax(0,1fr)}}
#fc0:checked~.fc-beats .fc-b:nth-child(1) .fc-ic{background:var(--deep-field);box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.42)}
#fc0:checked~.fc-beats .fc-b:nth-child(1) .fc-ic svg{stroke:#fff}
#fc0:checked~.fc-beats .fc-b:nth-child(1) .fc-t{color:var(--primary)}
#fc0:checked~.fc-panels .fc-p[data-fc="0"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#fc0:focus-visible~.fc-beats .fc-b:nth-child(1) .fc-ic{box-shadow:var(--focus),var(--amb-2)}
#fc1:checked~.fc-beats .fc-b:nth-child(2) .fc-ic{background:var(--deep-field);box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.42)}
#fc1:checked~.fc-beats .fc-b:nth-child(2) .fc-ic svg{stroke:#fff}
#fc1:checked~.fc-beats .fc-b:nth-child(2) .fc-t{color:var(--primary)}
#fc1:checked~.fc-panels .fc-p[data-fc="1"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#fc1:focus-visible~.fc-beats .fc-b:nth-child(2) .fc-ic{box-shadow:var(--focus),var(--amb-2)}
#fc2:checked~.fc-beats .fc-b:nth-child(3) .fc-ic{background:var(--deep-field);box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.42)}
#fc2:checked~.fc-beats .fc-b:nth-child(3) .fc-ic svg{stroke:#fff}
#fc2:checked~.fc-beats .fc-b:nth-child(3) .fc-t{color:var(--primary)}
#fc2:checked~.fc-panels .fc-p[data-fc="2"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#fc2:focus-visible~.fc-beats .fc-b:nth-child(3) .fc-ic{box-shadow:var(--focus),var(--amb-2)}
#fc3:checked~.fc-beats .fc-b:nth-child(4) .fc-ic{background:var(--deep-field);box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.42)}
#fc3:checked~.fc-beats .fc-b:nth-child(4) .fc-ic svg{stroke:#fff}
#fc3:checked~.fc-beats .fc-b:nth-child(4) .fc-t{color:var(--primary)}
#fc3:checked~.fc-panels .fc-p[data-fc="3"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#fc3:focus-visible~.fc-beats .fc-b:nth-child(4) .fc-ic{box-shadow:var(--focus),var(--amb-2)}
#fc4:checked~.fc-beats .fc-b:nth-child(5) .fc-ic{background:var(--deep-field);box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.42)}
#fc4:checked~.fc-beats .fc-b:nth-child(5) .fc-ic svg{stroke:#fff}
#fc4:checked~.fc-beats .fc-b:nth-child(5) .fc-t{color:var(--primary)}
#fc4:checked~.fc-panels .fc-p[data-fc="4"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#fc4:focus-visible~.fc-beats .fc-b:nth-child(5) .fc-ic{box-shadow:var(--focus),var(--amb-2)}
#fc5:checked~.fc-beats .fc-b:nth-child(6) .fc-ic{background:var(--deep-field);box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.42)}
#fc5:checked~.fc-beats .fc-b:nth-child(6) .fc-ic svg{stroke:#fff}
#fc5:checked~.fc-beats .fc-b:nth-child(6) .fc-t{color:var(--primary)}
#fc5:checked~.fc-panels .fc-p[data-fc="5"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#fc5:focus-visible~.fc-beats .fc-b:nth-child(6) .fc-ic{box-shadow:var(--focus),var(--amb-2)}
/* ---------- l'echelle des kits, et ce que chacune connecte ----------
   Les tuiles sont des etiquettes de radios caches : aucun JS, clavier natif,
   et la section reste entiere sans script (meme mecanique que le selecteur de
   l'accueil). Chaque tuile ouvre son mini-schema, dont la colonne de droite
   est le vrai propos : ce que l'unite fait TOUTE SEULE. */
.ld-wrap{position:relative}
.ld{list-style:none;margin:clamp(28px,3.2vw,44px) 0 0;padding:0;display:grid;
  gap:clamp(18px,2.2vw,30px);grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr))}
.ld-t{position:relative;display:grid;align-content:start;gap:10px;cursor:pointer;
  padding:clamp(20px,2.2vw,26px);border-radius:16px;background:#fff;
  box-shadow:var(--amb-1),inset 0 0 0 1px rgba(0,42,60,.07);
  transition:box-shadow var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.ld-t:hover{box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,91,125,.24);transform:translateY(-2px)}
/* 🔴 hauteur fixe + contain : `max-height:100%` ne resout pas dans une zone de
   grille, et l'AXON vertical (809x1600) etirait sa tuile a 700 px de haut. */
.ld-pic{height:104px;margin-bottom:4px}
.ld-pic img{width:100%;height:100%;object-fit:contain;
  filter:drop-shadow(0 12px 16px rgba(0,42,60,.18))}
.ld-k{font:600 9.5px/1 var(--font-tech);letter-spacing:.16em;text-transform:uppercase;
  color:var(--mid)}
.ld-n{font-family:var(--font-display);font-weight:600;letter-spacing:-.015em;
  font-size:clamp(1rem,1.2vw,1.1875rem);line-height:1.15;color:var(--deepest)}
.ld-x{font:500 13.5px/1.55 var(--font-body);color:var(--muted)}
.ld-takes{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.ld-takes span{font:600 9.5px/1 var(--font-tech);letter-spacing:.12em;text-transform:uppercase;
  color:var(--primary);padding:6px 9px;border-radius:6px;background:rgba(0,91,125,.06);
  box-shadow:inset 0 0 0 1px rgba(0,91,125,.14)}
.ld-scale{margin-top:6px;padding-top:12px;border-top:1px solid rgba(0,91,125,.12);
  font:600 11px/1.4 var(--font-tech);letter-spacing:.08em;color:var(--primary)}
/* l'invite de clic : discrete au repos, elle se remplit a la selection */
.ld-more{display:inline-flex;align-items:center;gap:8px;
  font:600 10px/1 var(--font-tech);letter-spacing:.13em;text-transform:uppercase;
  color:var(--mid);transition:color var(--t-fast) var(--ease)}
.ld-more::after{content:"";width:6px;height:6px;border-right:1.7px solid currentColor;
  border-bottom:1.7px solid currentColor;transform:rotate(45deg);
  transition:transform var(--t-fast) var(--ease)}
.ld-t:hover .ld-more{color:var(--primary-hover)}
/* le libelle est du vrai texte, pas un `content:` CSS : sur un site trilingue
   un `content:` reste en anglais pour toujours et aucun lecteur d'ecran ne le lit */
.ld-flag{position:absolute;top:0;right:clamp(20px,2.2vw,26px);z-index:1;
  transform:translateY(-50%);padding:6px 10px;border-radius:6px;background:var(--deep-field);
  color:#fff;font:600 9px/1 var(--font-tech);letter-spacing:.13em;text-transform:uppercase}
.ld-here{box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,168,224,.34)}
/* ---- l'etat choisi ---- */
.ld-in{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;margin:0}
.ld-sc{display:none;margin-top:clamp(26px,3vw,40px);
  padding-top:clamp(24px,2.8vw,34px);border-top:1px solid rgba(0,91,125,.14);
  grid-template-columns:minmax(0,1fr) 100px 232px minmax(0,.86fr);
  grid-template-areas:"in fan unit out";align-items:center;gap:0}
.ld-sc-in{grid-area:in;position:relative}
.ld-sc-u{grid-area:unit;text-align:center;margin-left:14px}
/* 🔴 la zone d'image de la mini-scene a besoin de la MEME borne que les tuiles :
   `.ly-unit{height:44px}` ne borne que la hauteur du conteneur, et l'AXON
   vertical (809x1600) debordait de sa carte. Hauteur fixe + contain. */
.ld-sc-u .ly-mark{height:110px}
.ld-sc-u .ly-unit img{width:100%;height:100%;object-fit:contain}
.ld-sc-u .ly-role{max-width:30ch;margin-inline:auto}
.ld-sc-out{grid-area:out;margin-left:clamp(20px,2.4vw,38px)}
.ld-sc-out ul{list-style:none;margin:12px 0 0;padding:0;display:grid;gap:12px}
.ld-sc-out li{padding-left:16px;position:relative;
  font:500 13px/1.55 var(--font-body);color:var(--muted)}
.ld-sc-out li::before{content:"";position:absolute;left:0;top:7px;width:7px;height:7px;
  border-radius:2px;background:var(--signal)}
.ld-sc-out b{display:block;font:600 9.5px/1 var(--font-tech);letter-spacing:.14em;
  text-transform:uppercase;color:var(--primary);margin-bottom:5px}
.ld-sc .sy-fan{position:absolute;left:100%;bottom:0;width:113px;overflow:visible;pointer-events:none}
/* 🔴 Les jetons vont sur le CONTENEUR, pas sur la ligne : `--sy-rg` est
   consomme par `.sy-rows{gap:var(--sy-rg)}`, c'est-a-dire par le PARENT. Pose
   sur `.sy-row`, il etait invisible pour lui, le gap tombait a zero et les
   points se serraient a 54 px pendant que le faisceau, lui, espace ses departs
   de 62. Troisieme forme du meme piege : un jeton defini au mauvais etage. */
.ld-sc{--sy-rh:54px;--sy-rg:8px}
#ld0:checked~.ld .ld-t:nth-of-type(1){box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.5)}
#ld0:checked~.ld .ld-t:nth-of-type(1) .ld-more{color:var(--primary)}
#ld0:checked~.ld .ld-t:nth-of-type(1) .ld-more::after{transform:rotate(-135deg)}
#ld0:checked~.ld-scenes .ld-sc[data-ldv="0"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#ld0:focus-visible~.ld .ld-t:nth-of-type(1){box-shadow:var(--focus),var(--amb-2)}
#ld1:checked~.ld .ld-t:nth-of-type(2){box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.5)}
#ld1:checked~.ld .ld-t:nth-of-type(2) .ld-more{color:var(--primary)}
#ld1:checked~.ld .ld-t:nth-of-type(2) .ld-more::after{transform:rotate(-135deg)}
#ld1:checked~.ld-scenes .ld-sc[data-ldv="1"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#ld1:focus-visible~.ld .ld-t:nth-of-type(2){box-shadow:var(--focus),var(--amb-2)}
#ld2:checked~.ld .ld-t:nth-of-type(3){box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.5)}
#ld2:checked~.ld .ld-t:nth-of-type(3) .ld-more{color:var(--primary)}
#ld2:checked~.ld .ld-t:nth-of-type(3) .ld-more::after{transform:rotate(-135deg)}
#ld2:checked~.ld-scenes .ld-sc[data-ldv="2"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#ld2:focus-visible~.ld .ld-t:nth-of-type(3){box-shadow:var(--focus),var(--amb-2)}
#ld3:checked~.ld .ld-t:nth-of-type(4){box-shadow:var(--amb-3),inset 0 0 0 1px rgba(0,168,224,.5)}
#ld3:checked~.ld .ld-t:nth-of-type(4) .ld-more{color:var(--primary)}
#ld3:checked~.ld .ld-t:nth-of-type(4) .ld-more::after{transform:rotate(-135deg)}
#ld3:checked~.ld-scenes .ld-sc[data-ldv="3"]{display:grid;animation:fl-swap 460ms var(--ease) both}
#ld3:focus-visible~.ld .ld-t:nth-of-type(4){box-shadow:var(--focus),var(--amb-2)}
@media (max-width:1000px){
  .ld-sc{grid-template-columns:minmax(0,1fr);grid-template-areas:"in" "unit" "out";gap:22px 0}
  .ld-sc .sy-fan{display:none}
  .ld-sc .sy-row{grid-template-columns:1fr auto}
  .ld-sc .sy-row .p{display:none}
  .ld-sc-u{text-align:left;margin-left:0}
  .ld-sc-u .ly-role{margin-inline:0}
  .ld-sc-out{margin-left:0}
}
/* ---------- Tait : une interface qui rend beaucoup ----------
   Six colonnes, deux rangees. L'unite, le lien montant, le rail et la console
   tiennent sur les deux rangees, donc **un seul fil** part de la station de
   base et un **eventail** part du site : le contraste est le propos de la
   page. Les jetons de ligne sont redefinis ici (un var() indefini invalide la
   declaration et decale le faisceau — paye sur NEXEDGE). */
.tt-stage{--sy-rh:54px;--sy-rg:8px;--sy-rail:28px;--sy-hubgap:clamp(10px,1.4vw,20px);
  display:grid;align-items:center;
  grid-template-columns:minmax(0,1.02fr) 96px 26px 210px clamp(80px,8.5vw,116px) var(--sy-rail) minmax(0,.9fr);
  grid-template-areas:"iface w1 col unit up rail hub" "site fan col unit up rail hub";
  gap:26px 0}
/* Le collecteur : le fil unique de la station et l'eventail du site arrivent a
   des hauteurs differentes (chacun au centre de SA rangee), l'unite est
   centree sur les deux. Sans lui, deux fleches finissaient dans le vide de
   part et d'autre de la carte. Bus vertical a bouts fondus, puis une seule
   entree dans l'unite, a 50 % — donc pile sur son centre. */
/* align-self:stretch obligatoire : la scene est en align-items:center, donc une
   cellule VIDE se reduit a une hauteur nulle et le bus ne se voit pas. Meme
   cause que le rail. */
.tt-col{grid-area:col;position:relative;align-self:stretch}
.tt-col::before{content:"";position:absolute;left:50%;top:8%;bottom:8%;width:2px;
  transform:translateX(-50%);border-radius:2px;
  background:linear-gradient(180deg,transparent,rgba(0,168,224,.6) 16%,rgba(0,168,224,.6) 84%,transparent)}
.tt-col::after{content:"";position:absolute;left:50%;right:-10px;top:50%;height:2px;
  background:linear-gradient(90deg,rgba(0,168,224,.6),rgba(0,91,125,.3))}
.tt-arrow{position:absolute}
.tt-stage .tt-n{position:relative}
.tt-stage .tt-n::before{content:"";position:absolute;left:-11px;top:50%;width:7px;height:7px;
  border-top:1.8px solid var(--signal);border-right:1.8px solid var(--signal);
  transform:translate(-50%,-50%) rotate(45deg)}
/* les fils vont jusqu'au collecteur */
.tt-w1 .ly-line{margin-right:-13px}
.tt-iface{grid-area:iface}
.tt-w1{grid-area:w1}
.tt-site{grid-area:site}
.tt-n{grid-area:unit;text-align:center}
.tt-up{grid-area:up}
.tt-stage .sy-rail{grid-area:rail;align-self:stretch}
.tt-stage .sy-hubx{grid-area:hub}
.tt-stage .sy-fan{bottom:0;top:auto;transform:none;width:calc(96px + 13px)}
/* la carte de lecture : un instrument, pas une tuile de plus */
.tt-card{position:relative;padding:clamp(16px,1.8vw,22px);border-radius:16px;background:#fff;
  box-shadow:var(--amb-2),inset 0 0 0 1px rgba(0,42,60,.07)}
.tt-card .ly-mark{height:26px;margin-bottom:12px}
.tt-card .ly-n{margin:0 0 12px}
.tt-vals{list-style:none;margin:0;padding:0;display:grid;gap:0}
.tt-vals li{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:8px 0;border-bottom:1px solid rgba(0,91,125,.10)}
.tt-vals li:last-child{border-bottom:0}
.tt-vals span{font:500 13.5px/1.3 var(--font-body);color:var(--text)}
.tt-vals i{font-style:normal;font:600 9.5px/1 var(--font-tech);letter-spacing:.13em;
  text-transform:uppercase;color:var(--primary);padding:5px 8px;border-radius:6px;
  background:rgba(0,91,125,.06);box-shadow:inset 0 0 0 1px rgba(0,91,125,.14)}
.tt-foot{margin:14px 0 0;font:500 12.5px/1.5 var(--font-body);color:var(--muted)}
/* le fil unique est plus epais que ceux de l'eventail : il porte tout */
.tt-w1 .ly-line{height:3px}
.tt-n .ly-role{max-width:28ch;margin-inline:auto}
@media (max-width:1080px){
  .tt-stage{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"iface" "w1" "site" "fan" "unit" "up" "rail" "hub";gap:18px 0}
  .tt-stage .sy-fan,.tt-stage .sy-rail,.tt-col{display:none}
  .tt-stage .tt-n::before{display:none}
  .tt-w1 .ly-line{margin-right:0}
  .tt-stage .sy-row{grid-template-columns:1fr auto}
  .tt-stage .sy-row .p{display:none}
  .tt-n{text-align:left}
  .tt-n .ly-role{margin-inline:0}
  .tt-stage .ly-wire{padding:14px 0 0}
  .tt-stage .cx-g1,.tt-stage .cx-g2{display:none}
  .tt-stage .sy-hubx{margin-left:0;margin-top:16px}
}
/* ---------- la cascade NEXEDGE ----------/* ---------- la cascade NEXEDGE ----------
   Deux etages de la meme grammaire (lignes + faisceau + appareil), le lien
   vertical NEURO -> CORTEX, le rail, la console multi-sites. Les centres
   s'alignent parce que chaque etage vit dans SA rangee de grille et que tout
   y est centre : aucune coordonnee manuelle. */
/* 🔴 --sy-rh et --sy-rg DOIVENT etre definis ici : .sy-row{height:var(--sy-rh)}
   les consomme, et un jeton indefini rend la declaration invalide — les lignes
   retombaient en hauteur auto pendant que le faisceau, lui, calcule ses departs
   sur 54 px. Les fils partaient a cote de leurs lignes (LC, 2026-08-24). */
.cx-stage{--sy-rh:54px;--sy-rg:8px;--sy-rail:28px;--sy-hubgap:clamp(10px,1.4vw,20px);
  display:grid;align-items:center;
  grid-template-columns:minmax(0,1.1fr) 100px 216px clamp(76px,8vw,108px) var(--sy-rail) minmax(0,.9fr);
  grid-template-areas:"ga fa n1 . rail hub" ". . lk . rail hub" "gb fb n2 w2 rail hub";
  gap:14px 0}
.cx-ga{grid-area:ga}
.cx-gb{grid-area:gb}
.cx-n1{grid-area:n1}
.cx-n2{grid-area:n2}
.cx-lk{grid-area:lk}
.cx-w2{grid-area:w2}
.cx-stage .sy-rail{grid-area:rail;align-self:stretch}
.cx-stage .sy-hubx{grid-area:hub}
.cx-g{position:relative}
.cx-g .sy-fan{bottom:0;top:auto;transform:none}
/* la photo du capteur en tete de ligne : boite fixe, contain */
.cx-th{flex:none;width:34px;height:34px;display:grid;place-items:center}
.cx-th img{max-width:100%;max-height:100%;width:auto;height:auto;
  filter:drop-shadow(0 3px 5px rgba(0,42,60,.22))}
.cx .sy-row .t{display:flex;align-items:center;gap:11px}
/* le lien vertical entre les deux unites : il traverse les deux gaps pour
   toucher les cartes, la fleche pointe vers le bas, le libelle a droite */
.cx-lk{position:relative;min-height:56px}
.cx-lk::before{content:"";position:absolute;left:50%;top:-16px;bottom:-16px;width:2px;
  transform:translateX(-50%);border-radius:2px;
  background:linear-gradient(180deg,rgba(0,91,125,.26),rgba(0,168,224,.6))}
.cx-lk::after{content:"";position:absolute;left:50%;bottom:-16px;width:7px;height:7px;
  border-bottom:1.8px solid var(--signal);border-right:1.8px solid var(--signal);
  transform:translate(-50%,0) rotate(45deg)}
.cx-lk-lbl{position:absolute;left:calc(50% + 12px);top:50%;transform:translateY(-50%);
  white-space:nowrap;font:600 9.5px/1 var(--font-tech);letter-spacing:.13em;
  text-transform:uppercase;color:var(--primary)}
/* les sites fantomes derriere la console : il y en a plusieurs, c'est le point */
.cx-g1,.cx-g2{position:absolute;inset:0;border-radius:10px;background:#fff;
  box-shadow:var(--amb-1),inset 0 0 0 1px rgba(0,42,60,.10)}
.cx-g1{transform:translate(9px,-9px)}
.cx-g2{transform:translate(18px,-18px);opacity:.55}
.cx .sy-shot > img{position:relative}
.cx .sy-shot::before,.cx .sy-shot::after{z-index:1}
@media (max-width:1080px){
  .cx-stage{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"ga" "fa" "n1" "lk" "gb" "fb" "n2" "w2" "rail" "hub"}
  .cx-stage .sy-fan,.cx-stage .sy-rail{display:none}
  .cx-stage .sy-row{grid-template-columns:1fr auto}
  .cx-stage .sy-row .p{display:none}
  .cx-lk{min-height:44px}
  .cx-lk::before{top:-8px;bottom:-8px}
  .cx-lk-lbl{left:calc(50% + 14px)}
  .cx-stage .ly-wire{padding:16px 0 0}
  .cx-g1,.cx-g2{display:none}
  .cx-stage .sy-hubx{margin-left:0;margin-top:16px}
}
/* La console : un ecran qui flotte/* La console : un ecran qui flotte, pose par son ombre, et le panneau
   d'alarmes qui deborde en bas a gauche — le langage de l'accueil (LC :
   la carte blanche etiree « pas vraiment beau non plus »). Le pied porte le
   logo et la phrase de role. */
.sy-hubx{grid-area:hub;align-self:center;margin-left:var(--sy-hubgap);
  display:grid;gap:0}
/* le cutout flottant : l'objet, son ombre, une legende discrete */
.itg-float{margin-inline:0}
.itg-float img{width:min(100%,520px);height:auto;border-radius:0;box-shadow:none;
  filter:drop-shadow(0 22px 30px rgba(0,42,60,.20)) drop-shadow(0 5px 9px rgba(0,42,60,.11))}
.itg-float figcaption{margin-top:16px;text-transform:none;letter-spacing:0;text-align:left;
  font:400 13px/1.55 var(--font-body);color:var(--muted);max-width:60ch}
/* ---------- catalogue : les versions d'une reference ----------
   Une tuile = une famille (« ILPS »), mais on commande un ILPS5012N ou un
   ILPS48N. Le tableau des versions vient de la liste de prix, la seule source
   qui decrit chaque reference. Sans JS il reste dans la tuile ; avec JS il
   passe dans un <dialog> natif, le meme pattern que les modals de specs des
   pages produit. */
.ct-card.ct-has{cursor:pointer}
/* La tuile passe en colonne flex — meme rendu qu'en grille — pour que l'appel
   se pose en bas : sur une rangee, les « 6 versions » s'alignent au lieu de
   flotter a la hauteur du texte le plus long. Surcharge locale : la regle de
   base vit dans CSS_FIELD, partagee par les autres pages. */
.ct-quote{margin-top:auto;padding-top:10px;display:inline-flex;align-items:center;gap:8px;
  font:600 12px/1 var(--font-body);color:var(--primary);text-decoration:none;align-self:start}
.ct-quote .bub{width:24px;height:24px;border-radius:var(--r-bub);display:grid;place-items:center;
  background:rgba(0,42,60,.055);transition:background var(--t-fast) var(--ease)}
.ct-quote .bub svg{width:12px;height:12px;stroke:currentColor;stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.ct-quote:hover{color:var(--primary-hover);text-decoration:none}
.ct-quote:hover .bub{background:rgba(0,168,224,.18)}
.ct-grid .ct-card{display:flex;flex-direction:column}
.ct-open{justify-self:start;margin-top:auto;padding-top:11px;border:0;background:none;cursor:pointer;
  display:inline-flex;align-items:center;gap:9px;color:var(--primary);
  font:600 10px/1 var(--font-tech);letter-spacing:.14em;text-transform:uppercase}
.ct-open .bub{width:24px;height:24px;border-radius:var(--r-bub);display:grid;place-items:center;
  background:rgba(0,42,60,.055);transition:background var(--t-fast) var(--ease)}
.ct-open .bub svg{width:13px;height:13px;stroke:currentColor;stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.ct-card.ct-has:hover .ct-open .bub{background:rgba(0,168,224,.16)}
.ct-open:focus-visible{outline:2px solid var(--primary);outline-offset:4px;border-radius:4px}
.ct-detail{margin-top:12px}
/* le JS pose la classe : sans lui, aucune version ne se cache derriere un etat */
.js-ctmod .ct-detail{display:none}
.ct-tbl{width:100%;border-collapse:collapse;text-align:left}
.ct-tbl .ct-pn{font:600 12.5px/1.6 var(--font-tech);color:var(--primary)}
.ct-tbl tbody td{color:var(--muted);font-size:14px;line-height:1.62}
/* Deux contextes, deux mises en page. Dans la tuile (repli sans JS, 224 px de
   large) une table a deux colonnes se comprime en accordeon : on empile. Dans
   le dialog, la largeur existe, la table se lit comme une table. */
.ct-detail .ct-tbl thead{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0)}
.ct-detail .ct-tbl tbody tr,.ct-detail .ct-tbl tbody th,
.ct-detail .ct-tbl tbody td{display:block;padding:0}
.ct-detail .ct-tbl tbody tr{padding:11px 0}
.ct-detail .ct-tbl tbody tr+tr{border-top:1px solid var(--border)}
.ct-detail .ct-tbl .ct-pn{padding-bottom:4px}
.ct-detail .ct-tbl tbody td{font-size:12.5px;line-height:1.55}
.ct-dlg .ct-tbl thead th{font:600 10px/1 var(--font-tech);letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap;
  padding:0 22px 11px 0;border-bottom:1px solid var(--border)}
.ct-dlg .ct-tbl tbody th,.ct-dlg .ct-tbl tbody td{padding:14px 22px 14px 0;
  vertical-align:top}
.ct-dlg .ct-tbl tbody tr+tr{border-top:1px solid var(--border)}
.ct-dlg .ct-tbl .ct-pn{white-space:nowrap}
.ct-dlg .ct-tbl tbody td{padding-right:0}
/* sous 620 px la table du dialog s'empile a son tour */
@media (max-width:620px){
  .ct-dlg .ct-tbl thead{position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(0 0 0 0)}
  .ct-dlg .ct-tbl tbody tr,.ct-dlg .ct-tbl tbody th,
  .ct-dlg .ct-tbl tbody td{display:block;padding:0}
  .ct-dlg .ct-tbl tbody tr{padding:14px 0}
  .ct-dlg .ct-tbl .ct-pn{padding-bottom:5px}
}
dialog.ct-dlg{border:0;padding:0;border-radius:var(--r-lg);width:min(92vw,780px);
  max-height:86vh;box-shadow:var(--amb-4);background:var(--white);overflow:hidden}
dialog.ct-dlg:not([open]){display:none}
dialog.ct-dlg::backdrop{background:rgba(0,26,38,.55);backdrop-filter:blur(6px)}
.ct-dlg .dlg-body{max-height:calc(86vh - 216px)}
.ct-dlg-id{display:flex;align-items:center;gap:16px;min-width:0}
.ct-dlg-pic{flex:0 0 auto;width:62px;height:62px;display:grid;place-items:center}
.ct-dlg-pic img{max-width:62px;max-height:62px;width:auto;height:auto;object-fit:contain;
  filter:var(--lift)}
.ct-dlg-id .mono{margin:0 0 7px;color:var(--primary)}
.ct-dlg-id h3{font-size:1.25rem}
@media (prefers-reduced-motion:no-preference){
  dialog.ct-dlg[open]{animation:ct-in var(--t-fast) var(--ease)}
}
@keyframes ct-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* ---------- module de reservation Zoho Bookings (2026-08-20) ----------
   Le portail arrive avec son propre fond tres pale (#f4f4f4) et sa propre
   typographie : on ne l'habille pas, on lui donne un cadre du systeme (filet,
   coins a 10 px, ombre d'ambiance) et on le laisse respirer. */
.bookframe{position:relative;margin-top:clamp(26px,3vw,40px);
  border-radius:var(--r-md);background:var(--white);overflow:hidden;
  box-shadow:var(--hairline),var(--amb-2)}
/* Hauteur : mesuree sur le rendu servi, l'assistant Zoho occupe environ 600 px
   a l'etape « Date & Time » et grandit a l'etape « Your Info ». 750 px est la
   valeur de la production; on garde la meme enveloppe, avec une marge pour les
   grands ecrans. Plus haut, le cadre laisse une plage blanche morte sous
   l'assistant; plus bas, le visiteur defile dans un cadre a l'interieur d'une
   page qui defile deja. */
.bookframe iframe{display:block;width:100%;height:clamp(750px,72vh,820px);border:0}
/* Le filet cyan de la marque, pose sur la tranche haute du cadre. */
.bookframe::before{content:"";position:absolute;inset:0 0 auto 0;height:2px;z-index:1;
  background:linear-gradient(90deg,var(--primary),var(--signal) 62%,var(--pale))}
/* Secours : un tiers peut echouer (blocage de traceurs, reseau d'entreprise).
   Sans cette ligne, la page ne serait qu'un rectangle vide. */
.bookfall{margin-top:14px;color:var(--muted);font:400 13px/1.6 var(--font-tech)}
.bookfall a{color:var(--primary);text-decoration:underline;text-underline-offset:3px}
.bookfall a:hover{color:var(--primary-hover)}
@media (max-width:760px){.bookframe iframe{height:clamp(720px,120vh,1040px)}}
/* les trois systemes prouves, dans le hero. LC 2026-08-18 : « je veux les trois
   petites tuiles des manufacturiers dans le hero, meme si on doit descendre le
   hero ». Elles se posent sous les boutons, en rangee, et passent en colonne
   sous 560 px. */
.hero-oems{margin-top:clamp(26px,3vw,38px);display:flex;flex-wrap:wrap;align-items:center;
  gap:10px}
.hero-oems .mono{flex:0 0 100%;margin:0 0 4px;color:var(--primary)}
.hero-oem{display:inline-flex;align-items:center;gap:12px;padding:10px 12px 10px 14px;
  border-radius:var(--r-btn);background:var(--white);box-shadow:var(--hairline),var(--amb-1);
  text-decoration:none;color:var(--deepest);
  transition:transform var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.hero-oem:hover{transform:translateY(-2px);box-shadow:var(--hairline),var(--amb-2)}
.hero-oem img{height:20px;width:auto;max-width:78px;object-fit:contain}
.hero-oem span{font:600 13px/1 var(--font-body)}
.hero-oem .bub{width:24px;height:24px;border-radius:var(--r-bub);display:grid;place-items:center;
  background:rgba(0,42,60,.055);transition:background var(--t-fast) var(--ease)}
.hero-oem .bub svg{width:13px;height:13px;stroke:currentColor;stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.hero-oem:hover .bub{background:rgba(0,168,224,.16)}
@media (max-width:560px){.hero-oem{width:100%}}
/* la rangee des integrations prouvees (section 06) : meme tuile que le
   catalogue, dont le CSS vit ailleurs. Trois regles suffisent ici. */
.pl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,232px),1fr));
  gap:clamp(12px,1.4vw,18px)}
body.dv-telecom .pl-pic{display:grid;place-items:center;height:70px}
body.dv-telecom .pl-pic img{max-width:78%;max-height:44px;width:auto;height:auto;object-fit:contain}
.pl-card .bub{width:28px;height:28px;border-radius:var(--r-bub);display:grid;place-items:center;
  background:rgba(0,42,60,.055);justify-self:start;
  transition:background var(--t-fast) var(--ease)}
.pl-card .bub svg{width:14px;height:14px;stroke:currentColor;stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
/* ---------- ajouts propres a Telecom & Public Safety ---------- */
body.dv-telecom .split.brochure-row{margin-top:clamp(36px,4vw,56px);align-items:center;
  grid-template-columns:minmax(0,240px) minmax(0,1fr)}
body.dv-telecom .brochure-row .pic img{max-width:min(100%,230px);width:auto;margin-inline:auto;display:block;
  border-radius:var(--r-md);box-shadow:var(--hairline),var(--amb-2)}
.rep-row{margin-top:clamp(40px,4.6vw,64px);align-items:center}
.rep-row .pic img{max-width:min(100%,470px);width:auto;margin-inline:auto;display:block}
body.dv-telecom #how .wide-viz img{max-width:min(100%,900px)}
/* ---------- l'editeur de blocs, remis au niveau de la maquette ----------
   WordPress pose margin-block-start:24px sur chaque enfant non-premier d'un
   groupe. Un decor absolu en est DEPLACE : le voile d'une division sombre
   commencait 24px sous sa photo, d'ou une bande pale a chaque transition.
   La maquette ne donne de marge a aucun de ces elements. Genere. */
.wp-block-group > .photo,
.wp-block-group > .veil,
.wp-block-group > .glow,
.wp-block-group > .grid-field,
.wp-block-group > .wrap{margin-block-start:0}

/* ---------- contraintes de largeur des titres, portees en classe ----------
   Les maquettes les ecrivent en `style` en ligne ; en blocs le style ne
   survit pas (l'editeur le refuserait), la classe si. Genere. */
.dvs-mt12px-mw70ch{margin-top:12px;max-width:70ch}
.dvs-mt14px{margin-top:14px}
.dvs-mt14px-mw64ch{margin-top:14px;max-width:64ch}
.dvs-mt16px{margin-top:16px}
.dvs-mt16px-mw70ch{margin-top:16px;max-width:70ch}
.dvs-mt16px-mw72ch{margin-top:16px;max-width:72ch}
.dvs-mt16px-mw74ch{margin-top:16px;max-width:74ch}
.dvs-mt18px-mw64ch{margin-top:18px;max-width:64ch}
.dvs-mt18px-mw70ch{margin-top:18px;max-width:70ch}
.dvs-mt20px-mw64ch{margin-top:20px;max-width:64ch}
.dvs-mt20px-mw70ch{margin-top:20px;max-width:70ch}
.dvs-mt20px-mw72ch{margin-top:20px;max-width:72ch}
.dvs-mt20px-mw74ch{margin-top:20px;max-width:74ch}
.dvs-mtclamp24px26vw34px-mw76ch{margin-top:clamp(24px,2.6vw,34px);max-width:76ch}
.dvs-mtclamp30px34vw44px{margin-top:clamp(30px,3.4vw,44px)}
.dvs-mw22ch{max-width:22ch}
.dvs-mw24ch{max-width:24ch}
.dvs-mw26ch{max-width:26ch}
.dvs-mw28ch{max-width:28ch}
.dvs-mw30ch{max-width:30ch}
.dvs-mw32ch{max-width:32ch}
.dvs-mw34ch{max-width:34ch}
.dvs-mw56ch{max-width:56ch}
/* ---------- fil d'Ariane ----------
   Meme micro-typographie que la pastille `.tag` et les reperes `.ref` : le fil
   n'introduit aucune convention nouvelle. Survol vers le fonce, jamais vers le
   clair. */
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:16px;
  font:600 12px/1.5 var(--font-tech);letter-spacing:.1em;text-transform:uppercase}
.crumbs a{color:var(--muted);text-decoration:none;border-bottom:1px solid transparent;
  transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.crumbs a:hover{color:var(--deepest);border-bottom-color:var(--deepest)}
.crumbs .cr-step{color:var(--muted)}
.crumbs .cr-sep{color:var(--muted);opacity:.45}
.crumbs .cr-here{color:var(--primary)}
@media (max-width:640px){.crumbs{font-size:11px;gap:8px}}

/* Fond off-white des sections alternees.
   🔴 Repare un degat silencieux. Les gabarits portaient
   `<section class="sec style="background:var(--off-white)"">` : le `style`
   etait avale par le `class`, donc le fond n'a JAMAIS ete applique. La
   conversion en blocs a fige la faute en base, ou 42 pages portaient
   `class="... sec style="`, sans meme la valeur. Les gabarits sont corriges;
   cette classe rend le fond aux pages en blocs. */
.dvs-offwhite{background:var(--off-white)}
