/* =====================================================================
   WAOUH v1 — Élévation éditoriale premium
   (synthèse creative director après workflow 4-lens / 32 propositions)

   Top picks implémentés :
   #1 Rotator hero amplifié + axes variables Fraunces (wow/s)
   #2 Optical sizing Fraunces sur displays + body (high/xs)
   #3 Modular scale tokens --fs-* (high/s)
   #4 /tarifs cascade musicale 4-beats (high/s)
   #5 Scroll-driven morph displays sticky (wow/s)
   #6 Heure d'Antananarivo repeint hero (wow/s)
   #7 Pull quotes éditoriales (high/s)
   #8 Zone de silence /tarifs (wow/xs)
   #9 Marquee scroll-velocity-reactive (high/xs)
   #10 Drop cap éditoriaux (high/xs)

   Rejetés : Masthead, Rail, Cmd+K, Konami, eye-tracking, FLIP cross-page.
   Tous les effets respectent prefers-reduced-motion.
   ===================================================================== */

:root {
    /* ── Fallback tokens (au cas où landing.css n'est pas chargé,
       ex: portfolio.html charge uniquement styles.css) ──── */
    --gold:       #c8a25c;
    --gold-2:     #e4c486;
    --ivory:      #ede5d6;
    --ivory-2:    #d6cdb9;
    --ivory-3:    #968d83;
    --rose:       #c4717f;
    --serif:      'Times New Roman', serif;
    --mono:       'JetBrains Mono', ui-monospace, monospace;

    /* ── #3 Modular scale (ratio 1.25 — major third) ──── */
    --fs-micro:    clamp(.68rem, .65rem + .15vw, .78rem);
    --fs-meta:     clamp(.78rem, .72rem + .3vw,  .95rem);
    --fs-body:     clamp(1rem,   .92rem + .4vw,  1.15rem);
    --fs-lede:     clamp(1.2rem, 1rem + 1vw,     1.6rem);
    --fs-h3:       clamp(1.6rem, 1.2rem + 2vw,   2.4rem);
    --fs-h2:       clamp(2.2rem, 1.6rem + 3vw,   3.6rem);
    --fs-display:  clamp(3rem,   2rem + 6vw,     6.4rem);
    --fs-rotator:  clamp(1.8rem, 1rem + 3.8vw,   3rem);

    /* ── Easings ─────────────────────────────────────── */
    --ease-expo:   cubic-bezier(.16, 1, .3, 1);
    --ease-soft:   cubic-bezier(.4, 0, .2, 1);

    /* ── #6 Time-of-day mood — set by JS ─────────────── */
    --mood-glow:   rgba(200,162,92,0);

    /* ── #9 Scroll velocity (set by JS) ──────────────── */
    --scroll-vel:    0;
    --marquee-speed: 1;
}

/* =====================================================================
   #2 OPTICAL SIZING FRAUNCES — UNIQUEMENT sur les éléments Fraunces

   Important : font-variation-settings appliqué sur Syne (qui supporte
   wght mais pas opsz/SOFT) override le font-weight et fait paraître
   les titres "étirés/aérés" car le wght 360-440 remplace le 700-800
   natif Syne. On limite donc strictement aux selectors Fraunces.
   ===================================================================== */
.tarifs-title,
.ds-title,
.tarifs-title em,
.ds-title em,
.legal-title em,
.notfound-title em,
.t-line em,
.t-line-italic em,
.pullquote {
    font-variation-settings: 'opsz' 144, 'wght' 360, 'SOFT' 100;
}

/* Body Fraunces (em italique dans paragraphes) — opsz 14 + body weight */
.ed-bio-line em,
.tarifs-sub em,
.legal-body p em,
.proj-section-text em {
    font-variation-settings: 'opsz' 14, 'wght' 400, 'SOFT' 0;
}

/* =====================================================================
   #1 ROTATOR HERO AMPLIFIÉ (axes variables morph)
   ===================================================================== */
.ed-rotator {
    align-items: baseline;
    gap: .6rem;
    margin-top: 1.2rem;
    margin-bottom: 2.5rem;
    flex-wrap: wrap;
    row-gap: .3rem;
    font-size: var(--fs-rotator);
}

.ed-rotator .rot-prefix {
    font-size: .42em;
    color: var(--ivory-3);
    letter-spacing: 0.06em;
    flex-shrink: 0;
    text-transform: lowercase;
}

.ed-rotator .rot-stage {
    font-family: var(--serif);
    font-style: italic;
    font-size: 1em;
    line-height: 1.05;
    letter-spacing: -.02em;
    height: 1.15em;
    min-width: clamp(220px, 28vw, 460px);
    color: var(--gold-2, var(--gold));
}

.ed-rotator .rot-word {
    font-variation-settings: 'opsz' 144, 'wght' 220, 'SOFT' 0;
    transition: transform .85s var(--ease-expo),
                opacity .7s var(--ease-expo),
                font-variation-settings .85s var(--ease-expo);
}

.ed-rotator .rot-word.is-active {
    font-variation-settings: 'opsz' 144, 'wght' 480, 'SOFT' 100;
}

/* Ligne or sous le rotator retirée — créait un effet "couleur dorée qui
   s'arrête au milieu" car la ligne ne peut pas dépasser le rot-stage. */

@media (prefers-reduced-motion: reduce) {
    .ed-rotator .rot-word { transition: opacity .4s; transform: none !important; }
}

/* =====================================================================
   #5 SCROLL-DRIVEN MORPH retiré — causait du repaint à chaque frame
   du scroll sur les axes variables. Préférer un effet statique discret.
   ===================================================================== */

/* =====================================================================
   #6 TIME-OF-DAY MOOD (data-mood sur body, JS set selon heure Tana)
   ===================================================================== */
body[data-mood="dawn"]   { --mood-glow: rgba(228,196,134,.16); }
body[data-mood="day"]    { --mood-glow: rgba(255,255,255,.06); }
body[data-mood="golden"] { --mood-glow: rgba(200,162,92,.22); }
body[data-mood="night"]  { --mood-glow: rgba(196,113,127,.12); }

/* Halo mood retiré — le radial-gradient at 85% 18% ne couvrait que le
   coin haut-droite, donnant l'impression que ".ed-stage s'arrête au milieu".
   En plus, le mix-blend-mode: screen interférait avec le marquee meta
   (texte qui paraissait dédoublé). On garde data-mood pour usage futur
   (marker discret), mais sans halo radial. */

/* Marqueur visuel discret dans le header — la "lumière" du moment */
[data-mood-marker] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--mono, 'JetBrains Mono', monospace);
    font-size: var(--fs-micro);
    letter-spacing: .15em;
    color: var(--ivory-3, rgba(255,255,255,.5));
}
[data-mood-marker]::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gold);
    box-shadow: 0 0 8px var(--mood-glow);
    transition: box-shadow 2s var(--ease-soft);
}
body[data-mood="dawn"] [data-mood-marker]::before   { background: #e4c486; }
body[data-mood="day"] [data-mood-marker]::before    { background: var(--gold-2, #e4c486); }
body[data-mood="golden"] [data-mood-marker]::before { background: var(--gold, #c8a25c); }
body[data-mood="night"] [data-mood-marker]::before  { background: var(--rose, #c4717f); }

/* =====================================================================
   #7 PULL QUOTES éditoriales (Fraunces XL avec hanging quote)
   ===================================================================== */
.pullquote {
    font-family: var(--serif, serif);
    font-style: italic;
    font-variation-settings: 'opsz' 144, 'wght' 320, 'SOFT' 100;
    font-size: clamp(2.4rem, 6vw, 5.6rem);
    line-height: .98;
    letter-spacing: -.02em;
    color: var(--ivory, #ede5d6);
    text-wrap: balance;
    max-width: 20ch;
    margin: clamp(4rem, 9vw, 8rem) auto;
    padding: 0 24px;
    position: relative;
    hanging-punctuation: first;
}
.pullquote::before {
    content: open-quote;
    color: var(--gold, #c8a25c);
    margin-right: .04em;
    font-style: italic;
}
.pullquote::after {
    content: close-quote;
    color: var(--gold, #c8a25c);
    margin-left: .02em;
    font-style: italic;
}
.pullquote-attr {
    display: block;
    font-family: var(--mono, monospace);
    font-style: normal;
    font-size: var(--fs-micro);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ivory-3);
    margin-top: 1.2rem;
}

/* =====================================================================
   #8 ZONE DE SILENCE /tarifs (espace négatif avant booking)
   ===================================================================== */
.tarifs-silence {
    text-align: center;
    padding: clamp(8rem, 18vw, 14rem) clamp(1.5rem, 5vw, 5rem);
    color: var(--ivory-3, rgba(255,255,255,.45));
    position: relative;
}
.tarifs-silence::before,
.tarifs-silence::after {
    content: "";
    position: absolute;
    left: 50%;
    width: 1px;
    height: clamp(3rem, 7vw, 5rem);
    background: var(--gold);
    opacity: .3;
}
.tarifs-silence::before { top: 0; }
.tarifs-silence::after  { bottom: 0; }
.tarifs-silence-text {
    font-family: var(--serif, serif);
    font-style: italic;
    font-size: clamp(1.1rem, 1.6vw, 1.4rem);
    line-height: 1.7;
    max-width: 32ch;
    margin: 0 auto;
    font-variation-settings: 'opsz' 32, 'wght' 360, 'SOFT' 100;
}
.tarifs-silence-meta {
    font-family: var(--mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: .25em;
    text-transform: uppercase;
    color: var(--gold);
    margin-top: 1.5rem;
    opacity: .6;
}

/* =====================================================================
   #4 /tarifs CASCADE MUSICALE 4-beats (hero + packages)
   Filter: blur() retiré — trop coûteux pour le GPU, causait du jank
   scroll. On garde opacity + translateY (transformations hardware-accelerated).
   ===================================================================== */
/* Hero stagger : eyebrow → titre → sub → stats */
.tarifs-hero .tarifs-eyebrow,
.tarifs-hero .tarifs-title,
.tarifs-hero .tarifs-sub,
.tarifs-hero .tarifs-stats {
    opacity: 0;
    transform: translate3d(0, 24px, 0);
    transition: opacity .8s var(--ease-expo),
                transform .8s var(--ease-expo);
    transition-delay: calc(var(--i, 0) * 120ms);
    will-change: opacity, transform;
}
.tarifs-hero.is-in .tarifs-eyebrow,
.tarifs-hero.is-in .tarifs-title,
.tarifs-hero.is-in .tarifs-sub,
.tarifs-hero.is-in .tarifs-stats {
    opacity: 1;
    transform: none;
    will-change: auto;
}
.tarifs-hero .tarifs-eyebrow { --i: 0; }
.tarifs-hero .tarifs-title   { --i: 1; }
.tarifs-hero .tarifs-sub     { --i: 2; }
.tarifs-hero .tarifs-stats   { --i: 3; }

/* Packages cascade RETIRÉE — les cards restaient invisibles quand
   l'IO ne triggered pas (IO loaded async pouvait manquer les éléments). */

@media (prefers-reduced-motion: reduce) {
    .tarifs-hero .tarifs-eyebrow,
    .tarifs-hero .tarifs-title,
    .tarifs-hero .tarifs-sub,
    .tarifs-hero .tarifs-stats {
        opacity: 1; transform: none; transition: none;
    }
}

/* =====================================================================
   #9 MARQUEE — vitesse accélérée + perf
   ===================================================================== */
.marquee-track       { animation-duration: 22s !important; }
.text-marquee-track  { animation-duration: 18s !important; }
.tech-marquee-track  { animation-duration: 24s !important; }
@media (prefers-reduced-motion: reduce) {
    .marquee-track,
    .text-marquee-track,
    .tech-marquee-track { animation: none !important; }
}

/* =====================================================================
   PERF NUCLEAR — zéro latence (règle user explicite)
   ===================================================================== */

/* Retire TOUS les backdrop-filter du site (audit révélait 41 éléments
   avec blur(8-20px) qui forcent le compositing GPU à chaque frame).
   Les backgrounds restent semi-transparents pour le glassmorphism
   visuel, mais sans le blur (économie GPU massive). */
*,
*::before,
*::after {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* Retire les will-change permanents (238 éléments dans le DOM
   avaient will-change défini → saturation des GPU layers). Le browser
   sait déjà optimiser les transforms/opacity, pas besoin d'hint
   explicite permanent. Les éléments qui en ont vraiment besoin
   recevront un will-change temporaire via JS au moment de l'animation. */
.split-char,
.grain,
.fade-in,
.reveal-line,
.bento-preview,
.bento-card,
.service-card,
.tech-marquee-track,
.case-study-track,
.cursor-dot,
.cursor-ring,
.cursor-view,
.hero-content,
.hero-visual,
.hero-dual-tag,
.t-line .t-word,
.t-char,
[data-magnetic],
.logo-letter,
.logo-brace,
.eyebrow-line,
.scroll-indicator {
    will-change: auto !important;
}

/* Retire les mix-blend-mode qui forcent le compositing
   (grain overlay, cursor-dot difference) */
/* Grain DÉSACTIVÉ — user signalait du bruit pixel visible sur l'interface.
   On masque complètement le grain plutôt que de jouer sur l'opacité. */
.grain { display: none !important; }
.cursor-dot, .cursor-ring { mix-blend-mode: normal !important; }

/* =====================================================================
   #10 DROP CAP éditorial (Vignelli / Cereal / Kinfolk)
   ===================================================================== */
.lede::first-letter,
.manifesto-item .manifesto-text:first-of-type::first-letter,
.proj-section-text.is-lede::first-letter,
.case-intro::first-letter {
    font-family: var(--serif);
    font-style: italic;
    font-weight: 320;
    font-variation-settings: 'opsz' 144, 'wght' 320, 'SOFT' 100;
    font-size: 4.4em;
    line-height: .82;
    float: left;
    padding: .08em .14em 0 0;
    color: var(--gold);
}
@media (max-width: 640px) {
    .lede::first-letter,
    .manifesto-item .manifesto-text:first-of-type::first-letter,
    .proj-section-text.is-lede::first-letter,
    .case-intro::first-letter {
        font-size: 3.4em;
    }
}

/* =====================================================================
   CHAR REVEAL (helper pour split text — déjà utilisé par .reveal-line)
   ===================================================================== */
.t-char {
    display: inline-block;
    transform: translateY(110%);
    opacity: 0;
    transition: transform .9s var(--ease-expo) calc(var(--i, 0) * 28ms),
                opacity .6s var(--ease-soft) calc(var(--i, 0) * 28ms);
    will-change: transform;
}
.t-line.is-visible .t-char,
.t-line-italic.is-visible .t-char {
    transform: translateY(0);
    opacity: 1;
}
.t-line-italic .t-char { transition-duration: 1.2s, .8s; }
@media (prefers-reduced-motion: reduce) {
    .t-char { transition: none; transform: none; opacity: 1; }
}

/* =====================================================================
   LIGHT MODE — fixes spécifiques pour éviter les éléments invisibles
   ou désagréables visuellement (pulsations flashy, hover blanc, etc.)
   ===================================================================== */

/* Fix #1 : .text-marquee:hover en light → texte devenait blanc invisible.
   On force la couleur sombre du texte en light mode. */
html[data-theme="light"] .text-marquee:hover .text-marquee-track > span:not(.tmq-sep) {
    color: rgba(10, 14, 26, 0.92) !important;
    -webkit-text-stroke-color: transparent !important;
}

/* Fix #2 : Pulsations à gauche en light mode trop flashy (glow vert sur
   fond blanc). On désactive le glow-pulse/pin-pulse en light, on garde
   un dot statique discret pour conserver l'indication "online/live". */
html[data-theme="light"] .hero-badge-dot,
html[data-theme="light"] .contact-avail-dot {
    animation: none !important;
    box-shadow: 0 0 4px rgba(20, 17, 13, 0.2) !important;
    background: #4d7242 !important;
}
html[data-theme="light"] .activity-pulse {
    animation: none !important;
    box-shadow: 0 0 4px rgba(20, 17, 13, 0.2) !important;
    background: #4d7242 !important;
    transform: none !important;
}
html[data-theme="light"] .case-slide-hint {
    animation: none !important;
    opacity: 0.7 !important;
    transform: none !important;
}

/* Fix #3 : Sections animations en light mode — les fade-in opacity 0
   sur fond clair se confondaient. On force opacity 1 en light si l'IO
   n'a pas encore triggered. */
html[data-theme="light"] .fade-in:not(.visible) {
    opacity: 1 !important;
    transform: none !important;
}

/* Fix #4 : .activity-card.online-pulse et autres glow verts en light */
html[data-theme="light"] [class*="-pulse"]:not(.text-marquee):not(.fade-in) {
    animation: none !important;
}

/* =====================================================================
   FIGMA BOARD VISUAL — remplacement compta.webp moche
   Composant 100% CSS qui illustre "Maquettes Figma haute fidélité"
   ===================================================================== */
.case-slide-figma {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}
.figma-board {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    background: linear-gradient(180deg, #f8f9fb 0%, #eef0f4 100%);
    border-radius: 16px;
    overflow: hidden;
    box-shadow:
        0 24px 60px -16px rgba(0,0,0,.5),
        0 0 0 1px rgba(255,255,255,.04);
    font-family: var(--mono, 'JetBrains Mono', monospace);
    color: #1f2937;
}
.figma-board-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: #ffffff;
    border-bottom: 1px solid rgba(0,0,0,.06);
}
.figma-tool {
    width: 14px; height: 14px;
    border-radius: 4px;
    background: rgba(31, 41, 55, .12);
}
.figma-tool--active {
    background: #0a0907;
}
.figma-board-name {
    margin-left: auto;
    font-size: 10px;
    letter-spacing: .12em;
    color: #6b7280;
    text-transform: uppercase;
}
.figma-board-canvas {
    position: relative;
    height: calc(100% - 38px);
    padding: 20px 22px;
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    grid-template-rows: auto auto;
    gap: 12px;
}
.figma-frame {
    background: #ffffff;
    border-radius: 8px;
    padding: 12px;
    box-shadow: 0 1px 0 rgba(0,0,0,.04);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.figma-frame--hero {
    grid-column: 1 / 2;
    grid-row: 1 / 3;
    justify-content: center;
}
.figma-frame--cards {
    grid-column: 2 / 3;
    grid-row: 1 / 2;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    padding: 8px;
}
.figma-frame--swatches {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
}
.figma-bar {
    height: 6px;
    border-radius: 3px;
    background: linear-gradient(90deg, rgba(31,41,55,.85), rgba(31,41,55,.4));
}
.figma-bar--w90 { width: 90%; }
.figma-bar--w80 { width: 80%; }
.figma-bar--w75 { width: 75%; }
.figma-bar--w70 { width: 70%; }
.figma-bar--w60 { width: 60%; }
.figma-bar--w55 { width: 55%; }
.figma-bar--w50 { width: 50%; height: 4px; opacity: .7; }
.figma-cta {
    margin-top: 6px;
    width: 100px;
    height: 14px;
    border-radius: 999px;
    background: linear-gradient(135deg, #c8a25c, #b8924c);
}
.figma-card {
    background: #f7f8fa;
    border-radius: 5px;
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.figma-thumb {
    aspect-ratio: 1.2;
    border-radius: 3px;
}
.figma-thumb--a { background: linear-gradient(135deg, #c4717f, #a85d6b); }
.figma-thumb--b { background: linear-gradient(135deg, #6b8a5e, #4d7242); }
.figma-thumb--c { background: linear-gradient(135deg, #c8a25c, #8e6628); }
.figma-card .figma-bar { height: 3px; }
.figma-swatch {
    flex: 1;
    aspect-ratio: 1;
    max-width: 28px;
    border-radius: 6px;
    box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
}
.figma-swatch--ink    { background: #0a0907; }
.figma-swatch--gold   { background: #c8a25c; }
.figma-swatch--rose   { background: #c4717f; }
.figma-swatch--green  { background: #6b8a5e; }
.figma-swatch--ivory  { background: #ede5d6; box-shadow: inset 0 0 0 1px rgba(0,0,0,.1); }
.figma-board-cursors {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.figma-cursor {
    position: absolute;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 7px 3px 4px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 500;
    color: #ffffff;
    font-family: var(--sans, 'Inter', system-ui, sans-serif);
}
.figma-cursor svg {
    width: 10px;
    height: 10px;
    margin-right: 2px;
}
.figma-cursor--mitia {
    top: 35%; left: 32%;
    background: #6b8a5e;
}
.figma-cursor--client {
    top: 62%; right: 18%;
    background: #c4717f;
}

/* Light mode adaptation : darker board background pour rester contrastée */
html[data-theme="light"] .figma-board {
    background: linear-gradient(180deg, #ffffff 0%, #f1ede4 100%);
    box-shadow: 0 12px 30px -8px rgba(20,17,13,.18), 0 0 0 1px rgba(20,17,13,.06);
}

/* Caption au-dessus du figma board pour clarifier ce que c'est */
.figma-board-caption {
    font-family: var(--mono, 'JetBrains Mono', monospace);
    font-size: var(--fs-micro, .75rem);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ivory-3, rgba(255,255,255,.5));
    text-align: center;
    margin: 0 0 .75rem 0;
}
html[data-theme="light"] .figma-board-caption {
    color: rgba(20, 17, 13, 0.55);
}

/* =====================================================================
   FIX DÉFINITIF zéro-clipping (workflow ultracode 4-agents)
   Audit a identifié 129 selectors avec letter-spacing négatif et
   3 mécanismes cumulatifs :
   1. Glyph ink > advance width (Fraunces italic terminaisons jusqu'à 0.32em
      d'overshoot, Syne 800-900 jusqu'à 0.075em sur K/V/W/X/Y/k/y)
   2. Letter-spacing trailing (CSS Text 3 : appliqué APRÈS dernier glyphe)
   3. Overflow:hidden ancestors qui hard-crop le débordement

   Solution en 5 couches défensives :
   - Couche 1 : padding-inline-end .18em sur tous titres roman (80+ sel.)
   - Couche 1b : padding-inline-end .3em sur em italiques Fraunces
   - Couche 1c : padding-inline-end .22em sur em italiques Syne
   - Couche 2 : overflow-clip-margin .6em sur conteneurs overflow:hidden
   - Couche 3 : ZWSP ::after sur em italiques (neutralise trailing spacing)
   - Couche 4 : watermarks géants avec margin-end négatif compensateur
   - Couche 5 : padding-bottom sur gradient text-clip (j/g/p descendants)
   ===================================================================== */

/* ---------- Couche 1 : padding roman tous titres ---------- */
.hero-title,
.section-title,
.manifesto-title,
.case-slide-title,
.case-slide-h,
.pkg-name,
.pkg-price-amount,
.step-title,
.step-num,
.tarifs-title,
.ds-title,
.ds-section-title,
.ds-typo-name,
.ds-typo-sample,
.ds-principle-num,
.ds-scale-sample,
.legal-title,
.legal-body h2,
.legal-body h3,
.notfound-title,
.notfound-code,
.proj-title,
.proj-section-title,
.proj-feature-num,
.proj-feature-title,
.proj-stat-num,
.proj-cta-title,
.proj-nav-name,
.proj-watermark,
.proj-kpi-num,
.proj-process-title,
.ed-title,
.ed-rotator .rot-stage,
.booking-title,
.bcta-label,
.cta-final-title,
.cta-label,
.faq-q-text,
.atelier-title,
.atelier-cta-title,
.atelier-card-title,
.discipline-title,
.av2-hero-title,
.av2-section-title,
.av2-pull,
.av2-cta-title,
.av2-colophon-title,
.cahier-title,
.cahier-pullquote,
.cahier-signature,
.pullquote,
.brand-mark,
.bento-title,
.service-card-title,
.service-num,
.about-stat-val,
.hero-stat-num,
.hero-watermark,
.intro-loader-name,
.showcase-status-name,
.metric-num,
.case-stat-num,
.case-client,
.case-slide-pullquote,
.client-name,
.client-stat-num,
.imagine-result-title,
.imagine-result-meta-val,
.scr-title,
.scr-stats-amount,
.scr-time,
.typo-cycle,
.t-line,
.t-line-italic,
.tarifs-stats strong,
.project-sheet-title,
.hd-typo-big {
    padding-inline-end: .18em;
}

/* ---------- Couche 1b : italiques Fraunces padding maximal ---------- */
.hero-title em,
.section-title em,
.manifesto-title em,
.case-slide-title em,
.case-slide-h em,
.tarifs-title em,
.tarifs-stats strong em,
.ds-title em,
.ds-typo-sample em,
.legal-title em,
.notfound-title em,
.proj-title em,
.proj-section-title em,
.proj-cta-title em,
.ed-title em,
.av2-hero-title em,
.av2-section-title em,
.av2-pull em,
.av2-cta-title em,
.av2-colophon-title em,
.cahier-title em,
.cahier-pullquote em,
.cahier-signature em,
.cahier-prose em,
.cta-final-title em,
.booking-title em,
.step-num em,
.pullquote em,
.brand-mark em,
.case-system-color em,
.case-accent,
.imagine-option em,
.imagine-option-card em,
.showcase-testimonial-quote em,
.case-slide-pullquote em,
.t-line-italic em,
.t-line-italic {
    display: inline-block;
    padding-inline-end: .3em;
}

/* ---------- Couche 1c : italiques Syne overshoot modéré ---------- */
.atelier-card-title em,
.atelier-card-title .atelier-card-italic,
.atelier-card-italic,
.imagine-accent,
.discipline-title em,
.atelier-cta-title em,
.proj-feature-title em,
.bento-title em,
.service-card-title em,
.metric-num em,
.client-name em,
.imagine-result-title em {
    display: inline-block;
    padding-inline-end: .22em;
}

/* ---------- Couche 1d : accents Syne roman block (location, activity, contact) ---------- */
.location-accent,
.activity-accent,
.contact-title-accent,
.reveal-line.location-accent,
.reveal-line.activity-accent,
.reveal-line.contact-title-accent {
    padding-inline-end: .18em;
}

/* ---------- Couche 2 : overflow-clip-margin defense-in-depth ---------- */
/* Chrome 90+/Firefox 102+/Safari 16+. Dégradation silencieuse sur anciens. */
.t-line,
.proj-feature-item,
.pkg-card,
.booking-stage,
.ds-typo-card,
.ds-typo-sample-wrap,
.ds-principle-card,
.ds-scale-sample-wrap,
.cahier,
.av2-hero,
.av2-section,
.av2-cta,
.atelier-card,
.case-slide,
.client-card,
.proj-stat-card,
.proj-feature-card,
.bento-item,
.service-card,
.figma-board,
.imagine-result,
.imagine-option-card,
.tarifs-stats,
.scr-card,
#about,
#work,
#skills,
#services,
#contact {
    overflow-clip-margin: 0.6em;
}

/* ---------- Couche 3 : ZWSP reset letter-spacing trailing ---------- */
.hero-title em::after,
.section-title em::after,
.tarifs-title em::after,
.ds-title em::after,
.proj-title em::after,
.ed-title em::after,
.av2-hero-title em::after,
.av2-section-title em::after,
.av2-cta-title em::after,
.av2-colophon-title em::after,
.cahier-title em::after,
.cta-final-title em::after,
.booking-title em::after,
.case-slide-title em::after,
.t-line-italic em::after {
    content: "\200B";
    letter-spacing: 0;
    font-style: normal;
}

/* ---------- Couche 4 : watermarks géants compensation centrage ---------- */
.hero-watermark,
.proj-watermark,
.notfound-code,
.ds-principle-num,
.proj-feature-num,
.service-num {
    padding-inline-end: .12em;
    margin-inline-end: -.12em;
}

/* ---------- Couche 5 : gradient text-clip descender safety ---------- */
.case-stat-num,
.scr-stats-amount,
.proj-stat-num,
.client-stat-num,
.t-line-italic em,
.t-line-italic {
    padding-bottom: .04em;
}
