@import "tailwindcss";
/* Ne jamais scanner la documentation : les extraits de classes dans docs/**
   generaient des utilitaires morts dans le CSS de production. */
@source not "../../docs";
/* Corps des articles du blog : l'utility `prose` habille le HTML issu du MDX
   (voir `blog/PostLayout.tsx`). Plugin CSS pur, chargé par la directive
   `@plugin` de Tailwind v4 — pas un import JS, donc rien à declarer dans
   `experimental.optimizePackageImports`. */
@plugin "@tailwindcss/typography";
/* `animate-in` / `animate-out` / `fade-in-*` / `zoom-in-*` / `slide-in-from-*`,
   consommes par le menu deroulant de `ui/select.tsx`. */
@import "tw-animate-css";
/* VIVANT, malgre les apparences : le paquet `shadcn` l'expose par la condition
   `style` de ses `exports` (`./tailwind.css` → `./dist/tailwind.css`). Il livre
   les variants `data-open` / `data-closed` / `data-checked` / `data-selected` /
   `data-disabled` / `data-active` / `data-horizontal` / `data-vertical` — que
   `ui/select.tsx`, `ui/field.tsx` et consorts consomment — ainsi que l'utility
   `no-scrollbar` (donc inutile de la redeclarer plus bas). Le supprimer casse
   les composants shadcn. Voir docs/audits/globals-css-2026-08.md § 2. */
@import "shadcn/tailwind.css";

@custom-variant dark (&:is(.dark *));

@theme {
  /* Largeur a partir de laquelle le menu horizontal complet tient sans deborder.
     Mesure a 1440 (conteneur editorial max-w-1440 + px-16 = 1312px utiles, gaps
     de 12px) : anglais 1300px de contenu logo compris, francais 1264px. C'est
     donc l'anglais qui contraint, avec ~12px de marge : tout libelle de nav
     rallonge doit etre remesure ici. En dessous : menu burger. HeaderShell lit
     ce token au runtime (getComputedStyle) : rien a repercuter ailleurs. */
  --breakpoint-nav: 1440px;
  --font-sans: var(--font-montserrat), system-ui, sans-serif;
  --font-display: var(--font-tenor-sans), Georgia, "Times New Roman", serif;
  --font-mono:
    Monaco, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", "Courier New",
    monospace;

  /* ── Grille editoriale ────────────────────────────────────────────────
     Conteneur unique des sections (max-w-editorial). Consomme de preference
     l'utility `shell` plus bas, qui y ajoute les gouttieres. */
  --container-editorial: 1440px;
  --container-lead: 720px;

  /* ── Rythme vertical ──────────────────────────────────────────────────
     Valeurs STATIQUES mesurees sur la Home. --spacing-header / -lg = hauteur
     du header non scrolle, pour les padding-top de page ; a ne pas confondre
     avec --header-h, publie au runtime par HeaderShell et qui varie au scroll.
     --spacing-section-sm / --spacing-section = rythme mobile / desktop. */
  --spacing-header: 75px;
  --spacing-header-lg: 90px;
  --spacing-section-sm: 76px;
  --spacing-section: 104px;

  /* Rythme interne du header et du hero (mesures des composants actuels). */
  --spacing-header-y: 15px;
  --spacing-header-y-lg: 22px;
  --spacing-cta-x: 26px;
  --spacing-monogram-lg: 34px;
  --spacing-hero: 640px;

  /* Chrome du header : flou et ombre au scroll. */
  --blur-header: 20px;
  --blur-header-compact: 14px;
  --shadow-header: 0 1px 20px -8px rgba(26, 28, 27, 0.25);

  /* ── Typographie ──────────────────────────────────────────────────────
     Deux trackings pour le role « Label-Caps » de docs/brand.md, pas six. */
  --tracking-caps: 0.2em;
  --tracking-caps-wide: 0.26em;
  --leading-body: 1.65;

  /* Label-Caps : `text-label` embarque tracking + graisse ; `text-micro` et
     `text-label-md` restent nus, on leur applique `tracking-caps[-wide]`. */
  --text-micro: 10.5px;
  --text-label: 11px;
  --text-label--line-height: 1.2;
  --text-label--letter-spacing: var(--tracking-caps);
  --text-label--font-weight: 600;
  --text-label-md: 12.5px;
  --text-label-lg: 13px;
  --text-label-lg--line-height: 1;
  --text-label-lg--letter-spacing: 0.14em;

  /* Wordmark — tracking tres large, propre a la marque (voir BrandLogo). */
  --text-wordmark: 19px;
  --text-wordmark--letter-spacing: 0.32em;
  --text-wordmark-sub: 10px;
  --text-wordmark-sub--letter-spacing: 0.42em;

  /* Corps de texte. */
  --text-lead: 17px;
  --text-card-title: 21px;
  --text-card-title--line-height: 1.3;

  /* Titres — clamps fluides : ils remplacent les paires `text-x lg:text-y`. */
  --text-h3: 22px;
  --text-h2: clamp(31px, 2.78vw, 40px);
  --text-h2--line-height: 1.16;
  --text-display-sm: 40px;
  --text-display-sm--line-height: 1.08;
  --text-display-sm--letter-spacing: -0.01em;
  --text-display-lg: clamp(36px, 4.6vw, 58px);
  --text-display-lg--line-height: 1.08;
  --text-display-lg--letter-spacing: -0.01em;

  /* Numeraux des statistiques et filigrane de fond. */
  --text-stat: 54px;
  --text-stat--line-height: 0.9;
  --text-stat-md: clamp(46px, 5vw, 64px);
  --text-stat-lg: clamp(60px, 7vw, 88px);
  --text-stat-lg--line-height: 0.9;
  --text-watermark: clamp(90px, 13vw, 176px);

  --color-slate-850: hsl(222deg 47% 16%);

  /* Brand-specific tokens (not part of the shadcn semantic set) */
  --color-tertiary: #176a60;
  --color-on-tertiary: #ffffff;
  --color-tertiary-container: #ffffff;
  --color-on-tertiary-container: #368278;
  --color-brand: #176a60;

  /* Metallics — used for technical details, dividers, hallmark tags */
  --color-brushed-steel: #8e8e93;
  --color-machined-silver: #e5e5e7;
  --color-burnished-gold: #c5a059;
  --color-industrial-grid: #f1f1f1;

  /* Modern Editorial — gold accents (text/hover vs hairlines-numerals).
     --color-gold-text est le SEUL token pour du texte or (overlines, labels,
     hover). Decision client 2026-08-25 : retour a l'or clair d'origine du
     design Stitch (#c5a059, = --color-burnished-gold) — 2,33:1 sur blanc,
     sous le seuil AA texte (4,5:1), assume et consigne. L'alternative AA
     etait #856b33 (5,06:1). --color-gold (filets, puces, soulignements) prend
     la meme valeur #c5a059 (2,33:1 : sous le seuil 1.4.11 de 3:1 pour les
     objets graphiques, egalement assume) ; l'ancien #a6863f (3,26:1) reste
     l'alternative conforme. Deux tokens conserves pour pouvoir les separer. */
  --color-gold: #c5a059;
  --color-gold-text: #c5a059;
  --color-gold-bright: #e9c176;
  --color-hairline: #d7d9d7;
  --color-hairline-soft: #e6e7e5;

  /* Surface tonal layers (Material 3-style) for "Tonal Layering" elevation */
  --color-surface: #f9f9f7;
  --color-surface-dim: #dadad8;
  --color-surface-bright: #f9f9f7;
  --color-surface-container-lowest: #ffffff;
  --color-surface-container-low: #f4f4f2;
  --color-surface-container: #eeeeec;
  --color-surface-container-high: #e8e8e6;
  --color-surface-container-highest: #e2e3e1;
  --color-on-surface: #1a1c1b;
  --color-on-surface-variant: #444748;
  --color-inverse-surface: #2f3130;
  --color-on-inverse-surface: #f1f1ef;
  --color-outline-soft: #c4c7c7;
  --color-outline-strong: #747878;

  /* Voile sombre pose sur les images de fond (MaterialsSection, heros). */
  --color-scrim: #141514;
}

@theme inline {
  --color-sidebar-ring: var(--sidebar-ring);
  --color-sidebar-border: var(--sidebar-border);
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
  --color-sidebar-accent: var(--sidebar-accent);
  --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
  --color-sidebar-primary: var(--sidebar-primary);
  --color-sidebar-foreground: var(--sidebar-foreground);
  --color-sidebar: var(--sidebar);
  --color-chart-5: var(--chart-5);
  --color-chart-4: var(--chart-4);
  --color-chart-3: var(--chart-3);
  --color-chart-2: var(--chart-2);
  --color-chart-1: var(--chart-1);
  --color-ring: var(--ring);
  --color-input: var(--input);
  --color-border: var(--border);
  --color-destructive: var(--destructive);
  --color-accent-foreground: var(--accent-foreground);
  --color-accent: var(--accent);
  --color-muted-foreground: var(--muted-foreground);
  --color-muted: var(--muted);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-secondary: var(--secondary);
  --color-primary-foreground: var(--primary-foreground);
  --color-primary: var(--primary);
  --color-popover-foreground: var(--popover-foreground);
  --color-popover: var(--popover);
  --color-card-foreground: var(--card-foreground);
  --color-card: var(--card);
  --color-foreground: var(--foreground);
  --color-background: var(--background);
  --radius-sm: calc(var(--radius) * 0.6);
  --radius-md: calc(var(--radius) * 0.8);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) * 1.4);
  --radius-2xl: calc(var(--radius) * 1.8);
  --radius-3xl: calc(var(--radius) * 2.2);
  --radius-4xl: calc(var(--radius) * 2.6);
}

/*
 * Modern Editorial — light theme (the only canonical brand theme).
 * Shadcn semantic tokens are mapped to the Material 3-style palette so
 * existing components keep working while picking up the new identity.
 */
:root {
  --background: #f9f9f7;
  --foreground: #1a1c1b;
  --card: #ffffff;
  --card-foreground: #1a1c1b;
  --popover: #ffffff;
  --popover-foreground: #1a1c1b;
  --primary: #1a1c1b;
  --primary-foreground: #ffffff;
  --secondary: #e2dfde;
  --secondary-foreground: #1a1c1b;
  --muted: #eeeeec;
  --muted-foreground: #444748;
  --accent: #e8e8e6;
  --accent-foreground: #1a1c1b;
  --destructive: #ba1a1a;
  --border: #c4c7c7;
  --input: #c4c7c7;
  --ring: #1a1c1b;
  --chart-1: #8e8e93;
  --chart-2: #c5a059;
  --chart-3: #176a60;
  --chart-4: #5d5f5f;
  --chart-5: #1a1c1b;
  --radius: 0px;
  --sidebar: #f9f9f7;
  --sidebar-foreground: #1a1c1b;
  --sidebar-primary: #1a1c1b;
  --sidebar-primary-foreground: #ffffff;
  --sidebar-accent: #e8e8e6;
  --sidebar-accent-foreground: #1a1c1b;
  --sidebar-border: #c4c7c7;
  --sidebar-ring: #1a1c1b;
}

.dark {
  --background: #1c1b1b;
  --foreground: #f4f0ef;
  --card: #313030;
  --card-foreground: #f4f0ef;
  --popover: #313030;
  --popover-foreground: #f4f0ef;
  --primary: #f4f0ef;
  --primary-foreground: #1c1b1b;
  --secondary: #444748;
  --secondary-foreground: #f4f0ef;
  --muted: #313030;
  --muted-foreground: #c4c7c8;
  --accent: #444748;
  --accent-foreground: #f4f0ef;
  --destructive: #ba1a1a;
  --border: #444748;
  --input: #444748;
  --ring: #f4f0ef;
  --chart-1: #8e8e93;
  --chart-2: #c5a059;
  --chart-3: #176a60;
  --chart-4: #c6c6c7;
  --chart-5: #f4f0ef;
  --sidebar: #1c1b1b;
  --sidebar-foreground: #f4f0ef;
  --sidebar-primary: #f4f0ef;
  --sidebar-primary-foreground: #1c1b1b;
  --sidebar-accent: #444748;
  --sidebar-accent-foreground: #f4f0ef;
  --sidebar-border: #444748;
  --sidebar-ring: #f4f0ef;
}

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  body {
    @apply bg-background text-foreground;
  }
  html {
    @apply font-sans;
    /* Couleur du canvas = celle du footer : c'est ce que les navigateurs
       mobiles montrent au rebond de fin de page et derriere leur barre
       d'outils (le haut de page est couvert par `theme-color`). Une seule
       regle, pas de degrade ni de `h-full` : <body> est opaque et fait au
       moins 100dvh, la couleur n'apparait jamais dans le flux normal. */
    background-color: var(--foreground);
  }
  ::selection {
    background: var(--color-gold-bright);
    /* Brun tres sombre, sans token : il ne sert qu'ici, et l'ajouter a la
       palette serait un ajout d'API, pas un nettoyage. */
    color: #261900;
  }
}

@utility container {
  margin-inline: auto;
  @media (width >= 50rem) {
    max-width: 50rem;
  }
}

/* Coquille editoriale : centre le contenu sur --container-editorial et pose
   les gouttieres (24px, 64px a partir de lg). Absorbe les 35 occurrences de
   `mx-auto max-w-[1440px] px-6 lg:px-16`. */
@utility shell {
  @apply mx-auto max-w-editorial px-6 lg:px-16;
}

/* Modern Editorial motion — scroll reveal + slow float (see .reveal / .float-slow) */
@keyframes editorial-float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

@keyframes editorial-bounce {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(6px);
  }
}

@keyframes editorial-pulse {
  0%,
  100% {
    opacity: 0.9;
    transform: scale(1);
  }
  50% {
    opacity: 0.45;
    transform: scale(0.96);
  }
}

/* Scroll reveal — fade + 20px rise, driven by the element's own view progress
   timeline (docs/brand.md § Fade-Ins). `translate` rather than `transform` so a
   caller keeping its own `transform` utility is not overwritten. */
@keyframes reveal-in {
  from {
    opacity: 0;
    translate: 0 20px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* The gold hairline of DesignSteps, drawn from 0 to full width on the same
   timeline (it used to inherit the state of its `<Reveal>` parent). */
@keyframes rule-grow-in {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@layer components {
  /* Visible by default, on purpose: browsers without scroll-driven animations
     (Firefox < 144) and reduced-motion users get the final state and never a
     blank section. The animation below only ever *removes* opacity, so the SSR
     HTML is readable as shipped — no `opacity: 0` in the payload, no JS.

     PIEGE : ne JAMAIS poser `overflow-hidden` sur un ancetre d'un `.reveal`.
     `animation-timeline: view()` se resout sur le plus proche scroll container
     ancetre, et `overflow: hidden` en cree un (CSS Overflow 3) : la timeline
     devient celle de la section, qui ne defile jamais, donc l'element est en
     permanence au-dela de sa plage et l'animation est inerte. Utiliser
     `overflow-clip`, qui clippe a l'identique sans creer de scroll container. */
  .reveal {
    opacity: 1;
  }
  .float-slow {
    animation: editorial-float 8s ease-in-out infinite;
  }
  .bounce-slow {
    animation: editorial-bounce 2.2s ease-in-out infinite;
  }
  .pulse-slow {
    animation: editorial-pulse 2.4s ease-in-out infinite;
  }
  /* Pas de `.no-scrollbar` ici : `shadcn/tailwind.css` la declare deja en
     `@utility`, a l'identique. La redeclarer sortait les deux blocs dans le
     CSS livre. */
  /* Gold rule that draws itself as it enters the viewport. */
  .rule-grow {
    width: 100%;
  }
}

/* Everything below is opt-in: no scroll-driven animation support, or a stated
   preference for less motion, and the base rules above already hold.
   Both properties are required: a browser that accepts `animation-timeline`
   but drops `animation-range` would fall back to the `cover` range and keep
   the block half-transparent for as long as it is on screen (seen on
   /gallery, 2026-08-25). */
@supports (animation-timeline: view()) and (animation-range: entry 0% entry 30%) {
  @media (prefers-reduced-motion: no-preference) {
    @layer components {
      .reveal {
        /* The shorthand resets `animation-timeline`, so it comes first. No
           duration: on a view timeline the animation is mapped onto the range
           below instead of onto a clock. */
        animation: reveal-in linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 30%;
      }

      /* Stagger. Siblings of one row enter the viewport together, so the offset
         has to live in `animation-range` — a `delay` means nothing on a scroll
         timeline. 5% of the entry range per item stands in for the 90ms cascade
         of the JS component this replaced; past the 8th item the offset stops
         growing, otherwise the last cards would need most of the entry range to
         finish. Put `.reveal-stagger` on the flex/grid parent. */
      .reveal-stagger > .reveal:nth-child(2) {
        animation-range: entry 5% entry 35%;
      }
      .reveal-stagger > .reveal:nth-child(3) {
        animation-range: entry 10% entry 40%;
      }
      .reveal-stagger > .reveal:nth-child(4) {
        animation-range: entry 15% entry 45%;
      }
      .reveal-stagger > .reveal:nth-child(5) {
        animation-range: entry 20% entry 50%;
      }
      .reveal-stagger > .reveal:nth-child(6) {
        animation-range: entry 25% entry 55%;
      }
      .reveal-stagger > .reveal:nth-child(n + 7) {
        animation-range: entry 30% entry 60%;
      }

      .rule-grow {
        animation: rule-grow-in ease-in-out both;
        animation-timeline: view();
        animation-range: entry 0% entry 40%;
      }
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .float-slow,
  .bounce-slow,
  .pulse-slow {
    animation: none;
  }
}
