/* ============================================================================
   CABINET — parfums et bougies composés en France
   Système de design : palette de dix teintes, une seule rupture structurelle,
   profondeur obtenue par filets d'un pixel plutôt que par ombres portées.

   Conception et développement :
     Noélabs — agence IA & Django, Île-de-France · https://noelabs.com/
     Noésis Software Technologies · https://nsft.fr/

   Feuille écrite à la main : ni compilateur, ni chaîne d'outils, ni dépendance
   de construction (ADR-0034).
   ============================================================================ */

/* ============================================================================
   CABINET — jetons de design
   Blueprint §19. Servi tel quel : aucune compilation, aucun outillage Node.

   Toute valeur de design vit ici et nulle part ailleurs. Une couleur, une
   taille ou une durée écrite en dur dans un gabarit ou dans app.css fait
   échouer la porte G10.

   Les contrastes sont mesurés, pas estimés (§19.1). Trois règles en découlent
   et sont verrouillées par tests/contract/test_design_tokens.py :
     · gold ne porte JAMAIS de texte sur fond clair (2,07:1) → gold-ink
     · muted est interdit sur sand (4,43:1)
     · les formulaires ne se posent pas sur sand (bordure à 2,88:1)
   ========================================================================== */

/* ── Polices auto-hébergées ──────────────────────────────────────────────────
   Aucun CDN : CSP stricte (§18), aucun transfert hors UE (§25), et le LCP ne
   dépend d'aucun tiers.

   Les deux fichiers sont sous SIL Open Font License 1.1 — redistribution et
   usage commercial autorisés. Les textes de licence voyagent avec eux dans
   static/fonts/licences/ ; l'OFL l'exige, un test le vérifie.

   RÈGLE DURE : ne jamais déclarer un @font-face vers un fichier non expédié.
   Le post-traitement du manifeste échoue, collectstatic sort en erreur, et
   TOUTES les pages répondent 500. C'est arrivé le 19 juillet 2026. Porte G17. */

@font-face {
  font-family: "Inter Variable";
  src: url("/static/fonts/InterVariable.260c81a4759b.woff2") format("woff2-variations");
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Instrument Serif";
  src: url("/static/fonts/InstrumentSerif-Regular.9b8dd1ecf641.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ── Palette ──────────────────────────────────────────────────────────────
     Dix jetons, pas onze. La variété visuelle vient des dégradés et des
     mélanges déclarés plus bas, jamais d'une couleur supplémentaire. */
  --color-ink: #212121;
  --color-paper: #ffffff;
  --color-cream: #faf6f0;
  --color-sand: #f1e9dd;
  --color-line: #e5e4e3;
  --color-line-strong: #8e8981;
  --color-muted: #6b6b6b;
  --color-gold: #cdb087;
  --color-gold-ink: #7a5c30;
  --color-signal: #b83520;

  /* Dérivés de l'encre. Déclarés ici comme tout le reste : app.css ne contient
     aucune couleur littérale, pas même une transparence. */
  --veil: rgb(33 33 33 / 42%);
  --ink-hairline: rgb(33 33 33 / 12%);
  --paper-hairline: rgb(255 255 255 / 24%);
  --paper-soft: rgb(255 255 255 / 72%);

  /* ── Tuiles éditoriales (C-14) ────────────────────────────────────────────
     « Dégradés entre tokens uniquement, jamais de couleur libre » (§19.7).
     `color-mix` produit les demi-teintes sans introduire de onzième couleur :
     la palette reste celle du §19.1, au caractère près. */
  --tile-linen: linear-gradient(148deg, var(--color-sand), var(--color-cream));
  --tile-amber: linear-gradient(
    148deg,
    color-mix(in oklab, var(--color-gold) 46%, var(--color-cream)),
    var(--color-cream)
  );
  --tile-ash: linear-gradient(
    148deg,
    color-mix(in oklab, var(--color-line-strong) 26%, var(--color-cream)),
    var(--color-cream)
  );
  --tile-clay: linear-gradient(
    148deg,
    color-mix(in oklab, var(--color-signal) 16%, var(--color-sand)),
    var(--color-cream)
  );
  --tile-ink: linear-gradient(
    148deg,
    var(--color-ink),
    color-mix(in oklab, var(--color-gold-ink) 40%, var(--color-ink))
  );

  /* Voile posé au bas d'un visuel pour que du texte clair y reste lisible.
     Un dégradé, pas un aplat : le haut de la photographie n'est pas assombri. */
  --scrim: linear-gradient(
    to top,
    rgb(33 33 33 / 78%) 0%,
    rgb(33 33 33 / 46%) 38%,
    rgb(33 33 33 / 0%) 78%
  );

  /* Voile renforcé pour un fond animé. Une vidéo traverse des éclaircies qu'une
     photographie fixe n'a pas : mesuré sur les trois sources fournies, le point
     le plus clair sous le panneau atteint 0,635 de luminance, ce qui demande
     74 % d'encre pour tenir 4,5:1 avec du texte blanc. La vidéo reste une
     texture en mouvement plutôt qu'une image qu'on regarde — c'est le prix de
     la lisibilité, et `import_hero_video` refuse toute source qui n'y tient pas. */
  --scrim-video: linear-gradient(
    to top,
    rgb(33 33 33 / 88%) 0%,
    rgb(33 33 33 / 74%) 42%,
    rgb(33 33 33 / 34%) 100%
  );

  /* ── Typographie ──────────────────────────────────────────────────────────
     Auto-hébergée : CSP stricte (§18), aucun transfert hors UE (§25), LCP.
     Aucun hôte tiers n'apparaît dans ce fichier, et G10 le vérifie. */
  --font-sans: "Inter Variable", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-serif: "Instrument Serif", Georgia, "Times New Roman", serif;

  /* Échelle du §19.2, à la valeur près. Plancher à 12 px (§19.9 règle 6) :
     l'échelle 1:8 de l'ADR-0042 descendait à 10 px, sous le seuil, pour
     compenser une page sans imagerie. La page a maintenant son imagerie. */
  --text-2xs: 0.75rem;     /* 12px — mentions, prix au litre, badges */
  --text-xs: 0.875rem;     /* 14px — méta, libellés d'interface */
  --text-sm: 0.9375rem;    /* 15px — texte de carte produit */
  --text-base: 1rem;       /* 16px — plancher du texte courant */
  --text-md: 1.125rem;     /* 18px — chapô, prix en fiche */
  --text-lg: 1.25rem;      /* 20px — sous-titres */
  --text-xl: 1.375rem;     /* 22px — titres de carte */
  --text-2xl: 1.5rem;      /* 24px — titres de section mobile */
  --text-3xl: 1.875rem;    /* 30px — titres de section desktop */
  --text-4xl: 2.5rem;      /* 40px — titres de page */
  --text-5xl: 3.75rem;     /* 60px — héros desktop */
  --text-6xl: 4.75rem;     /* 76px — déclaration pleine largeur, ≥1024px */

  --leading-none: 1;
  --leading-tight: 1.08;
  --leading-snug: 1.32;
  --leading-normal: 1.6;
  --tracking-caps: 0.06em;    /* capitales : §19.2 */
  --tracking-wide: 0.02em;    /* interlettrage positif par défaut */
  --tracking-display: -0.02em;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-strong: 600;

  /* ── Espacement ───────────────────────────────────────────────────────────
     Base 4 px, échelle 4·8·12·16·24·32·48·64·96 (§19.3). */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;
  --space-32: 8rem;

  /* ── Structure ────────────────────────────────────────────────────────────
     Une seule rupture structurelle, à 1024px (§19.3). Les ruptures 768px et
     1280px n'ajustent que la densité d'une grille, jamais la mise en page. */
  --container-page: 1300px;
  --container-wide: 1560px;
  --width-form: 34rem;
  --width-prose: 68ch;
  --height-announcement: 48px;
  --height-header: 56px;

  /* Cible tactile minimale. 44 px est la valeur où un doigt adulte atteint sa
     cible du premier coup ; en dessous, le taux de ratés grimpe vite. Quand le
     dessin doit rester petit — la croix d'un bandeau, une pastille — c'est la
     zone cliquable qu'on étend, pas le visuel (WCAG 2.5.8, Apple HIG). */
  --target-min: 2.75rem;

  /* Opacité à l'appui. Le retour au doigt passe par la couleur et non par la
     géométrie : un déplacement, même de deux pixels, se lit comme une erreur
     de rendu sur un écran tenu à trente centimètres. */
  --pressed-opacity: 0.7;
  --height-btn: 48px;
  --height-btn-card: 40px;
  --height-btn-small: 36px;

  /* Le format des visuels est décidé une fois pour toutes, jamais au rendu. */
  --ratio-card: 1 / 1;         /* §19.3 : carré, 84 occurrences dans la référence */
  --ratio-hero: 3 / 4;         /* mobile */
  --ratio-hero-wide: 16 / 9;   /* ≥1024px */
  --ratio-tile: 4 / 5;
  --ratio-banner: 21 / 9;

  --radius-none: 0;
  --radius-sm: 8px;
  --radius-card: 20px;
  --radius-pill: 999px;

  /* §19.4 : aucune ombre, sauf pour les couches réellement flottantes. */
  --shadow-overlay: 0 0 10px rgb(33 33 33 / 10%);

  /* ── Mouvement ────────────────────────────────────────────────────────────
     Courbe unique (§19.4). 300ms est la durée d'inversion des pastilles. */
  --duration-fast: 200ms;
  --duration-base: 300ms;
  --duration-slow: 500ms;
  --ease-brand: cubic-bezier(0.4, 0, 0.2, 1);

  /* ── Plans ────────────────────────────────────────────────────────────────
     Une échelle courte et nommée. Un z-index inventé au fil de l'eau finit
     toujours par produire un tiroir derrière son propre voile. */
  --z-sticky: 40;
  --z-header: 300;
  --z-veil: 800;
  --z-drawer: 900;
  --z-skip: 1000;
}
