/* ══════════════════════════════════════════════════════════════════════════
   v5-floor.css — legibility and target floors, site-wide.

   Loaded last on every page so it wins without specificity tricks. It sets
   minimums, never a look: sizes go up, nothing else changes.

   The floors, agreed for the French Tech RC:
     body        >= 15px
     legal       >= 13px
     source      >= 13px
     status      >= 12px
     label       >= 12px
     interactive >= 13px text and a 44px hit area

   The site's own doctrine is that a maturity label, a source and a limit are
   product elements. They were the smallest text on the page, some of them at
   7px; a claim nobody can read is not a claim that has been made.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── labels and eyebrows: 12px floor, tracking eased so caps stay readable ── */
.eyebrow,
.menu-eyebrow,
.case-kicker,
.confident-kicker,
.confident-state-label,
.work-case-surface .surface-label,
.case-proof-object .case-object-label,
.wow-capability small,
.routes-label,
.chain-label,
.schema-label { font-size: .75rem; letter-spacing: .09em; }

/* ── maturity: never smaller than 12px, at any viewport ── */
.status,
.world-list span,
.wow-proof-status span,
.proof-shot figcaption span,
.terrain-state,
.system-state { font-size: .78rem; letter-spacing: .04em; }

/* ── proof grammar: the label reads, the claim reads ── */
.proof-lens dt,
.case-proof-list dt,
.case-evidence-grid strong { font-size: .78rem; letter-spacing: .07em; }
.proof-lens dd,
.case-proof-list dd,
.case-limits li,
.case-decisions li p,
.case-section > p { font-size: .95rem; line-height: 1.55; }

/* ── sources, captions and boundaries: 13px floor ── */
.case-hero-media figcaption,
.system-shot figcaption,
.work-case-boundary,
.work-index-note,
.result-routes-note,
.wow-reel-note,
.project-note,
.evidence span,
.reality-signals a,
.smart-bot-evidence small { font-size: .82rem; }

/* ── legal, privacy and consent: 13px floor ── */
.site-foot,
.legal-link,
.talk-note,
.callback-status,
.callback-attr-note,
.callback-field label,
.callback-consent,
.confident-boundary span,
.smart-bot-foot,
.risk-honesty { font-size: .82rem; }

/* ── interactive: 13px text and a real 44px target ── */
.text-link,
.work-index-head .work-back,
.case-rail a,
.project-link-row .text-link,
.work-case-link-row .text-link,
.case-actions .text-link {
  font-size: .82rem;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.brand { display: inline-flex; align-items: center; min-height: 44px; }
.skip { min-height: 44px; display: inline-flex; align-items: center; }
.text-button { font-size: .82rem; min-height: 44px; }
.callback-consent input[type="checkbox"] { width: 22px; height: 22px; }
.callback-consent { display: flex; align-items: flex-start; gap: 12px; min-height: 44px; }

/* The case rail is a horizontal scroller with its scrollbar hidden; taller
   targets and a visible edge make it usable rather than merely present. */
.case-rail a { padding: 0 2px; }

/* ── header: contrast that can actually be computed ──
   .site-head used mix-blend-mode:difference so one header could sit over both
   light and dark sections. The cost was that the brand and the navigation had
   no statically computable contrast at all, and inverted to near-black over the
   ink sections. A solid ground with a hairline is duller and correct.
   That ground then has to be actually solid. At .94 it was not: six percent of
   everything scrolling underneath kept coming through the bar — measured against
   an opaque control at 6% of the band at 1440, and at 85% there and 96% at 390
   over the ink sections, where a white heading crossed the header and collided
   with the navigation until neither could be read. Opacity is the entire fix;
   the height, the hairline and the type are untouched. */
.site-head {
  mix-blend-mode: normal;
  color: var(--ink);
  background: var(--paper);
  backdrop-filter: none;
  border-bottom: 1px solid var(--line);
}
.site-head .brand,
.site-head .desktop-nav a { color: var(--ink); }
.site-head .desktop-nav a { opacity: 1; color: #3f3f46; }
.site-head .desktop-nav a:hover,
.site-head .desktop-nav a:focus-visible { color: var(--ink); }
.menu-toggle span { background: var(--ink); }

/* ── one fixed-width illustration overflowed 320px viewports ── */
.companion { width: min(150px, 100%); height: auto; }

/* ── LOT 7b ──────────────────────────────────────────────────────────────
   --muted on the soft ground computed 4.4:1, just under AA, which put the
   capability attributions and several labels below the line on the patrimony
   section. Darkened just enough to clear 4.5:1 on both --paper and --soft. */
:root{--muted:#6a6a73}

.desktop-nav{font-size:.8rem}
.site-foot .legal-link{display:inline-flex;align-items:center;min-height:44px}
.work-case-surface span:last-child{font-size:.82rem}

/* Horizontal containment: the case rail scrolls on its own and the phone mock
   never pushes the document wider than the viewport. */
.case-rail{min-width:0;max-width:100%}
.phone-stage,.phone,.screen-duo,.health-screen,.obd-stage,.risk-stage{max-width:100%;overflow:hidden}

/* ── LOT 7c ──────────────────────────────────────────────────────────────
   Red on ink computes to 3.84:1. That clears AA for large text and fails for
   anything smaller, so the AUTORISER heading must stay large text at EVERY
   viewport, not only on desktop. Its floor was 20.8px at 320, below the 24px
   threshold. Raised so the authorised red never sits on sub-large type. */
.method-step h3{font-size:clamp(1.5rem,2.2vw,2.1rem)}

/* The system heading link measured 43.99px: a target that rounds to 44 is not
   a target that meets 44. */
.system-head h3 a{padding-block:10px}

/* ── LOT 8a — the last sub-12px text on the case pages ────────────────────
   Step indices and step labels inside the case proof object. They name the
   stages of a system; they are content, not ornament. */
.case-decisions li > span{font-size:.78rem}
.case-proof-object .case-object-steps b{font-size:.78rem}
.case-proof-object .case-object-steps span{font-size:.85rem}

/* ── LOT 8b — anchored headings must clear the fixed chrome ───────────────
   The header is fixed at 68px and the case rail is sticky under it. Without a
   scroll margin every in-page anchor lands with its own heading hidden behind
   them, which is worst on the rail the reader just used. */
main section[id],.case-section[id]{scroll-margin-top:132px}
@media(max-width:820px){main section[id],.case-section[id]{scroll-margin-top:120px}}

/* ── Cases that carry no media close their frame instead of leaving a hole ──
   The Valentin capture is withdrawn for this release: it bakes numeric claims
   into its pixels, and the live site it comes from frames the matter as a
   campaign, so a fresh capture would reproduce the problem rather than solve it.
   The text stays; the slot reopens when a clean file exists. */
.work-case--no-media{grid-template-columns:minmax(0,1fr)}
.case-hero--no-media{grid-template-columns:minmax(0,1fr)}

/* ── L5 blocker closure — responsive + WCAG AA ────────────────────────────
   A long case maturity label can otherwise size itself wider than the 280px
   content column at a 320px viewport. Keep it inside its grid area and allow
   normal wrapping. */
.case-title-row{min-width:0}
.case-title-row .status{max-width:100%;white-space:normal;overflow-wrap:anywhere}

/* Dark proof-object step indices were intentionally subdued at .35 alpha, but
   after the LOT 8a font floor they are content, not ornament. .50 alpha clears
   AA against the ink ground while keeping them visibly secondary. */
.case-proof-object:not(.light) .case-object-steps b{color:rgba(255,255,255,.5)}

/* ── L5 blocker closure v2 — AIchiever on narrow screens ─────────────────
   The unbroken word “d’accompagnement” exceeds the content column at the
   generic 40px H2 floor. Ease only this heading until the 40px type fits with
   both 20px gutters; covering 320–380px avoids the former 341–359px gap.
   Use the available column rather than the generic 12ch measure. Wrapping
   remains a fallback for text scaling; no page overflow is hidden. */
@media(max-width:380px){
  .case-aichiever .case-limits h2{
    font-size:clamp(2rem,calc(12.5vw - .5rem),2.5rem);
    max-width:100%;
    overflow-wrap:anywhere;
  }
}

/* ── LOT 2B.1C — la preuve réelle cesse d'être une fiche technique ──
   Les deux systèmes passaient d'abord sous un schéma doctrinal (2B.1 les a
   remontés) ; ils se lisaient ensuite comme deux tuiles de tableau de bord —
   cadre, fond gris, hauteur commune, phrase de preuve en 12px. Le fait était
   juste, la forme disait « documentation ».
   Ils redeviennent deux pièces éditoriales : un filet, un nom, un état, la
   capture quand elle existe, la phrase de ce qui est démontré à taille lisible,
   et un chemin vers le cas complet.
   Le traitement n'est PAS symétrique, et c'est le propos : Estimer a une
   capture réelle, Hop'n Bar n'en a aucune qui soit autorisée. Les aligner de
   force ferait passer un prototype pour un système fini — c'est exactement ce
   que la hauteur commune faisait. */
.hero-connected{display:grid;grid-template-columns:1fr 1fr;gap:26px 34px;align-items:start}
.hero-connected li{border:0;border-top:1px solid var(--ink);background:none;overflow:visible;
  padding:14px 0 0;display:flex;flex-direction:column}
.connected-shot,.connected-tile{height:auto;min-height:0}
/* v5-result-first stylise la dernière <p> de la tuile par POSITION
   (.connected-tile p:last-child, 0,0,2,1) : petites capitales grises, écrites
   quand la maturité fermait la tuile. Chaque paragraphe ajouté depuis en a
   hérité — la phrase de preuve d abord, le lien de cas ensuite. Corriger au cas
   par cas revenait à retomber dans le piège au paragraphe suivant : on
   neutralise la règle positionnelle ici, une fois, et le style repasse par les
   classes. Les règles de classe qui suivent sont à la même spécificité et
   l emportent par ordre de source. */
.connected-tile p:last-child{margin:0;font-size:inherit;font-weight:inherit;
  letter-spacing:normal;text-transform:none;color:inherit}

/* Le nom et l'état ouvrent la pièce. Côté Estimer ils sont portés par le
   <figcaption> — que tools/build-v5.4-result-first.mjs réinjecte à chaque
   build, donc on le restyle au lieu de le remplacer : il quitte la vignette
   noire posée sur l'image et remonte au-dessus d'elle par `order`. */
.connected-shot{display:flex;flex-direction:column}
.connected-shot .proof-shot{position:static;height:auto;flex:0 0 auto;margin:0;
  display:flex;flex-direction:column;background:transparent;box-shadow:none}
.connected-shot .proof-shot figcaption{order:-1;position:static;left:auto;right:auto;bottom:auto;
  display:flex;flex-direction:column;align-items:flex-start;gap:3px;
  padding:0 0 11px;background:none;color:var(--ink);
  font-size:1rem;font-weight:650;letter-spacing:-.02em;line-height:1.2}
.connected-tile p.connected-name{margin:0 0 3px;font-size:1rem;font-weight:650;
  letter-spacing:-.02em;line-height:1.2;text-transform:none;color:var(--ink)}
.connected-shot .proof-shot figcaption span,
.connected-tile .connected-maturity{margin:0;font-size:.72rem;font-weight:500;
  letter-spacing:.09em;text-transform:uppercase;color:var(--muted);flex:none}

/* La capture est une pièce à conviction, pas une vignette : elle prend toute la
   largeur de sa colonne et une hauteur qui laisse voir l'interface. */
.connected-shot .proof-shot img{width:100%;height:clamp(124px,12vw,168px);
  object-fit:cover;object-position:center top}
.connected-tile{justify-content:flex-start;padding:14px 0 0}

/* La phrase de preuve porte tout le sens de la pièce : elle quitte le 12px de
   note de bas de page. Deux règles, parce que v5-result-first pose
   .connected-tile p:last-child (0,0,2,1) — petites capitales grises écrites
   pour la ligne de maturité quand elle était la dernière ; une classe seule
   (0,0,2,0) perd contre elle. On qualifie au même niveau, sur la classe. */
.connected-proves,
.connected-tile p.connected-proves{margin:12px 0 0;padding:0;border:0;
  color:#26262c;font-size:.94rem;line-height:1.5;letter-spacing:0;text-transform:none}
.connected-shot .connected-proves{padding:0}

/* Le surtitre de la colonne était un cadre plein largeur : la première chose
   que l oeil rencontrait dans la colonne preuve était une boîte, pas une
   preuve. Il redevient un surtitre. */
.hero-proofstack .schema-label{border:0;background:none;padding:0;margin:0 0 4px;
  font-size:.72rem;letter-spacing:.13em;color:var(--muted)}

/* Chaque preuve mène à son cas, pas au carnet générique. */
.connected-case,
.connected-tile p.connected-case{margin:11px 0 0}
.connected-case a{display:inline-flex;align-items:center;gap:7px;min-height:44px;
  color:var(--ink);font-size:.86rem;font-weight:560;
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px}
.connected-case a:hover{color:var(--focus)}
.connected-case a span{color:var(--muted)}

/* ≤640px : deux colonnes de 130 à 175px transformaient chaque preuve en carte
   compressée — mesuré, 130,8px et 139,2px à 320px. On empile, chaque preuve
   prend la largeur utile, et la capture gagne la place de montrer une interface
   plutôt qu'une bande. */
@media(max-width:640px){
  .hero-connected{grid-template-columns:1fr;gap:22px}
  .connected-shot .proof-shot img{height:184px}
  .connected-proves,.connected-tile p.connected-proves{font-size:.98rem}
}

/* La différenciation descend en section 02 : elle explique la preuve au lieu
   de la précéder. */
.difference-limits{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:10px}
.difference-limits li{padding-left:14px;border-left:2px solid var(--line);
  color:#3f3f46;font-size:.92rem;line-height:1.5}

/* ── LOT 2B.1 — le premier écran n'attend pas son animation ──
   .wow-loaded .hero-copy>* posait opacity:0 puis une entrée échelonnée : le H1
   partait à .2s et finissait à .92s. C'est le P2 du premier rendu dans sa forme
   Hero — mesuré à 739 ms avant que l'accroche soit lisible en 390px. Le reste du
   document garde son système d'apparition ; ce qui porte la compréhension du
   premier écran ne l'attend plus. */
.wow-loaded .hero-copy>*{opacity:1;transform:none;animation:none}
.wow-loaded .hero-proofstack .schema-label,
.wow-loaded .hero-proofstack .schema,
.wow-loaded .hero-connected,
.hero-connected{opacity:1;transform:none;animation:none}

/* ── LOT 2B.1 · l'expérience causale avant sa catégorie ──
   Moins de boîtes, plus de typographie. Un seul rail, qui n'avance que pour
   expliquer une causalité : il ne boucle pas, il ne progresse pas tout seul, et
   il ne prétend jamais qu'un traitement est en cours. */
.causal{padding:clamp(56px,7vw,96px) 0;border-top:1px solid var(--line)}
.causal .wrap{width:min(1180px,100%);margin:0 auto;padding:0 var(--gutter)}
.causal h2{max-width:20ch;margin:12px 0 32px;font-size:clamp(1.7rem,3.2vw,2.9rem);
  line-height:1.06;letter-spacing:-.035em}

.causal-questions{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 30px}
.causal-q{display:inline-flex;align-items:center;min-height:44px;padding:11px 18px;
  border:1px solid var(--line);border-radius:999px;background:transparent;color:#3f3f46;
  font:inherit;font-size:.92rem;text-align:left;cursor:pointer;
  transition:border-color .18s var(--ease),color .18s var(--ease),background-color .18s var(--ease)}
.causal-q:hover{border-color:var(--ink);color:var(--ink)}
.causal-q:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.causal-q[aria-pressed=true]{background:var(--ink);border-color:var(--ink);color:#fff}

/* Le rail : quatre étapes nommées, l'étape concernée marquée. Rien ne bouge
   tant que le lecteur ne choisit pas. */
.causal-rail{position:relative;list-style:none;display:grid;grid-template-columns:repeat(4,1fr);gap:0;
  margin:0 0 28px;padding:0;border-top:1px solid var(--line)}
.causal-rail li{position:relative;padding:14px 14px 0 0;color:var(--muted);
  font-size:.72rem;letter-spacing:.09em;text-transform:uppercase;
  transition:color .2s var(--ease)}
.causal-rail li::before{content:"";position:absolute;left:0;right:6px;top:-1px;height:1px;
  background:var(--line);transition:background-color .2s var(--ease)}
.causal-rail li.is-current{color:var(--ink);font-weight:620}

/* ── LOT 2B.1C · le rail parcourt la chaîne, il ne clignote pas ──
   Quatre filets marqués un à un montraient QUELLES étapes sont concernées ;
   ils ne montraient pas que la réponse se construit EN LES TRAVERSANT. Une
   seule ligne les parcourt maintenant, et s ARRÊTE à l étape que la question
   interroge : la règle pour Q1, le résultat observé pour Q2, la preuve pour Q3.
   Ce n est pas une barre de progression : elle n avance jamais seule, elle ne
   revient pas, et rien n indique qu un temps s écoule ou qu un traitement est
   en cours. Elle représente le chemin logique nécessaire pour établir la
   réponse — et la portée est portée par data-reach, donc l état de départ est
   dans le document : au chargement la ligne est déjà à sa place, elle ne part
   pas de zéro. Une valeur initiale ne se transitionne pas. */
.causal-rail::after{content:"";position:absolute;left:0;top:-2px;height:2px;
  width:var(--causal-reach,0%);background:var(--focus);
  transition:width .22s var(--ease)}
.causal-rail[data-reach=rule]{--causal-reach:25%}
.causal-rail[data-reach=action]{--causal-reach:50%}
.causal-rail[data-reach=result]{--causal-reach:75%}
.causal-rail[data-reach=proof]{--causal-reach:100%}

/* La réponse suit le rail, elle ne le double pas : une seule respiration
   courte, posée par le script au moment du changement d état — jamais au
   chargement, où le panneau Q1 est déjà le défaut du document. */
@keyframes causal-panel-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.causal-panel.is-entering{animation:causal-panel-in .16s var(--ease) both}

.causal-panel[hidden]{display:none}
.causal-answer{margin:0 0 10px;max-width:30ch;font-size:clamp(1.25rem,2.1vw,1.85rem);
  line-height:1.18;letter-spacing:-.028em;font-weight:620}
.causal-oxann{margin:0 0 22px;max-width:52ch;color:#3f3f46;font-size:clamp(.98rem,1.2vw,1.1rem);line-height:1.5}
.causal-proof{padding-top:18px;border-top:1px solid var(--line);max-width:60ch}
.causal-proof-head{margin:0 0 8px;display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;
  font-size:.92rem;font-weight:620}
.causal-proof-head a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.causal-proof-line{margin:0;color:#26262c;font-size:1rem;line-height:1.5}
.causal-limit{margin:10px 0 0;padding-left:12px;border-left:2px solid var(--focus);
  color:var(--muted);font-size:.86rem;line-height:1.5}
.causal-next{margin:30px 0 0}

/* ≤820px le rail passait en 2x2, et la ligne continue devenait fausse : posée
   sur le bord supérieur, elle ne parcourait que la première rangée. Mesuré sur
   Q2 — portée 75 % — elle s arrêtait au milieu d ACTION pendant que RÉSULTAT
   OBSERVÉ était marqué atteint juste en dessous. Une ligne qui contredit l état
   qu elle illustre vaut moins que pas de ligne.
   Le rail se redresse : une colonne, quatre rangées, et la même ligne parcourt
   la chaîne de haut en bas. Une seule grammaire, tournée d un quart de tour —
   pas une seconde grammaire pour petits écrans. */
@media(max-width:820px){
  .causal-rail{grid-template-columns:1fr;gap:0;border-top:0;
    border-left:1px solid var(--line);padding-left:14px}
  .causal-rail li{padding:0 0 13px}
  .causal-rail li::before{display:none}
  .causal-rail::after{left:-1px;top:0;width:2px;height:var(--causal-reach,0%);
    transition:height .22s var(--ease)}
  .causal-q{width:100%}
}
@media(prefers-reduced-motion:reduce){
  .causal-q,.causal-rail li,.causal-rail li::before,.causal-rail::after{transition:none}
  .causal-panel.is-entering{animation:none}
}

/* La doctrine reçoit le schéma et la boucle : elle explique la causalité que le
   lecteur vient de manipuler, au lieu de la précéder. */
.difference .hero-loop,.difference .hero-situations-close{margin-top:18px}
.difference .schema-label{margin-top:26px}

/* ── LOT 2B.1C — le premier écran invite à continuer ──
   Mesuré sur 2100ef9 : v5.css verrouille .hero à min-height:100svh et centre
   son contenu, donc le blanc restant se répartit au-dessus ET au-dessous. À
   1440×900 : 253px de vide sous le dernier élément utile, et la section causale
   commence exactement au pixel où le premier écran finit — 0px de
   découvrabilité. À 1920×1080 : 324px de vide, 0px encore.
   Le plancher descend juste assez pour que « UNE SITUATION RÉELLE » entre dans
   le premier écran : la section causale ouvre sur clamp(56px,7vw,96px) de
   retrait, il faut donc ~110px pour révéler son surtitre entier.
   Le plafond de 880px existe parce que sur un écran très haut, soustraire une
   constante laisserait un Hero qui grandit sans rien gagner : le vide
   reviendrait à mesure que la fenêtre s'allonge.
   min-height reste un PLANCHER : un contenu plus haut pousse le Hero, rien
   n'est jamais rogné. Le mobile n'en a pas besoin — mesuré, sa section causale
   commence déjà avant la fin du premier écran. */
@media(min-width:1101px){
  .hero{min-height:min(calc(100svh - 168px),880px)}
}
