  /* Polices auto-hébergées : aucune requête vers un tiers.
     Sous-ensembles latin et latin-ext, fichiers dans /assets/fonts/. */
  @font-face{font-family:'Archivo';font-style:normal;font-weight:400 800;font-stretch:100% 125%;font-display:swap;
    src:url('/assets/fonts/archivo-latin-ext.woff2') format('woff2');
    unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'Archivo';font-style:normal;font-weight:400 800;font-stretch:100% 125%;font-display:swap;
    src:url('/assets/fonts/archivo-latin.woff2') format('woff2');
    unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400 600;font-stretch:100%;font-display:swap;
    src:url('/assets/fonts/instrument-sans-latin-ext.woff2') format('woff2');
    unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400 600;font-stretch:100%;font-display:swap;
    src:url('/assets/fonts/instrument-sans-latin.woff2') format('woff2');
    unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;
    src:url('/assets/fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
    unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;
    src:url('/assets/fonts/jetbrains-mono-latin.woff2') format('woff2');
    unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

  :root{
    --ink:#0E1319; --paper:#E9EBEC; --paper-2:#E1E4E6;
    --brand:#0066CC; --beacon:#F0B429; --slate:#69737C;
    --line:rgba(14,19,25,.16);
    --display:"Archivo","Helvetica Neue",Arial,sans-serif;
    --body:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
    --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  }
  *,*::before,*::after{box-sizing:border-box}
  html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
  body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);
       font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased}
  img,svg{max-width:100%}
  a{color:inherit}
  :focus-visible{outline:2px solid var(--brand);outline-offset:3px}

  .wrap{width:min(1180px,100% - 2.5rem);margin-inline:auto}
  .eyebrow{font-family:var(--mono);font-size:.72rem;letter-spacing:.2em;
           text-transform:uppercase;color:var(--brand);margin:0 0 1.1rem}
  h2.title{font-family:var(--display);font-variation-settings:"wdth" 112;font-weight:700;
           letter-spacing:-.022em;line-height:1.03;font-size:clamp(1.9rem,4vw,2.9rem);margin:0 0 1.2rem}
  .lede{font-size:clamp(1.02rem,1.6vw,1.18rem);color:#262E36;max-width:58ch;margin:0}

  .masthead{border-bottom:1px solid var(--line)}
  .masthead .inner{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding-block:1.25rem}
  .mark{font-family:var(--mono);font-size:1.05rem;letter-spacing:.17em;text-transform:uppercase;
        font-weight:500;text-decoration:none;display:flex;align-items:center;gap:.85rem}
  .mark img{display:block;width:46px;height:auto}
  .mark span{color:var(--brand)}
  .masthead nav{display:flex;gap:1.6rem;font-family:var(--mono);font-size:.75rem;
                letter-spacing:.12em;text-transform:uppercase}
  .masthead nav a{text-decoration:none;color:var(--slate);padding-block:.2rem;border-bottom:1px solid transparent}
  .masthead nav a:hover{color:var(--ink);border-bottom-color:var(--beacon)}
  @media(max-width:980px){.masthead nav{display:none}}
  /* Le bloc de droite du bandeau : navigation (ou retour) plus sélecteur de langue.
     Le sélecteur reste visible quand la navigation disparaît. */
  .mhx{display:flex;align-items:center;gap:2.2rem}
  /* Commutateur encadré plutôt qu'une paire de liens : le visiteur doit
     l'identifier comme un choix, pas comme deux entrées de menu de plus. */
  .lang{display:flex;margin:0;border:1px solid var(--ink);border-radius:2px;overflow:hidden;
        font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}
  .lang a{text-decoration:none;color:#333B43;padding:.45rem .78rem;line-height:1;
          transition:background .15s ease,color .15s ease}
  .lang a + a{border-left:1px solid var(--ink)}
  .lang a:hover{background:var(--paper-2);color:var(--ink)}
  .lang a[aria-current]{background:var(--ink);color:var(--paper)}

  .hero{padding-block:clamp(3.2rem,7vw,6rem) clamp(2.5rem,6vw,5rem)}
  /* En colonne unique l'ordre du DOM s'applique : texte, panneau, puis appel à
     l'action — qui reste ainsi sous le visuel. En deux colonnes, l'appel remonte
     sous le texte via les zones nommées. */
  .hero .grid{display:grid;gap:clamp(2.5rem,5vw,4rem);align-items:center}
  @media(min-width:940px){
    .hero .grid{grid-template-columns:1.02fr 1fr;
                grid-template-areas:"intro panel" "cta panel";
                column-gap:clamp(2.5rem,5vw,4rem);row-gap:2rem}
    .hero .intro{grid-area:intro;align-self:end}
    .hero .actions{grid-area:cta;align-self:start}
    .hero .panel{grid-area:panel}
  }
  h1{font-family:var(--display);font-variation-settings:"wdth" 108;font-weight:800;
     letter-spacing:-.035em;line-height:.95;font-size:clamp(2.4rem,5.9vw,4.5rem);
     margin:0 0 1.4rem;text-wrap:balance}
  h1 em{font-style:normal;color:var(--brand)}
  .actions{display:flex;flex-wrap:wrap;gap:.9rem 1.6rem;align-items:center}
  .btn{display:inline-block;background:var(--ink);color:var(--paper);text-decoration:none;
       font-family:var(--mono);font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;
       padding:.85rem 1.5rem;border-radius:2px;transition:background .18s ease,transform .18s ease}
  .btn:hover{background:var(--brand);transform:translateY(-1px)}
  .link-b{font-family:var(--mono);font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;
          text-decoration:none;border-bottom:2px solid var(--beacon);padding-bottom:2px}
  .link-b:hover{border-bottom-color:var(--ink)}

  .panel{background:var(--ink);border-radius:3px;padding:1rem 1rem .55rem}
  .panel svg{display:block;width:100%;height:auto}

  /* Hero — chronologie de détectabilité. Un curseur balaie les quatre stades de
     dégradation ; le premier, l'ultrason, est allumé dès le départ. */
  .mark-b{fill:var(--beacon)}
  .st{fill:#464E56}
  .stx{stroke:#464E56;stroke-width:2.6;stroke-linecap:round}
  .on{fill:rgba(233,235,236,.9)}
  .onx{stroke:rgba(233,235,236,.9);stroke-width:2.6;stroke-linecap:round}
  .lit1{animation:lit1 8s linear infinite}
  .lit2{animation:lit2 8s linear infinite}
  .lit3{animation:lit3 8s linear infinite}
  .lit4{animation:lit4 8s linear infinite}
  .callout{stroke:var(--beacon);stroke-width:1;opacity:.55}
  .tick.hi{fill:var(--beacon);opacity:.85}   /* ambre fixe : le .b du spectre est animé */
  .cur{opacity:0;animation:sweep 8s linear infinite}
  .cur line{stroke:rgba(233,235,236,.45);stroke-width:1;stroke-dasharray:2 4}
  .cur path{fill:rgba(233,235,236,.55)}
  .marge{fill:var(--beacon);transform-box:fill-box;transform-origin:left;
         animation:extend 8s linear infinite}
  /* Le curseur part avant le premier stade : la dégradation court déjà quand
     l'ultrason la capte. Les seuils suivent sa position sur l'axe. */
  @keyframes lit1{0%,18%{opacity:0}22%,88%{opacity:1}92%,100%{opacity:0}}
  @keyframes lit2{0%,37%{opacity:0}41%,88%{opacity:1}92%,100%{opacity:0}}
  @keyframes lit3{0%,56%{opacity:0}60%,88%{opacity:1}92%,100%{opacity:0}}
  @keyframes lit4{0%,75%{opacity:0}79%,88%{opacity:1}92%,100%{opacity:0}}
  @keyframes sweep{0%{transform:translateX(0);opacity:0}
                   3%{opacity:1}
                   75%,88%{transform:translateX(640px);opacity:1}
                   92%,100%{transform:translateX(640px);opacity:0}}
  @keyframes extend{0%,18%{transform:scaleX(0);opacity:0}22%{opacity:1}
                    75%,88%{transform:scaleX(1);opacity:1}
                    92%,100%{transform:scaleX(1);opacity:0}}

  /* Spectre d'enveloppe — section « Traitement local ». En haut le niveau global,
     plat, qui ne franchit jamais son seuil. En bas la famille d'harmoniques BPFO
     qui sort du bruit de fond. Tout en CSS, sans JS. */
  .axis{stroke:rgba(233,235,236,.14);stroke-width:1}
  .thresh{stroke:var(--beacon);stroke-width:1;stroke-dasharray:5 5;opacity:.45}
  .trace{fill:none;stroke:rgba(233,235,236,.6);stroke-width:1.4;
         stroke-linejoin:round;stroke-linecap:round}
  .floor{fill:none;stroke:rgba(233,235,236,.34);stroke-width:1.2}
  .rot{fill:rgba(233,235,236,.4)}
  .pk{fill:var(--beacon);transform-box:fill-box;transform-origin:bottom;
      animation:grow 7s ease-out infinite}
  .pkm{fill:var(--beacon);animation:fadein 7s ease-out infinite}
  .p2{animation-delay:.55s} .p3{animation-delay:1.1s} .p4{animation-delay:1.65s}
  .clabel{font-family:var(--mono);font-size:13px;fill:rgba(233,235,236,.6);letter-spacing:.11em}
  .clabel.b{fill:var(--beacon);opacity:.9}
  .tick{font-family:var(--mono);font-size:11px;fill:rgba(233,235,236,.42);letter-spacing:.05em}
  .tick.b{fill:var(--beacon);opacity:.85;animation:fadein 7s ease-out infinite}
  @keyframes grow{0%{transform:scaleY(.02);opacity:0}5%{opacity:1}
                  20%,88%{transform:scaleY(1);opacity:1}
                  97%,100%{transform:scaleY(.02);opacity:0}}
  @keyframes fadein{0%,4%{opacity:0}20%,88%{opacity:1}97%,100%{opacity:0}}

  .edge{stroke:rgba(233,235,236,.22);stroke-width:1.4}
  .edge.live{stroke:rgba(233,235,236,.5)}
  .edge.down{stroke:rgba(233,235,236,.1);stroke-dasharray:3 5}
  .halo{fill:none;stroke:rgba(233,235,236,.28);stroke-width:1}
  .node{fill:var(--paper)}
  .node.hub{fill:var(--beacon)}
  .node.offline{fill:#464E56}
  .nlabel{font-family:var(--mono);font-size:11px;fill:rgba(233,235,236,.55);letter-spacing:.1em}
  .packet{fill:var(--beacon)}
  .status{font-family:var(--mono);font-size:.68rem;letter-spacing:.11em;text-transform:uppercase;
          color:rgba(233,235,236,.6);margin:.35rem .3rem 0;display:flex;justify-content:space-between;gap:1rem}
  .status b{font-weight:500;color:var(--beacon)}

  .section{padding-block:clamp(3.4rem,7vw,6rem);border-top:1px solid var(--line)}
  .head{max-width:62ch;margin-bottom:clamp(2.2rem,4vw,3.4rem)}

  .split{display:grid;gap:clamp(2rem,4vw,3.6rem);align-items:start}
  @media(min-width:900px){.split{grid-template-columns:1fr 1fr}}
  .split.tight{align-items:center;margin-top:clamp(2.2rem,4vw,3.4rem)}

  .constraints{list-style:none;margin:0;padding:0}
  .constraints li{border-top:1px solid var(--line);padding:.95rem 0;display:grid;
                  grid-template-columns:auto 1fr;gap:1.1rem;align-items:baseline}
  .constraints li:last-child{border-bottom:1px solid var(--line)}
  .constraints .k{font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;
                  text-transform:uppercase;color:var(--brand);white-space:nowrap}
  .constraints .v{font-size:.97rem}

  .cards{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
  @media(min-width:860px){.cards{grid-template-columns:repeat(3,1fr)}}
  .card{background:var(--paper);padding:clamp(1.5rem,2.6vw,2.2rem);display:flex;flex-direction:column}
  .card h3{font-family:var(--display);font-variation-settings:"wdth" 105;font-weight:700;
           font-size:1.24rem;margin:.7rem 0 .6rem;letter-spacing:-.012em}
  .card p{margin:0 0 1.2rem;color:#333B43;font-size:.97rem}
  .card .tagm{font-family:var(--mono);font-size:.68rem;letter-spacing:.18em;
              text-transform:uppercase;color:var(--brand);margin:0}
  .card .fact{margin:auto 0 0;padding-top:1rem;border-top:1px solid var(--line);
              font-family:var(--mono);font-size:.72rem;letter-spacing:.06em;color:var(--slate)}

  /* Les trois cartes partagent quatre bandes — étiquette, titre, texte, repère —
     via une sous-grille. Le filet de pied s'aligne donc même quand un repère passe
     sur deux lignes, ce qui arrive en français comme en anglais selon la largeur.
     Ce bloc doit rester APRÈS les règles .card ci-dessus : une media query n'ajoute
     aucune spécificité, il serait sinon écrasé par display:flex et margin:auto.
     Sans prise en charge de subgrid, on retombe sur le flux flex d'origine. */
  @media(min-width:860px){
    @supports (grid-template-rows: subgrid){
      .cards{grid-template-rows:auto auto 1fr auto;row-gap:0}
      .card{display:grid;grid-row:span 4;grid-template-rows:subgrid}
      .card .fact{margin:0}
    }
  }

  .axes{margin:0;padding:0;list-style:none;display:grid;gap:1.6rem}
  .axes h3{font-family:var(--display);font-variation-settings:"wdth" 110;font-weight:700;
           font-size:1.12rem;margin:0 0 .35rem;letter-spacing:-.012em}
  .axes p{margin:0;font-size:.97rem;color:#333B43}
  .axes li{border-left:3px solid var(--beacon);padding-left:1.2rem}

  .pull{font-family:var(--display);font-variation-settings:"wdth" 100;font-weight:600;
        font-size:clamp(1.2rem,2.2vw,1.55rem);line-height:1.32;margin:0 0 2rem;
        border-left:3px solid var(--beacon);padding-left:1.2rem}

  .labels{list-style:none;margin:1.2rem 0 0;padding:0;display:flex;flex-wrap:wrap;gap:.6rem}
  .labels li{font-family:var(--mono);font-size:.76rem;letter-spacing:.06em;
             border:1px solid var(--line);padding:.5rem .85rem;border-radius:2px;color:#333B43}

  .bio{background:var(--paper-2);border:1px solid var(--line);border-top:3px solid var(--ink);
       padding:clamp(1.5rem,2.8vw,2.3rem)}
  .bio h3{font-family:var(--display);font-variation-settings:"wdth" 112;font-weight:800;
          font-size:clamp(1.3rem,2.2vw,1.7rem);margin:0 0 .15rem;letter-spacing:-.02em}
  .bio .role{font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;
             text-transform:uppercase;color:var(--brand);margin:0 0 1.1rem}
  .bio p{margin:0 0 1rem;font-size:.99rem}
  .bio p:last-child{margin-bottom:0}

  .contact{background:var(--ink);color:var(--paper)}
  .contact .wrap{padding-block:clamp(3.4rem,7vw,5.6rem)}
  .contact .eyebrow{color:var(--beacon)}
  .contact h2{font-family:var(--display);font-variation-settings:"wdth" 110;font-weight:800;
              font-size:clamp(1.9rem,4.4vw,3.1rem);letter-spacing:-.028em;line-height:1.03;margin:0 0 1.1rem}
  .contact p{color:rgba(233,235,236,.72);max-width:54ch;margin:0 0 2rem}
  .contact .btn{background:var(--beacon);color:var(--ink)}
  .contact .btn:hover{background:var(--paper)}
  .contact .link-b{color:rgba(233,235,236,.85)}

  footer{background:var(--ink);color:rgba(233,235,236,.45);border-top:1px solid rgba(233,235,236,.14)}
  footer .wrap{padding-block:1.5rem;display:flex;flex-wrap:wrap;gap:.6rem 2rem;justify-content:space-between;
               font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase}
  footer a{color:inherit;text-decoration:none}
  footer a:hover{color:var(--beacon)}


  /* ------------------------------------------------------------------
     Page « Mentions légales ». Tout est porté par .doc ou body.legal :
     h1, h2, p, ul, li et .intro existent déjà sur la page d'accueil.
     ------------------------------------------------------------------ */
  .back{font-family:var(--mono);font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;
        text-decoration:none;color:var(--slate);border-bottom:1px solid transparent;padding-block:.2rem}
  .back:hover{color:var(--ink);border-bottom-color:var(--beacon)}

  body.legal main{padding-block:clamp(2.8rem,6vw,4.5rem) clamp(3rem,6vw,5rem)}
  body.legal footer{margin-top:clamp(2rem,5vw,4rem)}

  .doc{max-width:72ch}
  .doc h1{font-family:var(--display);font-variation-settings:"wdth" 110;font-weight:800;
          letter-spacing:-.03em;line-height:1.02;font-size:clamp(2rem,5vw,3.2rem);margin:0 0 1.6rem}
  .doc h2{font-family:var(--display);font-variation-settings:"wdth" 110;font-weight:700;
          letter-spacing:-.018em;font-size:clamp(1.2rem,2.2vw,1.45rem);
          margin:2.6rem 0 .9rem;padding-top:1.5rem;border-top:1px solid var(--line)}
  .doc h2:first-of-type{margin-top:2rem}
  .doc p{margin:0 0 1rem}
  .doc .intro{font-size:clamp(1.02rem,1.6vw,1.12rem);color:#262E36}
  .doc ul{margin:0 0 1rem;padding-left:1.2rem}
  .doc li{margin-bottom:.4rem}

  .doc dl{margin:0;display:grid;gap:.1rem 1.4rem}
  @media(min-width:640px){.doc dl{grid-template-columns:auto 1fr}}
  .doc dt{font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
          color:var(--slate);padding-top:.35rem}
  .doc dd{margin:0 0 .7rem}
  @media(min-width:640px){.doc dd{margin-bottom:.35rem}}

  /* .todo en ambre : point bloquant, la page ne doit pas être publiée en l'état.
     .notice en bleu : information permanente. Ne pas confondre les deux. */
  .doc .todo,.doc .notice{border-left:3px solid var(--beacon);background:var(--paper-2);
                          padding:1rem 1.2rem;margin:0 0 1rem}
  .doc .notice{border-left-color:var(--brand)}
  .doc .todo p,.doc .notice p{margin:0}
  .doc .todo strong,.doc .notice strong{font-family:var(--mono);font-size:.72rem;
                    letter-spacing:.14em;text-transform:uppercase;display:block;margin-bottom:.4rem}
  @media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
