/* ═══════════════════════════════════════════════════════════════════════════
   PALETTE FORTALYS — SOURCE UNIQUE DE VÉRITÉ
   ───────────────────────────────────────────────────────────────────────────
   ⚠️  À LIRE AVANT TOUTE MODIFICATION (humain ou IA)  ⚠️

   Ce fichier est le SEUL endroit du dépôt où une couleur a le droit d'être
   écrite. Partout ailleurs — feuilles de style, composants, scripts, JSON de
   marque — on référence un jeton, jamais une valeur.

   RÈGLES NON NÉGOCIABLES
   1. Aucun `#rrggbb`, `rgb(n n n)` ou `hsl()` numérique hors de ce fichier.
      `npm run check:palette` le vérifie et fait échouer le build.
   2. Une nuance qui n'est pas dans la liste ci-dessous se compose, elle ne
      s'invente pas :
          color-mix(in srgb, var(--copper), var(--champagne) 15%)
      Le mélange suit automatiquement la palette si on la fait évoluer ;
      un hex recopié, non.
   3. Faire évoluer le site = modifier les triplets RGB de ce bloc, rien
      d'autre. Les alias sémantiques et tout le CSS suivent.
   4. `config/brand.json` ne stocke plus de couleur : il référence les noms de
      jetons ci-dessous, et `npm run generate:brand` résout les valeurs au
      moment de produire les SVG, PNG et favicons.

   DEUX EXCEPTIONS, ET SEULEMENT DEUX
   Les trames alvéolaires de `globals.css` (.hive-cells et .hive-beam) sont des
   SVG en data-URI. Un data-URI ne peut pas lire une variable CSS : leurs deux
   couleurs y sont écrites en clair, et sont déclarées comme exceptions dans
   `scripts/check-palette.mjs`. Toute modification de --color-stone-rgb ou
   --color-copper-light-rgb doit être reportée à la main dans ces deux URL.

   WEB ≠ PRINT — ET C'EST VOULU
   La charte client est spécifiée en Pantone, pour l'impression. Les valeurs
   écran ci-dessous s'en écartent délibérément, parce qu'elles ont un meilleur
   rendu sur fond lumineux. L'écart est documenté dans BRAND.md et mesurable
   à tout moment par `npm run report:palette`, qui est INFORMATIF et ne bloque
   jamais le build. Les valeurs Pantone ne s'appliquent qu'aux supports
   imprimés.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* — SOMBRES ————————————————————————————————————————————————————————————
     L'échelle de profondeur. `ink` est le fond dominant du site ; les trois
     autres sont des niveaux d'élévation, pas des couleurs autonomes. Toute
     nuance intermédiaire se compose par color-mix entre deux d'entre eux. */
  --color-ink-rgb: 11 15 16;            /* #0b0f10 · fond dominant */
  --color-ink-deep-rgb: 7 10 11;        /* #070a0b · voiles, creux, ombres portées */
  --color-ink-soft-rgb: 18 23 24;       /* #121718 · surfaces surélevées, champs */
  --color-ink-warm-rgb: 31 23 18;       /* #1f1712 · base chaude sous les photos */

  /* — CLAIRS ———————————————————————————————————————————————————————————— */
  --color-ivory-rgb: 245 240 232;       /* #f5f0e8 · texte principal, fond de la section contact */
  --color-stone-rgb: 152 139 128;       /* #988b80 · texte secondaire, libellés, filets */

  /* — CUIVRE ————————————————————————————————————————————————————————————
     `copper` est la couleur d'aplat et d'arête ; `copper-light` est l'accent
     LISIBLE sur fond sombre — c'est lui qui porte l'essentiel du texte accent
     du site. `champagne` est le reflet spéculaire, jamais une couleur de fond. */
  --color-copper-dark-rgb: 143 79 47;   /* #8f4f2f · fond des dégradés, index sur ivoire */
  --color-copper-rgb: 196 118 71;       /* #c47647 · accent d'aplat et d'arête */
  --color-copper-light-rgb: 225 170 120;/* #e1aa78 · accent texte sur fond sombre */
  --color-champagne-rgb: 240 199 159;   /* #f0c79f · reflet spéculaire, survol, succès */

  /* — SIGNAL ————————————————————————————————————————————————————————————
     Erreurs de formulaire uniquement. La palette de marque tient dans 28° de
     teinte : aucune de ses couleurs ne peut signaler une erreur sans se
     confondre avec l'accent. Celle-ci est à 36° du cuivre et dépasse le seuil
     AAA (7,24:1 sur --ink-soft, 7,72:1 sur --ink). Ne jamais l'employer comme
     couleur décorative : elle ne veut dire qu'une chose. */
  --color-signal-rgb: 242 133 122;      /* #f2857a · état d'erreur */

  /* — EXTRÊMES ——————————————————————————————————————————————————————————
     Lumière pure et noir pur. Ce ne sont pas des couleurs de marque : le blanc
     ne sert qu'aux reflets spéculaires et aux masques, le noir qu'aux ombres
     portées et aux masques. Jamais en couleur de texte ni de fond. */
  --color-white-rgb: 255 255 255;
  --color-black-rgb: 0 0 0;

  /* ─────────────────────────────────────────────────────────────────────────
     ALIAS SÉMANTIQUES — ce que l'on écrit dans les composants.
     Un alias n'ajoute pas de couleur : il nomme un rôle.
     ───────────────────────────────────────────────────────────────────────── */
  --ink: rgb(var(--color-ink-rgb));
  --ink-deep: rgb(var(--color-ink-deep-rgb));
  --ink-soft: rgb(var(--color-ink-soft-rgb));
  --ink-warm: rgb(var(--color-ink-warm-rgb));
  --ivory: rgb(var(--color-ivory-rgb));
  --ivory-dim: rgb(var(--color-ivory-rgb) / .68);
  --stone: rgb(var(--color-stone-rgb));
  --copper-dark: rgb(var(--color-copper-dark-rgb));
  --copper: rgb(var(--color-copper-rgb));
  --copper-light: rgb(var(--color-copper-light-rgb));
  --copper-highlight: rgb(var(--color-champagne-rgb));
  --signal: rgb(var(--color-signal-rgb));
  --white: rgb(var(--color-white-rgb));
  --black: rgb(var(--color-black-rgb));
  --line: rgb(var(--color-ivory-rgb) / .14);

  --ease: cubic-bezier(.22, .68, .18, 1);
  --button-ease: cubic-bezier(.16, 1, .3, 1);
  /* Courbe des GESTES DE SORTIE : symétrique, lente au départ comme à
     l'arrivée. --ease donne 90 % du chemin dans son premier tiers, ce qui
     escamote toute disparition ; on la réserve donc aux entrées. Jumelle
     exacte de `revealEase` dans components/fortalys/page-transition.tsx. */
  --ease-out-veil: cubic-bezier(.65, .02, .35, 1);
  --shell: min(1380px, calc(100vw - clamp(40px, 8vw, 144px)));

  /* Interlignage minimal des titres en Cormorant : sa grande amplitude
     verticale exige cette réserve pour que descendantes et ascendantes de
     deux lignes successives ne puissent jamais se chevaucher. */
  --display-leading: 1.1;
}

/* Artwork and typography: config/brand.json → npm run generate:brand.
   Animation may reveal/light the original paths, never reshape them. */
.brand-mark { aspect-ratio: 1; shape-rendering: geometricPrecision; }
.brand-wordmark { display: block; height: auto; overflow: visible; }
.hero-monogram-label .brand-wordmark { width: clamp(130px, 12vw, 185px); }
.page-loader-signature .brand-wordmark { width: clamp(170px, 18vw, 240px); }
.system-core .system-core-wordmark { position: relative; z-index: 1; width: 64%; margin-top: 4px; }
.stage-core .stage-core-wordmark { width: 52%; margin: 0 auto; }

/* The luminous arc is clipped to the exact filled rings from Illustrator.
   That band is 5.5 units wide, so stroke width cannot shape the comet — every
   pass is trimmed to the same ribbon and only its length, colour and weight
   count. Six passes share one leading edge (`--comet-seed` = length + 92) and
   fade champagne → copper, the artwork's own colour, so the light dissolves
   into the ring instead of ending on an edge. The offset only decreases, so
   the light always travels in the path direction — clockwise on screen. */
.brand-mark-highlight { stroke-linecap: round; stroke-linejoin: round; }
.brand-mark-comet-pass {
  stroke-width: 10;
  stroke-dashoffset: var(--comet-seed);
  opacity: calc(var(--pass-alpha) * var(--comet-gain, 1));
  animation: monogramContourHighlight var(--comet-run) linear var(--comet-phase) infinite;
  transition: opacity .8s var(--ease);
}
.brand-mark-comet--0 { --comet-run: 9.6s; --comet-phase: 0s; }
.brand-mark-comet--1 { --comet-run: 13.2s; --comet-phase: -5.4s; }
.brand-mark-comet-pass--0 { --comet-seed: 100px; stroke-dasharray: 8 92; stroke: var(--copper-highlight); --pass-alpha: .42; }
.brand-mark-comet-pass--1 { --comet-seed: 106px; stroke-dasharray: 14 86; stroke: var(--copper-highlight); --pass-alpha: .3; }
.brand-mark-comet-pass--2 { --comet-seed: 113px; stroke-dasharray: 21 79; stroke: var(--copper-light); --pass-alpha: .24; }
.brand-mark-comet-pass--3 { --comet-seed: 121px; stroke-dasharray: 29 71; stroke: var(--copper-light); --pass-alpha: .18; }
.brand-mark-comet-pass--4 { --comet-seed: 130px; stroke-dasharray: 38 62; stroke: var(--copper); --pass-alpha: .14; }
.brand-mark-comet-pass--5 { --comet-seed: 140px; stroke-dasharray: 48 52; stroke: var(--copper); --pass-alpha: .1; }
.brand-mark--loader .brand-mark-rings { animation: brandReveal .56s var(--ease) both; }
.brand-mark--loader .brand-mark-glyph { animation: brandReveal .48s .18s var(--ease) both; }
.contact-seal-mark .brand-mark-rings { opacity: var(--seal-ring); }
.contact-seal-mark .brand-mark-glyph { opacity: var(--seal-write); }

/* One turn of the contour, seed-relative so the three passes stay welded. */
@keyframes monogramContourHighlight {
  from { stroke-dashoffset: var(--comet-seed); }
  to { stroke-dashoffset: calc(var(--comet-seed) - 100px); }
}
@keyframes brandReveal { from { opacity: 0; clip-path: inset(0 0 100%); } to { opacity: 1; clip-path: inset(0); } }
/* Full artwork is the default, including reduced motion and browsers without
   scroll timelines. White pens reveal copper along the Illustrator contours. */
.brand-seal-pen { stroke-dasharray: 100; stroke-dashoffset: 0; }
@keyframes brandSealDraw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .contact { view-timeline-name: --contact-band; }
    .contact-seal-halo { animation: contactSealHalo linear both; animation-timeline: --contact-band; animation-range: cover 10% cover 50%; }
    .brand-seal-pen { animation: brandSealDraw linear both; animation-timeline: --contact-band; }
    .brand-seal-ring-0 { animation-range: cover 12% cover 38%; }
    .brand-seal-ring-1 { animation-range: cover 18% cover 44%; }
    .brand-seal-glyph-0 { animation-range: cover 26% cover 46%; }
    .brand-seal-glyph-1 { animation-range: cover 36% cover 48%; }
    .brand-seal-glyph-2 { animation-range: cover 40% cover 54%; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .brand-mark-highlight { display: none; }
  .brand-mark--loader .brand-mark-rings, .brand-mark--loader .brand-mark-glyph { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SYSTÈME DE BOUTONS — SOURCE UNIQUE DE VÉRITÉ
   ───────────────────────────────────────────────────────────────────────────
   ⚠️  À LIRE AVANT TOUTE MODIFICATION (humain ou IA)  ⚠️

   Le site ne connaît que DEUX templates de boutons. Ils sont définis ICI,
   et NULLE PART AILLEURS :

     .button-primary    → bouton cuivre plein
                          « Parler à un expert » (header)
                          « Découvrir le groupe » (hero)

     .button-secondary  → bouton onyx à liseré cuivre  (template par défaut)
                          « Parler à un expert » (hero)
                          « Prendre contact » (section contact)

   RÈGLES NON NÉGOCIABLES
   1. Tout bouton passe par <KineticButton variant="primary|secondary">
      (components/fortalys/home-page.tsx). On n'écrit jamais un bouton à la
      main, et on ne duplique jamais son markup.
   2. L'apparence d'un template se règle UNIQUEMENT via les variables
      --button-* du bloc de ce template. Changer une variable dans
      .button-primary ou .button-secondary met à jour TOUS les boutons de ce
      template, partout sur le site — c'est exactement l'objectif.
   3. INTERDIT : styler un bouton depuis son contexte
      (ex. `.hero-actions .button { background: … }`), ou créer une classe
      one-off pour un seul bouton. Un bouton qui doit être visuellement
      différent est soit un NOUVEAU template déclaré ici, soit pas un bouton.
   4. Le contexte ne pilote que le PLACEMENT (marge, largeur, flex) — jamais
      les couleurs, le relief, ni les animations.
   5. Structure et interactions (.button-frame / -core / -halo / -lustre /
      -grain / -impact, ainsi que :hover, :focus-visible, :active) sont
      partagées et n'existent qu'une seule fois, dans le bloc `.button`.
      Si un template a besoin d'un hover différent, on ajoute une VARIABLE
      au bloc partagé — on ne réécrit pas la règle d'état.

   ÉTATS AU SURVOL : ils se règlent PAR TOKENS, jamais en réécrivant une règle.
     --button-rim / --button-rim-hover        épaisseur du liseré, repos / survol
     --button-edge / --button-edge-hover      teinte du liseré, repos / survol
     --button-halo-hover, --button-frame-hover-filter, …
   Les tokens `-hover` ont un repli neutre : un template qui ne les redéfinit
   pas conserve au survol exactement son apparence de repos.

   MODIFICATEURS DE TAILLE (ne touchent que la géométrie, jamais la peau) :
     .button-compact     → version réduite, utilisée dans la barre de navigation
     .button-nav-mobile  → version grand format pour le menu mobile et tablette,
                           calibrée à l'échelle de la typographie du burger menu

   AJOUTER UN TEMPLATE : dupliquer un bloc de template ci-dessous, renommer,
   ne redéfinir que des variables --button-*, puis étendre le type `variant`
   de KineticButton. Rien d'autre à toucher.
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- Structure + comportement partagés par TOUS les templates ------------- */
.button {
  /* Géométrie — surchargeable par un modificateur de taille (.button-compact) */
  --button-notch: 13px;
  --button-rim: 1px;      /* épaisseur du liseré (bordure) */
  --button-rim-hover: var(--button-rim);   /* épaisseur du liseré au survol */
  --button-height: 54px;
  --button-padding-x: 27px;
  --button-gap: 15px;
  --button-font-size: .7rem;
  --button-arrow-size: 18px;

  /* La peau (couleurs, dégradés, lueurs) est fournie par le template.
     Voir « TEMPLATE SECONDAIRE » / « TEMPLATE PRIMAIRE » plus bas.
     Repli neutre : un template qui ne redéfinit pas --button-edge-hover
     garde son liseré de repos au survol. */
  --button-edge-hover: var(--button-edge);

  position: relative;
  isolation: isolate;
  min-height: var(--button-height);
  padding: 0 var(--button-padding-x);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--button-gap);
  border: 0;
  color: var(--button-text);
  font-size: var(--button-font-size);
  font-weight: 700;
  letter-spacing: .045em;
  cursor: pointer;
  transform: translate3d(0, 0, 0);
  transition: color .4s var(--button-ease), filter .45s var(--button-ease), transform .45s var(--button-ease);
  -webkit-tap-highlight-color: transparent;
}
.button-frame {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--button-edge);
  clip-path: polygon(var(--button-notch) 0, calc(100% - var(--button-notch)) 0, 100% 50%, calc(100% - var(--button-notch)) 100%, var(--button-notch) 100%, 0 50%);
  transform: translateZ(0);
  backface-visibility: hidden;
  contain: paint;
  transition: inset .5s var(--button-ease), filter .45s var(--button-ease);
}
.button-frame::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  background: var(--button-edge-hover);
  transition: opacity .42s var(--button-ease);
}
.button-frame::after {
  content: '';
  position: absolute;
  inset: 5px 7px;
  z-index: 5;
  padding: 1px;
  opacity: var(--button-inline-opacity);
  pointer-events: none;
  background: var(--button-inline);
  clip-path: polygon(calc(var(--button-notch) - 7px) 0, calc(100% - var(--button-notch) + 7px) 0, 100% 50%, calc(100% - var(--button-notch) + 7px) 100%, calc(var(--button-notch) - 7px) 100%, 0 50%);
  -webkit-mask: linear-gradient(var(--black) 0 0) content-box, linear-gradient(var(--black) 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}
.button-core,
.button-halo,
.button-lustre,
.button-grain {
  position: absolute;
  pointer-events: none;
}
.button-core {
  inset: var(--button-rim);
  background: var(--button-core);
  clip-path: polygon(calc(var(--button-notch) - var(--button-rim)) 0, calc(100% - var(--button-notch) + var(--button-rim)) 0, 100% 50%, calc(100% - var(--button-notch) + var(--button-rim)) 100%, calc(var(--button-notch) - var(--button-rim)) 100%, 0 50%);
  transition: inset .42s var(--button-ease), clip-path .42s var(--button-ease);
}
.button-core::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0;
  background: var(--button-core-hover);
  transition: opacity .42s var(--button-ease);
}
.button-halo {
  inset: var(--button-rim);
  z-index: 2;
  opacity: var(--button-halo-opacity);
  background: var(--button-halo);
  transition: opacity .42s var(--button-ease), transform .55s var(--button-ease), inset .42s var(--button-ease);
}
.button-lustre {
  z-index: 3;
  top: -55%;
  bottom: -55%;
  left: -44%;
  width: 34%;
  opacity: 0;
  background: linear-gradient(90deg, transparent, rgb(var(--color-white-rgb) / .72), transparent);
  transform: translate3d(-70%, 0, 0) skewX(-18deg);
  transition: opacity .24s ease, transform .78s var(--button-ease);
  mix-blend-mode: soft-light;
}
.button-grain {
  inset: var(--button-rim);
  z-index: 4;
  opacity: .1;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 110 56' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.86' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.5'/%3E%3C/svg%3E");
  mix-blend-mode: soft-light;
}
.button-label {
  position: relative;
  z-index: 2;
  white-space: nowrap;
}
.button-arrow {
  position: relative;
  z-index: 1;
  width: var(--button-arrow-size);
  height: var(--button-arrow-size);
  flex: 0 0 auto;
  overflow: visible;
  transform: translate3d(0, 0, 0);
  transition: transform .5s var(--button-ease), opacity .35s ease;
}
.button-impact {
  position: absolute;
  z-index: 3;
  left: var(--impact-x);
  top: var(--impact-y);
  width: 14px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(var(--color-white-rgb) / .84), rgb(var(--color-champagne-rgb) / .28) 40%, transparent 72%);
  transform: translate(-50%, -50%) scale(0);
  animation: buttonBloom .62s var(--button-ease) both;
  mix-blend-mode: screen;
  pointer-events: none;
}

/* États partagés — un template ne les réécrit jamais, il ajuste ses variables. */
.button:hover,
.button:focus-visible { --button-rim: var(--button-rim-hover); }
.button:hover .button-frame::before,
.button:focus-visible .button-frame::before { opacity: 1; }
.button:hover {
  color: var(--button-text-hover);
  filter: drop-shadow(0 12px 18px var(--button-glow)) drop-shadow(0 2px 4px rgb(var(--color-black-rgb) / .22));
  transform: translate3d(0, -2px, 0);
}
.button:hover .button-frame,
.button:focus-visible .button-frame { inset: -2px -5px; filter: var(--button-frame-hover-filter); }
.button:hover .button-core::after,
.button:focus-visible .button-core::after { opacity: 1; }
.button:hover .button-halo,
.button:focus-visible .button-halo {
  opacity: var(--button-halo-hover-opacity);
  background: var(--button-halo-hover);
  transform: scale(var(--button-halo-hover-scale));
}
.button:hover .button-lustre,
.button:focus-visible .button-lustre { opacity: .62; transform: translate3d(430%, 0, 0) skewX(-18deg); }
.button:hover .button-arrow { transform: translate3d(3px, -3px, 0); }
.button:active { filter: drop-shadow(0 4px 9px var(--button-glow)); transform: translate3d(0, 0, 0); transition-duration: .12s; }
.button:active .button-frame { inset: 0 -1px; transition-duration: .12s; }
.button:focus-visible { outline: 1px solid var(--copper-highlight); outline-offset: 5px; filter: drop-shadow(0 0 8px rgb(var(--color-copper-light-rgb) / .42)); }
.button:disabled { cursor: wait; opacity: .64; filter: saturate(.55); pointer-events: none; }

/* ═══ TEMPLATE SECONDAIRE — onyx à liseré cuivre ═══════════════════════════
   Utilisé par : « Parler à un expert » (hero) et « Prendre contact » (contact).

   ⚠️ Ce bloc ne DOIT cibler que .button-secondary. Ne jamais y rajouter `.button`
   « au cas où » : ce sélecteur toucherait aussi les boutons primaires, qui
   hériteraient en silence de tout token que .button-primary ne redéfinit pas.
   C'est exactement ce qui est arrivé aux tokens de survol. Chaque bouton reçoit
   toujours une classe de template, garantie par KineticButton (variant typé,
   valeur par défaut 'secondary') — le filet de sécurité est donc côté composant.
   ═══════════════════════════════════════════════════════════════════════════ */
.button-secondary {
  --button-edge: linear-gradient(118deg, rgb(var(--color-copper-rgb) / .5), rgb(var(--color-copper-light-rgb) / .34) 45%, rgb(var(--color-ink-soft-rgb) / .92) 100%);
  --button-core: linear-gradient(118deg, color-mix(in srgb, var(--ink), var(--ink-deep) 65%) 0%, color-mix(in srgb, var(--ink-soft), var(--white) 5%) 52%, var(--ink) 100%);
  --button-core-hover: linear-gradient(118deg, rgb(var(--color-ivory-rgb) / .025) 0%, rgb(var(--color-copper-rgb) / .055) 48%, rgb(var(--color-ink-soft-rgb) / .18) 100%);
  --button-inline: linear-gradient(118deg, rgb(var(--color-champagne-rgb) / .9), rgb(var(--color-copper-rgb) / .18) 50%, rgb(var(--color-champagne-rgb) / .74));
  --button-inline-opacity: .1;
  --button-rim-hover: 2px;
  --button-edge-hover: linear-gradient(118deg, rgb(var(--color-copper-light-rgb) / .82), rgb(var(--color-champagne-rgb) / .95) 45%, rgb(var(--color-copper-rgb) / .58) 100%);
  --button-text: var(--ivory);
  --button-text-hover: var(--ivory);
  --button-light: rgb(var(--color-copper-light-rgb) / .34);
  --button-glow: rgb(var(--color-black-rgb) / .34);
  --button-halo: radial-gradient(circle 92px at 82% 18%, var(--button-light), transparent 72%);
  --button-halo-opacity: .36;
  --button-halo-hover: radial-gradient(circle 104px at 82% 18%, rgb(var(--color-copper-light-rgb) / .09), rgb(var(--color-ivory-rgb) / .025) 42%, transparent 72%);
  --button-halo-hover-opacity: .58;
  --button-halo-hover-scale: 1.16;
  --button-frame-hover-filter: brightness(1.065) contrast(1.015);
}

/* ═══ TEMPLATE PRIMAIRE — cuivre plein ═════════════════════════════════════
   Utilisé par : « Parler à un expert » (header) et « Découvrir le groupe » (hero).

   Au survol : liseré doré plus épais, et surtout une face PLUS lumineuse.
   Attention au piège corrigé ici — éclaircir en superposant du blanc
   (--button-core-hover / --button-halo-hover) délave le dégradé cuivre et
   aplatit son modelé : le bouton paraît alors plus terne survolé qu'au repos.
   La luminosité se gagne par --button-frame-hover-filter, qui multiplie et
   préserve le contraste ; les voiles ne servent qu'à réchauffer légèrement.
   ═══════════════════════════════════════════════════════════════════════════ */
.button-primary {
  /* — Rampe cuivrée locale du bouton primaire —
     Les dix arrêts de ses quatre dégradés étaient écrits en dur ; ce sont en
     réalité dix positions sur une même rampe, toutes composables depuis la
     palette. Les nommer ici plutôt que de les inliner rend le modelé lisible
     et le fait suivre automatiquement toute évolution du cuivre.
     Du plus sombre au plus lumineux : */
  --pc-900: color-mix(in srgb, var(--copper-dark), var(--copper) 25%);
  --pc-800: color-mix(in srgb, var(--copper-dark), var(--copper) 35%);
  --pc-700: color-mix(in srgb, var(--copper-dark), var(--copper) 65%);
  --pc-600: color-mix(in srgb, var(--copper), var(--black) 5%);
  --pc-500: color-mix(in srgb, var(--copper), var(--copper-highlight) 5%);
  --pc-400: color-mix(in srgb, var(--copper), var(--white) 10%);
  --pc-300: color-mix(in srgb, var(--copper-dark), var(--copper-light) 80%);
  --pc-200: color-mix(in srgb, var(--copper), var(--copper-light) 90%);
  --pc-100: color-mix(in srgb, var(--copper-light), var(--copper-highlight) 95%);
  --pc-050: color-mix(in srgb, var(--copper-highlight), var(--white) 30%);

  --button-edge: linear-gradient(118deg, var(--pc-400) 0%, var(--pc-600) 45%, var(--pc-800) 100%);
  --button-edge-hover: linear-gradient(118deg, var(--pc-100) 0%, var(--pc-050) 45%, var(--pc-300) 100%);
  --button-rim-hover: 2px;
  --button-core: linear-gradient(118deg, var(--pc-900) 0%, var(--pc-500) 38%, var(--pc-200) 73%, var(--pc-700) 100%);
  --button-core-hover: linear-gradient(118deg, rgb(var(--color-champagne-rgb) / .18) 0%, transparent 46%, rgb(var(--color-champagne-rgb) / .16) 100%);
  --button-inline: linear-gradient(118deg, rgb(var(--color-champagne-rgb) / .9), rgb(var(--color-copper-rgb) / .18) 50%, rgb(var(--color-champagne-rgb) / .74));
  --button-inline-opacity: .1;
  --button-text: var(--ink-deep);
  --button-text-hover: var(--ink-deep);
  --button-light: rgb(var(--color-white-rgb) / .58);
  --button-glow: rgb(var(--color-copper-light-rgb) / .34);
  --button-halo: radial-gradient(circle 92px at 82% 18%, var(--button-light), transparent 72%);
  --button-halo-opacity: .36;
  --button-halo-hover: radial-gradient(circle 104px at 82% 18%, rgb(var(--color-champagne-rgb) / .5), transparent 70%);
  --button-halo-hover-opacity: .6;
  --button-halo-hover-scale: 1.16;
  --button-frame-hover-filter: saturate(1.16) brightness(1.13);
}

/* Modificateur de TAILLE — ne redéfinit que la géométrie, jamais la peau.
   Combinable avec n'importe quel template. */
.button-compact {
  --button-notch: 10px;
  --button-height: 44px;
  --button-padding-x: 19px;
  --button-gap: 11px;
  --button-font-size: .64rem;
  --button-arrow-size: 16px;
}

@keyframes buttonBloom { 0% { opacity: .82; transform: translate(-50%, -50%) scale(0); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(20); } }

/* ═══════════════════════════════════════════════════════════════════════════
   PAGE D'ATTENTE FORTALYS — mise en page
   ───────────────────────────────────────────────────────────────────────────
   ⚠️  À LIRE AVANT TOUTE MODIFICATION (humain ou IA)  ⚠️

   Page autonome et TEMPORAIRE, compilée par scripts/build-construction.mjs.
   La feuille servie concatène, dans cet ordre :
     app/theme.css     palette — la seule source des couleurs
     app/brand.css     animations officielles du logo (comète, révélation)
     .button…          bloc « SYSTÈME DE BOUTONS » extrait de app/globals.css
     ce fichier        la mise en page de la page d'attente, et rien d'autre

   RÈGLES
   1. Aucune couleur écrite ici : jetons, rgb(var(--color-…-rgb) / a) ou
      color-mix(). `npm run check:palette` scrute ce dossier.
   2. Le bouton d'envoi est celui du site (KineticActionButton) : ne jamais
      restyler `.button` ici, sa peau vit dans globals.css.
   3. Ce fichier n'est PAS traité par Lightning CSS : les préfixes nécessaires
      (-webkit-backdrop-filter) s'écrivent à la main, avant la propriété.
   4. La trame alvéolaire reprend la tuile officielle
      public/assets/brand/honeycomb-tile-*.svg et la géométrie de la trame du
      site (rayon 42 px), sans data-URI : aucune exception de palette en plus.
   ═══════════════════════════════════════════════════════════════════════════ */

/* — Polices auto-hébergées (variables, sous-ensemble latin) ———————————— */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/cormorant-garamond-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/cormorant-garamond-italic-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-latin.woff2') format('woff2');
}
/* Replis métriques identiques à ceux de next/font : pas de saut à l'affichage. */
@font-face {
  font-family: 'Cormorant Garamond Fallback';
  src: local('Times New Roman');
  ascent-override: 95.27%;
  descent-override: 29.59%;
  line-gap-override: 0%;
  size-adjust: 96.98%;
}
@font-face {
  font-family: 'Manrope Fallback';
  src: local('Arial');
  ascent-override: 103.31%;
  descent-override: 29.07%;
  line-gap-override: 0%;
  size-adjust: 103.19%;
}

@property --sweep { syntax: '<angle>'; inherits: false; initial-value: 0deg; }

:root {
  --font-display: 'Cormorant Garamond', 'Cormorant Garamond Fallback';
  --font-sans: 'Manrope', 'Manrope Fallback';
  /* Les entrées de la page attendent l'ouverture du rideau. */
  --intro-delay: 1.3s;
  color-scheme: dark;
}
html.intro-seen { --intro-delay: 0s; }

/* — Socle ——————————————————————————————————————————————————————————————— */
* { box-sizing: border-box; }
html { background: var(--ink); -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  overflow-x: hidden;
  background: var(--ink);
  color: var(--ivory);
  font-family: var(--font-sans), sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
/* Grain photographique du site : bruit sans couleur, en lumière douce. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: .045;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
a { color: inherit; text-decoration: none; }
button, input, textarea { color: inherit; font: inherit; }
/* Le reset Tailwind du site (preflight) n'est pas servi ici : sans lui, le fond
   gris natif de <button> déborderait des pointes du bouton cinétique. */
button { border: 0; background: transparent; }
img, svg { display: block; max-width: 100%; }
::selection { background: var(--copper); color: var(--ink); }
:focus-visible { outline: 1px solid var(--copper-light); outline-offset: 5px; }
.shell { width: var(--shell); margin-inline: auto; }

/* ═══ RIDEAU D'OUVERTURE ════════════════════════════════════════════════════
   Le monogramme se révèle (animation « loader » de brand.css), la signature
   monte, un filet cuivré se trace, puis deux panneaux s'écartent sur la page.
   Une fois par session ; jamais en mouvement réduit. */
.intro {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  pointer-events: none;
  animation: introGone 0s linear 2.2s forwards;
}
html.intro-seen .intro { display: none; }
.intro-panel {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50.5%;
  background:
    radial-gradient(120% 70% at var(--panel-origin) 50%, rgb(var(--color-copper-rgb) / .06), transparent 60%),
    var(--ink-deep);
  animation: introPanel .9s var(--ease-out-veil) 1.2s forwards;
}
.intro-panel--left { left: 0; --panel-origin: 100%; --panel-exit: -101%; }
.intro-panel--right { right: 0; --panel-origin: 0%; --panel-exit: 101%; }
.intro-core {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 22px;
  animation: introCoreOut .5s var(--ease-out-veil) 1.02s forwards;
}
.intro-mark { width: clamp(84px, 9vw, 116px); filter: drop-shadow(0 12px 40px rgb(var(--color-black-rgb) / .5)); }
.intro-wordmark { width: clamp(170px, 17vw, 224px); color: var(--ivory); animation: fadeUp .8s var(--ease) .28s both; }
.intro-line { position: relative; width: 132px; height: 1px; overflow: hidden; background: var(--line); }
.intro-line i {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--copper-dark), var(--copper-light), var(--copper-highlight));
  transform-origin: left;
  animation: lineDraw .9s var(--ease) .12s both;
}

/* ═══ SCÈNE ═════════════════════════════════════════════════════════════════ */
.stage {
  position: relative;
  isolation: isolate;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  overflow: hidden;
}
.stage-media {
  position: absolute;
  inset: 0 0 auto;
  z-index: -3;
  /* Le premier écran seulement : au-delà, l'ombre fond la photo dans l'onyx. */
  height: min(100%, 100svh);
  overflow: hidden;
}
.stage-media picture {
  position: absolute;
  inset: -3%;
  display: block;
  animation: stageZoom 9s var(--ease) var(--intro-delay) both;
}
.stage-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 46%; }
.stage-shade {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(52% 64% at 76% 46%, rgb(var(--color-copper-rgb) / .1), transparent 66%),
    linear-gradient(90deg, rgb(var(--color-ink-deep-rgb) / .95) 0%, rgb(var(--color-ink-deep-rgb) / .8) 34%, rgb(var(--color-ink-deep-rgb) / .42) 62%, rgb(var(--color-ink-deep-rgb) / .62) 100%),
    linear-gradient(0deg, var(--ink) 0%, rgb(var(--color-ink-rgb) / .55) 24%, transparent 54%),
    linear-gradient(180deg, rgb(var(--color-ink-deep-rgb) / .7), transparent 24%);
}

/* — Trame alvéolaire : taupe au repos, lumière et alvéoles cuivrées autour
     du pointeur (ou d'une dérive lente quand personne ne bouge). —————————— */
.hive {
  --hive-r: 42px;
  --hive-w: calc(var(--hive-r) * 1.7320508);
  --hive-h: calc(var(--hive-r) * 3);
  --hive-x: 0px;
  --hive-y: 0px;
  --halo: 720px;
  --beam: 540px;
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.hive-cells {
  position: absolute;
  inset: 0;
  opacity: .085;
  background: url('/assets/brand/honeycomb-tile-taupe.svg') 0 0 / var(--hive-w) var(--hive-h);
  mask-image: linear-gradient(180deg, transparent, var(--black) 16%, var(--black) 84%, transparent);
}
.hive-halo,
.hive-beam {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  transition: opacity 1.1s var(--ease);
  will-change: translate;
}
.hive-halo {
  width: var(--halo);
  height: var(--halo);
  translate: calc(var(--hive-x) - var(--halo) / 2) calc(var(--hive-y) - var(--halo) / 2);
  background: radial-gradient(circle closest-side, rgb(var(--color-copper-rgb) / .17), rgb(var(--color-copper-rgb) / .05) 42%, transparent 76%);
}
.hive-beam {
  width: var(--beam);
  height: var(--beam);
  translate: calc(var(--hive-x) - var(--beam) / 2) calc(var(--hive-y) - var(--beam) / 2);
  /* Décalage inverse : les alvéoles cuivrées retombent sur la trame taupe. */
  background: url('/assets/brand/honeycomb-tile-copper.svg') calc(var(--beam) / 2 - var(--hive-x)) calc(var(--beam) / 2 - var(--hive-y)) / var(--hive-w) var(--hive-h);
  mask-image: radial-gradient(circle closest-side, var(--black), rgb(var(--color-black-rgb) / .32) 46%, transparent);
}
.hive.is-lit .hive-halo { opacity: 1; transition-duration: .6s; }
.hive.is-lit .hive-beam { opacity: .26; transition-duration: .6s; }
.hive.is-drifting .hive-halo { opacity: .75; }
.hive.is-drifting .hive-beam { opacity: .15; }

/* ═══ EN-TÊTE ═══════════════════════════════════════════════════════════════ */
/* Trois colonnes : logo à gauche, mention au centre exact de la page, la
   troisième colonne vide ne sert qu'à équilibrer. */
.topbar {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 18px 28px;
  padding-top: max(env(safe-area-inset-top), clamp(22px, 3.4vw, 40px));
  animation: fadeIn 1s var(--ease) var(--intro-delay) both;
}
.topbar-brand { display: block; justify-self: start; width: clamp(148px, 13vw, 184px); }
.topbar-brand img { width: 100%; height: auto; aspect-ratio: 904.9 / 200; }

/* Mention « Nouveau site en finalisation » : deux filets cuivrés se tracent
   depuis le texte vers l'extérieur, puis un reflet champagne parcourt les
   lettres de loin en loin — la même lumière que la comète du monogramme. */
.topbar-status {
  --status-track: .34em;
  display: inline-flex;
  align-items: center;
  gap: clamp(14px, 1.6vw, 22px);
  margin: 0;
  font-size: clamp(.68rem, .86vw, .82rem);
  font-weight: 600;
  letter-spacing: var(--status-track);
  text-transform: uppercase;
  white-space: nowrap;
}
.topbar-status::before,
.topbar-status::after {
  content: '';
  width: clamp(28px, 4.4vw, 68px);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--copper-light));
  transform-origin: right;
  animation: lineDraw 1.2s var(--ease) calc(var(--intro-delay) + .2s) both;
}
.topbar-status::after { background: linear-gradient(90deg, var(--copper-light), transparent); transform-origin: left; }
.topbar-status-text {
  /* L'interlettrage s'ajoute aussi après la dernière lettre : on le reprend
     pour que le texte reste centré entre ses deux filets. */
  margin-right: calc(var(--status-track) * -1);
  background: linear-gradient(100deg, var(--ivory-dim) 42%, var(--copper-highlight) 50%, var(--ivory-dim) 58%) 100% 0 / 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: statusSheen 7s var(--ease-out-veil) calc(var(--intro-delay) + 1.4s) infinite;
}

/* ═══ CONTENU ═══════════════════════════════════════════════════════════════ */
.stage-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(420px, 520px);
  gap: clamp(48px, 7vw, 128px);
  align-items: center;
  padding-block: clamp(40px, 6vh, 80px) clamp(32px, 5vh, 64px);
}
/* Le titre se règle sur SA colonne : « Structurer aujourd’hui. » mesure
   8,2 em en Cormorant, 11.8cqi le garde toujours sur une ligne. */
.pitch { container-type: inline-size; }

.eyebrow {
  margin: 0;
  color: var(--copper-light);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .28em;
  text-transform: uppercase;
  animation: fadeUp .9s var(--ease) calc(var(--intro-delay) + .05s) both;
}
.eyebrow::before {
  content: '';
  display: inline-block;
  width: 34px;
  height: 1px;
  margin-right: 14px;
  background: var(--copper);
  vertical-align: middle;
}

.pitch h1 {
  margin: clamp(22px, 3vh, 34px) 0 0;
  font: 400 clamp(2.7rem, 11.8cqi, 5.4rem) / var(--display-leading) var(--font-display), serif;
  letter-spacing: -.035em;
}
.title-line { display: block; overflow: hidden; padding-bottom: .11em; }
.title-line > span { display: block; animation: titleIn 1.2s var(--ease) calc(var(--intro-delay) + .12s) both; }
.title-line + .title-line > span { animation-delay: calc(var(--intro-delay) + .26s); }
.title-line--copper { color: var(--copper-light); }

.pitch-lead {
  max-width: 35em;
  margin: clamp(22px, 3.2vh, 34px) 0 0;
  color: var(--ivory-dim);
  font-size: clamp(.95rem, 1.08vw, 1.06rem);
  font-weight: 300;
  line-height: 1.8;
  animation: fadeUp 1s var(--ease) calc(var(--intro-delay) + .5s) both;
}

.trio {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(14px, 2vw, 30px);
  max-width: 640px;
  margin: clamp(30px, 4.6vh, 50px) 0 0;
  padding: 0;
  list-style: none;
}
.trio li {
  --i: 0;
  position: relative;
  display: grid;
  gap: 7px;
  padding-top: 18px;
  animation: fadeUp .9s var(--ease) calc(var(--intro-delay) + .62s + var(--i) * .1s) both;
}
.trio li:nth-child(2) { --i: 1; }
.trio li:nth-child(3) { --i: 2; }
.trio li::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, var(--copper), rgb(var(--color-ivory-rgb) / .1));
  transform-origin: left;
  animation: lineDraw 1.1s var(--ease) calc(var(--intro-delay) + .7s + var(--i) * .12s) both;
}
.trio b { color: var(--copper-light); font: 400 1.75rem / 1 var(--font-display), serif; }
.trio strong { font-size: .64rem; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; }
.trio small { color: var(--stone); font-size: .74rem; line-height: 1.5; }

.direct {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin-top: clamp(30px, 4.4vh, 46px);
  animation: fadeUp .9s var(--ease) calc(var(--intro-delay) + .92s) both;
}
.direct > p { margin: 0; color: var(--stone); font-size: .84rem; }
.text-button {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 0 0 6px;
  border: 0;
  border-bottom: 1px solid rgb(var(--color-copper-light-rgb) / .5);
  background: none;
  color: var(--ivory);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .02em;
  cursor: pointer;
  transition: color .35s var(--ease), gap .35s var(--ease), opacity .35s var(--ease);
}
.text-button svg { width: 16px; height: 16px; }
.text-button:hover { color: var(--copper-light); gap: 18px; }
.text-button:disabled { cursor: wait; opacity: .6; }
.coordinates {
  display: grid;
  flex-basis: 100%;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px 28px;
  max-width: 640px;
}
.coordinates[hidden] { display: none; }
.coordinate {
  --i: 0;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
  animation: fadeUp .7s var(--ease) calc(var(--i) * .08s) both;
}
.coordinate:nth-child(2) { --i: 1; }
.coordinate:nth-child(3) { --i: 2; }
.coordinate svg { flex: none; width: 18px; height: 18px; margin-top: 4px; color: var(--copper-light); stroke-width: 1.5; }
.coordinate small {
  display: block;
  color: var(--stone);
  font-size: .54rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
}
.coordinate [data-value] { font-size: .88rem; line-height: 1.5; transition: color .3s var(--ease); }
a.coordinate:hover [data-value] { color: var(--copper-light); }
.direct-error { flex-basis: 100%; color: var(--signal); font-size: .74rem; }
.direct-error:empty { display: none; }

/* ═══ PANNEAU DE CONTACT ════════════════════════════════════════════════════
   Verre fumé sur la photographie, liseré parcouru par une lumière cuivrée,
   sceau du monogramme (comète officielle de brand.css) à cheval sur le bord. */
.panel {
  --panel-x: 72%;
  --panel-y: 0%;
  position: relative;
  isolation: isolate;
  padding: clamp(56px, 5vw, 66px) clamp(24px, 3vw, 44px) clamp(24px, 2.4vw, 32px);
  animation: panelIn 1.3s var(--ease) calc(var(--intro-delay) + .3s) both;
}
.panel::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(circle 420px at var(--panel-x) var(--panel-y), rgb(var(--color-copper-rgb) / .1), transparent 72%),
    linear-gradient(150deg, rgb(var(--color-ink-soft-rgb) / .88), rgb(var(--color-ink-deep-rgb) / .93));
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
  backdrop-filter: blur(18px) saturate(1.08);
  box-shadow: 0 40px 120px rgb(var(--color-black-rgb) / .48), inset 0 0 90px rgb(var(--color-black-rgb) / .3);
}
.panel::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: 1px;
  pointer-events: none;
  background:
    conic-gradient(from var(--sweep), transparent 0 70%, rgb(var(--color-copper-light-rgb) / .2) 78%, rgb(var(--color-copper-light-rgb) / .9) 86%, rgb(var(--color-champagne-rgb) / .95) 87.5%, transparent 91%),
    linear-gradient(rgb(var(--color-ivory-rgb) / .13), rgb(var(--color-ivory-rgb) / .13));
  mask-image: linear-gradient(var(--black) 0 0), linear-gradient(var(--black) 0 0);
  mask-clip: content-box, border-box;
  mask-composite: exclude;
  animation: panelSweep 8s linear infinite;
}

.panel-seal {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: clamp(76px, 6.4vw, 92px);
  aspect-ratio: 1;
  translate: -50% -50%;
}
.panel-seal-aura {
  position: absolute;
  inset: -22%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--ink-deep) 40%, rgb(var(--color-ink-deep-rgb) / .72) 54%, transparent 71%);
  animation: fadeIn .8s var(--ease) calc(var(--intro-delay) + .5s) both;
}
.panel-seal .seal-mark {
  position: relative;
  width: 100%;
  filter: drop-shadow(0 10px 26px rgb(var(--color-black-rgb) / .5));
  animation: sealIn 1.3s var(--ease) calc(var(--intro-delay) + .55s) both;
}

.panel-view[hidden] { display: none; }
.panel-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; }
.panel-kicker {
  margin: 0 0 10px;
  color: var(--copper-light);
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .24em;
  text-transform: uppercase;
}
.panel h2 {
  margin: 0;
  font: 400 clamp(1.85rem, 2.5vw, 2.4rem) / var(--display-leading) var(--font-display), serif;
  letter-spacing: -.012em;
}
.panel h2 em { color: var(--copper-light); font-weight: 300; }
.panel-count { flex: none; color: var(--stone); font-size: .54rem; font-weight: 700; letter-spacing: .15em; white-space: nowrap; }
.panel-count b { color: var(--copper-light); font: 400 1.9rem / 1 var(--font-display), serif; letter-spacing: 0; }
.panel-progress { position: relative; display: block; height: 1px; margin: 18px 0 22px; overflow: hidden; background: var(--line); }
.panel-progress i {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--copper-dark), var(--copper-light), var(--copper-highlight));
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  transition: transform .8s var(--ease);
}

/* — Champs ——————————————————————————————————————————————————————————————— */
.form { display: flex; flex-direction: column; gap: 17px; }
.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 17px 20px; }
.field { position: relative; display: flex; flex-direction: column; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.field-label {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 0;
  color: rgb(var(--color-ivory-rgb) / .72);
  font-size: .56rem;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
  transition: color .4s var(--ease);
}
.field-label b { color: var(--copper-light); font-size: .48rem; letter-spacing: .16em; transition: color .4s var(--ease); }
.field-label i { color: var(--copper-light); font-style: normal; }
.field-label small { margin-left: auto; color: rgb(var(--color-stone-rgb) / .8); font-size: .48rem; letter-spacing: .1em; }
.field:focus-within > .field-label { color: var(--ivory); }
.field.is-valid > .field-label b { color: var(--copper-highlight); }
.field input,
.field textarea {
  width: 100%;
  min-width: 0;
  border: 0;
  border-bottom: 1px solid rgb(var(--color-ivory-rgb) / .16);
  border-radius: 0;
  outline: 0;
  background: rgb(var(--color-black-rgb) / .16);
  color: var(--ivory);
  font: 300 .88rem / 1.5 var(--font-sans), sans-serif;
  transition: border-color .45s var(--ease), background .45s var(--ease), box-shadow .45s var(--ease);
}
.field input { height: 46px; padding: 0 12px; }
.field textarea { min-height: 96px; max-height: 42vh; padding: 12px; overflow-y: hidden; resize: none; }
.field input::placeholder,
.field textarea::placeholder { color: rgb(var(--color-stone-rgb) / .6); }
.field input:focus,
.field textarea:focus {
  border-color: var(--copper-light);
  background: rgb(var(--color-copper-rgb) / .07);
  box-shadow: 0 1px 0 var(--copper-light);
}
.field input:-webkit-autofill {
  -webkit-text-fill-color: var(--ivory);
  box-shadow: inset 0 0 0 100px var(--ink-soft);
  caret-color: var(--ivory);
}
.field.is-invalid input,
.field.is-invalid textarea { border-color: var(--signal); box-shadow: 0 1px 0 rgb(var(--color-signal-rgb) / .5); }
.field-feedback { color: var(--signal); font-size: .7rem; line-height: 1.45; }
.field-feedback:empty { display: none; }

/* — Domaines : pastilles à pointes, la découpe des boutons du site ———————— */
.field--chips > .field-label { margin-bottom: 10px; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { --notch: 9px; position: relative; display: inline-flex; cursor: pointer; }
.chip input { position: absolute; inset: 0; z-index: 1; margin: 0; opacity: 0; cursor: pointer; }
.chip span {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 calc(var(--notch) + 9px);
  background: rgb(var(--color-ivory-rgb) / .2);
  color: var(--ivory-dim);
  font-size: .7rem;
  font-weight: 600;
  clip-path: polygon(var(--notch) 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, var(--notch) 100%, 0 50%);
  transition: background .35s var(--ease), color .35s var(--ease);
}
.chip span::before {
  content: '';
  position: absolute;
  inset: 1px;
  z-index: -1;
  background: var(--ink-soft);
  clip-path: polygon(calc(var(--notch) - .5px) 0, calc(100% - var(--notch) + .5px) 0, 100% 50%, calc(100% - var(--notch) + .5px) 100%, calc(var(--notch) - .5px) 100%, 0 50%);
  transition: background .35s var(--ease);
}
.chip:hover span { background: rgb(var(--color-copper-light-rgb) / .6); color: var(--ivory); }
.chip input:checked + span { background: linear-gradient(118deg, var(--copper-highlight), var(--copper)); color: var(--copper-highlight); }
.chip input:checked + span::before {
  background: linear-gradient(118deg, color-mix(in srgb, var(--ink-soft), var(--copper) 26%), var(--ink-soft) 80%);
}
.chip input:focus-visible + span { background: var(--copper-highlight); color: var(--ivory); }
.field--chips.is-invalid .chip span { background: rgb(var(--color-signal-rgb) / .55); }

.honeypot { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* — Envoi ———————————————————————————————————————————————————————————————— */
.form-submit { display: flex; align-items: center; justify-content: space-between; gap: 16px 20px; margin-top: 4px; }
.form-status { display: flex; align-items: center; gap: 11px; max-width: 26ch; margin: 0; color: var(--stone); font-size: .72rem; line-height: 1.45; transition: color .35s var(--ease); }
.form-status-icon { position: relative; flex: none; width: 18px; height: 18px; color: var(--copper-light); }
.form-status-icon svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  stroke-width: 1.6;
  opacity: 0;
  transform: scale(.7);
  transition: opacity .35s var(--ease), transform .45s var(--ease);
}
.form-status:is([data-state='idle'], [data-state='sending']) .form-status-lock,
.form-status[data-state='error'] .form-status-alert,
.form-status[data-state='success'] .form-status-check { opacity: 1; transform: none; }
.form-status[data-state='sending'] .form-status-lock { animation: lockPulse 1.1s var(--ease) infinite; }
.form-status[data-state='error'] { color: var(--signal); }
.form-status[data-state='error'] .form-status-icon { color: var(--signal); }
.form-status.is-shake { animation: statusShake .5s var(--ease); }
.form-submit .button { flex: none; }
.form-legal { margin: 2px 0 0; color: rgb(var(--color-stone-rgb) / .85); font-size: .62rem; line-height: 1.65; }
.form-legal a {
  color: var(--ivory-dim);
  text-decoration: underline;
  text-decoration-color: rgb(var(--color-copper-light-rgb) / .45);
  text-underline-offset: 2px;
}
.form-legal a:hover { color: var(--copper-light); }
/* Badge masqué : la mention reCAPTCHA requise par Google est écrite ci-dessus. */
.grecaptcha-badge { visibility: hidden; }

/* — Confirmation ————————————————————————————————————————————————————————— */
.panel-view--success { display: flex; flex-direction: column; align-items: center; padding: 26px 0 10px; text-align: center; outline: 0; }
.success-emblem { width: 84px; margin-bottom: 26px; }
.success-emblem svg { width: 100%; height: auto; overflow: visible; }
.success-ring {
  stroke: var(--copper-light);
  stroke-width: 1.4;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: ringDraw 1.5s var(--ease) .1s forwards;
}
.success-ring--inner { stroke: rgb(var(--color-copper-light-rgb) / .38); stroke-width: 1; animation-delay: .4s; }
.success-check {
  stroke: var(--copper-highlight);
  stroke-width: 2.2;
  stroke-linecap: square;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: ringDraw .8s var(--ease) .95s forwards;
}
.panel-view--success h2 { margin-bottom: 18px; }
.success-copy { max-width: 34ch; margin: 0 0 30px; color: var(--ivory-dim); font-weight: 300; line-height: 1.75; }

/* ═══ PIED DE PAGE ══════════════════════════════════════════════════════════ */
.colophon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
  padding-block: 18px max(env(safe-area-inset-bottom), clamp(18px, 2.6vh, 26px));
  border-top: 1px solid var(--line);
  color: var(--stone);
  font-size: .64rem;
  letter-spacing: .04em;
  animation: fadeIn 1s var(--ease) calc(var(--intro-delay) + .9s) both;
}
.colophon p { margin: 0; }
.colophon-motto { font-size: .55rem; font-weight: 600; letter-spacing: .28em; text-transform: uppercase; }

/* ═══ ANIMATIONS ════════════════════════════════════════════════════════════ */
@keyframes introGone { to { visibility: hidden; } }
@keyframes introPanel { to { translate: var(--panel-exit) 0; } }
@keyframes introCoreOut { to { opacity: 0; transform: scale(1.04); } }
@keyframes titleIn { from { transform: translateY(110%); } to { transform: none; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes lineDraw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes stageZoom { from { transform: scale(1.08); } to { transform: scale(1); } }
@keyframes panelIn { from { opacity: 0; transform: translateY(34px); } to { opacity: 1; transform: none; } }
@keyframes sealIn { from { opacity: 0; transform: scale(.72) rotate(-10deg); } to { opacity: 1; transform: none; } }
@keyframes panelSweep { to { --sweep: 360deg; } }
/* Le reflet traverse le mot en 30 % du cycle, puis le texte reste au repos. */
@keyframes statusSheen { 0% { background-position: 100% 0; } 30%, 100% { background-position: 0 0; } }
@keyframes lockPulse { 50% { transform: scale(.86); opacity: .55; } }
@keyframes statusShake {
  20% { transform: translateX(-5px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}
@keyframes ringDraw { to { stroke-dashoffset: 0; } }

/* ═══ ADAPTATION ════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  .stage-grid { grid-template-columns: minmax(0, 1fr); gap: clamp(76px, 12vw, 104px); padding-top: clamp(48px, 9vw, 80px); }
  .pitch { max-width: 720px; }
  .panel { width: 100%; max-width: 640px; }
}
@media (max-width: 620px) {
  .stage-shade {
    background:
      radial-gradient(90% 50% at 60% 40%, rgb(var(--color-copper-rgb) / .08), transparent 70%),
      linear-gradient(180deg, rgb(var(--color-ink-deep-rgb) / .78) 0%, rgb(var(--color-ink-deep-rgb) / .62) 40%, rgb(var(--color-ink-rgb) / .8) 78%, var(--ink) 100%);
  }
  .stage-media img { object-position: 58% 46%; }
  .form-row { grid-template-columns: minmax(0, 1fr); }
  .trio { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .trio li { grid-template-columns: 2.4rem auto 1fr; align-items: baseline; gap: 12px; padding: 14px 0; }
  .trio small { justify-self: end; text-align: right; }
  .form-submit { flex-direction: column; align-items: stretch; }
  .form-status { max-width: none; }
}
@media (max-width: 860px) {
  .topbar { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .topbar-brand { justify-self: start; }
}
@media (max-width: 420px) {
  .topbar-status { --status-track: .24em; font-size: .6rem; }
}

@media (prefers-reduced-motion: reduce) {
  :root { --intro-delay: 0s; }
  .intro { display: none; }
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
