@import 'tailwindcss';

/*
  Source explicite : la détection automatique rate certains fichiers
  (fichiers créés serveur allumé).
*/
@source '../..';

/* ── Design tokens ─────────────────────────────────────────────────────────
   Source unique des valeurs visuelles. Les composants ne codent aucune
   couleur, durée ou courbe en dur : ils lisent ces variables.
   Les valeurs de mouvement ont leur miroir GSAP dans app/utils/motion.ts.
   ───────────────────────────────────────────────────────────────────────── */
:root {
  /* Clairs */
  --c-ivory: #f6f2ea;
  --c-linen: #ece5d8;
  --c-sand: #d9cdb8;
  /* Matière */
  --c-walnut: #a06f45;
  --c-sage: #8a9279;
  /* Sombres */
  --c-ink: #23211f;
  --c-ink-soft: #5c574f;
  --c-forest: #18231c;
  --c-forest-soft: #223027;
  /* Accent M2B : réservé aux appels à l'action */
  --c-red: #c4161c;
  --c-red-deep: #a01116;
  /* Textes sur fonds sombres */
  --c-on-dark: #f6f2ea;
  --c-on-dark-soft: rgb(246 242 234 / 0.72);
  /* Filets */
  --c-rule: rgb(35 33 31 / 0.14);
  --c-rule-on-dark: rgb(246 242 234 / 0.2);

  /* Typographie */
  --font-display: 'Newsreader', 'Iowan Old Style', Georgia, serif;
  --font-sans: 'Hanken Grotesk', 'Helvetica Neue', Arial, sans-serif;

  /*
    Échelle typographique. Chaque taille a un plancher (mobile), une progression et un
    plafond (grand écran). Le titre du hero tient aussi compte de la hauteur de l'écran :
    il ne grossit pas sur un écran large mais peu haut.
  */
  --text-hero: clamp(2.125rem, min(7vw, 5.2svh + 1rem), 4.75rem);
  --text-display: clamp(1.875rem, 1.3rem + 1.9vw, 3.5rem);
  --text-title: clamp(1.375rem, 1.15rem + 0.7vw, 1.75rem);
  --text-lead: clamp(1rem, 0.95rem + 0.25vw, 1.1875rem);
  --text-body: 1rem;
  --text-small: 0.875rem;
  --text-label: 0.75rem;

  /* Espace */
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --content-max: clamp(100rem, 68vw, 120rem);
  --section-space: clamp(5rem, 3rem + 7vw, 11rem);
  /* Hauteur des vagues de transition entre les sections. */
  --wave-height: clamp(1.5rem, 0.75rem + 3.2vw, 4.5rem);
  --header-height: clamp(4.25rem, 3.4rem + 2vw, 6rem);
  /* Hauteur du bord de l'en-tête (vague et languette du logo) qui déborde sur la page. */
  --header-edge: 1.25rem;

  /* Formes */
  --radius-frame: 2px;
  --radius-soft: 0.5rem;
  --radius-pill: 999px;

  /* Ombres : chaudes, jamais grises */
  --shadow-float: 0 1.5rem 3.5rem -1.5rem rgb(58 40 22 / 0.28);

  /* Mouvement */
  --ease-air: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-air-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 0.35s;
  --dur-base: 0.7s;
  --dur-slow: 1.2s;
}

/* Les mêmes tokens, exposés aux utilitaires Tailwind (bg-ivory, text-ink…). */
@theme inline {
  --color-ivory: var(--c-ivory);
  --color-linen: var(--c-linen);
  --color-sand: var(--c-sand);
  --color-walnut: var(--c-walnut);
  --color-sage: var(--c-sage);
  --color-ink: var(--c-ink);
  --color-ink-soft: var(--c-ink-soft);
  --color-forest: var(--c-forest);
  --color-red: var(--c-red);

  --font-display: var(--font-display);
  --font-sans: var(--font-sans);

  --ease-air: var(--ease-air);
}

/* À partir de la tablette, le logo repose sur une languette plus haute. */
@media (min-width: 768px) {
  :root {
    --header-edge: 3rem;
  }
}

/* ── Base ──────────────────────────────────────────────────────────────── */
html {
  background: var(--c-ivory);
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
}

/*
  La barre de défilement du navigateur laisse la place à celle du site (composant
  PageScrollbar), sur tous les écrans. Sans JavaScript, la barre native reste en place.
*/
html.js {
  scrollbar-width: none;
  scrollbar-gutter: auto;
}

html.js::-webkit-scrollbar,
html.js body::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

/* Pendant que l'on fait glisser la poignée, rien ne se sélectionne dans la page. */
html.is-scroll-dragging {
  cursor: grabbing;
  user-select: none;
}

/* Menu mobile ouvert : la page ne défile plus derrière le panneau. */
html.is-menu-open {
  overflow: hidden;
}

body {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: 1.65;
  color: var(--c-ink);
  background: var(--c-ivory);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* `clip` et non `hidden` : ne crée pas de conteneur de défilement, le sticky reste intact. */
  overflow-x: clip;
}

/* Les ancres ne passent pas sous l'en-tête fixe. */
[id] {
  scroll-margin-top: calc(var(--header-height) + var(--header-edge));
}

::selection {
  background: var(--c-sand);
  color: var(--c-ink);
}

/* Tailwind v4 ne met plus cursor:pointer sur les boutons — on le rétablit. */
button:not(:disabled) {
  cursor: pointer;
}

/* Focus clavier : un filet net, toujours visible, qui s'adapte au fond. */
:focus-visible {
  outline: 2px solid var(--focus-color, var(--c-ink));
  outline-offset: 4px;
}

/* Cible d'une ancre : elle reçoit le focus pour le clavier, sans contour autour de la section. */
[tabindex='-1']:focus-visible {
  outline: none;
}

.on-dark {
  --focus-color: var(--c-on-dark);
  color: var(--c-on-dark);
}

.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-pill);
  background: var(--c-ink);
  color: var(--c-on-dark);
  font-size: var(--text-small);
  font-weight: 500;
  transform: translateY(-200%);
}

.skip-link:focus-visible {
  transform: none;
  --focus-color: var(--c-red);
}

/* ── Gabarit ───────────────────────────────────────────────────────────── */
.shell {
  width: min(100% - 2 * var(--gutter), var(--content-max));
  margin-inline: auto;
}

/*
  Grille à fond perdu : le contenu reste aligné sur .shell tandis qu'une image
  peut filer jusqu'au bord de l'écran (colonnes `full-start` / `full-end`).
*/
.bleed-grid {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [content-start] minmax(0, var(--content-max))
    [content-end] minmax(var(--gutter), 1fr)
    [full-end];
}

.bleed-grid > * {
  grid-column: content;
}

/* ── Typographie ───────────────────────────────────────────────────────── */
.t-hero,
.t-display,
.t-title {
  font-family: var(--font-display);
  font-weight: 300;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.t-hero {
  font-size: var(--text-hero);
  line-height: 1.02;
}

.t-display {
  font-size: var(--text-display);
  line-height: 1.06;
}

.t-title {
  font-size: var(--text-title);
  line-height: 1.15;
  letter-spacing: -0.012em;
}

.t-lead {
  font-size: var(--text-lead);
  line-height: 1.6;
  text-wrap: pretty;
}

.t-body {
  font-size: var(--text-body);
  line-height: 1.65;
  text-wrap: pretty;
}

.t-small {
  font-size: var(--text-small);
  line-height: 1.55;
}

.t-label {
  font-size: var(--text-label);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.t-soft {
  color: var(--c-ink-soft);
}

.on-dark .t-soft {
  color: var(--c-on-dark-soft);
}

/* ── Révélations ───────────────────────────────────────────────────────────
   États initiaux, posés uniquement quand <html> porte la classe `anim`
   (JavaScript actif et animations acceptées — voir app.vue). GSAP anime
   ensuite vers l'état visible, puis marque l'élément `data-revealed`.
   ───────────────────────────────────────────────────────────────────────── */

/* Ligne de titre : un masque, et le texte qui monte à l'intérieur. */
.line {
  display: block;
  /* Le masque déborde un peu de la ligne : jambages (g, p, y) et accents restent entiers. */
  clip-path: inset(-0.1em -0.1em -0.18em);
}

.line__inner {
  display: block;
  transform-origin: 0 100%;
}

html.anim [data-reveal='lines']:not([data-revealed]) .line__inner {
  transform: translateY(120%);
}

html.anim [data-reveal='fade']:not([data-revealed]),
html.anim [data-reveal='group']:not([data-revealed]) [data-reveal-item] {
  opacity: 0;
}

html.anim [data-reveal='mask']:not([data-revealed]) {
  clip-path: inset(0 100% 0 0);
}

html.anim [data-reveal='mask'][data-reveal-from='right']:not([data-revealed]) {
  clip-path: inset(0 0 0 100%);
}

html.anim [data-reveal='mask'][data-reveal-from='bottom']:not([data-revealed]) {
  clip-path: inset(100% 0 0 0);
}

/* ── Défilement adouci (Lenis, écrans avec souris) ─────────────────────── */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: clip;
}

/* ── Respiration des images ────────────────────────────────────────────── */
@keyframes breathe {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.035);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .breathe {
    animation: breathe 14s var(--ease-air-in-out) infinite alternate;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
