/* ============================================================================
   FORGE — canonical design system (consistency layer)
   ----------------------------------------------------------------------------
   Single source of truth for cross-page primitives that had drifted between
   the hand-built pages: the typographic scale and the hero component.

   Loaded LAST in <head> (after each page's inline <style>) so that, on
   equal-specificity rules, source order makes this file authoritative. It is
   intentionally NON-DESTRUCTIVE: it overrides only the typographic and
   geometric properties that must be identical site-wide, and leaves each
   page's layout-specific rules (max-width, margins, text-align, grids,
   animations) untouched.

   To revert: remove the <link> to this file from the pages. Nothing else
   depends on it.
   ----------------------------------------------------------------------------
   Fonts (loaded by every page): Archivo (display/body) + Space Mono (labels).
   ========================================================================== */

:root{
  /* ---- Unified type scale (fluid) ---------------------------------------- */
  /* Plancher bas (1.1rem) pour que le titre rétrécisse vraiment sur mobile : avec
     2.4rem il restait bloqué à 38.4px sous ~738px de viewport et la ligne longue
     ("forgées pour vous appartenir.") débordait/était coupée sur iPhone. Le coeff vw
     (5.8) est dimensionné pour que cette ligne reste ~87% de la largeur dispo a 375px
     (donc une seule ligne, avec marge) tout en restant aussi grosse que possible. Le
     max 4.4rem (desktop) est inchangé ; seules les petites largeurs grossissent. */
  --fs-display: clamp(1.1rem, 5.8vw, 4.4rem);   /* h1 / hero title          */
  --fs-h2:      clamp(1.6rem, 2.8vw, 2.5rem);    /* section headings         */
  --fs-h3:      clamp(1.15rem, 1.7vw, 1.45rem);  /* sub-headings             */

  --lh-display: 1.06;
  --lh-h2:      1.12;
  --lh-h3:      1.2;

  --track-display: -0.04em;
  --track-h2:      -0.025em;

  /* ---- Hero geometry tokens --------------------------------------------- */
  --hero-pad-top:    clamp(116px, 16vh, 200px);
  --hero-pad-bottom: clamp(48px, 6vw, 72px);

  /* Lean (content-index) hero used by studio / lab / réalisations / contact */
  --hero-lean-min:        78svh;
  --hero-lean-pad-top:    clamp(116px, 13vh, 168px);
  --hero-lean-pad-bottom: clamp(64px, 8vw, 92px);
}

/* ============================================================================
   1. TYPOGRAPHY — one scale everywhere
   Only the type properties are set here. Spacing, measure (max-width),
   alignment and color stay owned by the page so centered CTA headings,
   bio columns, etc. keep their layout.
   ========================================================================== */

/* Empêche le "font boosting" de Safari iOS de gonfler le titre et de défaire le
   dimensionnement responsive ci-dessous (sinon la ligne longue déborde du masque). */
html{ -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

.hero h1,
h1{
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
}

h2{
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--track-h2);
}

h3{
  font-family: 'Archivo', sans-serif;
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: -0.015em;
}

/* ============================================================================
   2. HERO — one reusable component, two intentional archetypes
   ----------------------------------------------------------------------------
   A) .hero (default) — immersive, full-bleed, title anchored low over the 3D
      scene. Used by: home, the four case studies, the two service pillars.
      The title now sits at the SAME vertical position on all of these pages.

   B) .hero.hero--index — leaner, vertically-centered hero for the
      content-index pages (studio, lab, réalisations, contact). Shorter,
      calmer, no 3D stage to anchor against.

   The masked line-reveal (h1 .l > span { translateY }) is height-relative and
   keeps working unchanged under the new type scale.
   ========================================================================== */

.hero{
  min-height: 100svh;
  justify-content: flex-end;
  padding: var(--hero-pad-top) var(--pad) var(--hero-pad-bottom);
}

.hero.hero--index{
  min-height: var(--hero-lean-min);
  justify-content: center;
  padding: var(--hero-lean-pad-top) var(--pad) var(--hero-lean-pad-bottom);
}

/* Full-bleed immersive hero, but content vertically centered (home). Keeps the
   100svh stage and immersive padding; only the anchor differs from .hero. */
.hero.hero--center{
  justify-content: center;
}

/* Hero meta line (breadcrumb + sector label) must stay on ONE line on mobile,
   across every page. The case-study breadcrumbs ("ACCUEIL / SOLUTIONS / …") are
   longer than the home's, so the type shrinks fluidly to fit the longest one
   rather than wrapping. Each span stays unbroken; flex space-between keeps the
   two parts pinned to the edges. */
@media (max-width: 600px){
  .hero-top{
    font-size: clamp(0.5rem, 2.6vw, 0.72rem);
    gap: 8px;
    letter-spacing: 0;
  }
  .hero-top span{ white-space: nowrap; }
  /* Longer case-study breadcrumbs (cockpit, simulation, reflective-echoes)
     shrink a little more so they still hold one line down to ~320px. */
  .hero-top.hero-top--long{ font-size: clamp(0.4rem, 2.05vw, 0.68rem); }
}

/* Split heroes (empreinte, reflective-echoes) keep their two-column inner
   layout and stay vertically centered. Higher specificity than the base .hero
   so the shared "anchor low" default does not push their columns down. The
   inner .hwrap already centers its two columns via align-items:center, so both
   the text and the viewer land on the same vertical axis. */
.hero.split-hero{
  justify-content: center;
}

/* ============================================================================
   3. DARK MODE — centralized theme layer
   ----------------------------------------------------------------------------
   Activation : data-theme="dark" sur <html> (posé par le snippet anti-flash
   en <head>, puis géré par assets/js/theme.js). Auto via prefers-color-scheme,
   bascule manuelle persistée dans localStorage['df-theme'].

   Pourquoi tout vit ici : forge.css est chargé EN DERNIER, donc
     html[data-theme="dark"]{…}        (spécificité 0,0,1,1)
   bat le :root inline de chaque page   (spécificité 0,0,1,0),
   et
     html[data-theme="dark"] .x{…}      (0,0,2,1)
   bat la règle .x{…} d’une page         (0,0,1,0).
   ~95% des surfaces utilisent var(--token) et basculent donc toutes seules ;
   on ne traite ci-dessous que les tokens + les surfaces « hostiles au thème »
   (couleurs en dur, filtres, dégradés métal, SVG de data-viz).

   Refs WCAG (ratio sur --bg #0c0b12) :
     corps  --ink #ece4d3  15.5:1 (AAA)
     --mut  #8a8170         5.1:1 (AA texte)
     --gold #9a7a3e         4.9:1 (AA texte) · --gold-hi #c9a96a 8.7:1
   ----------------------------------------------------------------------------
   Préférence couleur : pour respecter le suivi système quand l’utilisateur
   n’a pas tranché, le snippet anti-flash pose toujours data-theme explicitement
   (dark|light) — on ne s’appuie donc pas sur @media (prefers-color-scheme).
   ========================================================================== */

html[data-theme="dark"]{
  /* ---- Tokens (élévation : bg2/panel légèrement PLUS clairs que bg) ------ */
  --bg:#0c0b12;
  --bg2:#14110b;          /* surface élevée (cartes, lignes alternées)        */
  --panel:#100e0a;        /* panneau profond                                  */
  --ink:#ece4d3;          /* texte — 15.5:1 sur --bg                          */
  --mut:#8a8170;          /* texte secondaire — 5.1:1                         */
  --faint:#6f685a;        /* labels décoratifs / placeholders — 3.6:1 (large) */
  --line:rgba(255,255,255,.12);
  --line2:rgba(255,255,255,.06);
  --line-hi:rgba(255,255,255,.20);
  /* --gold / --gold-lo / --gold-hi / --gold-grad : inchangés (l’or porte
     parfaitement sur fond sombre). */
  color-scheme: dark;
}

/* ---- Atmosphère : halos chauds → halos dorés très assourdis, plus froids
   en bas pour creuser la profondeur sans virer « boueux » -------------------- */
html[data-theme="dark"] body::after{
  background:
    radial-gradient(120% 80% at 70% 0%, rgba(201,169,106,.10), transparent 55%),
    radial-gradient(100% 60% at 0% 100%, rgba(60,72,96,.10), transparent 50%),
    radial-gradient(60% 40% at 20% 80%, rgba(154,122,62,.10), transparent 60%);
}
/* Grain : un peu plus présent qu’en clair pour casser le banding du fond foncé. */
html[data-theme="dark"] body::before{ opacity:.07; }

/* ---- Curseur custom : en clair c’est #fff + mix-blend-mode:difference (qui
   « inverse » le fond). Sur fond très sombre, difference rend le blanc presque
   blanc → OK, mais on retire le blend pour un blanc franc et stable, et on
   monte la visibilité de l’anneau. -------------------------------------------- */
html[data-theme="dark"] .cur{ mix-blend-mode:normal; }
html[data-theme="dark"] .cur i{ background:#f3ecdd; }
html[data-theme="dark"] .cur .ring{ border-color:rgba(243,236,221,.65); }

/* ---- Barre de nav au scroll : fond OPAQUE (var(--bg) -> clair en light, sombre
   en dark) au lieu du translucide flou. Sinon, en scrollant, le contenu de la
   page transparait au-dessus du nav-inner (et sous la barre d'etat iOS). Le token
   --bg gere les deux themes, donc plus besoin d'un override dark separe ici. ---- */
nav.scrolled{ background:var(--bg); backdrop-filter:none; -webkit-backdrop-filter:none; }

/* iOS Safari : la barre d'etat / zone d'overscroll est teintee a partir du fond
   de l'element RACINE <html> (et non du theme-color, ni des elements fixes). Seul
   body avait un fond ; on fixe aussi html a var(--bg) -> noir en dark, creme en
   light, pour que la bande du haut reste solide quand le contenu defile dessous. */
html{ background:var(--bg); }

/* ---- iOS Safari : barre d'etat / zone d'overscroll en haut. Safari la teinte
   avec ce qui se trouve JUSTE AU-DESSUS du bord haut du viewport (y<0). Sur index,
   le prechargeur #pre (fixe, fond var(--bg), glisse a translateY(-100%)) occupe
   exactement cette bande -> barre d'etat solide. Les autres pages n'ont pas de
   #pre, d'ou le contenu (ex. poster d'empreinte) qui s'y montre. On replique avec
   un cache fixe en var(--bg) occupant la zone au-dessus du viewport (bottom:100%
   = bord haut, height vers le haut). Clair/sombre via --bg ; sans env()/viewport-fit. */
html::before{
  content:""; position:fixed; left:0; right:0;
  bottom:100%; height:100vh;
  background:var(--bg); z-index:9999; pointer-events:none;
}
/* Bas : on garde les CTA fixes au-dessus de l'indicateur d'accueil (home bar). */
.sticky-cta{ padding-bottom:calc(13px + env(safe-area-inset-bottom, 0px)); }
html[data-theme="dark"] body.menu-open nav{
  background:rgba(12,11,18,.97);
  border-bottom-color:var(--line);
}
html[data-theme="dark"] .mega{
  background:rgba(16,14,10,.97);
  box-shadow:0 40px 80px -40px rgba(0,0,0,.7);
}
html[data-theme="dark"] .mega a.mi:hover{ background:rgba(201,169,106,.12); }

/* ---- Crest du logo (SVG blanc teinté par filter). En clair : or sombre +
   ombre sombre. En sombre : on garde l’or mais on l’éclaircit et on remplace
   l’ombre sombre par une légère lueur claire pour qu’il décolle du fond. ------- */
html[data-theme="dark"] .brand .brand-crest{
  filter:brightness(0) saturate(100%) invert(72%) sepia(38%) saturate(560%)
         hue-rotate(2deg) brightness(95%) contrast(92%)
         drop-shadow(0 1px 3px rgba(0,0,0,.6));
}

/* ---- CTA métal (.navcta / .btn) + texte .gold-txt : l’or porte déjà très
   bien sur sombre. On ne touche pas le dégradé ; on renforce juste l’ancrage
   (ombre portée plus profonde + filet lumineux interne) pour qu’il « pose »
   sur le fond noir au lieu de flotter. Le texte reste #1c1408 (8.1:1). -------- */
html[data-theme="dark"] .navcta,
html[data-theme="dark"] .btn{
  box-shadow:0 1px 0 rgba(255,249,228,.85) inset,
             0 -2px 4px rgba(110,82,30,.40) inset,
             0 14px 30px -12px rgba(0,0,0,.75),
             0 0 0 1px rgba(201,169,106,.10);
}
html[data-theme="dark"] .navcta:hover,
html[data-theme="dark"] .btn:hover{
  box-shadow:0 1px 0 rgba(255,252,236,.92) inset,
             0 -2px 4px rgba(110,82,30,.40) inset,
             0 20px 38px -12px rgba(0,0,0,.85),
             0 0 22px -6px rgba(201,169,106,.45);
}
/* Bouton fantôme : sa couleur passe par var(--ink) → déjà OK ; on s’assure que
   le filet or reste net. */
html[data-theme="dark"] .btn.ghost{ color:var(--ink); border-color:var(--gold-hi); }

/* ---- Indice DEFILER (.scrollhint) : déjà blanc en dur, parfait sur sombre ;
   on retire juste l’éventuelle aura sombre devenue inutile. Rien à forcer côté
   couleur — laissé tel quel volontairement. ---------------------------------- */

/* ---- Preloader #pre : fond via var(--bg) (auto). Le logo « éteint »
   .lg-dark est #cfc4b1 (clair) — il deviendrait trop lumineux/laiteux sur le
   noir ; on le rend sombre-discret pour que le remplissage doré reste le héros. */
html[data-theme="dark"] #pre .lg-dark{ fill:#2a2620; }

/* ============================================================================
   3b. Surfaces de data-viz / diagrammes (présentes sur certaines pages)
   Centralisé ici : si la page n’a pas l’élément, la règle ne fait rien.
   Les attributs SVG en dur (stroke=…, fill=…) sont des attributs de
   présentation : une règle CSS les bat toujours, même sans !important.
   ========================================================================== */

/* KPI chart (reflective-echoes) — lignes de grille rgba(42,37,32,.10) =
   invisibles sur sombre → on re-trace en clair ; labels d’axe re-éclaircis ;
   ligne or (url(#kpiGold)) et ligne rouge #c4502e conservées (rouge 4.2:1,
   > 3:1 requis pour un trait graphique). ------------------------------------- */
html[data-theme="dark"] #kpiChart g[stroke] line{
  stroke:rgba(255,255,255,.14);
}
html[data-theme="dark"] #kpiChart text{
  fill:#9a9080;                 /* 6.2:1 sur --bg                              */
}
/* Jauge demi-cercle (même bloc .gauge) : l’arc de fond hérite aussi de
   rgba(42,37,32,.10). On cible le 1er <path> (fond) sans toucher #kpiArc (or). */
html[data-theme="dark"] .gauge svg path:not([id]){
  stroke:rgba(255,255,255,.12);
}

/* Diagramme d’architecture .archd (cockpit) : ses fills sont déjà sombres
   (#100e0a / #16130d) et se fondaient dans le nouveau --bg #0c0b12. On donne
   au conteneur un panneau légèrement plus clair + un filet doré discret pour
   qu’il se détache comme une carte. ------------------------------------------ */
html[data-theme="dark"] .archd{
  background:linear-gradient(180deg, #17140d, #100d09);
  border-color:rgba(201,169,106,.22);
  box-shadow:0 30px 70px -40px rgba(0,0,0,.7);
}

/* Placeholder vidéo (.player video, fond #cfc4b1 clair = flash laiteux avant
   lecture) → placeholder sombre. -------------------------------------------- */
html[data-theme="dark"] .player video{ background:#100e0a; }
/* Idem hero player (index) si présent. */
html[data-theme="dark"] .hp-video,
html[data-theme="dark"] .hp-stage{ background:#08070b; }

/* Fallback statique du hero #hero3d (mobile / sans 3D) : heroStatic() ajoute la
   classe .hero3d-static au lieu d'un fond inline, pour que le thème pilote la
   couleur (et réagisse au toggle). Sans ça le radial clair restait en mode sombre. */
#hero3d.hero3d-static{ background:radial-gradient(circle at 62% 44%,#e8e0d2,#cfc4b1 70%); }
html[data-theme="dark"] #hero3d.hero3d-static{ background:radial-gradient(circle at 62% 44%,#1c1810,#0c0b12 72%); }
/* Surfaces viewer/placeholder au radial clair codé en dur (.spec-stage, .vis,
   .reel-soon) → radial sombre en mode sombre. */
html[data-theme="dark"] .spec-stage{ background:radial-gradient(circle at 50% 42%,#16130d,#0c0b12 74%); }
html[data-theme="dark"] .vis{ background:radial-gradient(circle at 50% 40%,#16130d,#0c0b12 76%); }
html[data-theme="dark"] .reel-soon{ background:radial-gradient(circle at 50% 38%,#16130d,#0c0b12 78%); }
/* Encart tarif pilote (.pilot, empreinte [06]) : dégradé crème codé en dur → version
   sombre (le texte .big hérite --ink, donc clair et lisible une fois le fond sombre). */
html[data-theme="dark"] .pilot{ background:linear-gradient(180deg,#16130d,#0c0b12); }

/* ============================================================================
   3c. Bouton bascule de thème (sun/moon) — voir markup dans les pages
   ([data-theme-toggle]). Variante desktop : .theme-toggle (dans .navlinks).
   Variante mobile : .theme-toggle--m (dans .mobilemenu).
   ========================================================================== */
.theme-toggle{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:40px;height:40px;
  margin-left:10px;
  border:1px solid var(--line-hi);
  border-radius:999px;
  background:transparent;
  color:var(--mut);
  cursor:inherit;            /* respecte le curseur custom (cursor:none) */
  transition:color .2s ease, border-color .25s ease, background .25s ease,
             transform .3s cubic-bezier(.16,1,.3,1);
  flex:none;
  -webkit-tap-highlight-color:transparent;
}
.theme-toggle:hover{ color:var(--gold); border-color:var(--gold); }
.theme-toggle:active{ transform:scale(.94); }
.theme-toggle svg{ width:18px;height:18px;display:block; }
/* Le SVG porte deux glyphes empilés ; on montre lune (clair → action sombre)
   ou soleil (sombre → action clair) selon l’état. */
.theme-toggle .ic-sun{ display:none; }
.theme-toggle .ic-moon{ display:block; }
html[data-theme="dark"] .theme-toggle .ic-sun{ display:block; }
html[data-theme="dark"] .theme-toggle .ic-moon{ display:none; }
.theme-toggle:focus-visible{
  outline:2px solid var(--gold);
  outline-offset:3px;
}

/* Variante mobile : pleine largeur du menu, alignée avec les .mlink. */
.theme-toggle--m{
  width:auto;
  height:auto;
  margin:14px 0 4px;
  padding:13px 16px;
  align-self:flex-start;
  gap:12px;
  border-radius:3px;
  font-family:'Space Mono', monospace;
  font-size:.78rem;
  letter-spacing:.08em;
  text-transform:uppercase;
}
.theme-toggle--m .tt-label{ color:var(--mut); transition:color .2s ease; }
.theme-toggle--m:hover .tt-label{ color:var(--gold); }
/* Libellé contextuel : on affiche l’action que produira le clic. */
.theme-toggle--m .tt-label::after{ content:"Mode sombre"; }
html[data-theme="dark"] .theme-toggle--m .tt-label::after{ content:"Mode clair"; }

@media (prefers-reduced-motion: reduce){
  .theme-toggle,
  .theme-toggle:active{ transition:color .2s ease, border-color .2s ease; transform:none; }
}
