/* ===================================================================
   UNIVERS · la lumière réelle de chaque produit, lue dans son code.

   Chaque univers redéfinit les 7 tokens de la salle (DESIGN.md) avec les
   valeurs EXACTES du produit, sa fonte d'affichage (--u-display, --u-poids,
   --u-espace), sa fonte d'interface (--u-sans), sa nappe de lumière
   (--u-lumiere : les orbes, halos ou scrims du produit) et son grain
   (--u-grain : le même feTurbulence que le produit, mêmes réglages).

   Puis son spécimen : un composant du produit, markup et CSS repris du
   dépôt, scoped sous .u-<slug>. Les variables locales portent les noms
   du produit pour que le CSS reste lisible à côté de sa source.

   Sources : rapports d'extraction du 29 août 2026, un par dépôt (voir
   docs/RECITS-DECLENCHEURS.md pour la table de provenance).
   =================================================================== */

/* -------------------------------------------------------------------
   FONTES DES PRODUITS · auto-hébergées ici, sous-ensemble latin.
   Inter, Plus Jakarta Sans, Caveat, Schibsted Grotesk : Google Fonts,
   telles que les produits les chargent. Fraunces, Archivo, JetBrains
   Mono : copies des fichiers Fontsource servis par Toul'Barz. Arverna :
   la police maison de l'Abeille (capitales seules).
   ------------------------------------------------------------------- */
@font-face{font-family:'Inter';src:url('univers/fonts/inter-var.woff2') format('woff2');font-weight:400 600;font-display:swap}
@font-face{font-family:'Plus Jakarta Sans';src:url('univers/fonts/plus-jakarta-sans-var.woff2') format('woff2');font-weight:400 800;font-display:swap}
@font-face{font-family:'Caveat';src:url('univers/fonts/caveat-600.woff2') format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:'Schibsted Grotesk';src:url('univers/fonts/schibsted-grotesk-var.woff2') format('woff2');font-weight:400 600;font-display:swap}
@font-face{font-family:'Fraunces Variable';src:url('univers/fonts/fraunces-var.woff2') format('woff2-variations');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:'Fraunces Variable';src:url('univers/fonts/fraunces-var-italic.woff2') format('woff2-variations');font-weight:100 900;font-style:italic;font-display:swap}
@font-face{font-family:'Archivo Variable';src:url('univers/fonts/archivo-var.woff2') format('woff2-variations');font-weight:100 900;font-display:swap}
@font-face{font-family:'JetBrains Mono Variable';src:url('univers/fonts/jetbrains-mono-var.woff2') format('woff2-variations');font-weight:100 800;font-display:swap}
@font-face{font-family:'Arverna';src:url('univers/fonts/arverna.woff2') format('woff2');font-weight:normal;font-display:swap}


/* ===================================================================
   01 · QSE (« Brunel ») · src/index.css, index.html, MessageBubble.tsx
   Clair et seulement clair : ardoise 50, encre ardoise 900, bleu 600.
   Pile système (la CSP interdit toute fonte tierce), hiérarchie par le
   poids : font-black 900. Orbes bleu / indigo / cyan, grain 0.8 à 2 %.
   =================================================================== */
html[data-univers="qse"]{
  --noir:#f8fafc;--surface:#ffffff;--ligne:#e2e8f0;--blanc:#0f172a;--gris:#475569;
  --ambre:#2563eb;--ambre-clair:#1d4ed8;
  --u-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --u-sans:var(--u-display);--u-poids:900;--u-espace:-.025em;
  /* Une seule nappe, centrée en haut : les deux nappes d'angle (haut gauche,
     bas droite) donnaient a la page elle-meme deux coins teintes, exactement la
     ou la fenetre en avait deja. Symetrique, on ne lit plus d'angle nulle part. */
  --u-lumiere:radial-gradient(125% 78% at 50% -12%,rgba(219,234,254,.5) 0%,rgba(224,231,255,.22) 42%,transparent 66%);
  --u-grain:url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --u-grain-taille:200px 200px;--u-grain-mode:multiply;--u-grain-opacite:.02;
}
.u-qse{
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:#0f172a;
  -webkit-font-smoothing:antialiased;
}
/* la coque de la fenêtre de chat : atmosphère, orbes, verre (ChatInterface.tsx) */
.qse-fenetre{
  position:relative;overflow:hidden;border-radius:32px;padding:22px 20px 20px;
  background:linear-gradient(to bottom right,#f8fafc,rgba(239,246,255,.3));
  box-shadow:0 25px 50px -12px rgba(15,23,42,.35),0 0 0 1px rgba(15,23,42,.09);outline:1px solid rgba(255,255,255,.35);
}
/* Les orbes coloraient les angles de la fenêtre, que le rayon de 32 px coupait
   net : sur la page claire, l'angle teinté se détachait comme un coin sale.
   Le masque radial est calé sur 76 % de la boîte, donc il est deja tout à fait
   transparent quand on atteint un angle (à 90 % de la course) : le pourtour de
   la carte est exactement sa couleur de fond, la lueur reste au centre. */
.qse-orbes{
  position:absolute;inset:0;border-radius:inherit;overflow:hidden;pointer-events:none;
  -webkit-mask-image:radial-gradient(76% 76% at 50% 50%,#000 0,#000 38%,transparent 84%);
  mask-image:radial-gradient(76% 76% at 50% 50%,#000 0,#000 38%,transparent 84%);
}
.qse-orbes i{position:absolute;border-radius:50%;filter:blur(76px);opacity:.62;pointer-events:none}
.qse-orbes .o1{top:-6%;left:-3%;width:270px;height:270px;background:#60a5fa}
.qse-orbes .o2{bottom:-6%;right:-3%;width:230px;height:230px;background:#818cf8}
.qse-orbes .o3{top:38%;left:32%;width:140px;height:140px;background:#22d3ee}
.qse-verre{position:absolute;inset:0;background:rgba(255,255,255,.6);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px)}
.qse-fil{position:relative;display:flex;flex-direction:column;gap:12px}
.qse-msg{display:flex;gap:10px;align-items:flex-end;max-width:86%}
.qse-moi{align-self:flex-end}
/* l'avatar biométrique et son aura (BiometricAvatar.tsx : cyan-400 quand la crédibilité est haute) */
.qse-avatar{
  width:40px;height:40px;border-radius:50%;background:#0f172a;border:2px solid #22d3ee;
  display:grid;place-items:center;color:#fff;font-weight:900;font-size:11px;flex:none;
  animation:qse-aura 3s ease-in-out infinite;
}
@keyframes qse-aura{0%,100%{box-shadow:0 0 10px #22d3ee}50%{box-shadow:0 0 25px #22d3ee}}
.qse-nom{margin:0 0 6px 4px;font-size:10px;font-weight:900;letter-spacing:.1em;text-transform:uppercase;color:#475569}
.qse-bulle{padding:14px 20px;font-size:15px;border-radius:24px}
.qse-ia .qse-bulle{
  background:rgba(248,250,252,.8);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  color:#1e293b;border:1px solid rgba(255,255,255,.6);box-shadow:0 2px 10px rgba(0,0,0,.03);
  line-height:1.75;letter-spacing:-.01em;
}
.qse-moi .qse-bulle{
  background:linear-gradient(to bottom right,#2563eb,#4f46e5);color:#fff;
  font-weight:500;letter-spacing:.025em;line-height:1.55;
  box-shadow:0 10px 15px -3px rgba(59,130,246,.3);border:1px solid rgba(59,130,246,.5);
}
/* la capsule de saisie et l'orbe micro (ChatInput.tsx) */
.qse-saisie{display:flex;gap:10px;align-items:center;margin-top:6px}
.qse-capsule{
  flex:1;min-width:0;height:56px;display:flex;align-items:center;padding:0 8px 0 22px;border-radius:2rem;
  background:rgba(248,250,252,.8);border:1px solid rgba(255,255,255,.6);
  box-shadow:inset 0 2px 4px rgba(0,0,0,.02);color:#64748b;font-weight:500;font-size:15px;
}
.qse-placeholder{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.qse-envoi{
  margin-left:auto;flex:none;width:40px;height:40px;border-radius:50%;background:#2563eb;color:#fff;
  display:grid;place-items:center;box-shadow:0 10px 15px -3px rgba(59,130,246,.3);
}
.qse-micro{
  width:56px;height:56px;border-radius:50%;background:#fff;color:#475569;flex:none;
  border:1px solid rgba(255,255,255,.6);box-shadow:0 10px 15px -3px rgba(0,0,0,.1);display:grid;place-items:center;
}
.qse-envoi svg,.qse-micro svg{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round}
.qse-envoi svg{width:20px;height:20px;stroke-width:2.5}
.qse-micro svg{width:24px;height:24px;stroke-width:2}
/* Le reste de la fenêtre, partagé depuis le 5 septembre 2026 par la page
   (jouable) et le mur (la démo, projets/demos.js) : l'en-tête et ses témoins
   (ChatHeader.tsx), le fil qui défile, l'entrée d'une bulle, les points de
   frappe (ChatInterface.tsx), la carte d'indice (SystemMessageCard.tsx). Les
   états de crédibilité et le formulaire restent propres à la page. */
.qse-tete{position:relative;display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:0 4px 14px;border-bottom:1px solid rgba(15,23,42,.06);margin-bottom:6px}
.qse-tete .qse-avatar{width:56px;height:56px;font-size:15px}
.qse-tete-id{display:flex;flex-direction:column;justify-content:center;min-width:0}
.qse-tete-nom{margin:0;font-size:clamp(18px,4.6vw,24px);font-weight:900;letter-spacing:-.025em;line-height:1;color:#0f172a}
.qse-tete-role{display:inline-block;margin-top:6px;padding:2px 12px;border-radius:999px;font-size:10px;font-weight:600;color:#475569;background:rgba(255,255,255,.5);border:1px solid rgba(255,255,255,.6);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);width:max-content}
/* choisir le témoin : quatre boutons, l'anneau cyan marque celui qu'on interroge
   (sur le mur, des spans et la classe est-choisi : rien n'y est cliquable) */
.qse-temoins{margin-left:auto;display:flex;gap:6px;align-items:center}
.qse-choix{
  width:40px;height:40px;border-radius:50%;background:#0f172a;color:#fff;border:2px solid rgba(255,255,255,.65);
  font:900 11px/1 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;letter-spacing:.02em;
  display:grid;place-items:center;cursor:pointer;padding:0;opacity:.5;
  transition:opacity .25s ease,transform .3s cubic-bezier(.22,1,.36,1),border-color .3s ease,box-shadow .3s ease;
}
.qse-choix:hover{opacity:.85;transform:translateY(-2px)}
.qse-choix[aria-pressed="true"],.qse-choix.est-choisi{opacity:1;border-color:#22d3ee;transform:scale(1.08);box-shadow:0 0 12px rgba(34,211,238,.6)}
.qse-choix:focus-visible{outline:2px solid #2563eb;outline-offset:2px}
.qse-choix[aria-disabled="true"]{cursor:default}
/* le fil : zone qui défile, masquée en haut et en bas (ChatInterface.tsx:235-236).
   Hauteur fixe, pas un maximum : sinon la fenêtre entière change de taille à
   chaque réplique qui arrive, et toute la page tressaute. */
.qse-liste{
  display:flex;flex-direction:column;gap:12px;height:min(25rem,54vh);overflow-y:auto;padding:14px 4px;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 6%,#000 94%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 6%,#000 94%,transparent 100%);
  scrollbar-width:none;overscroll-behavior:contain;
}
.qse-liste::-webkit-scrollbar{display:none}
.qse-liste .qse-msg{flex:none}
.qse-corps{min-width:0}
/* entrée d'une bulle : 6 px, 280 ms (MessageBubble.tsx:58-61) ; l'avatar surgit avec 100 ms de retard */
.qse-msg.entre{animation:qse-entree .28s cubic-bezier(.22,1,.36,1) both}
@keyframes qse-entree{from{opacity:0;transform:translateY(6px)}}
.qse-msg.entre .qse-avatar{animation:qse-aura 3s ease-in-out infinite,qse-pop .45s cubic-bezier(.34,1.56,.64,1) .1s both}
@keyframes qse-pop{from{transform:scale(0);opacity:0}}
/* suite d'un même témoin : coins de continuité à 4 px, avatar sur la dernière bulle seulement (MessageBubble.tsx:36-45, 69) */
.qse-ia.suite .qse-bulle{border-top-left-radius:4px}
.qse-ia.avant-suite .qse-bulle{border-bottom-left-radius:4px}
.qse-ia.suite .qse-nom{display:none}
.qse-ia.avant-suite .qse-avatar{visibility:hidden;animation:none}
.qse-moi.suite .qse-bulle{border-top-right-radius:4px}
.qse-moi.avant-suite .qse-bulle{border-bottom-right-radius:4px}
.qse-ia .qse-bulle{overflow-wrap:anywhere}
/* les trois points de frappe (ChatInterface.tsx:307-309 : animate-bounce, 75 et 150 ms) */
.qse-frappe{display:flex;align-items:center;gap:6px;height:26px}
.qse-frappe i{width:6px;height:6px;border-radius:50%;background:#94a3b8;animation:qse-bond 1s infinite}
.qse-frappe i:nth-child(2){animation-delay:75ms}.qse-frappe i:nth-child(3){animation-delay:150ms}
@keyframes qse-bond{0%,100%{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}
/* la carte d'indice : « ÉLÉMENT IDENTIFIÉ » (bleu) ou « CAUSE RACINE » (ambre) (SystemMessageCard.tsx:84-131) */
.qse-sys{display:flex;justify-content:center;width:100%;padding:0 8px;margin:14px 0}
.qse-sys.entre{animation:qse-carte-entree .6s cubic-bezier(.34,1.35,.64,1) both}
@keyframes qse-carte-entree{from{opacity:0;transform:scale(.9) translateY(20px)}}
.qse-carte{position:relative;width:100%;max-width:24rem}
.qse-carte::before{content:'';position:absolute;inset:-4px;border-radius:24px;filter:blur(6px);opacity:.1;background:linear-gradient(to right,#60a5fa,#6366f1,#9333ea);transition:opacity 1s ease}
.qse-carte.est-cause::before{background:linear-gradient(to right,#fbbf24,#f97316,#dc2626)}
.qse-carte:hover::before{opacity:.25}
.qse-carte-corps{
  position:relative;display:flex;flex-direction:column;gap:14px;padding:22px;border-radius:28px;
  background:rgba(255,255,255,.9);backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px);border:1px solid #f1f5f9;
  box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);
}
.qse-carte-haut{display:flex;align-items:center;gap:14px}
.qse-carte-icone{width:48px;height:48px;border-radius:16px;background:#2563eb;color:#fff;display:grid;place-items:center;flex:none;box-shadow:0 10px 15px -3px rgba(0,0,0,.1)}
.qse-carte.est-cause .qse-carte-icone{background:#f59e0b}
.qse-carte-icone svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.qse-carte-cat{margin:0 0 2px;font-size:9px;font-weight:900;text-transform:uppercase;letter-spacing:.2em;color:#2563eb}
.qse-carte.est-cause .qse-carte-cat{color:#d97706}
.qse-carte-titre{margin:0;font-size:16px;font-weight:900;letter-spacing:-.025em;line-height:1.15;color:#0f172a}
.qse-carte-retour{margin:0;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:#94a3b8}
.qse-carte-prog{padding-top:12px;border-top:1px solid #f8fafc}
.qse-carte-ligne{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:8px;font-size:10px;text-transform:uppercase;letter-spacing:.1em}
.qse-carte-ligne span{font-weight:700;color:#94a3b8}
.qse-carte-ligne b{font-weight:900;color:#1e293b}
.qse-carte-barre{height:6px;border-radius:999px;background:#f1f5f9;overflow:hidden}
.qse-carte-barre i{display:block;height:100%;border-radius:999px;background:#2563eb;width:0;transition:width .6s cubic-bezier(.22,1,.36,1)}
.qse-carte.est-cause .qse-carte-barre i{background:#f59e0b}
/* LE MUR (projets/demos.js) : la question se tape dans la capsule (sur la page,
   c'est un vrai champ), le curseur bat, la fin du texte reste en vue ; l'orbe
   d'envoi s'enfonce au départ. Le fil tient dans l'écran de la salle, avec
   la phrase à côté, et les premières bulles se posent au bas du fil, contre
   la capsule, comme une conversation en cours. */
.qse-tape{flex:1;min-width:0;overflow:hidden;white-space:pre;font-weight:500;color:#334155}
.qse-tape::after{content:'';display:inline-block;width:1px;height:1.05em;margin-left:1px;vertical-align:-.15em;background:#334155;animation:qse-curseur 1s steps(1) infinite}
@keyframes qse-curseur{50%{opacity:0}}
.qse-envoi{transition:transform .15s ease,background-color .2s ease}
.qse-envoi.appuie{transform:scale(.86);background:#1d4ed8}
.specimen .qse-liste{height:min(19rem,40vh)}
.specimen .qse-liste > :first-child{margin-top:auto}
/* LA VRILLE (mur, 6 septembre 2026, projets/demos.js) : la fenêtre arrive du
   bord droit de l'écran en tournant sur elle-même. La perspective est sur son
   parent, le point de fuite vers le bord d'où elle vient. */
.specimen .u-qse{perspective:1400px;perspective-origin:90% 40%}
.specimen .qse-fenetre{will-change:transform}
/* à 1280 de large, l'en-tête tient sur une ligne : nom et témoins un peu plus petits */
.specimen .qse-tete-nom{font-size:20px}
.specimen .qse-choix{width:36px;height:36px}
@media (prefers-reduced-motion:reduce){
  .qse-msg.entre,.qse-sys.entre,.qse-frappe i,.qse-avatar,.qse-msg.entre .qse-avatar,.qse-tape::after{animation:none!important}
  .qse-carte-barre i{transition:none}
}


/* ===================================================================
   03 · STUDIO 9 · app/vue.mjs (source unique de la console)
   Clair par défaut, neutres à chroma nul, un vert « en marche », un
   ocre-rouge qui signale. Inter 400/500/600, cv05 + ss01. Blocs bordés
   jamais ombrés, aucun grain, aucune image : la lumière est plate.
   =================================================================== */
html[data-univers="studio9"]{
  --noir:#ffffff;--surface:#f6f6f7;--ligne:#e5e5ea;--blanc:#141416;--gris:#63636b;
  --ambre:#166b41;--ambre-clair:#2f5bd1;
  --alerte:#d0342c; /* le rouge dont la machine peint le double (machine.js le lit, second tour, docs/V8-MACHINE.md) */
  --u-display:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;--u-sans:var(--u-display);
  --u-poids:600;--u-espace:-.02em;
  --u-lumiere:none;--u-grain:none;--u-grain-opacite:0;
}
.u-s9{
  --fond:#ffffff;--fond-2:#f6f6f7;--encre:#141416;--doux:#63636b;--tres-doux:#6e6e78;
  --trait:#e5e5ea;--trait-fort:#cfcfd6;--action:#141416;--sur-action:#ffffff;
  --actif:#166b41;--actif-fond:#e9f3ed;--alerte:#9c3418;--alerte-fond:#fbeee9;
  --r-s:8px;--r-m:12px;--e1:4px;--e2:8px;--e3:12px;--e4:16px;--e5:24px;
  --sortie:cubic-bezier(.22,1,.36,1);
  font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;font-size:.9375rem;line-height:1.55;
  font-feature-settings:"cv05" 1,"ss01" 1;-webkit-font-smoothing:antialiased;color:var(--encre);
}
.s9-page{background:var(--fond);border:1px solid var(--trait);border-radius:var(--r-m);padding:var(--e5) var(--e4) var(--e4)}
/* l'en-tête : marque typographique, pastille d'état, interrupteur (vue.mjs:76-111, 182-200) */
.s9-marque{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--e4)}
.s9-marque .s9-titre{margin:0;font-size:1.0625rem;font-weight:600;letter-spacing:-.011em;line-height:1.3;color:var(--encre)}
.s9-marque p{margin:2px 0 0;font-size:.8125rem;color:var(--doux);line-height:1.3}
.s9-droite{display:flex;flex-direction:column;align-items:flex-end;gap:var(--e3);flex:0 1 auto;min-width:0;margin-left:auto}
.s9-etat{
  display:inline-flex;align-items:center;gap:7px;margin-top:2px;font-size:.8125rem;font-weight:500;
  padding:5px 11px;border-radius:99px;white-space:nowrap;
  color:var(--actif);border:1px solid color-mix(in srgb,var(--actif) 40%,transparent);background:var(--actif-fond);
}
.s9-point{width:7px;height:7px;border-radius:50%;background:var(--actif)}
.s9-inter{display:inline-flex;align-items:center;gap:10px;font-size:.8125rem;color:var(--doux)}
.s9-switch{position:relative;width:38px;height:22px;border-radius:99px;background:var(--actif)}
.s9-switch::after{
  content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:99px;
  background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.28);transform:translateX(16px);
}
/* la pastille des signalements (vue.mjs, .signaler) */
.s9-signaler{
  display:inline-flex;align-items:center;gap:8px;padding:4px 12px 4px 8px;border-radius:99px;
  border:1px solid color-mix(in srgb,var(--alerte) 45%,transparent);background:var(--alerte-fond);
  color:var(--alerte);font-size:.8125rem;font-weight:500;white-space:nowrap;
}
.s9-signaler .s9-n{
  display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 6px;border-radius:99px;
  background:var(--alerte);color:var(--fond);font-weight:600;font-size:.75rem;font-variant-numeric:tabular-nums;
}
.s9-pastilles{display:flex;align-items:center;gap:var(--e2);flex-wrap:wrap;justify-content:flex-end}
/* sur le mur (projets/demos.js), le compte de la pastille saute quand un signalement arrive */
.s9-signaler.saute .s9-n{animation:s9-saute .45s cubic-bezier(.34,1.56,.64,1)}
@keyframes s9-saute{from{transform:scale(.4)}}
/* les compteurs (vue.mjs, .chiffres) */
.s9-chiffres{display:flex;gap:var(--e5);flex-wrap:wrap;margin-top:var(--e5)}
.s9-chiffre b{display:block;font-size:1.375rem;font-weight:600;letter-spacing:-.02em;line-height:1.15;font-variant-numeric:tabular-nums;color:var(--encre)}
.s9-chiffre span{font-size:.8125rem;color:var(--doux)}
.s9-chiffre.s9-vert b{color:var(--actif)}
.s9-onglets{display:flex;border-bottom:1px solid var(--trait);margin-top:var(--e5);overflow:hidden}
.s9-onglets span{border-bottom:2px solid transparent;margin-bottom:-1px;padding:9px 0;margin-right:var(--e5);font-size:.9375rem;color:var(--doux);white-space:nowrap}
.s9-onglets span[aria-current]{color:var(--encre);border-color:var(--encre);font-weight:500}
/* la carte de signalement (vue.mjs:1044-1059, 225-231) : le message que le studio reçoit */
.s9-signal{border:1px solid var(--trait);border-radius:var(--r-m);padding:var(--e4);background:var(--fond);margin-top:var(--e4)}
.s9-haut{display:flex;align-items:baseline;justify-content:space-between;gap:var(--e3)}
.s9-signal b{font-size:1rem;font-weight:600;letter-spacing:-.008em}
.s9-signal time{font-size:.8125rem;color:var(--tres-doux);white-space:nowrap}
.s9-ou{font-size:.8125rem;color:var(--doux);margin-top:2px}
.s9-signal p{margin:var(--e1) 0 0;font-size:.875rem;line-height:1.5;color:var(--encre)}
.s9-actions{display:flex;gap:var(--e2);margin-top:var(--e3);flex-wrap:wrap}
.s9-bouton{
  display:inline-flex;align-items:center;padding:6px 12px;border-radius:var(--r-s);
  background:var(--action);color:var(--sur-action);font-size:.8125rem;font-weight:500;border:1px solid var(--action);
}
.s9-creux{background:transparent;color:var(--encre);border-color:var(--trait-fort)}
/* LE RÉCIT DU REGISTRE (mur, 6 septembre 2026, projets/demos.js) : le seul
   cas que le registre cherche à voir, joué. Un groupe (l'anneau et ses
   membres, comme dans le schéma de la page), une personne qui y entre, en
   sort, y revient, et le journal qui l'écrit ligne à ligne, puis l'alerte.
   Plat, bordé, jamais ombré : la lumière de l'outil. */
.s9-recit .s9-chiffres{margin-top:var(--e4)}
.s9-recit .s9-chiffre b{font-size:1.25rem}
.s9-scene{position:relative;display:flex;align-items:center;gap:var(--e4);margin-top:var(--e5);padding:var(--e4) 0 var(--e3);border-top:1px solid var(--trait)}
.s9-anneau{position:relative;width:76px;height:76px;border-radius:50%;border:2px solid var(--trait-fort);flex:none}
.s9-anneau i{position:absolute;width:11px;height:11px;border-radius:50%;background:var(--trait-fort)}
.s9-anneau i:nth-child(1){left:31px;top:11px}
.s9-anneau i:nth-child(2){left:15px;top:28px}
.s9-anneau i:nth-child(3){left:47px;top:28px}
.s9-anneau i:nth-child(4){left:22px;top:48px}
.s9-anneau i:nth-child(5){left:41px;top:48px}
/* la place de Lea dans le groupe : pleine quand elle y est */
.s9-anneau .s9-place{left:31px;top:31px;background:var(--encre);opacity:0;transform:scale(.4)}
.s9-groupe{min-width:0;padding-right:5.5rem}
.s9-groupe-nom{margin:0;font-size:.9375rem;font-weight:500;letter-spacing:-.008em}
.s9-note{margin:4px 0 0;font-size:.78rem;line-height:1.45;color:var(--tres-doux)}
.s9-personne{
  position:absolute;right:0;top:50%;transform:translateY(-50%);padding:5px 12px;border-radius:99px;
  border:1px solid var(--trait-fort);background:var(--fond);font-size:.8125rem;font-weight:500;white-space:nowrap;
}
.s9-journal{list-style:none;margin:var(--e2) 0 0;padding:0;font-size:.8125rem;font-variant-numeric:tabular-nums}
.s9-journal li{display:flex;gap:var(--e3);padding:7px 0;border-top:1px solid var(--trait)}
.s9-journal time{flex:none;width:5.6rem;color:var(--doux)}
.s9-journal span{color:var(--encre)}
.s9-journal .s9-alerte span{color:var(--alerte);font-weight:500}
.s9-recit .s9-signal{margin-top:var(--e3)}


/* ===================================================================
   04 · STEP UP FACTORY · bilan.stepupfactory.fr, src/index.css, tokens.ts
   Sombre : ardoise bleue 161C28, cartes 252D3D, pastilles 1E2535. Lime
   c1ff72 en action, tri-dégradé pêche > magenta > lime toujours en
   « to top right ». SF Pro Display 400 à -0.025em (.title-ios). Aucun
   grain dans l'app de réservation.
   =================================================================== */
html[data-univers="stepup"]{
  --noir:#161C28;--surface:#252D3D;--ligne:color-mix(in srgb,#ffffff 10%,#161C28);--blanc:#f2f2f2;
  --gris:color-mix(in srgb,#f2f2f2 60%,#161C28);--ambre:#c1ff72;--ambre-clair:#d8ff9f;
  --u-display:"SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --u-sans:var(--u-display);--u-poids:400;--u-espace:-.025em;
  --u-lumiere:radial-gradient(38% 40% at 84% 12%,rgba(255,189,89,.10),transparent 65%),radial-gradient(36% 38% at 14% 88%,rgba(193,255,114,.08),transparent 65%),radial-gradient(30% 30% at 50% 50%,rgba(255,155,217,.05),transparent 65%);
  --u-grain:none;--u-grain-opacite:0;
}
.u-su{
  --su-bg:#161C28;--su-card:#252D3D;--su-chip:#1E2535;--su-lime:#c1ff72;--su-peach:#ffbd59;--su-magenta:#ff9bd9;--su-text:#f2f2f2;
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  color:#fff;-webkit-font-smoothing:antialiased;position:relative;
}
.su-page{background:var(--su-bg);border-radius:20px;padding:18px 16px 16px;box-shadow:0 24px 60px -20px rgba(0,0,0,.65);border:1px solid rgba(255,255,255,.06)}
/* le hero de la page de réservation : badge d'offre, titre .title-ios, tagline (App.tsx:193-197, 1219-1295) */
.su-badge{
  display:inline-flex;align-items:center;gap:8px;padding:5px 11px;border-radius:9999px;background:var(--su-chip);
  font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;box-shadow:0 10px 15px -3px rgba(0,0,0,.3);
}
.su-badge s{font-weight:500;color:rgba(242,242,242,.6)}
.su-titre{margin:12px 0 0;font-size:26px;font-weight:400;letter-spacing:-.025em;line-height:1.1}
.su-titre b{font-weight:400;color:var(--su-lime)}
.su-tag{margin:6px 0 0;font-size:13px;color:rgba(242,242,242,.6)}
.su-label{margin:18px 0 8px;font-size:12px;text-transform:uppercase;letter-spacing:.14em;color:rgba(242,242,242,.5)}
/* le sélecteur de jour (DaySelector.tsx:50-77) */
.su-jours{display:flex;gap:12px;overflow:hidden}
.su-jour{
  flex:none;min-width:104px;padding:8px 12px;min-height:48px;border-radius:9999px;
  border:1px solid rgba(255,255,255,.1);background:var(--su-chip);color:rgba(242,242,242,.8);
  font-size:12px;white-space:nowrap;display:flex;flex-direction:column;justify-content:center;
}
.su-jour b{font-weight:600}
.su-jour small{font-size:10px;color:rgba(242,242,242,.6)}
.su-jour.est-actif{border-color:transparent;color:#000;background:linear-gradient(to top right,var(--su-lime),var(--su-peach),var(--su-magenta))}
.su-jour.est-actif small{color:rgba(0,0,0,.6)}
/* la grille de créneaux (SlotGrid.tsx:89-161) */
.su-grille{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.su-creneau{
  position:relative;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;
  min-height:74px;padding:12px;border-radius:1rem;border:1px solid var(--su-chip);background:rgba(30,37,53,.8);
  box-shadow:0 1px 2px rgba(0,0,0,.3);font-size:14px;
}
.su-creneau b{font-weight:500;color:#fff}
.su-creneau small{font-size:11px;color:rgba(242,242,242,.6)}
.su-creneau.est-choisi{border-color:var(--su-lime);background:var(--su-chip)}
.su-coche{position:absolute;top:8px;right:8px;width:16px;height:16px;border-radius:50%;background:var(--su-lime)}
.su-coche::after{content:"";position:absolute;left:5px;top:2.5px;width:4px;height:7px;border:solid #000;border-width:0 2px 2px 0;transform:rotate(45deg)}


/* LE PARCOURS DE RÉSERVATION, à ses durées (DaySelector.tsx, SlotGrid.tsx,
   SuccessTicket.tsx, TicketCountdown.tsx), partagé depuis le 5 septembre 2026
   par la page (où l'on touche) et le mur (où la démo touche, projets/demos.js) :
   le swap de grille 0,18 s, l'entrée des créneaux 0,2 s décalée de 0,04 s, la
   coche qui se pose, puis l'écran de succès et ses ressorts. */
.su-page{position:relative;overflow:hidden}
.su-page p{max-width:none}
.su-grille{transition:opacity .18s cubic-bezier(.25,.46,.45,.94)}
.su-grille.se-renouvelle .su-creneau{animation:su-entre .2s cubic-bezier(.25,.46,.45,.94) both}
.su-grille.se-renouvelle .su-creneau:nth-child(2){animation-delay:.04s}
.su-grille.se-renouvelle .su-creneau:nth-child(3){animation-delay:.08s}
.su-grille.se-renouvelle .su-creneau:nth-child(4){animation-delay:.12s}
@keyframes su-entre{from{opacity:0;transform:translateY(10px)}}
.su-coche.se-pose{animation:su-coche .2s cubic-bezier(.34,1.56,.64,1) both}
@keyframes su-coche{from{transform:scale(0)}}
html.js .su-succes{display:none}
.su-page.est-reserve .su-choix{display:none}
.su-page.est-reserve .su-succes{display:block}
html:not(.js) .su-succes{margin-top:22px;padding-top:18px;border-top:1px dashed rgba(255,255,255,.12)}
/* l'écran de succès (SuccessTicket.tsx:148-374, TicketCountdown.tsx) */
.su-succes{position:relative;text-align:center;padding-top:4px}
.su-halo{position:absolute;top:-70px;left:50%;width:220px;height:220px;margin-left:-110px;border-radius:50%;opacity:.1;filter:blur(48px);background:linear-gradient(to top right,var(--su-peach),var(--su-magenta),var(--su-lime));pointer-events:none;animation:su-halo 60s linear infinite}
@keyframes su-halo{to{transform:rotate(360deg)}}
.su-avatar{position:relative;display:inline-block;width:64px;height:64px;border-radius:50%;padding:2px;background:linear-gradient(to top right,var(--su-peach),var(--su-magenta),var(--su-lime));box-shadow:0 10px 15px -3px rgba(0,0,0,.4)}
.su-avatar-int{display:block;width:100%;height:100%;border-radius:50%;background:var(--su-bg);padding:2px}
.su-avatar-init{display:grid;place-items:center;width:100%;height:100%;border-radius:50%;background:var(--su-chip);font-size:16px;font-weight:600;color:#fff}
/* le portrait du coach remplace l'initiale, comme sur sa page publique */
.su-avatar-photo{display:block;width:100%;height:100%;border-radius:50%;object-fit:cover}
.su-avatar-coche{position:absolute;right:-4px;bottom:-4px;width:24px;height:24px;border-radius:50%;background:var(--su-lime);border:2px solid #121212;display:grid;place-items:center;box-shadow:0 4px 6px -1px rgba(0,0,0,.4)}
.su-avatar-coche svg{width:12px;height:12px;fill:none;stroke:#000;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.su-succes-titre{margin:10px 0 0;font-size:22px;font-weight:400;letter-spacing:-.025em;line-height:1.1;color:#fff;outline:none}
.su-succes-titre b{font-weight:400;color:var(--su-lime)}
.su-succes-sous{margin:4px auto 0;max-width:280px;font-size:12.5px;font-weight:500;line-height:1.5;color:rgba(242,242,242,.65)}
/* nowrap et overflow : quand le mot change (le mur), la pastille glisse d'une
   largeur à l'autre sans que le texte passe à la ligne, la page ne bouge pas */
.su-compte{display:inline-flex;align-items:center;gap:6px;margin:8px 0 0;padding:4px 10px;border-radius:9999px;border:1px solid rgba(193,255,114,.4);background:rgba(193,255,114,.1);color:var(--su-lime);font-size:11px;font-weight:500;white-space:nowrap;overflow:hidden;transition:border-color .35s ease,background-color .35s ease,color .35s ease}
.su-compte svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.su-compte.est-peche{border-color:rgba(255,189,89,.5);background:rgba(255,189,89,.1);color:var(--su-peach)}
.su-compte.est-magenta{border-color:rgba(255,155,217,.5);background:rgba(255,155,217,.1);color:var(--su-magenta)}
.su-billet{position:relative;display:flex;margin:16px 0 0;border-radius:20px;overflow:hidden;background:var(--su-card);box-shadow:0 24px 60px -20px rgba(0,0,0,.65);text-align:left}
.su-billet::before{content:"";position:absolute;inset:0;border-radius:20px;padding:1px;pointer-events:none;background:linear-gradient(140deg,rgba(255,189,89,.4),rgba(255,155,217,.2) 35%,rgba(193,255,114,.3) 70%,rgba(255,255,255,.04));-webkit-mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);-webkit-mask-composite:xor;mask-composite:exclude}
.su-billet-corps{flex:1;min-width:0}
.su-billet-tete{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:14px 16px 8px;border-bottom:1px solid rgba(255,255,255,.05);font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.2em;color:rgba(255,255,255,.55)}
.su-billet-tete span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.su-pers{flex:none;border:1px solid rgba(255,255,255,.15);border-radius:9999px;padding:2px 8px;letter-spacing:.18em;font-weight:400;color:rgba(255,255,255,.7)}
.su-billet-milieu{display:flex;align-items:flex-start;gap:14px;padding:14px 16px}
.su-qr{position:relative;flex:none;overflow:hidden;border-radius:12px;border:1px solid rgba(255,255,255,.15);background:#fff;padding:6px;box-shadow:0 6px 18px rgba(0,0,0,.4)}
.su-qr svg{display:block;width:94px;height:94px;fill:#0F1117}
.su-scan{position:absolute;left:6px;right:6px;top:6px;height:2px;border-radius:2px;opacity:0;background:linear-gradient(to right,transparent,var(--su-lime),transparent);box-shadow:0 0 10px 2px rgba(193,255,114,.7)}
/* la ligne de scan passe à l'arrivée au club, quand le script le dit (balaie),
   pas une seconde après le billet : c'est la fin de l'histoire, pas un ornement */
.su-scan.balaie{animation:su-scan 1.3s ease-in-out both}
@keyframes su-scan{0%{transform:translateY(-100px);opacity:0}50%{opacity:.85}100%{transform:translateY(100px);opacity:0}}
.su-billet-infos{flex:1;min-width:0}
.su-billet-jour{margin:0;font-size:10px;text-transform:uppercase;letter-spacing:.2em;color:rgba(255,255,255,.45)}
.su-billet-date{display:flex;align-items:baseline;gap:6px;margin:2px 0 0}
.su-billet-date b{font-size:2rem;line-height:1;letter-spacing:-.04em;font-weight:400;color:#fff}
.su-billet-date span{font-size:16px;letter-spacing:-.025em;color:rgba(255,255,255,.85)}
.su-billet-heure{margin:2px 0 0;font-size:13px;font-weight:600;color:var(--su-lime);font-variant-numeric:tabular-nums}
.su-billet-coach{display:flex;align-items:center;gap:6px;margin:8px 0 0;font-size:12px;font-weight:600;color:#fff}
.su-mini-avatar{display:block;width:20px;height:20px;border-radius:50%;border:1px solid rgba(255,255,255,.15);object-fit:cover;background:var(--su-chip)}
.su-billet-code{display:flex;justify-content:center;align-items:center;gap:8px;margin:0;padding:0 16px 8px;font-size:9px;text-transform:uppercase;letter-spacing:.22em;color:rgba(255,255,255,.45)}
.su-billet-code code{font-family:"SFMono-Regular",Menlo,Consolas,"Roboto Mono",monospace;font-size:15px;letter-spacing:.32em;color:#fff;text-transform:none}
.su-perfo{position:relative;height:16px}
.su-perfo::before,.su-perfo::after{content:"";position:absolute;top:50%;width:16px;height:16px;border-radius:50%;background:var(--su-bg);transform:translateY(-50%)}
.su-perfo::before{left:-8px}
.su-perfo::after{right:0}
.su-perfo i{position:absolute;left:16px;right:16px;top:50%;border-top:1px dashed rgba(255,255,255,.15)}
.su-lieu{margin:0;padding:4px 16px 14px;font-size:12px;line-height:1.4}
.su-lieu-et{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.18em;color:rgba(255,255,255,.45)}
.su-lieu b{display:block;font-weight:600;color:#fff}
.su-lieu span:last-child{display:block;color:rgba(242,242,242,.6)}
.su-bande{position:relative;flex:none;width:28px;background:linear-gradient(to bottom,var(--su-peach),var(--su-magenta),var(--su-lime))}
.su-bande span{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;writing-mode:vertical-rl;transform:rotate(180deg);padding:12px 8px;font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.32em;white-space:nowrap;color:rgba(0,0,0,.75)}
/* les ressorts du produit, approchés en CSS : avatar 200/18, pastille 280/18 à .3 s, trait .3 s à .45 s, billet 220/24 à .55 s, compte à rebours .65 s, lien .9 s */
.est-reserve .su-avatar{animation:su-pop .55s cubic-bezier(.34,1.56,.64,1) both}
@keyframes su-pop{from{transform:scale(.4);opacity:0}}
.est-reserve .su-avatar-coche{animation:su-pop2 .5s cubic-bezier(.34,1.56,.64,1) .3s both}
@keyframes su-pop2{from{transform:scale(0);opacity:0}}
.est-reserve .su-avatar-coche path{stroke-dasharray:14;stroke-dashoffset:14;animation:su-trace .3s ease-out .45s forwards}
@keyframes su-trace{to{stroke-dashoffset:0}}
.est-reserve .su-billet{animation:su-billet .6s cubic-bezier(.22,1.18,.36,1) .55s both}
@keyframes su-billet{from{opacity:0;transform:translateY(14px) scale(.97)}}
.est-reserve .su-compte{animation:su-monte .4s ease .65s both}
.est-reserve .su-autre{animation:su-monte .4s ease .9s both}
@keyframes su-monte{from{opacity:0;transform:translateY(4px)}}
.su-confetti{position:absolute;inset:0;z-index:5;pointer-events:none}
/* LE TIROIR DE CONFIRMATION (ConfirmationDrawer.tsx) : monte du bas de la page
   sur un voile noir à 50 %, l'anse, le titre en capitales, la date et l'heure
   choisies, deux champs, la note, le bouton lime qui dit « Envoi... » le temps
   de l'envoi. Le script le mène (projets/demos.js) ; sans lui, rangé sous la
   page, invisible. */
.su-voile{position:absolute;inset:0;z-index:3;background:rgba(0,0,0,.5);opacity:0;pointer-events:none}
.su-tiroir{position:absolute;left:0;right:0;bottom:0;z-index:4;padding:0 16px 20px;border-radius:24px 24px 0 0;background:var(--su-card);border-top:1px solid rgba(255,255,255,.1);box-shadow:0 -24px 60px rgba(0,0,0,.6);transform:translateY(105%)}
.su-tiroir-anse{display:block;width:40px;height:4px;margin:8px auto 12px;border-radius:9999px;background:rgba(255,255,255,.2)}
.su-tiroir-titre{margin:0;font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:rgba(242,242,242,.5)}
.su-tiroir-date{margin:4px 0 0;font-size:14px;font-weight:600;color:#fff}
.su-tiroir-sous{margin:4px 0 0;font-size:11px;color:rgba(242,242,242,.7)}
.su-champ{margin:14px 0 0}
.su-champ span{display:block;margin-bottom:6px;font-size:12px;color:rgba(242,242,242,.8)}
.su-champ b{display:block;min-height:42px;padding:10px 12px;border-radius:1rem;border:1px solid rgba(255,255,255,.1);background:var(--su-bg);font-size:15px;font-weight:400;line-height:1.4;color:#fff;transition:box-shadow .15s ease,border-color .15s ease}
.su-champ b:empty::before{content:attr(data-vide);color:rgba(242,242,242,.35)}
.su-champ.est-actif b{border-color:transparent;box-shadow:0 0 0 2px var(--su-lime)}
.su-champ.est-actif b::after{content:"";display:inline-block;width:1.5px;height:1em;margin-left:1px;vertical-align:-2px;background:#fff;animation:su-caret 1s steps(2) infinite}
@keyframes su-caret{to{opacity:0}}
.su-tiroir-info{display:flex;gap:6px;align-items:flex-start;margin:12px 0 0;font-size:11px;line-height:1.5;color:rgba(242,242,242,.6)}
.su-tiroir-info svg{flex:none;width:14px;height:14px;margin-top:1px;fill:none;stroke:rgba(242,242,242,.4);stroke-width:2;stroke-linecap:round}
.su-confirmer{display:block;margin:16px 0 0;padding:12px 16px;border-radius:9999px;background:var(--su-lime);color:#000;font-size:13px;font-weight:600;text-align:center;box-shadow:0 4px 6px -1px rgba(0,0,0,.4);transition:opacity .2s ease}
.su-confirmer.est-envoi{opacity:.6}
/* LA MAIN (mur, 6 septembre 2026, projets/demos.js) : une main blanche au trait
   sombre, ombre portée ; le bout de l'index est son origine (36 % / 6 %), c'est
   lui qui s'enfonce. Elle vit dans .u-su, pas dans la page : la page coupe ce
   qui la déborde, et la main se pose au bord, à moitié dehors, sans jamais
   disparaître. Le rond de tape, lime, s'élargit sous le doigt. Le SVG respire
   pour lui (le script le berce). Invisibles sans le script. */
.su-doigt{position:absolute;left:0;top:0;z-index:6;width:38px;height:38px;opacity:0;pointer-events:none;transform-origin:36% 6%;filter:drop-shadow(0 6px 10px rgba(0,0,0,.5))}
.su-doigt svg{display:block;width:100%;height:100%;fill:#fff;stroke:#111;stroke-width:1.1;stroke-linejoin:round;transform-origin:36% 6%}
.su-tap{position:absolute;left:0;top:0;z-index:5;width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;border:2px solid var(--su-lime);opacity:0;pointer-events:none}
@media (prefers-reduced-motion:reduce){.su-page *,.su-page *::before,.su-page *::after{animation-delay:0s!important}}


/* ===================================================================
   05 · TOUL'BARZ · toulbarz-platform, design-system/tokens, WorkShell
   Monochrome strict : noir 080808, surface 111111, filet 1E1E1E, argent
   C4C4C4 pour le seuil, encre 14141A posée sur l'argent. Fraunces pour
   les titres, Archivo pour l'interface, aucun radius sur les primitives,
   aucune ombre, grain 0.82 en overlay à 7 %, halo qui respire en haut.
   =================================================================== */
html[data-univers="toulbarz"]{
  --noir:#080808;--surface:#111111;--ligne:#1E1E1E;--blanc:#FFFFFF;--gris:#7d7d7d;
  --ambre:#C4C4C4;--ambre-clair:#FFFFFF;
  --u-display:"Fraunces Variable",Fraunces,Georgia,serif;--u-sans:"Archivo Variable",Archivo,system-ui,sans-serif;
  --u-poids:400;--u-espace:-.03em;
  --u-lumiere:radial-gradient(115% 75% at 50% -8%,rgba(255,255,255,.16) 0%,rgba(255,255,255,.06) 22%,rgba(255,255,255,0) 52%),radial-gradient(circle at 50% 32%,transparent 0%,rgba(5,5,5,.66) 58%);
  --u-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch' seed='7'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
  --u-grain-taille:240px 240px;--u-grain-mode:overlay;--u-grain-opacite:.07;
}
.u-tb{
  --bg:#080808;--surface:#111111;--elevated:#181818;--border:#1E1E1E;--muted:#4A4A4A;--danger:#E55353;
  --w-canvas:#0a0a0c;--w-panel:#121216;--w-line:#26262d;--w-ink:#ededf0;
  font-family:"Archivo Variable",Archivo,system-ui,sans-serif;color:#fff;-webkit-font-smoothing:antialiased;
}
/* la coque de travail et son flare de titre (WorkShell.vue, PageHeader.vue:24-32) */
.tb-canvas{position:relative;background:var(--w-canvas);border:1px solid var(--w-line);border-radius:12px;padding:24px 22px 22px;overflow:hidden}
.tb-canvas::before{content:"";position:absolute;inset:0;background:radial-gradient(58% 80% at 22% 42%,rgba(255,255,255,.08),rgba(255,255,255,0) 70%);pointer-events:none}
.tb-canvas::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.28),rgba(255,255,255,0));
}
.tb-tete{position:relative}
.tb-tete p{margin:5px 0 0;font-size:.875rem;color:rgba(255,255,255,.55)}
.tb-tete .tb-titre{margin:0;font-family:"Fraunces Variable",Fraunces,Georgia,serif;font-weight:400;font-size:1.9rem;letter-spacing:-.025em;line-height:1.1;color:#fff}
/* le cycle de vie d'un événement en cinq états (StatusStepper.vue, ADR 0020) */
.tb-stepper{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:8px 0;margin-top:24px}
.tb-stepper i{width:16px;height:1px;margin:0 4px;background:rgba(255,255,255,.2)}
.tb-etape{
  border:1px solid rgba(255,255,255,.2);padding:6px 12px;font-size:11px;text-transform:uppercase;
  letter-spacing:.25em;color:rgba(255,255,255,.45);white-space:nowrap;
}
.tb-etape.est-passee{border-color:rgba(255,255,255,.4);color:rgba(255,255,255,.7)}
.tb-etape.est-courante{border-color:#fff;background:#fff;color:#000}
.tb-annuler{margin-left:8px;padding:6px 12px;font-size:12px;text-transform:uppercase;letter-spacing:.05em;color:rgba(255,255,255,.45);white-space:nowrap}
/* une ligne de la liste, à filet, sans radius */
.tb-ligne{position:relative;display:flex;align-items:center;gap:12px;margin-top:20px;padding-top:14px;border-top:1px solid var(--w-line);font-size:.875rem}
.tb-badge{display:inline-flex;align-items:center;padding:2px 8px;font-size:10px;text-transform:uppercase;letter-spacing:.25em;border:1px solid #7DDE92;color:#7DDE92}
.tb-nom{color:rgba(255,255,255,.85);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.tb-copier{margin-left:auto;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:rgba(255,255,255,.66);border-bottom:1px solid rgba(255,255,255,.3)}


/* LA PIEUVRE (mur et page, 5 et 6 septembre 2026, projets/demos.js) : blanc
   sur noir, Archivo pour les noms, JetBrains Mono pour ce qui vient de se
   passer. Les bras à 22 % de blanc, l'impulsion pleine avec sa lueur, le nœud
   atteint s'inverse (disque blanc, trait noir). L'anneau pointillé du centre
   est l'assistant, il tourne. Rien de tout cela n'a de cadre.
   Le décalage du tiret de l'impulsion (stroke-dashoffset) est posé par le
   script en style inline, jamais ici : une règle de feuille l'emporterait sur
   l'attribut animé, et les bras ne s'allumaient pas (constaté le 6 septembre
   2026). Le bras lui-même s'éclaire au passage (stroke, tween du script). */
.tb-pieuvre{display:block;width:100%;height:auto;overflow:visible;color:#fff}
.tb-fil{fill:none;stroke:rgba(255,255,255,.22);stroke-width:1.2}
.tb-pouls{fill:none;stroke:#fff;stroke-width:2.6;stroke-linecap:round;stroke-dasharray:16 84;opacity:0;filter:drop-shadow(0 0 3px #fff) drop-shadow(0 0 9px rgba(255,255,255,.8))}
.tb-disque{fill:#080808;stroke:rgba(255,255,255,.55);stroke-width:1.2;transition:fill .35s ease,stroke .35s ease}
.tb-hub-disque{stroke:#fff}
.tb-icone{fill:none;stroke:rgba(255,255,255,.82);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;transition:stroke .35s ease}
.tb-halo{fill:none;stroke:#fff;stroke-width:1.5;opacity:0}
.tb-anneau{fill:none;stroke:rgba(255,255,255,.35);stroke-width:1;stroke-dasharray:3 6}
.tb-nom{font-family:"Archivo Variable",Archivo,system-ui,sans-serif;font-size:12px;letter-spacing:.22em;text-transform:uppercase;fill:rgba(255,255,255,.55);text-anchor:middle;transition:fill .35s ease}
.tb-note{font-family:"JetBrains Mono Variable","JetBrains Mono",ui-monospace,monospace;font-size:12px;fill:#fff;text-anchor:middle;opacity:0}
.tb-noeud.est-allume .tb-disque{fill:#fff;stroke:#fff}
.tb-noeud.est-allume .tb-icone{stroke:#000}
.tb-noeud.est-allume .tb-nom{fill:#fff}
.tb-hub.est-eveille .tb-anneau{stroke:rgba(255,255,255,.7)}
.tb-hub.est-eveille .tb-nom{fill:#fff}


/* ===================================================================
   06 · L'ABEILLE ANGLOYE QUI RIT · portail.module.css, globals.css
   Crème fbf8f2, cire f3ecdd, miel d9a441 en remplissage et miel foncé
   8f6210 en texte (AA), encre chaude 2a211b, vert prairie sur les
   eyebrows. Arverna (police maison, capitales) sur le seul h1, Fraunces
   partout ailleurs, Schibsted Grotesk en corps. Grain 0.86 multiply à
   4 %, la « goutte de lumière » pollen en halo.
   =================================================================== */
html[data-univers="abeille"]{
  --noir:#fbf8f2;--surface:#f3ecdd;--ligne:#dcd2be;--blanc:#2a211b;--gris:#6e655a;
  --ambre:#8f6210;--ambre-clair:#2a211b;
  --u-display:"Fraunces Variable",Fraunces,Georgia,serif;--u-sans:"Schibsted Grotesk",system-ui,sans-serif;
  --u-poids:540;--u-espace:-.015em;
  --u-lumiere:radial-gradient(50% 60% at 72% 30%,rgba(232,198,107,.38) 0%,transparent 60%);
  --u-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  --u-grain-taille:160px 160px;--u-grain-mode:multiply;--u-grain-opacite:.04;
}
/* La machine de l'Abeille, sur sa toile seulement (second tour, docs/V8-MACHINE.md) :
   l'accent est l'or du site et son clair l'or clair, pas l'ocre et l'encre de la
   page, pour que les alvéoles s'allument comme au contre-jour du hero. */
html[data-univers="abeille"] .machine-toile{--ambre:#d9a441;--ambre-clair:#e8c66b}
.u-ab{
  --fond:#fbf8f2;--cire:#f3ecdd;--action:#d9a441;--action-fonce:#8f6210;--halo:#e8c66b;
  --encre:#2a211b;--encre-pale:#cbb38a;--sepia:#6e655a;--filet:#dcd2be;--prairie:#2f4a3c;
  font-family:"Schibsted Grotesk",system-ui,sans-serif;color:var(--encre);letter-spacing:-.006em;
}
/* la scène du hero : ambre profond ad7d41, scrim de lisibilité à gauche (portail.module.css:97, 205-224) */
.ab-scene{position:relative;overflow:hidden;border-radius:16px;background:#ad7d41;min-height:26rem;padding:1.1rem 1.1rem 1rem}
.ab-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(102deg,rgba(251,248,242,.86) 0%,rgba(251,248,242,.52) 26%,rgba(251,248,242,.12) 46%,transparent 62%),linear-gradient(to top,rgba(42,33,27,.18) 0%,transparent 22%);
}
.ab-marque{position:relative;margin:0;font-family:"Fraunces Variable",Fraunces,Georgia,serif;font-size:.98rem;font-weight:480;color:var(--encre)}
.ab-marque em{font-style:italic;font-weight:460}
/* le h1, en Arverna : capitales seules, fer forgé (portail.module.css:496-509) */
.ab-h1{
  position:relative;margin:.9rem 0 0;font-family:'Arverna',"Fraunces Variable",Georgia,serif;
  text-transform:uppercase;font-size:1.95rem;line-height:.98;letter-spacing:0;color:var(--encre);max-width:9ch;
}
/* le jeton de cire (portail.module.css:2238-2314) */
.ab-act{
  position:relative;display:inline-flex;align-items:center;gap:.5em;margin-top:.95rem;
  padding:.62em 1.05em;min-height:44px;font-weight:600;font-size:.95rem;color:var(--encre);
  border:1.5px solid var(--action);border-radius:5px;background:var(--action);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 4px 10px -4px rgba(140,98,16,.4);
}
.ab-act svg{display:block;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linejoin:round}
.ab-act i{font-style:normal;font-family:"JetBrains Mono Variable","JetBrains Mono",monospace;font-size:.9em}
/* les fiches-planche en verre teinté miel (portail.module.css:661-752) */
.ab-fiches{position:absolute;right:1rem;bottom:1rem;display:flex;align-items:flex-end;gap:.55rem}
.ab-fiche{
  display:flex;flex-direction:column;justify-content:flex-end;gap:.22rem;
  width:clamp(5.6rem,27%,7.6rem);height:9.4rem;padding:.8rem .7rem;border-radius:16px;color:var(--encre);
  background:linear-gradient(158deg,color-mix(in oklab,var(--halo) 30%,transparent),color-mix(in oklab,var(--cire) 68%,transparent));
  backdrop-filter:blur(11px) saturate(1.18);-webkit-backdrop-filter:blur(11px) saturate(1.18);
  border:1px solid color-mix(in oklab,var(--action) 32%,var(--filet));
  box-shadow:0 16px 42px -20px rgba(42,33,27,.55),inset 0 1px 0 rgba(255,252,245,.4);
}
/* l'abeille au fil : WebP animé à fond transparent, repris du hero du site.
   Elle était servie deux fois trop grande pour sa définition (400 px de source
   affichés sur 64 % de la scène) : 32 % la met à sa résolution native. */
.ab-num{font-family:"Fraunces Variable",Georgia,serif;font-size:.82rem;letter-spacing:.16em;color:var(--action-fonce);font-weight:600}
.ab-titre{font-family:"Fraunces Variable",Georgia,serif;font-size:.98rem;font-weight:540;line-height:1.05}
.ab-sous{font-size:.66rem;line-height:1.32;color:color-mix(in oklab,var(--sepia) 72%,var(--encre))}


/* ===================================================================
   07 · VOCAL FLOW · frontend/src/index.css, pages/landing2.css
   Thème « Atelier » : papier faf6f1, encre 292018, terracotta c2785c
   (texte a8623f), teal 1f8a94, panneau espresso 2b2119, beurre e3b761.
   Plus Jakarta Sans en corps, Fraunces 560 en titres, Caveat pour
   l'annotation. Grain 0.8 multiply, tampons inclinés, letterpress.
   =================================================================== */
html[data-univers="vocalflow"]{
  --noir:#faf6f1;--surface:#fdfbf8;--ligne:#d6ccc2;--blanc:#292018;--gris:#6b5d4f;
  --ambre:#a8623f;--ambre-clair:#7e4227;
  --u-display:"Fraunces Variable",Fraunces,Georgia,serif;--u-sans:"Plus Jakarta Sans",system-ui,-apple-system,sans-serif;
  --u-poids:560;--u-espace:-.015em;
  --u-lumiere:none;
  --u-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.055'/%3E%3C/svg%3E");
  --u-grain-taille:240px 240px;--u-grain-mode:multiply;--u-grain-opacite:1;
}
.u-vf{
  --paper:#faf6f1;--ink:#292018;--ink-2:#6b5d4f;--terra:#c2785c;--terra-deep:#a8623f;--teal:#1f8a94;
  --espresso:#2b2119;--espresso-2:#3a2d22;--cream:#f5eee4;--butter:#e3b761;
  --font-body:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;--font-display:'Fraunces Variable',Georgia,serif;--font-hand:'Caveat',cursive;
  font-family:var(--font-body);color:var(--ink);
}
/* l'annotation manuscrite du hero (landing2.css:119-127) */
.vfl-scribble{margin:0 0 .5rem .4rem;font-family:var(--font-hand);font-size:21px;font-weight:600;color:var(--terra-deep);transform:rotate(-2.5deg);transform-origin:left bottom}
/* la carte « appel du soir » (LandingPage2.jsx:245-297, landing2.css:291-395) */
/* L'APPEL · pas un fil de messages : deux personnes au téléphone. Les deux
   visages se font face, l'onde bat entre eux, et la réplique en cours s'écrit
   dessous, une à la fois, comme un sous-titre en direct. */
.vfl-call{background:var(--espresso);color:var(--cream);border-radius:20px;padding:22px;width:100%;box-shadow:0 30px 60px rgba(41,32,24,.30);position:relative;overflow:hidden}
.vfl-call::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(72% 52% at 50% 0%,rgba(227,183,97,.16),transparent 66%);
}
.vfl-call-head{position:relative;display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-bottom:14px;border-bottom:1px solid rgba(245,238,228,.12)}
.vfl-call-lieu{font-family:var(--font-display);font-size:15px;font-weight:600;letter-spacing:-.01em}
.vfl-call-status{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--butter);white-space:nowrap}
.vfl-dot{width:7px;height:7px;border-radius:50%;background:var(--butter);animation:vfl-pulse 2s ease-in-out infinite}
.vfl-listen{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:800;font-family:var(--font-body);color:var(--espresso);background:var(--butter);border:0;border-radius:10px;padding:10px 14px;box-shadow:0 3px 0 #a8823c;white-space:nowrap;cursor:pointer}

/* les deux visages, et l'onde entre eux */
.vfl-duo{position:relative;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:14px;padding:20px 0 4px}
.vfl-pers{display:flex;flex-direction:column;align-items:center;gap:7px;text-align:center;min-width:0}
.vfl-visage{
  position:relative;width:74px;height:74px;border-radius:50%;overflow:hidden;flex:none;
  box-shadow:0 0 0 1px rgba(245,238,228,.14),0 10px 22px rgba(0,0,0,.34);
  transition:box-shadow .35s ease,transform .35s cubic-bezier(.22,1,.36,1);
}
.vfl-visage svg{display:block;width:100%;height:100%}
.vfl-qui{font-family:var(--font-display);font-size:13.5px;font-weight:600;line-height:1.1}
.vfl-quoi{font-size:11px;color:rgba(245,238,228,.5);line-height:1.2}
/* qui parle : l'anneau s'allume, le visage avance d'un cheveu */
.vfl-call.parle-client .vfl-pers[data-de="client"] .vfl-visage,
.vfl-call.parle-ia .vfl-pers[data-de="ai"] .vfl-visage{
  transform:translateY(-3px) scale(1.04);
  box-shadow:0 0 0 2px var(--butter),0 0 26px rgba(227,183,97,.42),0 12px 26px rgba(0,0,0,.4);
}
.vfl-onde{display:flex;align-items:center;gap:3px;height:44px}
.vfl-onde i{
  display:block;width:3px;height:6px;border-radius:2px;background:rgba(245,238,228,.26);
  transition:height .18s ease,background-color .3s ease;
}
.vfl-call.parle-client .vfl-onde i,.vfl-call.parle-ia .vfl-onde i{
  background:var(--butter);animation:vfl-onde 1.05s ease-in-out infinite;
}
.vfl-onde i:nth-child(2){animation-delay:.09s}.vfl-onde i:nth-child(3){animation-delay:.18s}
.vfl-onde i:nth-child(4){animation-delay:.27s}.vfl-onde i:nth-child(5){animation-delay:.36s}
.vfl-onde i:nth-child(6){animation-delay:.45s}.vfl-onde i:nth-child(7){animation-delay:.54s}
@keyframes vfl-onde{0%,100%{height:7px}50%{height:30px}}

/* la réplique en cours, une seule à l'écran */
.vfl-call-body{position:relative;min-height:104px;padding:16px 2px 4px}
.vfl-bubble{
  position:absolute;left:0;right:0;top:16px;
  font-size:14.5px;line-height:1.55;color:var(--cream);
  opacity:0;transform:translateY(7px);
}
.vfl-bubble-tag{display:block;font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.11em;margin-bottom:5px}
.vfl-bubble-ai .vfl-bubble-tag{color:#8fc7cd}
.vfl-bubble-client .vfl-bubble-tag{color:#ecb99f}
.vfl-call-stamp{
  position:absolute;left:0;bottom:-6px;font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:#a3c292;border:2px solid currentColor;border-radius:5px;padding:7px 11px 6px;transform:rotate(-3.5deg) scale(1.3);opacity:0;
}
/* la chorégraphie du produit, rejouée à chaque fois que la salle entre chez lui
   (.bloc.actif sur la liste, .rejoue sur une page projet) */
.bloc.actif .vf-auto .vfl-bubble,.rejoue .vfl-bubble{animation:vfl-ligne 1.45s ease both;animation-delay:calc(var(--i) * 1.45s + .35s)}
@keyframes vfl-ligne{0%{opacity:0;transform:translateY(7px)}14%{opacity:1;transform:none}86%{opacity:1;transform:none}100%{opacity:0;transform:translateY(-5px)}}
.bloc.actif .vf-auto .vfl-call-stamp,.rejoue .vfl-call-stamp{animation:vfl-stamp-in 360ms cubic-bezier(.2,1.4,.4,1) forwards;animation-delay:7.6s}
/* piloté par l'audio : la réplique en cours seulement */
.vf-pilote .vfl-bubble{animation:none;opacity:0;transform:translateY(7px)}
.vf-pilote .vfl-bubble.is-actif{opacity:1;transform:none;transition:opacity .3s ease,transform .3s ease}
.vf-pilote .vfl-call-stamp{animation:none;opacity:0}
.vf-pilote .vfl-call-stamp.is-in{animation:vfl-stamp-in 360ms cubic-bezier(.2,1.4,.4,1) forwards}
@keyframes vfl-pulse{0%,100%{opacity:1}50%{opacity:.3}}
@keyframes vfl-bubble-in{to{opacity:1;transform:none}}
@keyframes vfl-stamp-in{0%{opacity:0;transform:rotate(-3.5deg) scale(1.5)}100%{opacity:1;transform:rotate(-3.5deg) scale(1)}}
@media (prefers-reduced-motion:reduce){
  .vfl-bubble{opacity:0;animation:none!important}
  .vfl-bubble[style*="--i:0"]{opacity:1;transform:none}
  .vfl-call-stamp{opacity:1;transform:rotate(-3.5deg) scale(1);animation:none!important}
  .vfl-call-stamp{transform:rotate(-3.5deg)}
  .vfl-dot{animation:none}
}
/* LES DEUX SPHÈRES LIBRES (mur, 5 septembre 2026, projets/demos.js) : plus de
   carte d'appel. Nathan et Aria flottent sur le papier de l'atelier, grands,
   l'onde bat entre eux ; la réplique en cours s'écrit sous celle ou celui qui
   parle, en texte libre, encre sur papier, puis s'efface ; à la fin, le tampon
   se pose entre les deux. Les visages, l'onde et le tampon sont ceux de la
   carte, sortis de leur boîte. */
.vfl-libre{position:relative}
.vfl-ciel{position:relative;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:14px;padding:10px 4px 0}
.vfl-libre .vfl-pers{gap:9px}
.vfl-libre .vfl-visage{width:118px;height:118px;box-shadow:0 0 0 1px rgba(41,32,24,.12),0 18px 40px rgba(41,32,24,.22)}
.vfl-libre .vfl-qui{font-size:16px;color:var(--ink)}
.vfl-libre .vfl-quoi{color:var(--ink-2)}
.vfl-libre .vfl-onde{height:56px}
.vfl-libre .vfl-onde i{background:rgba(41,32,24,.22)}
.vfl-libre.parle-client .vfl-onde i,.vfl-libre.parle-ia .vfl-onde i{background:var(--butter);animation:vfl-onde 1.05s ease-in-out infinite}
.vfl-libre.parle-client .vfl-pers[data-de="client"] .vfl-visage,
.vfl-libre.parle-ia .vfl-pers[data-de="ai"] .vfl-visage{
  transform:translateY(-4px) scale(1.05);
  box-shadow:0 0 0 3px var(--butter),0 0 34px rgba(227,183,97,.55),0 20px 44px rgba(41,32,24,.25);
}
.vfl-repliques{position:relative;min-height:112px;margin-top:22px}
.vfl-libre .vfl-bubble{position:absolute;top:0;max-width:27ch;font-size:15.5px;line-height:1.5;color:var(--ink);opacity:0;transform:translateY(8px)}
.vfl-libre .vfl-bubble-client{left:0;right:auto;text-align:left}
.vfl-libre .vfl-bubble-ai{left:auto;right:0;text-align:right}
.vfl-libre .vfl-bubble-ai .vfl-bubble-tag{color:var(--teal)}
.vfl-libre .vfl-bubble-client .vfl-bubble-tag{color:var(--terra-deep)}
.vfl-libre .vfl-call-stamp{left:50%;top:10px;bottom:auto;transform:translateX(-50%) rotate(-3.5deg) scale(1.3);color:#6c9a58}
.vfl-libre .vfl-call-stamp.est-pose{animation:vfl-stamp-libre 360ms cubic-bezier(.2,1.4,.4,1) forwards}
@keyframes vfl-stamp-libre{0%{opacity:0;transform:translateX(-50%) rotate(-3.5deg) scale(1.5)}100%{opacity:1;transform:translateX(-50%) rotate(-3.5deg) scale(1)}}
@media (prefers-reduced-motion:reduce){
  .vfl-libre .vfl-bubble[style*="--i:0"]{opacity:1;transform:none}
  .vfl-libre .vfl-call-stamp{opacity:1;transform:translateX(-50%) rotate(-3.5deg);animation:none!important}
}


/* ===================================================================
   08 · VOIXFLASH · voixflash.py (rumps + AppKit), aucune couleur propre
   Le produit ne peint rien : macOS peint tout. Ce qui suit reprend les
   couleurs système d'Apple en apparence sombre (barre des menus, menu,
   accent bleu 0A84FF) et la police système. Les libellés sont ceux du
   menu réel (voixflash.py:938-1006). Les cinq états sont nommés en
   français dans les pages : les noms des symboles d'Apple ne disent rien
   à qui lit, et on ne peut pas embarquer les glyphes.
   =================================================================== */
html[data-univers="voixflash"]{
  --noir:#1E1E1E;--surface:#282828;--ligne:#3D3D3D;--blanc:#FFFFFF;--gris:#98989D;
  --ambre:#0A84FF;--ambre-clair:#409CFF;
  --u-display:-apple-system,BlinkMacSystemFont,"SF Pro Display","Helvetica Neue",Helvetica,Arial,sans-serif;
  --u-sans:var(--u-display);--u-poids:700;--u-espace:-.02em;
  --u-lumiere:none;--u-grain:none;--u-grain-opacite:0;
}
.u-vx{
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif;
  color:#fff;-webkit-font-smoothing:antialiased;width:min(100%,21rem);margin-left:auto;
}
.vx-barre{
  display:flex;align-items:center;justify-content:flex-end;gap:14px;height:26px;padding:0 10px;
  background:rgba(30,30,30,.85);border-radius:8px 8px 0 0;font-size:13px;color:#fff;
}
/* l'icône de la barre : en surbrillance quand son menu est ouvert, comme sur
   macOS (est-presse sur le mur, aria-expanded sur la page) */
.vx-micro{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:4px;background:transparent;transition:background-color .12s ease}
.vx-micro.est-presse{background:rgba(255,255,255,.18)}
.vx-micro svg{width:15px;height:15px}
.vx-micro rect{fill:#fff}
.vx-micro path{fill:none;stroke:#fff;stroke-width:1.3;stroke-linecap:round}
.vx-menu{
  margin:2px 0 0;padding:5px;display:flex;flex-direction:column;
  background:rgba(40,40,40,.92);backdrop-filter:blur(30px);-webkit-backdrop-filter:blur(30px);
  border-radius:8px;border:1px solid rgba(255,255,255,.12);box-shadow:0 12px 34px rgba(0,0,0,.45);font-size:13px;
  transform-origin:top right;transition:opacity .12s ease,transform .12s ease,visibility .12s;
}
/* fermé : le menu garde sa place, il n'est pas là. Un clic sur l'icône l'ouvre
   (projets/demos.js sur le mur) ; sur le mur c'est le script qui mène
   l'ouverture (vx-anime : aucune transition), en douceur. */
.vx-menu.est-ferme{opacity:0;transform:scale(.985);visibility:hidden}
.vx-menu.vx-anime{transition:none}
.vx-menu span{position:relative;padding:3px 24px 3px 22px;border-radius:4px;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* la ligne sous le pointeur, bleu système (sur le mur, le curseur y descend) */
.vx-menu span.est-survole{background:#0A84FF}
/* LE CURSEUR (mur, 6 septembre 2026, projets/demos.js) : la flèche de macOS,
   noire au liseré blanc, sa pointe en haut à gauche ; il monte vers l'icône,
   clique, descend sur la première ligne. Invisible sans le script. */
.u-vx{position:relative}
.vx-curseur{position:absolute;left:0;top:0;z-index:4;width:19px;height:19px;opacity:0;pointer-events:none;transform-origin:28% 16%;filter:drop-shadow(0 1px 2px rgba(0,0,0,.55))}
.vx-curseur svg{display:block;width:100%;height:100%;fill:#000;stroke:#fff;stroke-width:1.5;stroke-linejoin:round}
.vx-sous::after{content:"\203A";position:absolute;right:9px;top:2px;font-weight:600;color:rgba(255,255,255,.6)}
.vx-coche::before{content:"\2713";position:absolute;left:7px;top:3px;font-size:12px}
.vx-menu hr{border:0;border-top:1px solid rgba(255,255,255,.14);margin:4px 8px}
.vx-etats{margin:10px 0 0;font-size:11px;color:#98989D;text-align:right;line-height:1.7}
.vx-etats code{font-family:inherit;color:#fff;font-size:11px}


/* ===================================================================
   02 · SAVE & CARE · V1/apps/web/src/index.css, TaskCard.tsx, Checkbox.tsx
   Papier crème f7f3eb, carte efe9da, encre 1c1a17, mousse 3d5a3e pour
   la case cochée et la rature, ocre pour le critique. Fraunces + Inter.
   Ombres ambrées, jamais grises. Aucun grain. Le mode soir existe (de
   19 h à 6 h, sans bouton) : ici, le jour.
   =================================================================== */
html[data-univers="sanctuaire"]{
  --noir:#f7f3eb;--surface:#efe9da;--ligne:#e6dfca;--blanc:#1c1a17;--gris:#5a5147;
  --ambre:#3d5a3e;--ambre-clair:#2c4530;
  --u-display:"Fraunces Variable",Fraunces,ui-serif,Georgia,serif;--u-sans:Inter,ui-sans-serif,system-ui,sans-serif;
  --u-poids:500;--u-espace:-.01em;
  --u-lumiere:none;--u-grain:none;--u-grain-opacite:0;
}
.u-sc{
  --cream:#f7f3eb;--cream-dim:#efe9da;--cream-deep:#e6dfca;--text:#1c1a17;--text-soft:#5a5147;--text-mute:#6a5f52;
  --text-on-dark:#f0ebde;--moss:#3d5a3e;--ochre:#c8965a;--ochre-deep:#8a5a1f;
  --shadow-warm:0 1px 2px rgba(80,50,20,.06),0 4px 12px rgba(80,50,20,.08);--sortie:cubic-bezier(.22,1,.36,1);
  font-family:Inter,ui-sans-serif,system-ui,-apple-system,sans-serif;font-size:16px;line-height:1.55;letter-spacing:.005em;
  color:var(--text);-webkit-font-smoothing:antialiased;
}
.sc-tete{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;padding:0 4px 14px}
.sc-salut{margin:0;font-family:"Fraunces Variable",Georgia,serif;font-weight:500;font-size:26px;line-height:1.1;letter-spacing:-.01em}
.sc-date{margin:0;font-size:14px;color:var(--text-mute);white-space:nowrap}
/* la section et son anneau de progression (SectionCard + ProgressRing) */
.sc-section-tete{display:flex;align-items:center;gap:12px;padding:0 6px 10px}
/* l'anneau suit le compte : 500 ms (ProgressRing.tsx:60-72), une ligne sur quatre au départ */
@property --sc-p{syntax:'<percentage>';inherits:false;initial-value:25%}
.sc-anneau{width:32px;height:32px;border-radius:50%;background:conic-gradient(var(--moss) var(--sc-p),var(--cream-deep) 0);display:grid;place-items:center;flex:none;transition:--sc-p .5s ease-in-out}
.sc-anneau::after{content:"";width:22px;height:22px;border-radius:50%;background:var(--cream)}
.sc-section-tete .sc-section-titre{margin:0;font-family:"Fraunces Variable",Georgia,serif;font-weight:500;font-size:18px;letter-spacing:-.01em;color:var(--text)}
.sc-compte{margin-left:auto;font-size:13px;color:var(--text-mute);font-variant-numeric:tabular-nums}
/* la ligne de tâche cochable (TaskCard.tsx:167-287) : toute la carte est la surface de tap */
.sc-lignes{display:flex;flex-direction:column;gap:8px}
.sc-ligne{
  display:flex;align-items:center;gap:12px;padding:16px;min-height:72px;border-radius:18px;
  background:var(--cream-dim);box-shadow:var(--shadow-warm);
  transition:background-color .28s var(--sortie),box-shadow .28s var(--sortie),opacity .24s var(--sortie);
}
.sc-case{
  width:32px;height:32px;border-radius:8px;border:2px solid var(--text-mute);flex:none;
  display:inline-flex;align-items:center;justify-content:center;transition:background-color .2s ease-out,border-color .2s ease-out;
}
.sc-case svg{width:20px;height:20px;fill:none;stroke:var(--text-on-dark);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;transform:scale(.5);opacity:0}
.sc-corps{flex:1;min-width:0}
/* La rature : dans le produit, un trait absolu de 1,5 px tiré de gauche à droite.
   Ici le même trait est un fond cloné par ligne (box-decoration-break), pour
   qu'il suive chaque fragment quand le titre se replie sur deux lignes. */
.sc-titre{
  display:inline;margin:0;font-size:16px;font-weight:500;line-height:1.375;transition:color .28s var(--sortie);
  background-image:linear-gradient(var(--moss),var(--moss));background-repeat:no-repeat;
  background-position:0 56%;background-size:0% 1.5px;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}
.sc-desc{margin:2px 0 0;font-size:14px;line-height:1.375;color:var(--text-soft)}
.sc-critique{display:inline-flex;align-items:center;margin-left:8px;padding:2px 8px;border-radius:99px;font-size:12px;font-weight:500;background:color-mix(in srgb,var(--ochre) 15%,transparent);color:var(--ochre-deep);vertical-align:2px}
.sc-portrait{
  width:56px;height:56px;border-radius:50%;flex:none;display:grid;place-items:center;overflow:hidden;
  background:var(--cream-deep);color:var(--ochre-deep);font-family:"Fraunces Variable",Georgia,serif;font-weight:500;font-size:22px;
  box-shadow:0 0 0 1px var(--cream-deep);
}
/* le vrai portrait quand il existe : le produit affiche la photo, sinon l'initiale */
.sc-portrait img{width:100%;height:100%;object-fit:cover;display:block}
/* une tâche faite ne quitte pas sa section : elle s'installe sur place */
.sc-ligne.est-faite{background:transparent;box-shadow:none;opacity:.65;min-height:0;padding:10px 16px}
.est-faite .sc-case{background:var(--moss);border-color:var(--moss)}
.est-faite .sc-case svg{transform:none;opacity:1}
.est-faite .sc-titre{color:var(--text-soft);background-size:100% 1.5px}
.est-faite .sc-desc,.est-faite .sc-portrait{display:none}
/* LE GESTE DE COCHER, à ses durées (TaskCard.tsx, Checkbox.tsx), partagé depuis
   le 5 septembre 2026 par la page (où l'on coche) et le mur (où la démo coche,
   projets/demos.js) : la case, le ressort de la coche (300/25 à l'entrée),
   la rature (320 ms après 40 ms), la consigne qui se replie (260 ms), le
   portrait qui se retire (180 ms), la ligne qui s'installe. */
.u-sc .sc-ligne{transition:background-color .28s var(--sortie),box-shadow .28s var(--sortie),padding .28s var(--sortie),min-height .28s var(--sortie),opacity .24s var(--sortie),transform .1s ease}
.u-sc .sc-case svg{transition:transform .3s ease-in,opacity .15s ease-in}
.u-sc .est-faite .sc-case svg{transition:transform .45s cubic-bezier(.34,1.56,.64,1),opacity .2s ease-out}
.u-sc .sc-titre{transition:color .28s var(--sortie),background-size .1s ease-out}
.u-sc .est-faite .sc-titre{transition:color .28s var(--sortie),background-size .32s var(--sortie) .04s}
.u-sc .est-faite .sc-critique{display:none}
.u-sc .sc-pli{display:grid;grid-template-rows:1fr;transition:grid-template-rows .26s var(--sortie),opacity .26s var(--sortie)}
.u-sc .est-faite .sc-pli{grid-template-rows:0fr;opacity:0}
.u-sc .sc-desc,.u-sc .est-faite .sc-desc{display:block;min-height:0;overflow:hidden}
.u-sc .sc-portrait{overflow:hidden;transition:width .18s var(--sortie),height .18s var(--sortie),opacity .18s var(--sortie),transform .18s var(--sortie)}
.u-sc .sc-portrait img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block;-webkit-touch-callout:none}
.u-sc .est-faite .sc-portrait{display:grid;width:0;height:0;opacity:0;transform:scale(.8);box-shadow:none}
.est-complete .sc-section-titre{color:var(--moss)}
/* L'ÉCRAN DE FIN DE ROUTINE (EndOfRoutineCard.tsx:19-107), quand les quatre
   tâches sont cochées : le produit prend l'écran en fondu seul, 600 ms. Ici
   la cérémonie dit aussi ce que les coches viennent d'écrire : le mot, le
   compte, puis trois fils tirés l'un après l'autre. Sur la page, il se retire
   au bout de 5 s ou au clic ; sur le mur, il reste jusqu'au projet suivant. */
.sc-scene,.specimen .u-sc{position:relative}
.sc-fin{
  position:absolute;inset:0;z-index:2;margin:0;border:0;border-radius:18px;
  display:grid;align-content:center;justify-items:center;gap:.55rem;padding:1.2rem;
  background:var(--noir);color:var(--blanc);text-align:center;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  opacity:0;transition:opacity .6s ease-in-out;
}
.sc-fin[hidden]{display:none}
.sc-fin.est-visible{opacity:1}
.sc-fin:focus-visible{outline:2px solid var(--ambre);outline-offset:2px}
.sc-fin-titre{
  font-family:var(--u-display);font-weight:500;letter-spacing:-.01em;line-height:1.15;
  font-size:clamp(1.3rem,1.05rem + .8vw,1.75rem);
}
.sc-fin-compte{font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--gris)}
.sc-fin .schema{background:none;border:0;padding:0;margin:.8rem 0 0;width:min(100%,26rem)}
/* le filaire des schémas de la maison (socle.css), que l'accueil ne charge pas :
   les cinq règles que l'écran de fin emploie, mêmes valeurs */
.sc-fin-schema{display:block;height:auto}
.sc-fin-schema .s-boite{fill:none;stroke:var(--ligne);stroke-width:1.5}
.sc-fin-schema .s-trait{stroke:var(--ambre);stroke-width:1.5;fill:none}
.sc-fin-schema .s-titre{font-family:var(--u-sans);font-size:9.5px;font-weight:600;letter-spacing:.11em;fill:var(--gris)}
.sc-fin-schema .s-fin{font-family:var(--u-sans);font-size:9.5px;fill:var(--gris)}
.sc-fin-titre,.sc-fin-compte,.sc-fin-schema .cible{opacity:0}
.sc-fin-schema .fil{stroke-dasharray:96;stroke-dashoffset:96}
.sc-fin.est-visible .sc-fin-titre{animation:sc-parait .7s ease-in-out .2s forwards}
.sc-fin.est-visible .sc-fin-compte{animation:sc-parait .7s ease-in-out .45s forwards}
.sc-fin.est-visible .fil{animation:sc-fil .5s ease-out forwards}
.sc-fin.est-visible .cible{animation:sc-parait .5s ease-out forwards}
.sc-fin.est-visible .d1{animation-delay:.8s}
.sc-fin.est-visible .d2{animation-delay:1.05s}
.sc-fin.est-visible .d3{animation-delay:1.3s}
.sc-fin.est-visible .c1{animation-delay:1.15s}
.sc-fin.est-visible .c2{animation-delay:1.4s}
.sc-fin.est-visible .c3{animation-delay:1.65s}
@keyframes sc-parait{to{opacity:1}}
@keyframes sc-fil{to{stroke-dashoffset:0}}
@media (prefers-reduced-motion:reduce){
  .sc-fin{transition:none}
  .sc-fin-titre,.sc-fin-compte,.sc-fin-schema .cible{opacity:1;animation:none!important}
  .sc-fin-schema .fil{stroke-dashoffset:0;animation:none!important}
}
/* LES OBJETS DU MUR (6 septembre 2026, Anton : « de vrais objets en fausse 3D,
   avec une ombre, tout du long ») : la carte de la routine est un objet posé
   au-dessus de la table, papier plus clair que la salle, ombre chaude ; l'icône
   de l'application est un second objet, à son coin ; l'écran de fin est le
   dos de la carte, qui se retourne quand tout est coché (projets/demos.js).
   Trois enveloppes : flotte (la respiration), incline (le pointeur), carte (le
   retournement), pour que trois mouvements ne se disputent pas un transform. */
.sc-3d{perspective:1500px;perspective-origin:50% 30%;padding:34px 0 10px}
.sc-flotte,.sc-incline{position:relative;transform-style:preserve-3d}
.sc-carte{
  position:relative;transform-style:preserve-3d;border-radius:22px;padding:18px 16px 16px;
  background:#fdfbf6;
  box-shadow:0 1px 2px rgba(80,50,20,.08),0 18px 40px -18px rgba(80,50,20,.38),0 44px 90px -40px rgba(80,50,20,.32);
}
.sc-face{transform:translateZ(1px);backface-visibility:hidden;-webkit-backface-visibility:hidden}
.sc-3d .sc-tete{padding-left:74px;padding-top:2px}
.sc-3d .sc-lignes,.sc-3d .sc-ligne{transform-style:preserve-3d}
.sc-3d .sc-ligne{transition-property:background-color,box-shadow,padding,min-height,opacity}
.sc-app{
  position:absolute;z-index:3;top:-26px;left:14px;width:66px;height:66px;border-radius:17px;
  box-shadow:0 12px 26px -10px rgba(80,50,20,.5),0 2px 5px rgba(80,50,20,.14);transform-origin:50% 50%;
}
/* le dos de la carte : l'écran de fin, retourné, invisible tant que la carte
   est de face (backface-visibility). Les fondus de la version page ne
   s'appliquent pas ici, c'est la carte qui tourne. */
.sc-3d .sc-fin{
  opacity:1;transition:none;transform:rotateY(180deg) translateZ(1px);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;border-radius:22px;cursor:default;
}
/* quand la salle entre au sanctuaire, une ligne se coche : le geste du produit, à ses durées */
.bloc.actif .va-se-cocher,.rejoue .va-se-cocher{animation:sc-installe .28s var(--sortie) 1.15s forwards}
.bloc.actif .va-se-cocher .sc-case,.rejoue .va-se-cocher .sc-case{animation:sc-case .2s ease-out 1s forwards}
.bloc.actif .va-se-cocher .sc-case svg,.rejoue .va-se-cocher .sc-case svg{animation:sc-coche .45s cubic-bezier(.34,1.56,.64,1) 1.02s forwards}
.bloc.actif .va-se-cocher .sc-titre,.rejoue .va-se-cocher .sc-titre{
  animation:sc-titre .28s var(--sortie) 1.1s forwards,sc-rature .32s var(--sortie) 1.14s forwards;
}
@keyframes sc-case{to{background:var(--moss);border-color:var(--moss)}}
@keyframes sc-coche{to{transform:none;opacity:1}}
@keyframes sc-titre{to{color:var(--text-soft)}}
@keyframes sc-rature{to{background-size:100% 1.5px}}
@keyframes sc-installe{to{background:transparent;box-shadow:none;opacity:.65}}
@media (prefers-reduced-motion:reduce){
  .va-se-cocher,.va-se-cocher .sc-case,.va-se-cocher .sc-case svg,.va-se-cocher .sc-titre{animation-delay:0s!important}
}


/* ===================================================================
   09 · MES-MCP · envoi/web/css/console.css, image-gen/src/gallery.ts
   Des postes de travail sombres, denses, calmes, en fontes système, un
   seul accent bleu. Ici la console envoi, la seule porte de sortie :
   fond 0e1116, panneaux 151a21, filet 232a34, encre e8ebef, bleu 5b8def.
   Aucun grain. La matière du produit, c'est le journal des outils.
   =================================================================== */
html[data-univers="mesmcp"]{
  --noir:#0e1116;--surface:#151a21;--ligne:#232a34;--blanc:#e8ebef;--gris:#9aa4b1;
  --ambre:#5b8def;--ambre-clair:#7c97ff;
  --u-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;--u-sans:var(--u-display);
  --u-poids:650;--u-espace:-.01em;
  --u-lumiere:none;--u-grain:none;--u-grain-opacite:0;
}
.u-mcp{
  --bg:#0e1116;--bg-raised:#151a21;--bg-inset:#0a0d11;--border:#232a34;--border-strong:#303a47;
  --text:#e8ebef;--text-muted:#9aa4b1;--text-faint:#6b7684;--accent:#5b8def;--accent-soft:rgba(91,141,239,.14);
  --ok:#3fb27f;--radius:8px;--radius-sm:5px;--shadow:0 8px 28px rgba(0,0,0,.45);
  --font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;--mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  font-family:var(--font);font-size:14px;line-height:1.45;color:var(--text);-webkit-font-smoothing:antialiased;
}
.mcp-console{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
.mcp-topbar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 14px;
  background:rgba(14,17,22,.82);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--border);
}
.mcp-brand{display:inline-flex;align-items:center;gap:8px;font-size:13px}
.mcp-brand strong{font-weight:600;color:var(--text)}
.mcp-brand span{color:var(--text-muted)}
.mcp-logo{display:inline-block;width:16px;height:16px}
.mcp-badge{display:inline-flex;align-items:center;gap:6px;padding:2px 9px;border-radius:99px;font-size:12px;color:var(--ok);background:rgba(63,178,127,.14)}
.mcp-badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
.mcp-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:12px 14px 0}
.mcp-kpis div{background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px}
.mcp-kpis b{display:block;font-size:26px;font-weight:650;line-height:1.1;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.mcp-kpis span{font-size:12px;color:var(--text-muted)}
/* les projets : tout est compartimenté côté serveur */
.mcp-tenants{display:flex;flex-wrap:wrap;gap:6px;padding:12px 14px 0}
.mcp-tenants span{padding:2px 9px;border-radius:99px;border:1px solid var(--border-strong);font-size:12px;color:var(--text-muted);font-family:var(--mono)}
.mcp-tenants .est-actif{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
/* le journal : ce que les outils répondent, en phrases écrites pour un LLM (envoi/src/tools/send.ts) */
.mcp-log{
  margin:12px 14px 14px;padding:12px 14px;background:var(--bg-inset);border:1px solid var(--border);border-radius:var(--radius);
  font-family:var(--mono);font-size:11px;line-height:1.65;color:var(--text);white-space:pre-wrap;overflow:hidden;
}
.mcp-log .mcp-app{color:var(--accent);font-weight:600}
.mcp-log .mcp-doux{color:var(--text-muted)}
/* LA CONSOLE SANS FENÊTRE (mur, 5 septembre 2026, projets/demos.js) : le
   terminal sans sa boîte, les lignes mono à même le noir de la salle ; la
   marque et le badge en tête, les trois chiffres en grand, les projets en
   rangée, le journal, et l'invite qui attend avec son curseur. */
.mcp-nu{background:none;border:0;box-shadow:none;overflow:visible;border-radius:0}
.mcp-nu .mcp-topbar{background:none;backdrop-filter:none;-webkit-backdrop-filter:none;border:0;padding:0 0 4px}
.mcp-nu .mcp-kpis{gap:18px;padding:14px 0 0}
.mcp-nu .mcp-kpis div{background:none;border:0;padding:0}
.mcp-nu .mcp-kpis b{font-size:40px;letter-spacing:-.02em}
.mcp-nu .mcp-tenants{padding:16px 0 0}
.mcp-nu .mcp-log{margin:16px 0 0;padding:0;background:none;border:0;border-radius:0;font-size:12px}
.mcp-nu .mcp-entree{display:block;margin:0 0 8px}
.mcp-prompt{display:block}
.mcp-tape{color:var(--text)}
.mcp-curseur{display:inline-block;width:7px;height:1.05em;vertical-align:-.15em;background:var(--accent);animation:mcp-curseur 1s steps(1) infinite}
@keyframes mcp-curseur{50%{opacity:0}}
@media (prefers-reduced-motion:reduce){.mcp-curseur{animation:none}}
/* LE SYSTÈME (mur, 6 septembre 2026, projets/demos.js) : le diagramme qui a
   remplacé la console. Le LLM à gauche, la porte au milieu, les quatre
   familles à droite, un bus à angles droits ; des paquets bleus font
   l'aller, verts le retour ; la porte balaie ce qui passe ; la famille
   atteinte s'allume. Tout à même le noir, sans cadre. */
.mcp-systeme{font-family:var(--font)}
.mcp-sys-tete{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:0 0 12px;font-size:13px;color:var(--text-muted)}
.mcp-sys-tete strong{font-size:15px;font-weight:600;color:var(--text)}
.mcp-sys-tete b{font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}
.mcp-diag{display:block;width:100%;height:auto;overflow:visible}
.mcp-d-boite{fill:var(--bg-raised);stroke:var(--border-strong);stroke-width:1;transition:stroke .3s ease}
.mcp-d-llm.est-actif .mcp-d-boite{stroke:var(--accent)}
.mcp-d-pers{fill:none;stroke:var(--text-muted);stroke-width:1.5;stroke-linecap:round}
.mcp-d-porte{fill:rgba(91,141,239,.07);stroke:var(--accent);stroke-width:1;stroke-dasharray:3 4}
.mcp-d-ligne{fill:none;stroke:var(--border-strong);stroke-width:1.2}
.mcp-d-titre{font-family:var(--font);font-size:11px;font-weight:600;letter-spacing:.12em;fill:var(--text)}
.mcp-d-sous{font-family:var(--font);font-size:10px;fill:var(--text-muted)}
.mcp-d-mono{font-family:var(--mono);font-size:10px;fill:var(--text-faint);transition:fill .3s ease}
.mcp-d-appel{font-family:var(--mono);font-size:10.5px;fill:var(--accent)}
.mcp-d-note{font-family:var(--font);font-size:10.5px;fill:var(--text-muted);font-style:italic}
.mcp-d-noeud{fill:var(--bg-inset);stroke:var(--border-strong);stroke-width:1.2;transition:fill .3s ease,stroke .3s ease}
.mcp-d-rang.est-allume .mcp-d-noeud{fill:var(--accent);stroke:var(--accent)}
.mcp-d-rang.est-allume .mcp-d-mono{fill:var(--text)}
.mcp-d-paquet{fill:var(--accent);opacity:0;filter:drop-shadow(0 0 4px rgba(91,141,239,.95))}
.mcp-d-retour{fill:var(--ok);filter:drop-shadow(0 0 4px rgba(63,178,127,.9))}
.mcp-d-balayage{stroke:#fff;stroke-width:2;stroke-linecap:round;opacity:0;filter:drop-shadow(0 0 5px #fff)}


/* ===================================================================
   LES BOUTONS D'ENTRÉE · un par projet, dans le style exact du bouton
   principal du produit. Sur la liste, il apparaît quand le bloc est
   allumé ; sur la page, il ouvre le produit en ligne. Ce sont des
   objets visuels : la cible cliquable est la phrase (liste) ou le lien
   qui les enveloppe (page).
   =================================================================== */
.cta{
  display:inline-flex;align-items:center;gap:.6em;white-space:nowrap;cursor:pointer;
  text-decoration:none;-webkit-font-smoothing:antialiased;
  transition:transform .5s cubic-bezier(.22,1,.36,1),opacity .4s ease,box-shadow .3s ease,filter .3s ease;
}
.cta svg{display:block;flex:none}

/* LE SURVOL DES BOUTONS · chacun réagit dans l'idiome de son produit, jamais
   par un simple éclaircissement. La portée du survol est le bouton lui-même,
   rien de plus (4 septembre 2026). Avant, ces règles répondaient aussi à
   .bloc:hover parce que le bouton est décoratif sur l'accueil et que le bloc
   entier est la cible cliquable ; mais dans la salle épinglée le bloc fait
   tout l'écran, donc la pilule restait soulevée et la flèche sortie en
   permanence : un état de survol qui ne dit plus rien. Le bloc reste
   cliquable partout (app.js), seul son signal visuel se resserre.
   Rien ne bouge en mouvement réduit. */
.cta{transition:transform .38s cubic-bezier(.22,1,.36,1),opacity .4s ease,box-shadow .32s ease,background-color .28s ease,border-color .28s ease,color .28s ease,filter .3s ease}

/* QSE · la pilule dégradée se soulève, la pastille de flèche avance */
.cta-qse:hover{transform:translateY(-2px);box-shadow:0 14px 26px -12px rgba(37,99,235,.65)}
.cta-qse i{transition:transform .38s cubic-bezier(.22,1,.36,1)}
.cta-qse:hover i{transform:translateX(3px)}

/* Save & Care · le geste de la case : la carte se pose, la coche s'affirme */
.cta-sc:hover{transform:translateY(-2px);background:#33502f;box-shadow:0 12px 22px -14px rgba(0,0,0,.55)}
.cta-sc i{transition:background-color .28s ease,transform .38s cubic-bezier(.34,1.56,.64,1)}
.cta-sc:hover i{transform:scale(1.08)}

/* Studio 9 · sobre : l'encre s'éclaircit, rien ne bouge */
.cta-s9:hover{background:#2c2c31;border-color:#2c2c31}
.cta-s9 i{transition:color .28s ease,transform .38s cubic-bezier(.22,1,.36,1)}
.cta-s9:hover i{color:#fff;transform:translateX(3px)}

/* Step Up · le dégradé se met à luire, comme la page du coach */
.cta-su:hover{transform:translateY(-2px);box-shadow:0 0 0 1px rgba(255,255,255,.22),0 16px 30px -14px rgba(193,255,114,.55)}

/* Toul'Barz · monochrome absolu : le filet se tire, le cadre s'allume */
.cta-tb:hover{border-color:rgba(255,255,255,.85);background:rgba(255,255,255,.05)}
.cta-tb:hover::after{width:100%}

/* Abeille · le miel se fonce, le bouton s'assied */
.cta-ab:hover{background:#c08f2f;border-color:#c08f2f;transform:translateY(-1px);box-shadow:0 10px 18px -12px rgba(42,33,27,.6)}
.cta-ab i{transition:transform .38s cubic-bezier(.22,1,.36,1)}
.cta-ab:hover i{transform:translateX(3px)}

/* Vocal Flow · un vrai bouton en relief : il s'enfonce */
.cta-vf:hover{transform:translateY(1px);box-shadow:0 2px 0 #a8823c}

/* VoixFlash · bleu système : il se fonce à l'appui, comme sur macOS */
.cta-vx:hover{background:#0071e3}

/* mes-mcp · terminal : le cadre s'allume et le fond respire */
.cta-mcp:hover{background:#10151c;border-color:#5b8def;color:#fff}

@media (prefers-reduced-motion: reduce) {
  .cta,.cta i{transition-duration:.001ms}
  .cta:hover,.cta:hover i{transform:none}
}
/* Sur la liste : caché tant que le bloc n'est pas allumé. L'entrée se joue en
   transform, comme le survol : les deux écrivaient donc dans la même propriété
   et, à spécificité égale, c'était l'entrée qui gagnait puisqu'elle est écrite
   plus bas. Le soulèvement des boutons n'a donc jamais eu lieu sur l'accueil,
   seul le détail interne (la flèche) bougeait. Corrigé le 4 septembre 2026 :
   l'entrée ne pose sa transform que hors survol, le survol reprend la main. */
.bloc .cta{opacity:0}
.bloc.actif .cta{opacity:1;transition-delay:.12s}
.bloc .cta:not(:hover){transform:translateY(6px)}
.bloc.actif .cta:not(:hover){transform:none}

/* QSE : la capsule bleue de la saisie, l'orbe d'envoi (ChatInput.tsx) */
.cta-qse{
  height:48px;padding:0 6px 0 22px;border-radius:2rem;
  background:linear-gradient(to bottom right,#2563eb,#4f46e5);color:#fff;
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:14px;font-weight:600;letter-spacing:.01em;
  box-shadow:0 10px 15px -3px rgba(59,130,246,.3);border:1px solid rgba(59,130,246,.5);
}
.cta-qse i{width:36px;height:36px;border-radius:50%;background:#fff;color:#2563eb;display:grid;place-items:center;margin-left:8px}
.cta-qse i svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}

/* Save & Care : la ligne cochée, mousse sur crème (TaskCard + CheckboxVisual) */
.cta-sc{
  padding:12px 18px 12px 12px;border-radius:18px;background:#3d5a3e;color:#f0ebde;
  font-family:Inter,ui-sans-serif,system-ui,sans-serif;font-size:15px;font-weight:500;letter-spacing:.005em;
  box-shadow:0 1px 2px rgba(80,50,20,.06),0 4px 12px rgba(80,50,20,.18);
}
.cta-sc i{width:26px;height:26px;border-radius:7px;border:2px solid #f0ebde;display:grid;place-items:center}
.cta-sc i svg{width:16px;height:16px;fill:none;stroke:#f0ebde;stroke-width:3;stroke-linecap:round;stroke-linejoin:round}

/* Studio 9 : le bouton d'action, noir, radius 8 (vue.mjs) */
.cta-s9{
  padding:9px 14px;border-radius:8px;background:#141416;color:#fff;border:1px solid #141416;
  font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;font-size:.875rem;font-weight:500;
  font-feature-settings:"cv05" 1,"ss01" 1;
}
.cta-s9 i{font-style:normal;color:#9a9aa3}
.cta-s9 i svg{display:block;width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}

/* Step Up Factory : la pilule tri-dégradée, texte noir (DaySelector actif) */
.cta-su{
  padding:12px 20px;border-radius:9999px;color:#000;
  background:linear-gradient(to top right,#c1ff72,#ffbd59,#ff9bd9);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",Roboto,sans-serif;font-size:14px;font-weight:600;letter-spacing:-.01em;
  box-shadow:0 10px 15px -3px rgba(0,0,0,.3);
}

/* Toul'Barz : la pile « Entrer » de la vitrine, capitales espacées, filet qui s'étire */
.cta-tb{
  position:relative;padding:10px 18px;border:1px solid rgba(255,255,255,.35);color:#fff;background:transparent;
  font-family:"Archivo Variable",Archivo,system-ui,sans-serif;font-size:11px;text-transform:uppercase;letter-spacing:.28em;
}
.cta-tb::after{content:"";position:absolute;left:0;bottom:-1px;height:1px;width:0;background:#fff;transition:width .5s cubic-bezier(.22,1,.36,1)}
.cta-tb:hover::after{width:100%}
.cta-tb i{font-family:"Fraunces Variable",Fraunces,Georgia,serif;font-style:italic;font-size:14px;letter-spacing:0;text-transform:none;color:#C4C4C4}

/* L'Abeille : le jeton de cire, alvéole et flèche mono (portail.module.css) */
.cta-ab{
  padding:.62em 1.05em;min-height:44px;border-radius:5px;background:#d9a441;border:1.5px solid #d9a441;color:#2a211b;
  font-family:"Schibsted Grotesk",system-ui,sans-serif;font-size:.95rem;font-weight:600;letter-spacing:-.006em;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 4px 10px -4px rgba(140,98,16,.4);
}
.cta-ab svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linejoin:round}
.cta-ab i{font-style:normal;font-family:"JetBrains Mono Variable","JetBrains Mono",monospace;font-size:.9em}

/* Vocal Flow : le bouton beurre à ombre dure de la carte d'appel (vfl-listen) */
.cta-vf{
  padding:10px 14px;border-radius:10px;background:#e3b761;color:#2b2119;box-shadow:0 3px 0 #a8823c;
  font-family:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;font-size:13px;font-weight:800;
}
.cta-vf:hover{transform:translateY(1px);box-shadow:0 2px 0 #a8823c}
.cta-vf svg{width:12px;height:12px;fill:currentColor}

/* VoixFlash : le bouton système de macOS, accent bleu, apparence sombre */
.cta-vx{
  padding:5px 14px;border-radius:6px;background:#0A84FF;color:#fff;
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:500;
  box-shadow:0 1px 1px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.16);
}

/* mes-mcp : l'invite de la console, mono, curseur qui bat */
.cta-mcp{
  padding:8px 14px;border-radius:5px;background:#0a0d11;border:1px solid #303a47;color:#e8ebef;
  font-family:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;
}
.cta-mcp b{font-weight:600;color:#5b8def}
.cta-mcp::after{content:"";width:7px;height:13px;background:#e8ebef;margin-left:2px;animation:mcp-curseur 1.1s steps(1) infinite}
@keyframes mcp-curseur{50%{opacity:0}}
@media (prefers-reduced-motion:reduce){.cta-mcp::after{animation:none}}


/* le logo de la console envoi : les couleurs vivent ici, jamais dans le HTML
   des pages (la charte de la maison scanne les *.html de la racine) */
.mcp-logo-fond{fill:#5b8def}
.mcp-logo-trait{fill:none;stroke:#fff;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

/* LES MASCOTTES · quatre visages, trois couleurs chacun (deux pour le
   personnage, une pour le fond), quelques formes pleines et rondes. Elles
   remplacent les initiales et la seule photo qu'Aria avait : tout le monde a
   un visage, ou personne. Les couleurs vivent ici, comme le reste de la
   matiere citee, jamais dans un HTML de la racine. */
.m-n0{fill:#F2E3D5}.m-n1{fill:#C2785C}.m-n2{fill:#A8623F}.m-n3{fill:#3A2A1E}
.m-a0{fill:#F7E2EB}.m-a1{fill:#C25C8A}.m-a2{fill:#A8467A}.m-a3{fill:#E8A24A}.m-a4{fill:#3A1E2A}
.m-m0{fill:#DCE7F0}.m-m1{fill:#5C82C2}.m-m2{fill:#4A6EAC}.m-m3{fill:#CBDCEF}.m-m4{fill:#22375E}
.m-s0{fill:#DEEAE1}.m-s1{fill:#8FAE9B}.m-s2{fill:#6E8A7A}.m-s3{fill:#33453B}


/* ===================================================================
   LE MUR · ce que les deux projets les plus dessinés montrent d'eux.
   =================================================================== */

/* TOUL'BARZ · la vitrine du site devient le fond de la page entière quand la
   salle passe dans son univers : c'est cette image que voient le visiteur et
   le membre en arrivant. Voilée, elle reste une texture, jamais un décor qui
   dispute sa place au texte. Elle vit dans --u-lumiere, donc elle suit le
   même fondu que tout le reste de la salle. */
/* Le voile : un cran plus léger le 6 septembre 2026 (Anton : « à peine plus
   visible, un tout petit peu »), 86/90/95 vers 80/85/92. */
html[data-univers="toulbarz"]{
  --u-lumiere:
    radial-gradient(115% 75% at 50% -8%,rgba(255,255,255,.10) 0%,rgba(255,255,255,.03) 24%,rgba(255,255,255,0) 54%),
    linear-gradient(to bottom,rgba(6,6,6,.80) 0%,rgba(6,6,6,.85) 44%,rgba(6,6,6,.92) 100%),
    url("/projets/media/toulbarz/vitrine-desktop.webp") 50% 34%/cover no-repeat;
}

/* ABEILLE · la scène du site n'est pas une image, c'est une pile de plans.
   Sur le mur on la montre à plat sur la table de montage, chaque plan nommé ;
   en entrant dans la page, ils se remettent en registre (abeille.html). */
/* Plus de cadre (5 septembre 2026, Anton) : les plans flottent sur la salle.
   Ils arrivent du bas de l'écran (projets/demos.js pousse --vol de 90vh à 0)
   et le pointeur les déplace chacun selon son plan (--mx, --my sur la pile,
   --par par plan : le plus proche bouge le plus) et incline la pile d'un
   rien. Aucune transition CSS ici, c'est le script qui mène ; hors JS, la
   position de repos. Plus de légende (6 septembre 2026). */
.ab-tri{position:relative;min-height:29rem;padding:1rem 1.1rem 1rem}
.ab-tri-pile{position:absolute;inset:1rem 1.1rem 1rem;perspective:1200px;perspective-origin:50% 24%}
.ab-tr{
  --i:0;position:absolute;left:12%;top:30%;width:56%;aspect-ratio:16/9;
  border-radius:8px;overflow:hidden;border:1px solid var(--filet);background:var(--cire);
  box-shadow:0 16px 42px -20px rgba(42,33,27,.55);
  transform:translate(calc(var(--i) * 12px),calc(var(--i) * -12px));
  transition:transform .9s cubic-bezier(.22,1,.36,1),box-shadow .9s ease,left .9s cubic-bezier(.22,1,.36,1),top .9s cubic-bezier(.22,1,.36,1),width .9s cubic-bezier(.22,1,.36,1);
}
.ab-tr > img{width:100%;height:100%;object-fit:cover;display:block}
.ab-tr-scene{background:repeating-conic-gradient(var(--filet) 0 25%,var(--cire) 0 50%) 0 0/14px 14px}
.ab-tr-accents > img{position:absolute;width:auto;height:auto;object-fit:contain}
.ab-tr-accents .ab-tr-fleur{left:-4%;bottom:-8%;width:44%}
.ab-tr-accents .ab-tr-posee{right:10%;top:12%;width:34%;transform:rotate(8deg)}
.ab-tr-fil > img{object-fit:contain;padding:6%}
.ab-tr b{
  position:absolute;left:.5rem;bottom:.45rem;padding:.28rem .5rem;border-radius:3px;
  font-family:"Schibsted Grotesk",system-ui,sans-serif;font-size:.62rem;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;line-height:1;
  color:#fbf8f2;background:rgba(42,33,27,.84);
}
/* la salle s'allume : les plans s'écartent, comme on étale des calques. Le
   pointeur les pousse (13 px par rang, le double d'avant, 6 septembre 2026)
   et incline la pile de quelques degrés dans son sens. Plus grands et plus
   haut (64 % de large, à 46 % du haut ; second tour). En bout de chaîne,
   ce que la main a fait à chaque plan (projets/demos.js) : --dx, --dy le
   glissement sur la table, dans le repère du plan, --lev la levée le long
   de sa normale. */
.ab-tr{--par:calc((var(--i) + 1) * 13)}
.bloc.actif .ab-tr,.rejoue .ab-tr{
  left:10%;top:46%;width:64%;
  transform:translate3d(calc(var(--mx,0) * var(--par) * 1px),calc(var(--vol,0px) + var(--my,0) * var(--par) * .7px),0) rotateX(calc(56deg - var(--my,0) * 5deg)) rotateZ(calc(-22deg + var(--mx,0) * 4deg)) translateZ(calc(var(--i) * 80px)) translate3d(var(--dx,0px),var(--dy,0px),var(--lev,0px));
  box-shadow:0 30px 60px -22px rgba(42,33,27,.6);
}
/* sur le mur, le script mène (aucune transition de transform) ; chaque plan
   reçoit le pointeur, seul dans le spécimen (style.css l'interdit à tout le
   reste : le spécimen est un clic vers la page), se saisit et se glisse ;
   l'ombre suit la levée. */
.specimen .ab-tr{transition:box-shadow .5s ease;pointer-events:auto;cursor:grab}
.specimen .ab-tr > img{-webkit-user-drag:none;user-select:none}
.specimen .ab-tr.est-survole{box-shadow:0 44px 70px -26px rgba(42,33,27,.7)}
.specimen .ab-tr.est-saisi{cursor:grabbing;box-shadow:0 56px 80px -28px rgba(42,33,27,.75)}

/* L'ABEILLE DANS LA SALLE (page abeille.html) · elle traverse la page, pas un
   cadre. Fixée au viewport comme sur le site de l'association (AbeilleFil.tsx),
   elle descend avec le défilement le long d'une trajectoire chorégraphiée,
   dans les gouttières, jamais au travers d'un texte. La position vient du
   script ; ici, seulement la boîte. Écartée au pointeur grossier et en
   mouvement réduit : une trajectoire liée au scroll y est nauséogène. */
.salle-abeille{
  position:fixed;inset:0;z-index:3;pointer-events:none;overflow:hidden;
  opacity:0;transition:opacity .8s ease;
}
.salle-abeille.vole{opacity:1}
.salle-vol{
  position:absolute;left:0;top:0;display:block;
  width:clamp(4rem,6vw,5.75rem);
  will-change:transform;
}
.salle-vol img{display:block;width:100%;height:auto}
/* L'ABEILLE DU MUR (accueil, 6 septembre 2026) · même boîte, autre vie : elle
   ne suit plus le défilement, elle se pose dans une gouttière libre et fuit le
   pointeur (projets/demos.js). Jamais floue, jamais voilée : elle mérite d'être
   vue. Le script pose le transform ; l'origine au centre, pour virer sur
   place. Pas au doigt, pas en mouvement réduit. */
.mur-abeille{position:fixed;inset:0;z-index:3;pointer-events:none;overflow:hidden;opacity:0;transition:opacity .7s ease}
.mur-abeille.vole{opacity:1}
.mur-vol{position:absolute;left:0;top:0;display:block;width:clamp(4rem,6vw,5.75rem);transform-origin:50% 50%;will-change:transform}
.mur-vol img{display:block;width:100%;height:auto}
@media (prefers-reduced-motion: reduce){
  .ab-tr{transition:none}
  .salle-abeille,.mur-abeille{display:none}
}
@media (pointer: coarse){
  .salle-abeille,.mur-abeille{display:none}
}
