/* ==========================================================================
   Œuvra — Fonctionnalités · feuille du gabarit templates/page-fonctionnalites.php (chargée après main.css).
   1. Base = handoff/design/css/pages/fonctionnalites.css, copiée telle quelle (elle ne contient aucune déclaration prioritaire).
   2. Styles inline du prototype (prototype/fonctionnalites.html) convertis en classes + compléments de production.
   3. Illustrations (un bloc commenté par illustration) : DECO-F1, FV-F1 … FV-F10 — fragments convertis et
      contre-vérifiés (fvdiff, 0 écart), reportés tels quels. Plusieurs racines .fv-fN.c-fit__inner (0,2,0)
      doivent l'emporter sur .c-fit > .c-fit__inner de main.css par l'ORDRE de chargement : garder cette
      feuille après main.css (dépendance oeu-main, inc/assets.php).
   Composants partagés utilisés (main.css) : .l-section(--compact, --beige), .l-container, .l-grid--3, .l-split,
   .c-crumb (template-parts/layout/crumb.php), .c-shead, .c-tags, .c-card, .c-plan-tag, .c-fit / .fit-696x460 /
   .fit-616x460, .c-btns, .u-block, .c-cta (template-parts/layout/cta.php).
   Interactions (M10 marquee, M11 barre d'ancres, M12 fil collant, M13 schéma) : états et transitions ci-dessous,
   pilotage par assets/js/page-fonctionnalites.js (classes is-on, has-ind, is-overflow, is-end, is-offscreen).
   ========================================================================== */

/* ---------- 1. fonctionnalites.css du handoff ---------- */

/* ---------- Animations et états propres à la page (hérités des maquettes validées) ---------- */
@keyframes hp-marquee { from { transform: translateX(0); } to { transform: translateX(calc(-50% - 8px)); } }
.hp-marq { animation: hp-marquee var(--duree, 30s) linear infinite; }
.hp-marq--inv { animation-direction: reverse; }
.hp-marq-zone:hover .hp-marq { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .hp-marq { animation: none; } }
@keyframes oe-flux { 0% { offset-distance: 0%; opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
.oe-flux { animation: oe-flux 3.2s linear infinite; offset-rotate: 0deg; }
.oe-flux-1 { offset-path: path("M0 248 C 60 248, 60 56, 120 56"); }
.oe-flux-2 { offset-path: path("M0 248 C 60 248, 60 184, 120 184"); animation-delay: .4s; }
.oe-flux-3 { offset-path: path("M0 248 C 60 248, 60 312, 120 312"); animation-delay: .8s; }
.oe-flux-4 { offset-path: path("M0 248 C 60 248, 60 440, 120 440"); animation-delay: 1.2s; }
@media (prefers-reduced-motion: reduce) { .oe-flux { animation: none; opacity: 0; } }
/* Barre d’ancres collante sous le hero — même style que la navigation segmentée de la FAQ (.c-seg-nav) */
.fn-link { position: relative; z-index: 1; box-sizing: content-box; display: inline-flex; align-items: center; flex: none; gap: 6px; height: 40px; padding: 0 18px; border: 1px solid transparent; border-radius: var(--radius-full); font: 500 14px/20px var(--font-sans); color: var(--ink-900); text-decoration: none; white-space: nowrap; transition: background-color var(--duration-base) var(--ease-standard), border-color var(--duration-base) var(--ease-standard); }
.fn-link:hover { background: #1e1d1b0a; }
.fn-list.has-ind .fn-link:hover:not(.is-on) { background: #1e1d1b0a; }
.fn-link svg { flex: none; color: var(--brand-ink); }
.fn-link:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.fn-link.is-on { background: var(--bg-surface); border-color: var(--border-100); }
.fn-ind { position: absolute; z-index: 0; top: 4px; left: 0; box-sizing: border-box; height: 42px; width: 0; border: 1px solid var(--border-100); border-radius: var(--radius-full); background: var(--bg-surface); opacity: 0; transition: transform 380ms cubic-bezier(0.34, 1.3, 0.5, 1), width 380ms cubic-bezier(0.34, 1.3, 0.5, 1), opacity 150ms linear; }
.fn-list.has-ind .fn-ind { opacity: 1; }
/* Position et largeur de l'indicateur : variables posées par page-fonctionnalites.js (lien actif : offsetLeft / offsetWidth). */
.fn-list.has-ind .fn-ind { width: var(--fn-ind-w, 0px); transform: translateX(var(--fn-ind-x, 0px)); }
.fn-list.has-ind .fn-link.is-on { background: transparent; border-color: transparent; }
#fil, #logique, #modules, #chantier, #tout, #offres-bloc { scroll-margin-top: 72px; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { .fn-ind, .fn-link { transition: none; } html { scroll-behavior: auto; } }
/* Couleurs forcées (Contraste élevé de Windows) : l'anneau de focus de la barre est une ombre (--shadow-focus), que le
   navigateur retire ; la règle .fn-link:focus-visible ci-dessus (outline: none) annulerait aussi le contour de repli de
   main.css. Contour rétabli, comme sur le reste du site (main.css : 2 px CanvasText, décalage 2 px ; il tient dans le
   remplissage de 4 px de la pilule défilante, sans rognage). Lien actif : bordures transparentes forcées à LinkText sur
   les 6 liens (actif indiscernable) → filets des liens inactifs à la couleur du fond, lien actif en couleurs système de
   sélection (Highlight / HighlightText, sans plaque de fond du navigateur : forced-color-adjust: none) ; l'indicateur,
   décoratif, est masqué. Aucun effet hors couleurs forcées. */
@media (forced-colors: active) {
  .fn-link:focus-visible { outline: 2px solid CanvasText; outline-offset: 2px; }
  .fn-link { border-color: Canvas; }
  .fn-nav .fn-list .fn-link.is-on { forced-color-adjust: none; border-color: Highlight; background-color: Highlight; color: HighlightText; }
  .fn-nav .fn-list .fn-link.is-on svg { color: HighlightText; }
  .fn-ind { display: none; }
}
/* Le fil du projet : visuel collant (Desktop/Laptop) / séquence à plat (artboards, Tablette, Mobile) */
#fil { --ft-pas: 540px; }
#fil .ft-etape { min-height: var(--ft-pas); opacity: .45; transition: opacity var(--duration-slow) var(--ease-standard); }
#fil .ft-etape.is-on { opacity: 1; }
#fil .ft-num { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; background: var(--brand-100); font: 600 12px/16px var(--font-sans); letter-spacing: 0.04em; color: var(--brand-ink); transition: background var(--duration-base), color var(--duration-base); }
#fil .ft-etape.is-on .ft-num { background: var(--brand-ink); color: #ffffff; }
#fil .ft-texte { transform: translateY(8px); transition: transform var(--duration-slow) var(--ease-standard); }
#fil .ft-etape.is-on .ft-texte { transform: none; }
#fil .ft-visuel { opacity: 0; transform: translateY(12px); pointer-events: none; transition: opacity var(--duration-slow) var(--ease-standard), transform var(--duration-slow) var(--ease-standard); }
#fil .ft-visuel.is-on { opacity: 1; transform: none; pointer-events: auto; }
#fil .ft-inline { display: none; }
@media (prefers-reduced-motion: reduce) { #fil .ft-etape, #fil .ft-texte, #fil .ft-visuel, #fil .ft-num { transition: none; } #fil .ft-texte, #fil .ft-visuel { transform: none; } }

/* ---------- Composition et responsive ---------- */
/* Fonctionnalités — compositions propres à la page */

/* ---- Hero : texte + mur d’icônes défilant ---- */
.fn-hero { position: relative; box-sizing: border-box; height: 746px; padding: 72px 0 0; display: flex; align-items: center; overflow: hidden; background: linear-gradient(180deg, #e4dcf3 0%, #ece8f5 42%, #f3f2ef 72%, #f3f2ef 100%); }
.fn-hero__grid { display: flex; align-items: center; justify-content: space-between; gap: 80px; }
.fn-hero__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 24px; max-width: 680px; }
.fn-hero__wall { position: relative; flex: none; width: 440px; height: 392px; }
/* ---- Barre d’ancres collante ---- */
/* <main> sans boîte (display: contents, même procédé que .c-header dans main.css) : ses sections deviennent, comme
   dans le prototype, des éléments flex de .hp-root. La barre collante est ainsi contrainte par .hp-root et non plus
   par <main> : elle reste en haut jusqu'au pied inclus, comme dans le prototype (dans <main>, elle était repoussée
   hors de l'écran en fin de page dès que le pied dépasse la hauteur de la fenêtre : -63 px mesurés à 390).
   Mesuré : géométrie de la page inchangée, repère « main » toujours exposé, lien d'évitement « Aller au contenu »
   inchangé (le Tab suivant atteint le premier lien de <main>). */
#contenu { display: contents; }
.fn-nav { position: sticky; top: 0; z-index: 40; flex: none; width: 100%; box-sizing: border-box; padding: 12px 0; background: transparent; pointer-events: none; }
.fn-nav__inner { display: flex; justify-content: center; }
/* Pilule : même style que la navigation segmentée de la FAQ (.c-seg-nav) — fond border-100, onglet actif blanc à filet */
.fn-list { position: relative; box-sizing: border-box; display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: var(--radius-full); background: var(--border-100); pointer-events: auto; }
.fn-nav .fn-nav__inner .fn-list.is-end { -webkit-mask-image: none; mask-image: none; }
/* fondu retiré en fin de défilement ou si tout tient (classe posée en JS) */

/* ---- Le fil du projet (comportement en ligne : visuel collant à droite, étape active au défilement) ---- */
.ft-grid { margin-top: 72px; display: flex; align-items: flex-start; gap: 64px; }
.ft-etapes { position: relative; flex: none; width: 36.667%; }
.ft-etape { position: relative; box-sizing: border-box; scroll-margin-top: 96px; padding-left: 64px; }
.ft-rail { position: absolute; left: 17px; top: 36px; bottom: 0; width: 1px; background: var(--brand-300); }
.ft-etape:last-child .ft-rail { display: none; }
.ft-texte { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.ft-sticky { position: sticky; top: 112px; flex: 1 1 auto; height: 460px; }
.ft-visuel { position: absolute; inset: 0; }
/* ---- Une logique commune : photo + schéma Descriptif → 4 usages ---- */
.fn-logique { position: relative; box-sizing: border-box; padding: 72px 64px; border-radius: var(--radius-xl); overflow: hidden; display: flex; flex-direction: column; gap: 48px; background: var(--brand-100); }
.fn-logique__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.fn-logique__shade { position: absolute; inset: 0; background: linear-gradient(180deg, #1e1d1bad 0%, #1e1d1b73 42%, #1e1d1b1f 100%); opacity: 0.8; }
.fn-logique__body { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 48px; }
.fn-schema { display: flex; align-items: center; width: 100%; }
.fn-schema__src { flex: none; box-sizing: border-box; width: 39.179%; padding: 20px 24px; border-radius: var(--radius-lg); border: 1px solid var(--border-100); background: var(--bg-surface); }
.fn-schema__links { flex: none; width: 120px; height: 500px; }
.fn-schema__outs { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.fn-schema__out { box-sizing: border-box; flex: 1 1 0; padding: 18px 22px; border-radius: var(--radius-lg); border: 1px solid var(--border-100); background: var(--bg-surface); display: flex; flex-direction: column; gap: 6px; }
.fn-schema__node { display: none; }
/* ---- Avant le projet : trois modules ---- */
.fn-mods { margin-top: var(--head-gap); }
.fn-mod { box-sizing: border-box; display: flex; flex-direction: column; gap: 20px; padding: 28px; border-radius: var(--radius-xl); border: 1px solid var(--border-100); background: var(--bg-surface); }
.fn-mod__vis { max-width: none; border-radius: var(--radius-lg); overflow: hidden; }
.fn-mod__text { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
/* ---- Sur le chantier (PWA) ---- */
.fn-pwa { align-items: center; }
.fn-pwa__text { flex: none; width: 43.333%; display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
.fn-pwa__vis { flex: none; width: 51.333%; }
.fn-checks { margin-top: 8px; display: flex; flex-direction: column; gap: 14px; }
/* ---- Tout au même endroit ---- */
.fn-tout { margin-top: var(--head-gap); }
.fn-tout__card { gap: 10px; }
.fn-tout__icon { margin-bottom: 8px; }
/* ---- Offres (section de continuation) ---- */
.fn-offres { padding: 32px 0 var(--section-y-compact); }
.fn-offres__box { box-sizing: border-box; display: flex; align-items: center; gap: 80px; padding: 72px 80px; border-radius: var(--radius-xl); border: 1px solid var(--border-100); background: var(--bg-surface); overflow: hidden; }
.fn-offres__text { flex: 1 1 auto; min-width: 0; }
.fn-offres__actions { flex: none; align-self: flex-end; }
.fn-offres__btns { display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
@media (max-width: 1439px) {
.fn-hero { height: 700px; }
.fn-hero__grid { gap: 48px; }
.fn-hero__wall { width: 400px; height: 360px; }
.ft-grid { gap: 48px; }
.fn-logique { padding: 56px 48px; }
.fn-schema__links { width: 96px; }
.fn-mod { padding: 24px; }
.fn-offres__box { gap: 56px; padding: 56px 56px; }
/* barre d’ancres : si la liste ne tient pas dans le conteneur (≈ 1024–1135 px), défilement horizontal comme en Tablette
     (classe posée en JS quand la liste déborde ; sans JS, la pilule déborde symétriquement dans les marges) */
  .fn-nav__inner.is-overflow .fn-list { flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
}
@media (max-width: 1023px) {
.fn-hero { height: auto; padding: var(--hero-top) 0 var(--hero-bottom); }
.fn-hero__grid { flex-direction: column; align-items: stretch; gap: 40px; }
.fn-hero__text { max-width: 600px; }
.fn-hero__wall { width: 100%; height: 320px; }
.fn-nav { padding: 10px 0; }
/* la pilule occupe la largeur du conteneur et ses onglets défilent à l’intérieur, avec fondu à droite (comme la FAQ en Mobile) */
  .fn-list { flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); }
/* le fil : liste verticale, chaque étape suivie de son visuel */
  #fil .ft-grid { display: block; margin-top: 56px; }
#fil .ft-etapes { width: 100%; }
#fil .ft-etape { display: flex; flex-direction: column; align-items: stretch; gap: 32px; min-height: 0; opacity: 1; padding-bottom: 56px; }
#fil .ft-etape:last-child { padding-bottom: 0; }
#fil .ft-etape .ft-num, #fil .ft-etape.is-on .ft-num { background: var(--brand-100); color: var(--brand-ink); }
#fil .ft-texte { width: auto; transform: none; }
#fil .ft-inline { display: block; width: 100%; }
#fil .ft-sticky { display: none; }
/* logique : source au-dessus, quatre usages en grille 2 × 2 */
  .fn-logique { padding: 48px 32px; gap: 40px; }
.fn-logique__body { gap: 40px; }
.fn-schema { flex-direction: column; align-items: stretch; gap: 0; }
.fn-schema__src { width: auto; }
.fn-schema__links { display: none; }
/* arborescence : tronc parme sous la source, une branche et une pastille de jonction par usage (demande du 24/09) */
  .fn-schema__outs { display: flex; flex-direction: column; gap: 12px; padding: 28px 0 0 40px; }
.fn-schema__out { position: relative; flex: none; }
.fn-schema__out::before { content: ""; position: absolute; left: -24px; top: -12px; bottom: 0; width: 1.5px; background: var(--brand-100); }
.fn-schema__out:first-child::before { top: -28px; }
.fn-schema__out:last-child::before { bottom: 50%; }
.fn-schema__out::after { content: ""; position: absolute; left: -24px; top: 50%; width: 24px; height: 1.5px; margin-top: -0.75px; background: var(--brand-100); }
.fn-schema__node { display: block; position: absolute; z-index: 1; left: -28.25px; top: 50%; width: 10px; height: 10px; margin-top: -5px; border-radius: 50%; background: var(--lot-1); animation: fnNode 3.2s ease-in-out infinite; }
.fn-schema__out:nth-child(2) .fn-schema__node { animation-delay: 0.4s; }
.fn-schema__out:nth-child(3) .fn-schema__node { animation-delay: 0.8s; }
.fn-schema__out:nth-child(4) .fn-schema__node { animation-delay: 1.2s; }
.fn-offres__box { flex-direction: column; align-items: flex-start; gap: 32px; padding: 48px 40px; }
.fn-offres__actions { align-self: stretch; }
.fn-offres__btns { flex-direction: row; align-items: center; }
}
@media (max-width: 767px) {
.fn-hero__wall { height: 260px; margin: 0 calc(-1 * var(--gutter)); width: auto; }
.fn-nav { padding: 8px 0; }
.fn-nav .fn-link { height: 36px; padding: 0 14px; font-size: 13px; }
.fn-nav .fn-ind { height: 38px; }
#fil .ft-grid { margin-top: 40px; }
#fil .ft-etape { padding-left: 52px; gap: 24px; padding-bottom: 48px; }
#fil .ft-inline { margin-left: -52px; width: calc(100% + 52px); }
#fil .ft-etape .t-title-xl { font-size: var(--fs-title-xl); }
.fn-logique { padding: 40px 20px; border-radius: var(--radius-xl); }
.fn-schema__src { padding: 16px 16px; }
.fn-schema__outs { padding-left: 36px; }
.fn-schema__out::before, .fn-schema__out::after { left: -20px; }
.fn-schema__out::after { width: 20px; }
.fn-schema__node { left: -24.25px; }
.fn-schema__out { padding: 16px 18px; }
.fn-mod { padding: 16px 16px 24px; gap: 20px; }
.fn-mod__text { padding: 0 4px; }
.fn-offres { padding-top: 24px; }
.fn-offres__box { padding: 32px 24px; gap: 28px; }
.fn-offres__btns { flex-direction: column; align-items: stretch; }
}


/* Pastilles de jonction de l’arborescence (Tablette/Mobile) : pulsation en séquence, même rythme que les points du desktop (3,2 s, décalages 0 / 0,4 / 0,8 / 1,2 s) */
@keyframes fnNode { 0%, 60%, 100% { transform: scale(1); box-shadow: 0 0 0 0 #2fa3e866; } 20% { transform: scale(1.3); box-shadow: 0 0 0 6px #2fa3e800; } }
@media (prefers-reduced-motion: reduce) {
.fn-schema__node { animation: none; }
}

/* ---------- 2. Styles inline du prototype convertis en classes + compléments de production ---------- */

/* Hero : fil d'Ariane DANS la colonne texte (identiques.md §4) — l'écart vient du gap 24 de .fn-hero__text,
   pas de la marge du fil des autres héros (.c-crumb-wrap, 40 / 28). */
.fn-hero__text > .c-crumb-wrap { margin-bottom: 0; }
.fn-hero__head { display: flex; flex-direction: column; gap: 18px; }
.fn-hero__lead { max-width: 600px; }
.fn-hero__actions { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
/* Boutons secondaires blancs à filet (« Voir les tarifs », « Voir le comparatif ») : dans le prototype, style inline
   « background: var(--bg-surface); border-color: var(--border-100); color: var(--ink-900) » = bouton secondaire .c-btn-soft
   (design-system.md §8) = état de repos du .oe-btn--tertiary du DS, déjà donné par la classe : aucune règle. Le style
   inline figeait aussi le survol (effet de bord) ; survol du DS rétabli (motion-spec M09 : fond --bg-beige, filet
   --border-strong, 150 ms), comme les boutons secondaires de l'Accueil, de la FAQ, de Pour qui ? et de Tarifs (clôture
   Phase D). Écart voulu vs prototype : survol seulement. */
/* Mur d'icônes (M10) : pause hors écran [Recommandé, motion-spec §1.5] — classe posée par page-fonctionnalites.js. */
.fn-hero__wall.is-offscreen .hp-marq { animation-play-state: paused; }

/* Le fil du projet */
.fn-fil__head { max-width: 800px; }
.fn-fil__title { max-width: 800px; }
.fn-fil__lead { max-width: 640px; }
.ft-titre { display: flex; align-items: center; gap: 12px; margin-top: 2px; }
.ft-desc { max-width: 360px; }
/* Étiquette « Studio+ » de l'étape 02 : pilule .c-plan-tag aux mesures du prototype de cette page (28 px, 0 12, 11/16). */
.ft-plan-tag { margin: 0; box-sizing: border-box; height: 28px; padding: 0 12px; line-height: 16px; }
/* Sans JavaScript (html sans .has-js) : aucune étape n'est pilotée au défilement — texte des étapes à pleine opacité. */
html:not(.has-js) #fil .ft-etape { opacity: 1; }
html:not(.has-js) #fil .ft-texte { transform: none; }
/* Sans JavaScript, Desktop/Laptop : rien ne pilote le visuel collant (seul FV-F1 serait visible). Le fil est montré
   « déroulé », comme dans les artboards (D08 ; responsive.md §3.2 : texte + visuel 696 × 460, 80 px entre étapes) :
   chaque étape suivie à droite de son visuel en ligne (.ft-inline, même partial), colonne collante masquée (ses
   visuels sortent aussi de l'arbre d'accessibilité), numéros au même état. Requête : complément exact de
   (max-width: 1023px), comme page-fonctionnalites.js — une largeur fractionnaire entre 1023 et 1024 px (zoom, mise à
   l'échelle de l'écran) reçoit la mise en page Desktop/Laptop de la feuille, donc aussi ce repli. */
@media not all and (max-width: 1023px) {
  html:not(.has-js) #fil .ft-grid { display: block; }
  html:not(.has-js) #fil .ft-sticky { display: none; }
  html:not(.has-js) #fil .ft-etapes { width: auto; }
  html:not(.has-js) #fil .ft-etape { display: grid; grid-template-columns: minmax(300px, 1fr) minmax(0, 696px); align-items: start; column-gap: 64px; min-height: 0; padding-bottom: 80px; }
  html:not(.has-js) #fil .ft-etape:last-child { padding-bottom: 0; }
  html:not(.has-js) #fil .ft-etape.is-on .ft-num { background: var(--brand-100); color: var(--brand-ink); }
  html:not(.has-js) #fil .ft-inline { display: block; }
  @media (max-width: 1439px) {
    html:not(.has-js) #fil .ft-etape { column-gap: 48px; }
  }
}

/* Une logique commune : en-tête blanc sur la photo */
.fn-logique__img { object-position: 50% 60%; }
.fn-logique__head .fn-logique__kicker { color: #ffffff; }
.fn-logique__title { max-width: 1000px; color: #ffffff; }
.fn-logique__lead { max-width: 680px; color: rgba(255, 255, 255, 0.88); }

/* Avant le projet */
.fn-modules__head { max-width: 760px; }
.fn-modules__title { max-width: 760px; }
.fn-modules__lead { max-width: 640px; }
.fn-mod__desc { max-width: 400px; }
/* Repli .c-fit (html.oeu-fit-js, main.css 0,2,1) : garder le rognage à l'arrondi lg du cadre du visuel. */
html.oeu-fit-js .fn-mod__vis { overflow: hidden; }
/* Carte à image (Repeater ACF, visuel « Image ») : même format que les illustrations FV-F7…F9, image recadrée. */
.fn-mod__vis--img { aspect-ratio: 696 / 460; background: var(--bg-page); }
.fn-mod__img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Carrousel des modules (demande du 25/09 : en 3 colonnes les visuels FV-F7…F9 tombaient à ≈ 0,47).
   Piste .fn-mods hors .l-container, pleine largeur de la section : ses marges internes (= marges du conteneur,
   même formule que .l-container) alignent la 1re carte sur le texte ; les pourcentages des cartes se rapportent à la
   boîte de contenu de la piste = largeur du conteneur. Desktop/Laptop : 1 carte de la largeur du conteneur, en
   deux colonnes (visuel jusqu'à 696 px, échelle 1 à 1440 | texte), les voisines dépassent dans les marges (amorces) ;
   Tablette : 1 carte verticale + amorce ; Mobile : idem, amorce plus courte (demande du 25/09 : un seul visuel).
   Défilement natif avec aimantation (scroll-snap, bord gauche du conteneur) : doigt, pavé tactile, Maj + molette,
   clavier (piste focalisable) ; flèches et boucle en JS (§4 : cartes dupliquées de part et d'autre, d'où une amorce
   aussi à gauche). Barre de défilement masquée : les flèches et l'amorce la
   remplacent. */
.fn-modules__top { display: flex; align-items: flex-end; justify-content: space-between; gap: 32px; }
.fn-mods__nav { flex: none; display: flex; gap: 12px; }
.fn-mods__nav[hidden] { display: none; }
.fn-mods__btn { width: var(--control-lg); height: var(--control-lg); border-radius: var(--radius-full); color: var(--ink-900); }
.fn-mods__btn--prev .fn-mods__arrow { transform: scaleX(-1); }
.fn-mods { --mods-side: max(var(--gutter), (100% - var(--container)) / 2); --mods-card: 100%; position: relative; box-sizing: border-box; display: flex; align-items: stretch; gap: var(--grid-gap); padding: 0 var(--mods-side) 4px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--mods-side); scrollbar-width: none; outline: none; }
.fn-mods::-webkit-scrollbar { display: none; }
.fn-mods:focus-visible { box-shadow: inset 0 0 0 2px var(--brand-ink); }
.fn-mods > .fn-mod { flex: 0 0 var(--mods-card); scroll-snap-align: start; }
@media not all and (max-width: 1023px) {
	.fn-mods > .fn-mod { display: grid; grid-template-columns: minmax(0, 696px) minmax(280px, 1fr); align-items: center; column-gap: 56px; }
	.fn-mods > .fn-mod .fn-mod__vis { width: 100%; }
}
@media (min-width: 1024px) and (max-width: 1439px) {
	.fn-mods > .fn-mod { column-gap: 40px; }
}
/* Swipe à la souris (JS §4) : main ouverte / fermée, pas de sélection de texte, aimantation coupée pendant le glisser. */
html.has-js .fn-mods { cursor: grab; }
.fn-mods.is-dragging { cursor: grabbing; scroll-snap-type: none; -webkit-user-select: none; user-select: none; }
@media (max-width: 1023px) {
	.fn-modules__top { flex-wrap: wrap; row-gap: 24px; }
	.fn-mods { --mods-card: calc(100% - 96px); }
}
@media (max-width: 767px) {
	.fn-mods { --mods-card: calc(100% - 24px); }
	.fn-mods__btn { width: var(--control-md); height: var(--control-md); }
}

/* Sur le chantier (le gap 5,333 % cède sous 1024 au gap de .l-split de main.css, comme dans le prototype) */
.fn-pwa { gap: 5.333%; }
.fn-pwa__title { max-width: 520px; }
.fn-pwa__lead { max-width: 500px; }
.fn-check { display: inline-flex; align-items: center; gap: 12px; }
.fn-check__icon { flex: 0 0 auto; display: grid; place-content: center; width: 28px; height: 28px; border-radius: var(--radius-full); background: var(--brand-100); }
.fn-check__label { font-weight: 600; font-size: 17px; line-height: 24px; font-family: var(--font-sans); color: var(--ink-900); }
/* Sous 1024 : empilement du split écrit ici avec les valeurs de .l-split dans main.css. Les !important hérités de
   site.css (passation §10) y ont été retirés à la clôture de la Phase D : cette règle porte donc l'empilement (sinon
   les largeurs 43,333 % / 51,333 %, le gap 5,333 % et align-items: center de la page reprendraient la main) ; rendu
   inchangé (pagediff). Le cadre .c-fit du visuel prend toute la largeur (dessin 616 × 460 calé à gauche), comme dans
   le prototype. */
@media (max-width: 1023px) {
	.fn-pwa { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: var(--split-gap); }
	.fn-pwa__text, .fn-pwa__vis { width: auto; max-width: 100%; flex: none; }
}

/* Tout au même endroit */
.fn-tout__head { max-width: 760px; }
.fn-tout__title { max-width: 760px; }
.fn-tout__badge { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; background: var(--brand-100); }

/* Offres */
.fn-offres__title { max-width: 760px; }
.fn-offres__lead { max-width: 620px; }

/* Schéma FV-F6 (M13) : pause hors écran [Recommandé, motion-spec §1.5] — classe posée par page-fonctionnalites.js. */
.fn-schema.is-offscreen .oe-flux, .fn-schema.is-offscreen .fn-schema__node { animation-play-state: paused; }
/* Schéma FV-F6 (M13) : sans offset-path (navigateurs anciens), les points resteraient au coin haut gauche des
   liaisons — on les retire (liaisons seules, comme en mouvement réduit). */
@supports not (offset-path: path("M0 0 L1 1")) {
	.oe-flux { display: none; }
}

/* ---------- 3. Illustrations ---------- */

/* DECO-F1 — Fonctionnalités · mur d’icônes du hero (décor) : styles du dessin, convertis des styles inline du prototype.
   Partial : template-parts/visuals/deco-f1-mur-icones.php. Racine .deco-f1 (0,1,0), descendants 0,2,0.
   Restent dans la CSS de page : dimensions de la racine (.fn-hero__wall, 440 × 392 → 400 × 360 → 100 % × 320 → bord à bord × 260),
   animation M10 (keyframes hp-marquee, .hp-marq, .hp-marq--inv, pause au survol .hp-marq-zone:hover, mouvement réduit).
   Aucune surcharge responsive : les couches internes suivent la boîte de la racine (inset 0, rangées centrées).
   Seul ajout au style inline : -webkit-mask-image (même valeur, Safari < 15.4 ; alias de mask-image dans Chrome). */
.deco-f1 .deco-f1__mask { position: absolute; inset: 0px; display: flex; flex-direction: column; justify-content: center; gap: 24px; overflow: hidden; -webkit-mask-image: radial-gradient(52% 64%, rgb(0, 0, 0) 18%, transparent 96%); mask-image: radial-gradient(52% 64%, rgb(0, 0, 0) 18%, transparent 96%); }
/* Rangées (M10) : --duree est lue par la règle .hp-marq de la CSS de page (hp-marquee var(--duree, 30s) linear infinite). */
.deco-f1 .deco-f1__row { display: flex; gap: 16px; width: max-content; }
.deco-f1 .deco-f1__row--1 { --duree: 34s; }
.deco-f1 .deco-f1__row--2 { --duree: 40s; }
.deco-f1 .deco-f1__row--3 { --duree: 37s; }
.deco-f1 .deco-f1__group { display: flex; gap: 16px; }
.deco-f1 .deco-f1__tile { flex: 0 0 auto; box-sizing: border-box; width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-md); border-width: 1px; border-style: solid; border-top-color: var(--border-100); border-right-color: var(--border-100); border-bottom-color: var(--border-100); border-left-color: var(--border-100); background: var(--bg-surface); color: var(--brand-ink); }
.deco-f1 .deco-f1__icon { display: block; }
/* Tuile Œ fixe au centre, au-dessus des rangées */
.deco-f1 .deco-f1__center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 2; box-sizing: border-box; width: 104px; height: 104px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-lg); background: var(--brand-100); border-width: 4px; border-style: solid; border-top-color: var(--bg-surface); border-right-color: var(--bg-surface); border-bottom-color: var(--bg-surface); border-left-color: var(--bg-surface); }
.deco-f1 .deco-f1__logo { display: block; width: 52px; height: 52px; }

/* FV-F1 — Fonctionnalités · fil 01 « Structurer » : styles du dessin, convertis des styles inline du prototype.
   Partial : template-parts/visuals/fv-f1-fil-structurer.php — même balisage dans .ft-inline.c-fit.fit-696x460 (< 1024)
   et dans .ft-visuel[data-ftv="1"] (≥ 1024). Racine 0,1,0, descendants 0,2,0, aucune déclaration prioritaire.
   Pas d'animation interne (M12 = bascule du visuel collant, portée par .ft-visuel dans la CSS de page). */
.fv-f1 { --motif-size: 440px; --motif-x: -16%; --motif-y: 84%; position: relative; box-sizing: border-box; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
/* Contexte .ft-inline.c-fit : dans le prototype, le style inline « position: relative » l'emporte sur
   .c-fit > .c-fit__inner { position: absolute } (main.css, 0,2,0). Même spécificité ici, gagne par l'ordre
   (feuille de page chargée après main.css). La racine reste dans le flux : le cadre .c-fit garde 460 px de haut
   sous 696 px de large (rendu des masters Tablette/Mobile, reproduit tel quel). Sans effet dans .ft-visuel. */
.fv-f1.c-fit__inner { position: relative; }
.fv-f1 .fv-f1__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f1 .fv-f1__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f1 .fv-f1__tab { font-size: 12px; white-space: nowrap; }
.fv-f1 .fv-f1__body { box-sizing: border-box; height: 296px; padding: 14px 18px 16px; background: var(--bg-surface); display: flex; flex-direction: column; gap: 0px; }
.fv-f1 .fv-f1__view { margin: 0px 0px 10px; align-self: flex-start; }
.fv-f1 .fv-f1__head { display: flex; align-items: center; gap: 10px; padding: 0px 0px 8px; }
.fv-f1 .fv-f1__eyebrow { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f1 .fv-f1__end { margin-left: auto; }
.fv-f1 .fv-f1__lot { display: flex; align-items: center; gap: 10px; padding: 9px 0px; border-top-width: 1px; border-top-style: solid; border-top-color: var(--border-100); }
.fv-f1 .fv-f1__lot-swatch { flex: 0 0 auto; width: 12px; height: 12px; border-radius: 3px; background: var(--lot-1); }
.fv-f1 .fv-f1__lot-code { font-weight: 600; font-size: 11px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f1 .fv-f1__lot-name { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); letter-spacing: 0.04em; }
.fv-f1 .fv-f1__lot-amount { font-weight: 600; font-size: 13px; line-height: 18px; font-family: var(--font-sans); color: var(--ink-900); font-variant-numeric: tabular-nums; }
.fv-f1 .fv-f1__sublot { display: flex; align-items: center; gap: 10px; padding: 8px 0px 8px 22px; border-top-width: 1px; border-top-style: solid; border-top-color: var(--border-100); }
.fv-f1 .fv-f1__code { font-weight: 600; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f1 .fv-f1__sublot-name { font-weight: 600; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-900); letter-spacing: 0.04em; }
.fv-f1 .fv-f1__sublot-count { font-weight: 400; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f1 .fv-f1__task { margin: 6px 0px 0px 22px; box-sizing: border-box; padding: 12px 14px; border-radius: var(--radius-md); background: var(--bg-page); }
.fv-f1 .fv-f1__task-head { display: flex; align-items: center; gap: 10px; padding: 0px; }
.fv-f1 .fv-f1__task-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 4px; background: var(--action); }
.fv-f1 .fv-f1__task-name { font-weight: 600; font-size: 13px; line-height: 18px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f1 .fv-f1__qty { display: inline-flex; align-items: center; height: 20px; padding: 0px 8px; border-radius: var(--radius-full); background: var(--bg-surface); font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-700); white-space: nowrap; }
.fv-f1 .fv-f1__checklist { margin-top: 10px; display: flex; flex-direction: column; gap: 7px; }
.fv-f1 .fv-f1__check { display: flex; align-items: center; gap: 9px; }
.fv-f1 .fv-f1__box { flex: 0 0 auto; width: 14px; height: 14px; border-radius: 4px; background: var(--action); display: inline-flex; align-items: center; justify-content: center; }
.fv-f1 .fv-f1__box-empty { flex: 0 0 auto; box-sizing: border-box; width: 14px; height: 14px; border-radius: 4px; border-width: 1.5px; border-style: solid; border-top-color: var(--border-strong); border-right-color: var(--border-strong); border-bottom-color: var(--border-strong); border-left-color: var(--border-strong); }
.fv-f1 .fv-f1__check-label { font-weight: 400; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f1 .fv-f1__check-label--todo { color: var(--ink-900); }

/* FV-F2 — Fonctionnalités · fil 02 « Consulter » (écran DCE) : styles du dessin, convertis des styles inline du
   prototype (partial template-parts/visuals/fv-f2-fil-consulter.php, fiche
   handoff/design/ui-feature-illustrations/FV-F2-fil-consulter.md). Dessin 696 × 460, un seul partial pour les deux
   emplacements du fil : en ligne < 1024 (enveloppe .ft-inline.c-fit.fit-696x460, mise à l'échelle par main.css) et
   collant ≥ 1024 (enveloppe .ft-visuel[data-ftv="2"], bascule M12 portée par la CSS de page). Aucune surcharge
   responsive propre ; aucune animation interne (fiche : intention « À valider »).
   Racine .fv-f2 (0,1,0), descendants .fv-f2 .fv-f2__x (0,2,0), sans !important.
   Exception documentée : .fv-f2.c-fit__inner (0,2,0) — le prototype pose position: relative en ligne sur la racine,
   ce qui l'emporte sur .c-fit > .c-fit__inner (position: absolute, 0,2,0, main.css) ; la racine reste donc dans le
   flux et la boîte .c-fit garde la hauteur du dessin non réduit quand elle rétrécit (460 px sous 1024, comme le
   prototype et les masters). Égalité de spécificité : gagne parce que la feuille de page est chargée après main.css.
   Hors .c-fit (visuel collant), la règle de main.css ne s'applique pas (combinateur enfant) : rendu identique. */
.fv-f2 { --motif-size: 440px; --motif-x: -16%; --motif-y: 84%; position: relative; box-sizing: border-box; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f2.c-fit__inner { position: relative; }
.fv-f2 .fv-f2__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f2 .fv-f2__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f2 .fv-f2__tab { font-size: 12px; white-space: nowrap; }
.fv-f2 .fv-f2__panel { box-sizing: border-box; height: 296px; padding: 16px 18px; background: var(--bg-surface); display: flex; flex-direction: column; gap: 0px; }
.fv-f2 .fv-f2__eyebrow { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f2 .fv-f2__deadline { display: flex; align-items: center; gap: 10px; padding: 9px 0px; }
.fv-f2 .fv-f2__deadline--ruled { border-top: 1px solid var(--border-100); }
.fv-f2 .fv-f2__deadline-label { font-weight: 400; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-700); }
.fv-f2 .fv-f2__deadline-value { margin-left: auto; }
.fv-f2 .fv-f2__date { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); font-variant-numeric: tabular-nums; }
.fv-f2 .fv-f2__company { margin-top: 14px; box-sizing: border-box; padding: 14px 16px; border-radius: var(--radius-md); border: 1px solid var(--border-100); background: var(--bg-page); }
.fv-f2 .fv-f2__company-head { display: flex; align-items: center; gap: 10px; padding: 0px; }
.fv-f2 .fv-f2__avatar { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; background: var(--brand-100); }
.fv-f2 .fv-f2__company-name { font-weight: 600; font-size: 13px; line-height: 18px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f2 .fv-f2__company-status { margin-left: auto; }
.fv-f2 .fv-f2__badge { display: inline-flex; align-items: center; height: 20px; padding: 0px 8px; border-radius: var(--radius-full); background: var(--status-valid-tint); font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--status-valid-ink); white-space: nowrap; }
.fv-f2 .fv-f2__visit { margin-top: 10px; display: flex; align-items: center; gap: 10px; }
.fv-f2 .fv-f2__visit-date { font-weight: 500; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-900); font-variant-numeric: tabular-nums; }
.fv-f2 .fv-f2__lots { margin-top: 14px; display: flex; gap: 8px; }
.fv-f2 .fv-f2__lot { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0px 9px; border-radius: var(--radius-sm); border: 1px solid var(--border-100); background: var(--bg-surface); }
.fv-f2 .fv-f2__lot-swatch { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 3px; }
.fv-f2 .fv-f2__lot-swatch--lot-1 { background: var(--lot-1); }
.fv-f2 .fv-f2__lot-swatch--lot-2 { background: var(--lot-2); }
.fv-f2 .fv-f2__lot-swatch--lot-3 { background: var(--lot-3); }
.fv-f2 .fv-f2__lot-name { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-700); }

/* FV-F3 — Fonctionnalités · fil 03 « Planifier » (template-parts/visuals/fv-f3-fil-planifier.php, fiche
   handoff/design/ui-feature-illustrations/FV-F3-fil-planifier.md) : styles du dessin (696 × 460), convertis des styles
   inline du prototype. Racine .fv-f3 (0,1,0), descendants .fv-f3 .fv-f3__x (0,2,0), sans !important.
   Un seul partial pour les deux emplacements du fil : .ft-inline.c-fit.fit-696x460 (< 1024, mis à l'échelle par
   .c-fit > .c-fit__inner, main.css) et .ft-visuel[data-ftv="3"] (≥ 1024, collant ; .c-fit__inner n'y a aucun effet,
   la règle de main.css utilisant le combinateur enfant). Aucune surcharge responsive propre ; aucune animation interne
   (fiche : intention « à valider » ; la bascule du visuel collant M12 est portée par la page).
   Exception documentée : .fv-f3.c-fit__inner (0,2,0) — le prototype pose position: relative en ligne sur la racine,
   ce qui l'emporte sur .c-fit > .c-fit__inner (position: absolute, 0,2,0, main.css) ; la racine reste donc dans le
   flux et la boîte .c-fit garde la hauteur du dessin non réduit (460 px) quand elle rétrécit, comme le prototype et
   les masters Tablette/Mobile. Égalité de spécificité : gagne parce que la feuille de page est chargée après main.css. */
.fv-f3 { --motif-size: 440px; --motif-x: -16%; --motif-y: 84%; position: relative; box-sizing: border-box; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f3.c-fit__inner { position: relative; }
.fv-f3 .fv-f3__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f3 .fv-f3__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f3 .fv-f3__tab { font-size: 12px; white-space: nowrap; }
.fv-f3 .fv-f3__body { box-sizing: border-box; height: 296px; padding: 16px 18px; background: var(--bg-surface); display: flex; flex-direction: column; gap: 0px; }
/* période du projet : dates, durée, libellé de l'écran */
.fv-f3 .fv-f3__period { display: flex; align-items: center; gap: 10px; padding: 0px 0px 10px; }
.fv-f3 .fv-f3__dates { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); font-variant-numeric: tabular-nums; }
.fv-f3 .fv-f3__weeks { display: inline-flex; align-items: center; height: 20px; padding: 0px 8px; border-radius: var(--radius-full); background: var(--bg-page); font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-700); white-space: nowrap; }
.fv-f3 .fv-f3__screen { margin-left: auto; }
.fv-f3 .fv-f3__eyebrow { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
/* échelle de mois */
.fv-f3 .fv-f3__months { display: flex; padding-left: 188px; }
.fv-f3 .fv-f3__month { flex: 1 1 0px; text-align: center; }
/* Gantt des sous-lots : libellé (pastille, code, nom, durée) + piste (filets de mois, barre) */
.fv-f3 .fv-f3__rows { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.fv-f3 .fv-f3__row { display: flex; align-items: center; gap: 10px; height: 26px; }
.fv-f3 .fv-f3__label { flex: 0 0 auto; width: 178px; display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.fv-f3 .fv-f3__swatch { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 3px; }
.fv-f3 .fv-f3__swatch--lot-4 { background: var(--lot-4); }
.fv-f3 .fv-f3__swatch--lot-5 { background: var(--lot-5); }
.fv-f3 .fv-f3__swatch--lot-6 { background: var(--lot-6); }
.fv-f3 .fv-f3__code { font-weight: 600; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f3 .fv-f3__name { font-weight: 400; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f3 .fv-f3__duration { margin-left: auto; }
.fv-f3 .fv-f3__duration-value { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f3 .fv-f3__track { position: relative; flex: 1 1 auto; height: 16px; }
.fv-f3 .fv-f3__gridline { position: absolute; top: -6px; bottom: -6px; width: 1px; background: var(--border-100); }
.fv-f3 .fv-f3__gridline--1 { left: 25%; }
.fv-f3 .fv-f3__gridline--2 { left: 50%; }
.fv-f3 .fv-f3__gridline--3 { left: 75%; }
.fv-f3 .fv-f3__bar { position: absolute; top: 3px; height: 10px; border-radius: var(--radius-full); opacity: 0.9; }
.fv-f3 .fv-f3__bar--4a { left: 4%; width: 22%; background: var(--lot-4); }
.fv-f3 .fv-f3__bar--4b { left: 24%; width: 15%; background: var(--lot-4); }
.fv-f3 .fv-f3__bar--5a { left: 34%; width: 18%; background: var(--lot-5); }
.fv-f3 .fv-f3__bar--6a { left: 52%; width: 15%; background: var(--lot-6); }
.fv-f3 .fv-f3__bar--6c { left: 70%; width: 15%; background: var(--lot-6); }

/* ==========================================================================
   FV-F4 — Fonctionnalités · fil 04 « Suivre » (écran Situation) : styles du dessin, convertis des styles inline
   du prototype (fonctionnalites.html, deux occurrences identiques au c-fit__inner près).
   Partial : template-parts/visuals/fv-f4-fil-suivre.php — fiche handoff/design/ui-feature-illustrations/FV-F4-fil-suivre.md.
   Dessin fixe 696 × 460, un seul partial pour les deux emplacements du fil : en ligne < 1024 (enveloppe
   .ft-inline.c-fit.fit-696x460, mise à l'échelle par .c-fit > .c-fit__inner de main.css) et collant ≥ 1024
   (enveloppe .ft-visuel[data-ftv="4"], bascule M12 portée par la CSS de page). Aucune surcharge responsive propre ;
   aucune animation interne (fiche : intention « à valider avec prudence », non retenue).
   Racine .fv-f4 (0,1,0), descendants .fv-f4 .fv-f4__x (0,2,0), sans !important.
   Exception documentée : .fv-f4.c-fit__inner (0,2,0) — le prototype pose position: relative en ligne sur la racine,
   ce qui l'emporte sur .c-fit > .c-fit__inner (position: absolute, 0,2,0, main.css) ; la racine reste donc dans le
   flux et la boîte .c-fit garde la hauteur du dessin non réduit quand elle rétrécit (comme le prototype et les
   masters). Égalité de spécificité : gagne parce que la feuille de page est chargée après main.css. Hors .c-fit
   (visuel collant), la règle de main.css ne s'applique pas (combinateur enfant) : rendu identique.
   ========================================================================== */
.fv-f4 { --motif-size: 440px; --motif-x: -16%; --motif-y: 84%; position: relative; box-sizing: border-box; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f4.c-fit__inner { position: relative; }
.fv-f4 .fv-f4__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f4 .fv-f4__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f4 .fv-f4__tab { font-size: 12px; white-space: nowrap; }
.fv-f4 .fv-f4__body { box-sizing: border-box; height: 296px; padding: 16px 18px; background: var(--bg-surface); display: flex; flex-direction: column; gap: 0px; }
.fv-f4 .fv-f4__kpis { display: flex; gap: 10px; }
.fv-f4 .fv-f4__kpi { flex: 1 1 0px; box-sizing: border-box; padding: 12px 14px; border-radius: var(--radius-md); background: var(--bg-page); display: flex; flex-direction: column; gap: 4px; }
.fv-f4 .fv-f4__label { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f4 .fv-f4__kpi-value { font-weight: 600; font-size: 16px; line-height: 22px; font-family: var(--font-sans); color: var(--ink-900); font-variant-numeric: tabular-nums; }
.fv-f4 .fv-f4__kpi-value--due { color: var(--action-ink); }
.fv-f4 .fv-f4__companies { margin-top: 14px; }
.fv-f4 .fv-f4__companies-head { display: flex; align-items: center; gap: 10px; padding: 0px 0px 4px; }
.fv-f4 .fv-f4__head-end { margin-left: auto; }
.fv-f4 .fv-f4__company { display: flex; align-items: center; gap: 10px; padding: 11px 0px; border-top: 1px solid var(--border-100); }
.fv-f4 .fv-f4__swatch { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 3px; }
.fv-f4 .fv-f4__swatch--lot-1 { background: var(--lot-1); }
.fv-f4 .fv-f4__swatch--lot-2 { background: var(--lot-2); }
.fv-f4 .fv-f4__company-id { display: flex; flex-direction: column; gap: 2px; }
.fv-f4 .fv-f4__company-name { font-weight: 600; font-size: 12px; line-height: 18px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f4 .fv-f4__trade { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.06em; text-transform: uppercase; }
.fv-f4 .fv-f4__due { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.fv-f4 .fv-f4__badge { display: inline-flex; align-items: center; height: 20px; padding: 0px 8px; border-radius: var(--radius-full); background: var(--brand-100); font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--brand-ink); white-space: nowrap; }
.fv-f4 .fv-f4__amount { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); font-variant-numeric: tabular-nums; }
.fv-f4 .fv-f4__progress { margin-top: auto; display: flex; align-items: center; gap: 12px; }
.fv-f4 .fv-f4__gauge { flex: 1 1 auto; height: 6px; border-radius: var(--radius-full); background: var(--bg-page); }
.fv-f4 .fv-f4__percent { font-weight: 600; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-700); }

/* ==========================================================================
   FV-F5 — Fonctionnalités · fil 05 « Centraliser » (écran Documents) : styles du dessin, convertis des styles inline
   du prototype (fonctionnalites.html, deux occurrences identiques au c-fit__inner près).
   Partial : template-parts/visuals/fv-f5-fil-centraliser.php — fiche handoff/design/ui-feature-illustrations/FV-F5-fil-centraliser.md.
   Dessin fixe 696 × 460, un seul partial pour les deux emplacements du fil : en ligne < 1024 (enveloppe
   .ft-inline.c-fit.fit-696x460, mise à l'échelle par .c-fit > .c-fit__inner de main.css) et collant ≥ 1024
   (enveloppe .ft-visuel[data-ftv="5"], bascule M12 portée par la CSS de page). Aucune surcharge responsive propre ;
   aucune animation interne (fiche : intention « Brief F, à valider », non retenue — motion-spec).
   Photos (fond pierre, 3 vignettes) : fichiers du thème assets/img/fv-documents-*.jpg.
   Racine .fv-f5 (0,1,0), descendants .fv-f5 .fv-f5__x (0,2,0), sans !important.
   Exception documentée : .fv-f5.c-fit__inner (0,2,0) — le prototype pose position: relative en ligne sur la racine,
   ce qui l'emporte sur .c-fit > .c-fit__inner (position: absolute, 0,2,0, main.css) ; la racine reste donc dans le
   flux et la boîte .c-fit garde la hauteur du dessin non réduit quand elle rétrécit (comme le prototype et les
   masters). Égalité de spécificité : gagne parce que la feuille de page est chargée après main.css. Hors .c-fit
   (visuel collant), la règle de main.css ne s'applique pas (combinateur enfant) : rendu identique.
   ========================================================================== */
.fv-f5 { position: relative; box-sizing: border-box; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; background: rgb(201, 180, 150); }
.fv-f5.c-fit__inner { position: relative; }
.fv-f5 .fv-f5__bg { position: absolute; left: -300px; top: -330px; width: 1160px; height: auto; max-width: none; }
.fv-f5 .fv-f5__window { position: absolute; left: 40px; top: 40px; width: 616px; box-shadow: var(--shadow-lg); }
.fv-f5 .fv-f5__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f5 .fv-f5__tab { font-size: 12px; white-space: nowrap; }
.fv-f5 .fv-f5__body { box-sizing: border-box; height: 296px; padding: 18px 18px 12px; background: var(--bg-surface); display: flex; flex-direction: column; gap: 14px; }
.fv-f5 .fv-f5__group { display: flex; flex-direction: column; gap: 8px; }
.fv-f5 .fv-f5__group-head { display: flex; align-items: center; gap: 8px; }
.fv-f5 .fv-f5__label { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f5 .fv-f5__files { display: flex; gap: 8px; }
.fv-f5 .fv-f5__thumb { display: block; width: 104px; height: 68px; object-fit: cover; border-radius: var(--radius-sm); }
.fv-f5 .fv-f5__plan { box-sizing: border-box; width: 104px; height: 68px; padding: 4px; border-radius: var(--radius-sm); border: 1px solid var(--border-100); background: rgb(255, 255, 255); overflow: hidden; }
.fv-f5 .fv-f5__plan-drawing { display: block; background: rgb(255, 255, 255); }
.fv-f5 .fv-f5__plan-room { font-weight: 600; font-size: 8px; line-height: 1; font-family: var(--font-sans); letter-spacing: 0.08em; }
.fv-f5 .fv-f5__plan-dimension { font-weight: 400; font-size: 6px; line-height: 1; font-family: var(--font-sans); }
.fv-f5 .fv-f5__plan-title { font-weight: 600; font-size: 7px; line-height: 1; font-family: var(--font-sans); letter-spacing: 0.08em; }
.fv-f5 .fv-f5__plan-caption { font-weight: 400; font-size: 6px; line-height: 1; font-family: var(--font-sans); letter-spacing: 0.08em; }
.fv-f5 .fv-f5__folds { display: flex; flex-direction: column; }
.fv-f5 .fv-f5__fold { display: flex; align-items: center; gap: 10px; padding: 0px; border-top: 1px solid var(--border-100); height: 30px; }

/* FV-F6 — Fonctionnalités · schéma « Une logique commune » : styles du dessin, convertis des styles inline du prototype
   (et des couleurs SVG en var() posées en attributs de présentation). La mise en page du schéma (colonnes Desktop/Laptop,
   liaisons 96 px en Laptop, arborescence < 1024 — D09) et le mouvement M13 (oe-flux, fnNode, mouvement réduit) restent
   portés par les règles fn-schema* / oe-flux* de la CSS de page. */
.fv-f6 .fv-f6__src-title { margin: 0px 0px 10px; font-weight: 500; font-size: 11px; line-height: 16px; font-family: var(--font-sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-500); }
.fv-f6 .fv-f6__level { display: flex; align-items: center; gap: 12px; height: 44px; padding-left: 0px; }
.fv-f6 .fv-f6__level--sublot { padding-left: 22px; }
.fv-f6 .fv-f6__level--task { padding-left: 44px; }
.fv-f6 .fv-f6__level--checklist { padding-left: 66px; }
.fv-f6 .fv-f6__swatch { flex: 0 0 auto; width: 12px; height: 12px; border-radius: 3px; background: var(--lot-1); }
.fv-f6 .fv-f6__swatch--sublot { background: var(--lot-1-tint); }
.fv-f6 .fv-f6__swatch--task { background: var(--brand-300); }
.fv-f6 .fv-f6__swatch--checklist { background: var(--brand-100); }
.fv-f6 .fv-f6__level-name { font-weight: 600; font-size: 14px; line-height: 20px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f6 .fv-f6__level-value { font-weight: 400; font-size: 13px; line-height: 18px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f6 .fv-f6__links { stroke: var(--brand-300); }
.fv-f6 .fv-f6__link { stroke: var(--brand-100); }
.fv-f6 .fv-f6__dot { fill: var(--lot-1); }
.fv-f6 .fv-f6__out-title { font-weight: 600; font-size: 15px; line-height: 22px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f6 .fv-f6__out-desc { font-weight: 400; font-size: 13px; line-height: 20px; font-family: var(--font-sans); color: var(--ink-700); }
.fv-f6 .fv-f6__tag { margin-top: 6px; display: inline-flex; align-items: center; gap: 8px; }
.fv-f6 .fv-f6__tag-swatch { width: 12px; height: 12px; border-radius: 3px; background: var(--lot-1); }
.fv-f6 .fv-f6__tag-label { font-weight: 500; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-500); }

/* FV-F7 — Fonctionnalités · module « Bibliothèque » (template-parts/visuals/fv-f7-module-bibliotheque.php) :
   styles du dessin (696 × 460), convertis des styles inline du prototype. Racine .fv-f7 (0,1,0), descendants
   .fv-f7 .fv-f7__* (0,2,0), sans !important. Mise à l'échelle : .c-fit.fit-696x460.fn-mod__vis > .c-fit__inner
   (section de page, main.css) ; aucune surcharge responsive (le dessin est réduit d'un bloc par .c-fit). */
.fv-f7 { --motif-size: 440px; --motif-x: -16%; --motif-y: 84%; position: relative; box-sizing: border-box; flex: 0 0 auto; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f7 .fv-f7__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f7 .fv-f7__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f7 .fv-f7__tab { font-size: 12px; white-space: nowrap; }
.fv-f7 .fv-f7__body { box-sizing: border-box; height: 296px; padding: 16px 18px; background: var(--bg-surface); display: flex; gap: 16px; }
.fv-f7 .fv-f7__lots { flex: 1 1 auto; min-width: 0px; display: flex; flex-direction: column; }
.fv-f7 .fv-f7__lots-head { display: flex; align-items: center; gap: 10px; padding: 0px 0px 8px; }
.fv-f7 .fv-f7__eyebrow { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f7 .fv-f7__add { margin-left: auto; display: inline-flex; align-items: center; height: 20px; padding: 0px 8px; border-radius: var(--radius-sm); background: var(--action); font-weight: 600; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: #ffffff; white-space: nowrap; }
.fv-f7 .fv-f7__lot { display: flex; align-items: center; gap: 10px; height: 40px; padding: 0px 0px 0px 4px; border-top-width: 1px; border-top-style: solid; border-top-color: var(--border-100); }
.fv-f7 .fv-f7__lot--1 { box-shadow: inset 3px 0 0 var(--lot-1); }
.fv-f7 .fv-f7__lot--2 { box-shadow: inset 3px 0 0 var(--lot-2); }
.fv-f7 .fv-f7__lot--3 { box-shadow: inset 3px 0 0 var(--lot-3); }
.fv-f7 .fv-f7__lot--4 { box-shadow: inset 3px 0 0 var(--lot-4); }
.fv-f7 .fv-f7__lot--5 { box-shadow: inset 3px 0 0 var(--lot-5); }
.fv-f7 .fv-f7__lot-number { font-weight: 600; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); margin-left: 6px; }
.fv-f7 .fv-f7__lot-name { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); letter-spacing: 0.04em; white-space: nowrap; }
.fv-f7 .fv-f7__lot-count { margin-left: auto; padding-right: 4px; font-weight: 400; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-500); white-space: nowrap; }
.fv-f7 .fv-f7__template { flex: 0 0 auto; width: 216px; box-sizing: border-box; padding: 12px 14px; border-radius: var(--radius-md); background: var(--bg-page); display: flex; flex-direction: column; gap: 8px; }
.fv-f7 .fv-f7__template-title { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f7 .fv-f7__template-body { margin: 2px 0px 0px; font-weight: 400; font-size: 11px; line-height: 17px; font-family: var(--font-sans); color: var(--ink-700); }
.fv-f7 .fv-f7__variable { display: inline-block; padding: 0px 5px; border-radius: var(--radius-xs); background: var(--brand-100); color: var(--brand-ink); font-weight: 500; white-space: nowrap; }
.fv-f7 .fv-f7__template-foot { margin-top: auto; display: flex; align-items: center; gap: 6px; }
.fv-f7 .fv-f7__variable-count { margin-left: auto; font-weight: 500; font-size: 11px; line-height: 14px; font-family: var(--font-sans); color: var(--brand-ink); }

/* FV-F8 — Fonctionnalités · module « Leads et clients » (#leads-clients ; template-parts/visuals/fv-f8-module-leads-clients.php) :
   styles du dessin (696 × 460), convertis des styles inline du prototype (fonctionnalites.html). Racine .fv-f8 (0,1,0),
   descendants .fv-f8 .fv-f8__* (0,2,0), aucune déclaration forcée. Mise à l’échelle : .c-fit.fit-696x460.fn-mod__vis > .c-fit__inner
   (section de page ; .c-fit dans main.css, .fn-mod__vis dans la CSS de page, commune aux trois modules).
   Aucune surcharge responsive : le dessin est réduit d’un bloc par .c-fit (aucune règle de page ne touche l’intérieur).
   Aucune animation (fiche : « Dans la maquette : Aucune » ; intention de mouvement « À valider », non intégrée). */
.fv-f8 { --motif-size: 440px; --motif-x: 84%; --motif-y: 84%; position: relative; box-sizing: border-box; flex: 0 0 auto; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f8 .fv-f8__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f8 .fv-f8__body { box-sizing: border-box; height: 344px; padding: 14px 18px 16px; background: var(--bg-surface); display: flex; flex-direction: column; }
.fv-f8 .fv-f8__toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.fv-f8 .fv-f8__filter { margin-left: 0px; }
.fv-f8 .fv-f8__new { margin-left: auto; display: inline-flex; align-items: center; height: 26px; padding: 0px 10px; border-radius: var(--radius-sm); background: var(--action); font-weight: 600; font-size: 11px; line-height: 14px; font-family: var(--font-sans); color: #ffffff; white-space: nowrap; }
.fv-f8 .fv-f8__row { display: flex; align-items: center; gap: 10px; height: 40px; border-top-width: 1px; border-top-style: solid; border-top-color: var(--border-100); }
.fv-f8 .fv-f8__dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 4px; }
.fv-f8 .fv-f8__dot--lead { background: var(--status-progress); }
.fv-f8 .fv-f8__dot--client { background: var(--status-valid); }
.fv-f8 .fv-f8__name { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f8 .fv-f8__project { font-weight: 400; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f8 .fv-f8__status { margin-left: auto; display: inline-flex; align-items: center; height: 20px; padding: 0px 8px; border-radius: var(--radius-xs); font-weight: 500; font-size: 11px; line-height: 14px; font-family: var(--font-sans); }
.fv-f8 .fv-f8__status--lead { background: var(--status-progress-tint); color: var(--status-progress-ink); }
.fv-f8 .fv-f8__status--client { background: var(--status-valid-tint); color: var(--status-valid-ink); }
.fv-f8 .fv-f8__date { font-weight: 400; font-size: 11px; line-height: 15px; font-family: var(--font-sans); color: var(--ink-500); font-variant-numeric: tabular-nums; }
.fv-f8 .fv-f8__history { box-sizing: border-box; margin: 0px 0px 6px 18px; padding: 10px 12px; border-radius: var(--radius-md); background: var(--bg-page); display: flex; align-items: flex-start; gap: 16px; }
.fv-f8 .fv-f8__timeline { flex: 1 1 auto; min-width: 0px; display: flex; flex-direction: column; gap: 6px; }
.fv-f8 .fv-f8__eyebrow { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f8 .fv-f8__event { display: flex; gap: 8px; font-weight: 400; font-size: 11px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-700); }
.fv-f8 .fv-f8__event-date { flex: 0 0 auto; color: var(--ink-500); font-variant-numeric: tabular-nums; }
.fv-f8 .fv-f8__convert { flex: 0 0 auto; align-self: flex-end; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0px 12px; border-radius: var(--radius-sm); background: var(--brand-ink); font-weight: 600; font-size: 11px; line-height: 14px; font-family: var(--font-sans); color: #ffffff; white-space: nowrap; }

/* FV-F9 — Fonctionnalités · module « Documents avec variables » (#documents-variables ;
   template-parts/visuals/fv-f9-module-documents-variables.php) : styles du dessin (696 × 460), convertis des styles inline
   du prototype (fonctionnalites.html). Racine .fv-f9 (0,1,0), descendants .fv-f9 .fv-f9__* (0,2,0), aucune déclaration forcée.
   Mise à l’échelle : .c-fit.fit-696x460.fn-mod__vis > .c-fit__inner (section de page ; .c-fit dans main.css, .fn-mod__vis
   dans la CSS de page, commune aux trois modules). Aucune surcharge responsive : le dessin est réduit d’un bloc par .c-fit
   (aucune règle de page ne touche l’intérieur). Aucune animation (fiche : « Dans la maquette : Aucune » ; intention de
   mouvement « À valider », non intégrée). À charger après ds-oeuvra-bundle.css (fusion dans page-fonctionnalites.css). */
.fv-f9 { --motif-size: 440px; --motif-x: -16%; --motif-y: 84%; position: relative; box-sizing: border-box; flex: 0 0 auto; width: 696px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f9 .fv-f9__window { position: absolute; left: 40px; top: 40px; width: 616px; }
.fv-f9 .fv-f9__tabs { gap: 14px; padding: 4px 16px 0px; overflow: hidden; }
.fv-f9 .fv-f9__tab { font-size: 12px; white-space: nowrap; }
.fv-f9 .fv-f9__body { box-sizing: border-box; height: 296px; padding: 14px 18px 16px; background: var(--bg-surface); display: flex; gap: 14px; }
.fv-f9 .fv-f9__col { flex: 1 1 0px; min-width: 0px; display: flex; flex-direction: column; gap: 8px; }
.fv-f9 .fv-f9__col-head { display: flex; align-items: center; gap: 8px; }
.fv-f9 .fv-f9__eyebrow { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--ink-500); letter-spacing: 0.08em; text-transform: uppercase; }
.fv-f9 .fv-f9__var-count { margin-left: auto; font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--brand-ink); }
.fv-f9 .fv-f9__doc { flex: 1 1 auto; box-sizing: border-box; padding: 12px 14px; border-radius: var(--radius-md); border-width: 1px; border-style: solid; border-top-color: var(--border-100); border-right-color: var(--border-100); border-bottom-color: var(--border-100); border-left-color: var(--border-100); background: var(--bg-page); display: flex; flex-direction: column; gap: 7px; font-weight: 400; font-size: 11px; line-height: 17px; font-family: var(--font-sans); color: var(--ink-700); }
.fv-f9 .fv-f9__doc--generated { background: var(--bg-surface); box-shadow: var(--shadow-md); }
.fv-f9 .fv-f9__doc-title { font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f9 .fv-f9__var { display: inline-block; padding: 0px 5px; border-radius: var(--radius-xs); background: var(--brand-100); color: var(--brand-ink); font-weight: 500; }
.fv-f9 .fv-f9__mission { margin-top: 2px; padding-top: 7px; border-top-width: 1px; border-top-style: dashed; border-top-color: var(--border-100); }
.fv-f9 .fv-f9__total { display: flex; justify-content: space-between; font-weight: 600; color: var(--ink-900); }
.fv-f9 .fv-f9__total--figures { font-variant-numeric: tabular-nums; }
.fv-f9 .fv-f9__generate { align-self: flex-end; display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0px 10px; border-radius: var(--radius-sm); background: var(--action); font-weight: 600; font-size: 11px; line-height: 14px; font-family: var(--font-sans); color: rgb(255, 255, 255); white-space: nowrap; }
.fv-f9 .fv-f9__arrow { flex: 0 0 auto; align-self: center; display: grid; place-content: center; width: 28px; height: 28px; border-radius: 50%; background: var(--action); color: rgb(255, 255, 255); }
.fv-f9 .fv-f9__lead { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); color: var(--status-valid-ink); }
.fv-f9 .fv-f9__lead-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--status-valid); }

/* FV-F10 — Fonctionnalités · « Sur le chantier » (PWA hors connexion + dictée) : styles du dessin, convertis des
   styles inline du prototype (partial template-parts/visuals/fv-f10-chantier-hors-connexion.php, fiche
   handoff/design/ui-feature-illustrations/FV-F10-chantier-hors-connexion.md). Dessin 616 × 460, mis à l'échelle par
   .c-fit.fit-616x460 (main.css) ; aucune surcharge responsive propre ; aucune animation (fiche : intention « À valider »).
   Racine .fv-f10 (0,1,0), descendants .fv-f10 .fv-f10__… (0,2,0), aucune déclaration prioritaire.
   Exception documentée : .fv-f10.c-fit__inner (0,2,0) — le prototype pose position: relative en ligne sur la racine,
   ce qui l'emporte sur .c-fit > .c-fit__inner (position: absolute, 0,2,0, main.css) ; la racine reste donc dans le
   flux et la boîte .c-fit garde la hauteur du dessin non réduit quand elle rétrécit (460 px à 1024, comme le prototype
   et les masters). Égalité de spécificité : gagne parce que la feuille de page est chargée après main.css. */
.fv-f10 { --motif-size: 440px; --motif-x: 84%; --motif-y: 84%; position: relative; box-sizing: border-box; width: 616px; height: 460px; border-radius: var(--radius-xl); overflow: hidden; }
.fv-f10.c-fit__inner { position: relative; }
.fv-f10 .fv-f10__window { position: absolute; left: 40px; top: 40px; width: 536px; border-radius: 14px; border-width: 2px; border-style: solid; border-top-color: var(--ink-900); border-right-color: var(--ink-900); border-bottom-color: var(--ink-900); border-left-color: var(--ink-900); box-shadow: var(--shadow-lg); }
.fv-f10 .fv-f10__bar { height: 44px; }
.fv-f10 .fv-f10__badge { margin-left: auto; gap: 6px; }
.fv-f10 .fv-f10__body { box-sizing: border-box; height: 332px; padding: 16px 18px; background: var(--bg-surface); display: flex; flex-direction: column; gap: 12px; }
.fv-f10 .fv-f10__task { display: flex; align-items: center; gap: 10px; box-sizing: border-box; height: 40px; padding: 0px 12px; border-radius: var(--radius-md); background: var(--action-tint); }
.fv-f10 .fv-f10__task-code { font-weight: 500; font-size: 11px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f10 .fv-f10__task-name { font-weight: 600; font-size: 13px; line-height: 18px; font-family: var(--font-sans); color: var(--ink-900); white-space: nowrap; }
.fv-f10 .fv-f10__task-meta { margin-left: auto; font-weight: 400; font-size: 11px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f10 .fv-f10__card { box-sizing: border-box; flex: 1 1 auto; padding: 14px 16px; border-radius: var(--radius-md); border-width: 1px; border-style: solid; border-top-color: var(--border-100); border-right-color: var(--border-100); border-bottom-color: var(--border-100); border-left-color: var(--border-100); background: var(--bg-page); display: flex; flex-direction: column; gap: 10px; }
.fv-f10 .fv-f10__card-head { display: flex; align-items: center; gap: 10px; }
.fv-f10 .fv-f10__eyebrow { font-weight: 600; font-size: 10px; line-height: 14px; font-family: var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-500); }
.fv-f10 .fv-f10__status { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-weight: 500; font-size: 11px; line-height: 16px; font-family: var(--font-sans); color: var(--action-ink); }
.fv-f10 .fv-f10__status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--action); }
.fv-f10 .fv-f10__recorder { display: flex; align-items: center; gap: 14px; }
.fv-f10 .fv-f10__mic { flex: 0 0 auto; display: grid; place-content: center; width: 44px; height: 44px; border-radius: 50%; background: var(--action); color: rgb(255, 255, 255); }
.fv-f10 .fv-f10__wave { flex: 1 1 auto; display: flex; align-items: center; gap: 3px; height: 32px; }
/* forme d'onde figée (état « dictée en cours ») : 17 barres actives puis 7 barres de repos (6 px, border-100) */
.fv-f10 .fv-f10__wave-bar { width: 3px; height: 6px; border-radius: 2px; background: var(--border-100); }
.fv-f10 .fv-f10__wave-bar--h8 { height: 8px; }
.fv-f10 .fv-f10__wave-bar--h10 { height: 10px; }
.fv-f10 .fv-f10__wave-bar--h12 { height: 12px; }
.fv-f10 .fv-f10__wave-bar--h14 { height: 14px; }
.fv-f10 .fv-f10__wave-bar--h16 { height: 16px; }
.fv-f10 .fv-f10__wave-bar--h18 { height: 18px; }
.fv-f10 .fv-f10__wave-bar--h20 { height: 20px; }
.fv-f10 .fv-f10__wave-bar--h22 { height: 22px; }
.fv-f10 .fv-f10__wave-bar--h24 { height: 24px; }
.fv-f10 .fv-f10__wave-bar--h26 { height: 26px; }
.fv-f10 .fv-f10__wave-bar--h28 { height: 28px; }
.fv-f10 .fv-f10__wave-bar--h30 { height: 30px; }
.fv-f10 .fv-f10__wave-bar--brand-300 { background: var(--brand-300); }
.fv-f10 .fv-f10__wave-bar--brand-ink { background: var(--brand-ink); }
.fv-f10 .fv-f10__wave-bar--action { background: var(--action); }
.fv-f10 .fv-f10__timer { flex: 0 0 auto; font-weight: 500; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-500); font-variant-numeric: tabular-nums; }
.fv-f10 .fv-f10__transcript { display: flex; flex-direction: column; gap: 4px; }
.fv-f10 .fv-f10__label { font-weight: 500; font-size: 10px; line-height: 14px; font-family: var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-500); }
.fv-f10 .fv-f10__text { margin: 0px; box-sizing: border-box; padding: 10px 12px; border-radius: var(--radius-sm); border-width: 1px; border-style: solid; border-top-color: var(--border-100); border-right-color: var(--border-100); border-bottom-color: var(--border-100); border-left-color: var(--border-100); background: var(--bg-surface); font-weight: 400; font-size: 13px; line-height: 20px; font-family: var(--font-sans); color: var(--ink-900); }
.fv-f10 .fv-f10__caret { display: inline-block; width: 1px; height: 14px; margin-left: 2px; vertical-align: -2px; background: var(--action); }
.fv-f10 .fv-f10__foot { display: flex; align-items: center; gap: 10px; }
.fv-f10 .fv-f10__note { font-weight: 400; font-size: 11px; line-height: 16px; font-family: var(--font-sans); color: var(--ink-500); }
.fv-f10 .fv-f10__button { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0px 14px; border-radius: var(--radius-sm); background: var(--ink-900); font-weight: 600; font-size: 12px; line-height: 16px; font-family: var(--font-sans); color: rgb(255, 255, 255); white-space: nowrap; }
