/* ===========================================================================
 * Variant 4a — "La Grue / Polish"
 *
 * Refinement of V4. Metaphor lives in texture and artifact, not in vocabulary.
 *  - Removed: A/B/C axis labels, draftsman eyebrows, heavy section borders
 *  - Kept: paper/cyanotype palette, cotation marks, clean site footer
 *  - Crane upgraded: JOG sign on mast, extended jib, long cable, cycling payload
 *  - Motion: scroll reveals, hover states on every interactive, cable pendulum
 *  - Separators: designed cotation dividers, not naked 1px borders
 * ======================================================================== */

:root {
  --font-display: 'Fraunces', Georgia, serif;
  --font-body: 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Custom tokens this variant adds */
  --w-title: 18ch;
  --dur-xlong: 720ms;
  --ease-soft: cubic-bezier(0.2, 0.8, 0.2, 1);

  /* Section rule tokens — imported from V4c so section headers and
   * bordered surfaces share the same rhythm. */
  --rule: 1px solid var(--color-border);
  --rule-strong: 1.5px solid var(--color-text);
}

/* ---- Themes --------------------------------------------------------- */

[data-theme="light"] {
  --color-bg:          oklch(97% 0.008 90);     /* papier ivoire */
  --color-surface-1:   oklch(99% 0.005 90);
  --color-surface-2:   oklch(93% 0.012 90);
  --color-text:        oklch(22% 0.010 250);    /* graphite */
  --color-text-muted:  oklch(48% 0.012 250);
  --color-text-soft:   oklch(62% 0.010 250);
  --color-border:      oklch(86% 0.010 90);
  --color-border-strong: oklch(72% 0.012 90);
  --color-accent:      oklch(70% 0.148 65);     /* ocre Liebherr (exact v4c) */
  --color-accent-fg:   oklch(18% 0.012 250);
  --color-accent-hi:   oklch(78% 0.160 65);
  --color-stamp:       oklch(52% 0.170 30);     /* rouge-rouille */
  --color-steel:       oklch(55% 0.060 240);
  --color-cable:       oklch(30% 0.015 250);
  --shadow-card:       0 1px 0 oklch(86% 0.010 90), 0 14px 30px -20px oklch(20% 0.010 250 / 0.25);
  --shadow-card-hover: 0 1px 0 var(--color-accent), 0 24px 50px -20px oklch(20% 0.010 250 / 0.35);

  /* Accent de section — bande Maître d'œuvre */
  --c-terracotta:      oklch(58% 0.145 35);
  --c-terracotta-ink:  oklch(14% 0.020 30);
  --c-mortar:          oklch(24% 0.008 260);

  /* Cyanotype blueprint accent (ported from V4c — used for demo tape 02) */
  --color-blueprint:   oklch(42% 0.135 245);

  /* Paper-grid tokens (ported from V4c as-is — same density so the hero
   * grid reads uniformly, including the top-left quadrant). */
  --grid-color:        color-mix(in oklch, var(--color-text) 8%, transparent);
  --grid-major:        color-mix(in oklch, var(--color-blueprint) 14%, transparent);
}

[data-theme="dark"] {
  --color-bg:          oklch(18% 0.020 245);    /* cyanotype */
  --color-surface-1:   oklch(22% 0.024 245);
  --color-surface-2:   oklch(27% 0.026 245);
  --color-text:        oklch(95% 0.010 240);
  --color-text-muted:  oklch(76% 0.015 240);
  --color-text-soft:   oklch(60% 0.014 240);
  --color-border:      oklch(36% 0.022 245);
  --color-border-strong: oklch(48% 0.026 245);
  --color-accent:      oklch(82% 0.150 85);     /* ocre Liebherr dark (exact v4c) */
  --color-accent-fg:   oklch(20% 0.040 245);
  --color-accent-hi:   oklch(90% 0.165 85);
  --color-stamp:       oklch(70% 0.180 30);
  --color-steel:       oklch(75% 0.090 240);
  --color-cable:       oklch(88% 0.012 240);
  --shadow-card:       0 1px 0 oklch(36% 0.022 245), 0 14px 30px -18px oklch(0% 0 0 / 0.55);
  --shadow-card-hover: 0 1px 0 var(--color-accent), 0 24px 50px -18px oklch(0% 0 0 / 0.7);

  /* Accent de section — bande Maître d'œuvre */
  --c-terracotta:      oklch(62% 0.140 30);
  --c-terracotta-ink:  oklch(14% 0.020 30);
  --c-mortar:          oklch(20% 0.006 260);

  /* Cyanotype blueprint accent (ported from V4c — used for demo tape 02) */
  --color-blueprint:   oklch(82% 0.085 220);

  /* Paper-grid tokens (ported from V4c as-is — dark variant). */
  --grid-color:        color-mix(in oklch, var(--color-text) 12%, transparent);
  --grid-major:        color-mix(in oklch, var(--color-blueprint) 30%, transparent);
}

/* ---- Body + background texture ------------------------------------- */

body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  letter-spacing: -0.005em;
  /* v4c parity — solid bg, no vignette : the radial mask was darkening the
   * edges of gridded sections and visually hiding the 24 px minor grid in
   * the top-left / corners of the hero. Back to a flat paper so the grid
   * reads uniformly, exactly like variant-4c-synthesis. */
  background: var(--color-bg);
  color: var(--color-text);
  overflow-x: clip;
}

/* Fix sticky navbar — shared/base.css locks html/body to height:100%
 * which caps the sticky containing block at ~100vh. Override with auto. */
html, body { height: auto; min-height: 100%; }

/* Paper noise turbulence overlay (4c-style). The SVG noise adds a subtle
 * hand-drawn grain across the whole page so every section — grid or plain —
 * sits on the same paper stock. Kept light (opacity 0.22) so it never
 * fights with the Haïku line-work or the grid on gridded sections. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.12 0'/></filter><rect width='200' height='200' filter='url(%23n)'/></svg>");
  opacity: 0.22;
  mix-blend-mode: multiply;
}
[data-theme="dark"] body::after { mix-blend-mode: screen; opacity: 0.14; }

/* Paper grid (filigrane) — global, fixed to viewport, matches variant-4c-synthesis.
 * Grid must be uniform top-to-bottom and not scroll with content, so it lives
 * on body::before (position:fixed) rather than per-section. Plain sections have
 * tinted backgrounds that naturally cover this grid where needed. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    linear-gradient(to right,  var(--grid-major) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-major) 1px, transparent 1px),
    linear-gradient(to right,  var(--grid-color) 0.5px, transparent 0.5px),
    linear-gradient(to bottom, var(--grid-color) 0.5px, transparent 0.5px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  opacity: 0.55;
}

main { position: relative; z-index: 1; }

/* ---- Section rhythm : GRID vs PLAIN ---------------------------------
 * 4c alternates plates : the background changes visibly from one section
 * to the next, which removes the need for separator rules between them.
 * V5-test reproduces that rhythm :
 *
 *   hero        → .section--grid  (papier + grille visible)
 *   #problem    → .section--plain (tinted blueprint, no grid)
 *   #demos      → .section--grid  (papier + grille visible)
 *   #phases     → .section--plain (tinted accent, no grid)
 *   .moe-band   → terracotta solid (already handled)
 *   contact     → .section--plain (tinted accent, matches 4c detail)
 *
 * The grid is painted per-section (not on body) so plain sections sit
 * on clean tinted paper. Opacity 0.55 matches 4c's body grid. */

/* .section--grid : no own grid — the paper grid is painted globally on
 * body::before (fixed to viewport, matches variant-4c-synthesis). This
 * class just marks sections that stay transparent so the body grid shows
 * through; plain sections below use tinted backgrounds to mask it. */
.section--grid {
  position: relative;
}

/* Inner content must sit above the body grid (z-index:0). */
.section--grid > * { position: relative; z-index: 1; }

/* Plain sections — tinted, no grid. Tints ported from 4c :
 *   problem  : blueprint 4% light / 6% dark  (matches 4c .coupe)
 *   phases   : accent 4% light / 5% dark     (matches 4c .detail)
 *   contact  : accent 3% light / 4% dark     (kept from v5-test) */
.section--plain { position: relative; }

#problem.section--plain {
  background: color-mix(in oklch, var(--color-blueprint) 4%, var(--color-bg));
}
[data-theme="dark"] #problem.section--plain {
  background: color-mix(in oklch, var(--color-blueprint) 6%, var(--color-bg));
}
#phases.section--plain {
  background: color-mix(in oklch, var(--color-accent) 4%, var(--color-bg));
}
[data-theme="dark"] #phases.section--plain {
  background: color-mix(in oklch, var(--color-accent) 5%, var(--color-bg));
}
.section--contact.section--plain {
  background: color-mix(in oklch, var(--color-accent) 3%, var(--color-bg));
}
[data-theme="dark"] .section--contact.section--plain {
  background: color-mix(in oklch, var(--color-accent) 4%, var(--color-bg));
}

/* ---- Section separator lines (v4) -----------------------------------
 * Thin hairlines between every major section, matching the navbar
 * bottom border exactly (1px solid var(--color-border)). Adds to the
 * grid/plain alternation — both cues cumulate. The .moe-band is itself
 * a <section>, so the single `section + section` rule covers it; its
 * own border-top/bottom are also normalized to the same hairline spec
 * (see .moe-band below). The footer already carries a matching
 * border-top. */
main > section + section {
  border-top: 1px solid var(--color-border);
}

/* ---- Typography ---------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  font-variation-settings: 'opsz' 144, 'SOFT' 40;
  letter-spacing: -0.022em;
  line-height: 1.05;
  color: var(--color-text);
}

.mono { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; }

/* ---- Discreet ruler ticks (desktop only, very faded) --------------- */

.ruler {
  position: fixed;
  z-index: 0;
  pointer-events: none;
  display: none;
  color: var(--color-text-soft);
  opacity: 0.35;
}
.ruler span {
  display: block;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.06em;
}
.ruler--top {
  top: 2px;
  left: 60px;
  right: 60px;
  display: none;
  justify-content: space-between;
}
.ruler--top span::before { content: '│'; color: currentColor; }
.ruler--left {
  top: 140px;
  bottom: 60px;
  left: 6px;
  flex-direction: column;
  justify-content: space-between;
}
.ruler--left span::before { content: '─'; color: currentColor; }

@media (min-width: 1280px) {
  .ruler--top { display: flex; }
  .ruler--left { display: flex; }
}

/* ---- Theme toggle (floating, bottom-left, icons) ------------------- */

.theme-toggle {
  border: 1px solid var(--color-border);
  border-radius: 0;
  background: transparent;
  padding: 2px;
  display: inline-flex;
  gap: 0;
}
.theme-toggle button {
  color: var(--color-text-muted);
  border-radius: 0;
  transition: background var(--dur-fast) var(--ease-soft), color var(--dur-fast) var(--ease-soft);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 8px;
}
.theme-toggle button svg {
  display: block;
  width: 16px;
  height: 16px;
}
.theme-toggle button:hover { color: var(--color-text); }
.theme-toggle button[aria-pressed="true"] {
  background: var(--color-accent);
  color: var(--color-accent-fg);
  box-shadow: none;
}

.theme-toggle--fixed {
  position: fixed;
  bottom: var(--s-4);
  left: var(--s-4);
  z-index: 50;
  background: color-mix(in oklch, var(--color-bg) 92%, transparent);
  backdrop-filter: saturate(160%) blur(8px);
  -webkit-backdrop-filter: saturate(160%) blur(8px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14);
}
@media (prefers-reduced-motion: reduce) {
  .theme-toggle button { transition: none; }
}

/* ---- Nav ----------------------------------------------------------- */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in oklch, var(--color-bg) 88%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--color-border);
  padding: 0;
}
.site-nav__inner {
  max-width: var(--w-max);
  margin: 0 auto;
  padding: var(--s-4) var(--s-6);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-6);
}
.site-nav__logo {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.02em;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: color var(--dur-fast) var(--ease-soft);
}
.site-nav__logo-mark {
  width: 22px;
  height: 22px;
  background: var(--color-accent);
  border-radius: 2px;
  display: inline-block;
  position: relative;
  transition: transform var(--dur-base) var(--ease-soft), box-shadow var(--dur-base) var(--ease-soft);
}
.site-nav__logo-mark::after {
  content: '';
  position: absolute;
  inset: 3px;
  border: 1px solid var(--color-accent-fg);
  opacity: 0.6;
}
.site-nav__logo:hover .site-nav__logo-mark {
  transform: rotate(45deg);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-accent) 30%, transparent);
}

.site-nav__links {
  display: none;
  gap: var(--s-6);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.site-nav__links a {
  position: relative;
  padding: 4px 0;
  transition: color var(--dur-fast) var(--ease-soft);
}
.site-nav__links a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  height: 1.5px;
  width: 0;
  background: var(--color-accent);
  transition: width var(--dur-base) var(--ease-soft);
}
.site-nav__links a:hover,
.site-nav__links a[aria-current="location"] {
  color: var(--color-text);
}
.site-nav__links a:hover::after,
.site-nav__links a[aria-current="location"]::after {
  width: 100%;
}
@media (min-width: 768px) {
  .site-nav__links { display: flex; }
}

/* ---- Buttons ------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px;
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
  position: relative;
  overflow: hidden;
}
.btn__arrow {
  width: 22px;
  height: 12px;
  transition: transform var(--dur-base) var(--ease-soft);
}
.btn:hover .btn__arrow { transform: translateX(4px); }

.btn--primary {
  background: var(--color-accent);
  color: var(--color-accent-fg);
  border-color: var(--color-accent);
}
.btn--primary:hover {
  background: var(--color-accent-hi);
  border-color: var(--color-accent-hi);
  transform: translateY(-1px);
}
.btn--secondary {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-border-strong);
}
.btn--secondary:hover {
  background: var(--color-text);
  color: var(--color-bg);
  border-color: var(--color-text);
  transform: translateY(-1px);
}

/* Stamp */
.stamp {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border: 2px solid var(--color-stamp);
  color: var(--color-stamp);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  transform: rotate(-6deg);
  transition: transform var(--dur-base) var(--ease-soft), box-shadow var(--dur-base) var(--ease-soft);
  position: relative;
  background: color-mix(in oklch, var(--color-bg) 80%, transparent);
}
.stamp svg { width: 14px; height: 10px; }
.stamp:hover {
  transform: rotate(3deg) scale(1.06);
  box-shadow: 0 6px 14px -6px color-mix(in oklch, var(--color-stamp) 40%, transparent);
}
.stamp--static { pointer-events: none; }

/* ---- HERO ---------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 92vh;
  padding: var(--s-16) var(--s-6) var(--s-24);
  overflow: visible;
  isolation: isolate;
}
.hero__inner {
  max-width: var(--w-max);
  margin: 0 auto;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: var(--s-8);
  min-height: 76vh;
  position: relative;
}
.hero__copy {
  max-width: 54ch;
  position: relative;
  z-index: 2;
}

/* Kicker with inline SVG marker */
.hero__kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--s-6);
  padding: 4px 10px 4px 4px;
  border: 1px solid var(--color-border);
  background: color-mix(in oklch, var(--color-surface-1) 80%, transparent);
}
.hero__kicker-mark {
  width: 16px;
  height: 16px;
  color: var(--color-accent);
  animation: kicker-pulse 3s ease-in-out infinite;
}
@keyframes kicker-pulse {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50% { transform: scale(1.12); opacity: 1; }
}

/* Title */
.hero__title {
  font-size: clamp(2.3rem, 1.8rem + 4.2vw, 5.4rem);
  font-weight: 400;
  line-height: 0.98;
  letter-spacing: -0.028em;
  color: var(--color-text);
  margin-bottom: var(--s-6);
  max-width: var(--w-title);
}
.hero__title-lift {
  color: var(--color-accent);
  font-style: italic;
  font-variation-settings: 'opsz' 144, 'SOFT' 80;
  display: inline-block;
  animation: lift-breathe 5s ease-in-out infinite;
  position: relative;
}
.hero__title-lift::after {
  content: '';
  position: absolute;
  left: 2%;
  right: 2%;
  bottom: 0.08em;
  height: 4px;
  background: var(--color-accent);
  opacity: 0.22;
  transform-origin: left center;
  animation: lift-underline 5s ease-in-out infinite;
}
@keyframes lift-breathe {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}
@keyframes lift-underline {
  0%, 100% { transform: scaleX(1); }
  50% { transform: scaleX(0.95); }
}

.hero__sub {
  font-size: 19px;
  line-height: 1.55;
  color: var(--color-text);
  max-width: 52ch;
  margin-bottom: var(--s-8);
}

.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
}
.hero__ctas .stamp {
  margin-left: var(--s-4);
}

/* ---- THE CRANE (Haïku v2) ------------------------------------------
 * Container positioning kept from the original crane wrapper so the hero
 * grid layout is unchanged. Animation CSS is scoped under .hero-haiku to
 * avoid collisions with any generic .trolley/.bird/.payload names.
 * ------------------------------------------------------------------- */

.crane {
  position: absolute;
  top: 0;
  right: clamp(-60px, -3vw, 40px);
  bottom: 0;
  width: clamp(280px, 38vw, 560px);
  pointer-events: none;
  z-index: 1;
  color: var(--color-text);
  display: flex;
  align-items: center;
  justify-content: center;
}
.crane svg {
  width: 100%;
  height: auto;
  max-height: 100%;
  overflow: visible;
}

/* ===== Haïku animation — all rules scoped under .hero-haiku ========
   36s master cycle = two 18s passes, ping-pong style.
   Beats: pick right → lift → cruise left → place → breathe → pick left
          → lift → cruise right → place → breathe (seamless loop).
   =================================================================== */

/* Trolley horizontal — ping-pong */
.hero-haiku .hk-trolley-group {
  animation: hk-trolley 36s cubic-bezier(.45,.05,.45,.95) infinite;
}
@keyframes hk-trolley {
  0%    { transform: translateX(498px); }
  7.5%  { transform: translateX(498px); }
  11%   { transform: translateX(498px); }
  22%   { transform: translateX(182px); }
  25.5% { transform: translateX(182px); }
  33%   { transform: translateX(182px); }
  50%   { transform: translateX(182px); }
  57.5% { transform: translateX(182px); }
  61%   { transform: translateX(182px); }
  72%   { transform: translateX(498px); }
  75.5% { transform: translateX(498px); }
  83%   { transform: translateX(498px); }
  100%  { transform: translateX(498px); }
}

/* Cable scaleY */
.hero-haiku .hk-cable-scale {
  transform-origin: 0 0;
  animation: hk-cable 36s cubic-bezier(.55,.05,.45,.95) infinite;
}
@keyframes hk-cable {
  0%   { transform: scaleY(1); }
  4%   { transform: scaleY(1); }
  11%  { transform: scaleY(.494); }
  22%  { transform: scaleY(.494); }
  33%  { transform: scaleY(.953); }
  50%  { transform: scaleY(.953); }
  54%  { transform: scaleY(.953); }
  61%  { transform: scaleY(.494); }
  72%  { transform: scaleY(.494); }
  83%  { transform: scaleY(1); }
  100% { transform: scaleY(1); }
}

/* Payload Y follows the cable (no teleport, no opacity flip) */
.hero-haiku .hk-payload {
  animation: hk-payloadY 36s cubic-bezier(.55,.05,.45,.95) infinite;
}
@keyframes hk-payloadY {
  0%   { transform: translateY(632px); }
  4%   { transform: translateY(632px); }
  11%  { transform: translateY(374px); }
  22%  { transform: translateY(374px); }
  33%  { transform: translateY(608px); }
  50%  { transform: translateY(608px); }
  54%  { transform: translateY(608px); }
  61%  { transform: translateY(374px); }
  72%  { transform: translateY(374px); }
  83%  { transform: translateY(632px); }
  100% { transform: translateY(632px); }
}

/* Left-placed outlined card — visible 33→54% */
.hero-haiku .hk-left-placed {
  opacity: 0;
  animation: hk-leftPlaced 36s steps(1,end) infinite;
}
@keyframes hk-leftPlaced {
  0%   { opacity: 0; }
  33%  { opacity: 1; }
  54%  { opacity: 0; }
  100% { opacity: 0; }
}

/* Right-top outlined card — visible 0→4% and 83→100% */
.hero-haiku .hk-right-top {
  opacity: 1;
  animation: hk-rightTop 36s steps(1,end) infinite;
}
@keyframes hk-rightTop {
  0%   { opacity: 1; }
  4%   { opacity: 0; }
  83%  { opacity: 1; }
  100% { opacity: 1; }
}

/* Payload filled visibility — visible only in transit */
.hero-haiku .hk-payload-visible {
  animation: hk-payloadVisible 36s steps(1,end) infinite;
}
@keyframes hk-payloadVisible {
  0%   { opacity: 0; }
  4%   { opacity: 1; }
  33%  { opacity: 0; }
  54%  { opacity: 1; }
  83%  { opacity: 0; }
  100% { opacity: 0; }
}

/* 3 red aviation warning lights — desynced organic blink */
.hero-haiku .hk-red-light {
  animation: hk-blink 2.4s ease-in-out infinite;
}
.hero-haiku .hk-red-light--apex      { animation-delay: 0s; }
.hero-haiku .hk-red-light--jib-right { animation-delay: -0.7s; }
.hero-haiku .hk-red-light--jib-left  { animation-delay: -1.4s; }
@keyframes hk-blink {
  0%, 55%  { opacity: 1;   filter: drop-shadow(0 0 4px var(--color-stamp)); }
  65%, 90% { opacity: .15; filter: drop-shadow(0 0 0 transparent); }
  100%     { opacity: 1;   filter: drop-shadow(0 0 4px var(--color-stamp)); }
}

/* Bird — perched on jib tip, hops to mast apex to dodge the trolley */
.hero-haiku .hk-bird {
  animation: hk-birdMove 36s cubic-bezier(.4,.0,.2,1) infinite;
}
@keyframes hk-birdMove {
  0%    { transform: translate(0,0); }
  15%   { transform: translate(0,0); }
  16.5% { transform: translate(60px,-78px); }
  18%   { transform: translate(118px,-63px); }
  85%   { transform: translate(118px,-63px); }
  86.5% { transform: translate(60px,-78px); }
  88%   { transform: translate(0,0); }
  100%  { transform: translate(0,0); }
}
.hero-haiku .hk-bird-head {
  animation: hk-birdHead 36s steps(1,end) infinite;
  transform-origin: 222px 115px;
}
@keyframes hk-birdHead {
  0%   { transform: scaleX(1); }
  14%  { transform: scaleX(1); }
  18%  { transform: scaleX(1); }
  50%  { transform: scaleX(-1); }
  85%  { transform: scaleX(1); }
  100% { transform: scaleX(1); }
}

/* Label cycling — forward-only 90s, 5 labels × 18s per pass */
.hero-haiku .hk-label-stack text { opacity: 0; }
.hero-haiku .hk-label-0 { animation: hk-lbl 90s steps(1,end) infinite; }
.hero-haiku .hk-label-1 { animation: hk-lbl 90s steps(1,end) infinite; animation-delay: -72s; }
.hero-haiku .hk-label-2 { animation: hk-lbl 90s steps(1,end) infinite; animation-delay: -54s; }
.hero-haiku .hk-label-3 { animation: hk-lbl 90s steps(1,end) infinite; animation-delay: -36s; }
.hero-haiku .hk-label-4 { animation: hk-lbl 90s steps(1,end) infinite; animation-delay: -18s; }
@keyframes hk-lbl {
  0%, 20%        { opacity: 1; }
  20.001%, 100%  { opacity: 0; }
}

/* Reduced-motion kill switch — freeze at "at rest on right pile" */
@media (prefers-reduced-motion: reduce) {
  .hero-haiku .hk-trolley-group,
  .hero-haiku .hk-cable-scale,
  .hero-haiku .hk-payload,
  .hero-haiku .hk-payload-visible,
  .hero-haiku .hk-left-placed,
  .hero-haiku .hk-right-top,
  .hero-haiku .hk-red-light,
  .hero-haiku .hk-bird,
  .hero-haiku .hk-bird-head,
  .hero-haiku .hk-label-0,
  .hero-haiku .hk-label-1,
  .hero-haiku .hk-label-2,
  .hero-haiku .hk-label-3,
  .hero-haiku .hk-label-4 {
    animation: none !important;
  }
  .hero-haiku .hk-trolley-group { transform: translateX(498px); }
  .hero-haiku .hk-cable-scale   { transform: scaleY(1); }
  .hero-haiku .hk-payload       { transform: translateY(632px); }
  .hero-haiku .hk-payload-visible { opacity: 0; }
  .hero-haiku .hk-right-top     { opacity: 1; }
  .hero-haiku .hk-left-placed   { opacity: 0; }
  .hero-haiku .hk-label-0       { opacity: 1; }
  .hero-haiku .hk-red-light     { opacity: 1; }
}

/* ---- Section separators : REMOVED ----------------------------------
 * 4c relies on the grid/plain alternation to give rhythm between
 * sections — no "01 · LE PROBLÈME" floating dividers, no naked 1px
 * border-tops between sections. The section number lives inside the
 * section heading itself (.eyebrow__num). */

/* ---- Sections ------------------------------------------------------ */

.section {
  padding: var(--s-24) var(--s-6);
  position: relative;
}
@media (min-width: 768px) { .section { padding: var(--s-32) var(--s-8); } }

/* (Section background rhythm is now governed by .section--grid /
 *  .section--plain — see top of file. The old body-wide grid + 3%
 *  blueprint tint has been replaced by per-section plates à la 4c.) */

/* ---- Section heading (4c-style) -------------------------------------
 * Reproduces 4c's .section-head : a muted mono eyebrow (numéro + titre de
 * la vue), a big Fraunces title on a 20ch measure, an optional italic
 * accent continuation, an optional muted lede. Aligned left by default.
 * Eyebrow is flat (no pill, no box) to match 4c. */

/* Section heading sits on the page gutter (same max-width as siblings)
 * but its title-column is clamped to ~20ch via .section__head h2 itself.
 * This reproduces 4c's "titre contre la gouttière gauche" alignment. */
.section__head {
  max-width: var(--w-max);
  margin: 0 auto clamp(2.5rem, 1.5rem + 4vw, 5rem);
}
.section__head--centered {
  text-align: center;
}
.section__head--centered .eyebrow { justify-content: center; }
.section__head--centered .section__lead { margin-inline: auto; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--s-4);
  padding: 0;
  border: 0;
  background: transparent;
}
/* Small geometric marker, 4c-sized (10px, not 16px pill). Color matches
 * the section "view type" : process=accent, data=blueprint, output=stamp.
 * Sections use semantic variants via a modifier class on the marker. */
.eyebrow__mark {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  color: var(--color-accent);
}
.eyebrow__mark--process  { color: var(--color-accent); }
.eyebrow__mark--data     { color: var(--color-blueprint); }
.eyebrow__mark--output   { color: var(--color-stamp); }

/* The section number ("01", "02"...) sits before the label as 4c does
 * with "VUE 01 — ÉLÉVATION". Weight 700 on the digits, normal on the
 * separator + label. */
.eyebrow__num {
  font-weight: 700;
  color: var(--color-text);
  letter-spacing: 0.16em;
}
.eyebrow__sep { opacity: 0.55; padding: 0 2px; }

/* Section title — 4c : Fraunces 400, 2.25→4rem, tight leading, 20ch. */
.section__head h2 {
  font-size: clamp(2.25rem, 1.6rem + 3.2vw, 4rem);
  font-weight: 400;
  max-width: 20ch;
  line-height: 1.02;
  letter-spacing: -0.03em;
}
.section__head--centered h2 { margin-inline: auto; }

/* Accent continuation — italic + accent color on a second line.
 * Used as <span class="section__head-accent"> inside the h2. */
.section__head-accent {
  display: block;
  font-style: italic;
  color: var(--color-accent);
  margin-top: 0.1em;
}

.section__lead {
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  color: var(--color-text-muted);
  margin-top: var(--s-4);
  max-width: 56ch;
  line-height: 1.55;
}

/* ---- Avant / Après ------------------------------------------------- */

.ba {
  max-width: var(--w-max);
  margin: 0 auto;
  display: grid;
  gap: var(--s-6);
}
@media (min-width: 880px) {
  .ba { grid-template-columns: 1fr 80px 1fr; align-items: stretch; gap: var(--s-6); }
}

.ba__side {
  padding: var(--s-6);
  border: 1.5px solid var(--color-border);
  background: var(--color-surface-1);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  min-height: 340px;
  position: relative;
  box-shadow: 4px 4px 0 0 color-mix(in oklch, var(--color-text) 10%, transparent);
  transition: border-color var(--dur-base) var(--ease-soft),
              transform var(--dur-base) var(--ease-soft),
              box-shadow var(--dur-base) var(--ease-soft);
}
.ba__side::before {
  content: '';
  position: absolute;
  top: -1.5px; left: -1.5px;
  width: 14px; height: 14px;
  border-top: 1.5px solid var(--color-border-strong);
  border-left: 1.5px solid var(--color-border-strong);
  transition: border-color var(--dur-base) var(--ease-soft),
              width var(--dur-base) var(--ease-soft),
              height var(--dur-base) var(--ease-soft);
}
.ba__side::after {
  content: '';
  position: absolute;
  bottom: -1.5px; right: -1.5px;
  width: 14px; height: 14px;
  border-bottom: 1.5px solid var(--color-border-strong);
  border-right: 1.5px solid var(--color-border-strong);
  transition: border-color var(--dur-base) var(--ease-soft),
              width var(--dur-base) var(--ease-soft),
              height var(--dur-base) var(--ease-soft);
}
.ba__side--after {
  border-color: color-mix(in oklch, var(--color-accent) 40%, var(--color-border));
}
.ba__side--after::before, .ba__side--after::after {
  border-color: var(--color-accent);
}

/* Hover : shadow-pop (V4b-inspired) + corner brackets grow + icon nudge */
.ba__side--before:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 0 color-mix(in oklch, var(--color-stamp) 55%, transparent);
  border-color: var(--color-stamp);
}
.ba__side--before:hover::before,
.ba__side--before:hover::after {
  border-color: var(--color-stamp);
  width: 22px; height: 22px;
}
.ba__side--after:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 0 color-mix(in oklch, var(--color-accent) 65%, transparent);
  border-color: var(--color-accent);
}
.ba__side--after:hover::before,
.ba__side--after:hover::after {
  width: 22px; height: 22px;
}
.ba__side:hover .ba__icon {
  transform: rotate(6deg) scale(1.05);
}
.ba__side:hover ul li {
  transform: translateX(2px);
}
.ba__side ul li {
  transition: transform var(--dur-base) var(--ease-soft);
}

.ba__side-head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.ba__icon {
  width: 36px; height: 36px;
  flex-shrink: 0;
  transition: transform var(--dur-base) var(--ease-soft);
}
.ba__icon--x { color: var(--color-stamp); }
.ba__icon--check { color: var(--color-accent); }
.ba__side.is-in .ba__icon-ring {
  animation: ring-draw 600ms var(--ease-soft) forwards 100ms;
}
.ba__side.is-in .ba__icon-stroke {
  stroke-dasharray: 40;
  stroke-dashoffset: 40;
  animation: stroke-draw 400ms var(--ease-soft) forwards 500ms;
}
@keyframes ring-draw {
  to { stroke-dashoffset: 0; }
}
@keyframes stroke-draw {
  to { stroke-dashoffset: 0; }
}

.ba__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-soft);
  margin-bottom: 2px;
}
.ba__side-head h3 {
  font-size: 1.5rem;
  font-weight: 400;
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: 'opsz' 144, 'SOFT' 60;
}

.ba__side ul {
  list-style: none;
  padding: 0;
  margin-top: var(--s-2);
  display: grid;
  gap: var(--s-3);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--color-text-muted);
}
.ba__side ul li {
  padding-left: 22px;
  position: relative;
}
.ba__side ul li::before {
  position: absolute;
  left: 0;
  top: 3px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
}
.ba__side--before li::before { content: '×'; color: var(--color-stamp); font-size: 16px; top: 0; }
.ba__side--after  li::before { content: '✓'; color: var(--color-accent); font-size: 13px; }

/* ---- Bridge : a dashed construction line between before / after --
 * Replaces the old yellow-ish arrow with a plan-drawing "connector":
 * two pilot dots, two dashed rules, one central circular node.
 * The node scales in and the rules draw in when the "après" side
 * scrolls into view (is-bridge-in class applied by enhance.js).
 * ------------------------------------------------------------------ */
.ba__bridge {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  color: var(--color-accent);
}
.ba__bridge-rule {
  flex: 1;
  height: 1.5px;
  background-image: linear-gradient(to right, currentColor 50%, transparent 50%);
  background-size: 8px 1.5px;
  background-repeat: repeat-x;
  opacity: 0.55;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 800ms var(--ease-soft), opacity var(--dur-base) var(--ease-soft);
}
.ba__bridge-rule:last-of-type {
  transform-origin: right center;
}
.ba__bridge-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
  flex-shrink: 0;
}
.ba__bridge-dot--a { color: var(--color-stamp); }
.ba__bridge-dot--b { color: var(--color-accent); }
.ba__bridge-node {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  background: var(--color-bg);
  position: relative;
  flex-shrink: 0;
  transform: scale(0);
  transition: transform 500ms var(--ease-soft) 400ms;
}
.ba__bridge-node::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.85;
}
.is-bridge-in .ba__bridge-rule {
  transform: scaleX(1);
}
.is-bridge-in .ba__bridge-node {
  transform: scale(1);
}

/* Sides hovered light up the bridge for the kinetic link.
   Note: .ba__bridge sits between the two sides, so we use :has() on the
   parent .ba container (graceful: browsers without :has just skip the extra
   flourish — core hover on the side still works). */
.ba__bridge-dot {
  transition: transform var(--dur-base) var(--ease-soft), opacity var(--dur-base) var(--ease-soft);
}
.ba:has(.ba__side--before:hover) .ba__bridge-dot--a,
.ba:has(.ba__side--after:hover)  .ba__bridge-dot--b {
  opacity: 1;
  transform: scale(1.5);
}
.ba:has(.ba__side:hover) .ba__bridge-node {
  transform: scale(1.15);
  transition: transform var(--dur-base) var(--ease-soft);
}

@media (max-width: 879px) {
  .ba__bridge { flex-direction: column; min-height: 80px; }
  .ba__bridge-rule {
    width: 1.5px;
    height: 20px;
    flex: 0 0 auto;
    background-image: linear-gradient(to bottom, currentColor 50%, transparent 50%);
    background-size: 1.5px 8px;
    background-repeat: repeat-y;
    transform: scaleY(0);
    transform-origin: top center;
  }
  .ba__bridge-rule:last-of-type { transform-origin: bottom center; }
  .is-bridge-in .ba__bridge-rule { transform: scaleY(1); }
}

/* ---- Démos (dossiers — style emprunté à V4c, sans pin rouge) ------ */

.dossiers {
  max-width: var(--w-max);
  margin: 0 auto;
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-8);
  grid-template-columns: 1fr;
}
@media (min-width: 700px) and (max-width: 1023px) {
  .dossiers { grid-template-columns: repeat(2, 1fr); gap: var(--s-6); }
}
@media (min-width: 1024px) {
  .dossiers { grid-template-columns: repeat(3, 1fr); gap: var(--s-6); }
}

.dossier {
  position: relative;
  list-style: none;
}
.dossier--tilt-l { transform: rotate(-0.6deg); }
.dossier--tilt-r { transform: rotate(0.7deg); }

.dossier__link {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-3) var(--s-4);
  background: var(--color-surface-1);
  border: 1.5px solid var(--color-border);
  color: var(--color-text);
  text-decoration: none;
  box-shadow: 4px 5px 0 0 color-mix(in oklch, var(--color-text) 18%, transparent);
  transition: transform 320ms var(--ease-soft),
              box-shadow 320ms var(--ease-soft),
              border-color 260ms var(--ease-soft);
  position: relative;
  height: 100%;
}
.dossier__link:hover {
  transform: rotate(0) translateY(-5px);
  box-shadow: 6px 8px 0 0 var(--color-accent);
  border-color: var(--color-text);
}
.dossier__link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 4px;
}

.dossier__tape {
  position: absolute;
  top: -10px;
  left: 16px;
  z-index: 2;
  background: var(--color-accent);
  color: var(--color-accent-fg);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  padding: 4px 10px;
  transform: rotate(-4deg);
  box-shadow: 2px 2px 0 rgba(0,0,0,0.18);
}
/* nth-child tape color overrides retired — colors now driven by .dossier--tint-N palette in shared/base.css */

.dossier__media {
  aspect-ratio: 16/10;
  overflow: hidden;
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
}
.dossier__media img,
.dossier__media video {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: contrast(1.03) saturate(0.95);
  transition: transform 600ms var(--ease-soft);
}
.dossier__link:hover .dossier__media img,
.dossier__link:hover .dossier__media video {
  transform: scale(1.03);
}

.dossier__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: 4px 8px 0;
  flex: 1;
}
.dossier__tag {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.dossier__title {
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 1.2rem + 0.5vw, 1.625rem);
  font-weight: 400;
  font-style: italic;
  font-variation-settings: 'opsz' 144, 'SOFT' 60;
  line-height: 1.1;
}
.dossier__desc {
  font-size: 14px;
  line-height: 1.55;
  color: var(--color-text-muted);
  flex: 1;
}
.dossier__cartouche {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--s-2) var(--s-3);
  align-items: center;
  padding-top: var(--s-3);
  border-top: 1px dashed var(--color-border);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.dossier__cartouche-num {
  color: var(--color-accent);
  font-weight: 500;
  font-size: 12px;
}
.dossier__stamp {
  color: var(--color-accent);
  font-weight: 500;
  padding: 2px 6px;
  border: 1px solid var(--color-accent);
}
.dossier__cta {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
  padding-bottom: 2px;
  border-bottom: 1.5px solid currentColor;
  align-self: flex-start;
}
.dossier__cta span { display: inline-block; transition: transform 260ms var(--ease-soft); }
.dossier__link:hover .dossier__cta span { transform: translateX(4px); }

.demos__footer {
  max-width: var(--w-max);
  margin: var(--s-12) auto 0;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
}

/* ---- Services (chronogramme — V4c visual style, layered expander) --------
 * Vertical list of service bars. Each bar:
 *   - diamond numbered block (V4c mechanic: `.chrono__num` is a 48-56px
 *     square that rotates 45° into a diamond on hover + accent fill)
 *   - a small time label above the title
 *   - title (Fraunces italic) + muted description
 *   - a 10px progress track that fills to `--target` on reveal (is-in)
 *   - contextual CTA row (.chrono__actions) : either an expander button
 *     (bar--has-detail) or one/two direct links — same visual pill, same
 *     height, same focus ring across all 4 cards for rhythmic consistency.
 *   - collapsed detail panel (Audit + BTP Dev) that spans the FULL card
 *     width, structured in 3 columns : Déroulement / Livrables / Résultats
 * ------------------------------------------------------------------------- */

.chrono {
  max-width: var(--w-max);
  margin: 0 auto;
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0;
  counter-reset: phase;
}

.chrono__bar {
  display: grid;
  grid-template-columns: 64px 1fr;
  column-gap: var(--s-6);
  row-gap: var(--s-2);
  padding: var(--s-6) 0;
  border-top: 1px solid var(--color-border);
  position: relative;
  align-items: start;
}
.chrono__bar:last-child { border-bottom: 1px solid var(--color-border); }

/* V4c mechanic : flat square, rotates 45° into a diamond on hover/open.
   The digit itself is rotated back only via font layout — since V4c keeps
   the digit readable because the rotation is only 45°, we keep the same
   effect without a counter-rotating inner span. */
.chrono__num {
  grid-column: 1;
  grid-row: 1 / span 5;
  width: 48px;
  height: 48px;
  background: var(--color-text);
  color: var(--color-bg);
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  font-weight: 700;
  align-self: start;
  transition: transform 300ms var(--ease-soft),
              background 280ms var(--ease-soft),
              color 280ms var(--ease-soft);
}
.chrono__bar:hover .chrono__num,
.chrono__bar.is-open .chrono__num {
  transform: rotate(45deg);
  background: var(--color-accent);
  color: var(--color-accent-fg);
}

.chrono__time {
  grid-column: 2;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 4px;
  display: block;
}
.chrono__title {
  grid-column: 2;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 1.3rem + 1vw, 2rem);
  font-style: italic;
  font-weight: 400;
  font-variation-settings: 'opsz' 144, 'SOFT' 60;
  line-height: 1.1;
  margin: 0 0 var(--s-2) 0;
}
.chrono__desc {
  grid-column: 2;
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-text-muted);
  max-width: 60ch;
  margin: 0 0 var(--s-4) 0;
}

/* Progress track (V4c) — fills to --target once the bar is in view.
   Bars 1–2 use finite percentages; bars 3–4 are "indéfinie" and get a
   subtle infinite shimmer instead of a fixed width. */
/* v4 — rail full-width (no max-width cap, comme variant-4c-synthesis),
   en flex row pour permettre un label aligné en fin de rail. */
.chrono__track {
  grid-column: 2;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  max-width: none;
  background: transparent;
  border: none;
  overflow: visible;
  position: relative;
  padding: 0;
}
/* Inner rail that carries the fill — keeps the visual track look.
   The fill is drawn as a left-aligned accent layer whose horizontal
   background-size goes from 0% (closed) to --target (open) once the
   .chrono__bar gains .is-in via the shared IntersectionObserver. */
.chrono__track::before {
  content: '';
  flex: 1 1 auto;
  display: block;
  height: 10px;
  background-color: var(--color-surface-2);
  border: 1px solid var(--color-border);
  position: relative;
  overflow: hidden;
  background-image: linear-gradient(to right, var(--color-accent), var(--color-accent));
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 0 100%;
  transition: background-size 1400ms var(--ease-soft);
}
.chrono__bar.is-in .chrono__track::before {
  background-size: var(--target, 0%) 100%;
}
/* The old .chrono__fill span is kept for markup stability but hidden —
   the fill is drawn by the track's ::before gradient for predictable
   full-width behaviour alongside the right-aligned label. */
.chrono__fill {
  display: none;
}
.chrono__bar--1 .chrono__track { --target: 25%; }
.chrono__bar--2 .chrono__track { --target: 50%; }
.chrono__bar--3 .chrono__track { --target: 75%; }
.chrono__bar--4 .chrono__track { --target: 100%; }

/* v4 — engagement label at end of rail, small caps, color matches fill */
.chrono__track::after {
  content: attr(data-engagement);
  flex: 0 0 auto;
  color: var(--color-accent);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* v4 — .chrono__fill is now hidden; the rail fills via ::before gradient
   driven by --target. Retained selector kept as a no-op for safety. */
.chrono__bar.is-in .chrono__fill { width: var(--target); }

/* "Indéfinie" bar 4 : once filled (100%), overlay a subtle indeterminate
   shimmer over the accent fill so the rail reads as ongoing. Two-layer
   background — shimmer (top) + accent fill (bottom, same as base). */
.chrono__bar--4.is-in .chrono__track::before {
  background-image:
    linear-gradient(
      90deg,
      transparent 0%,
      color-mix(in oklch, var(--color-bg) 55%, transparent) 50%,
      transparent 100%
    ),
    linear-gradient(to right, var(--color-accent), var(--color-accent));
  background-repeat: no-repeat, no-repeat;
  background-size: 50% 100%, var(--target, 100%) 100%;
  background-position: -50% 0, 0 0;
  animation: chronoShimmer 2800ms linear infinite;
  animation-delay: 1400ms;
}
@keyframes chronoShimmer {
  0%   { background-position: -50% 0, 0 0; }
  100% { background-position: 150% 0, 0 0; }
}

/* ---- Actions row : homogeneous CTA surface for all 4 services ----------
 * Audit (expander button) / Application (#demos link) / Gestion (2 links) /
 * BTP Dev (expander button). Same pill element across the 4 so the rhythm
 * of the chronogram stays constant — behaviour changes, look doesn't. */
.chrono__actions {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-3);
}
.chrono__actions--duo {
  /* Two CTAs side by side for the "Gestion des données" card. */
  gap: var(--s-3);
}

/* Shared CTA pill — button or anchor, same visual. */
.chrono__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: transparent;
  border: 1px solid var(--color-border-strong);
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
.chrono__cta:hover,
.chrono__cta:focus-visible {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-fg);
  outline: none;
}
.chrono__cta:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-accent) 45%, transparent);
}
.chrono__cta-chev,
.chrono__cta-arrow {
  display: inline-flex;
  width: 14px; height: 14px;
  transition: transform var(--dur-base) var(--ease-soft);
}
.chrono__cta-arrow svg,
.chrono__cta-chev svg { width: 100%; height: 100%; }
.chrono__cta:hover .chrono__cta-arrow {
  transform: translateX(2px);
}
.chrono__bar.is-open .chrono__cta-chev { transform: rotate(180deg); }
.chrono__bar.is-open .chrono__cta-label {
  visibility: hidden;
  position: relative;
}
.chrono__bar.is-open .chrono__cta-label::before {
  content: 'Masquer';
  visibility: visible;
  position: absolute;
  inset: 0;
}

/* Detail panel : collapsed by default, animates open via grid 1fr trick.
   Pure CSS — JS just toggles .is-open. Visibility transition is delayed on
   close so the element stays paintable through the full rows/opacity sweep,
   then hides instantly at the end. No transitionend dance, no [hidden] JS. */
.chrono__detail {
  grid-column: 2 / -1;
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  margin-top: 0;
  overflow: hidden;
  visibility: hidden;
  transition: grid-template-rows 360ms var(--ease-soft),
              opacity 220ms var(--ease-soft),
              margin-top 360ms var(--ease-soft),
              visibility 0s linear 360ms;
  will-change: grid-template-rows, opacity;
}
.chrono__bar.is-open .chrono__detail {
  grid-template-rows: 1fr;
  opacity: 1;
  margin-top: var(--s-8);
  visibility: visible;
  transition: grid-template-rows 360ms var(--ease-soft),
              opacity 260ms var(--ease-soft) 80ms,
              margin-top 360ms var(--ease-soft),
              visibility 0s linear 0s;
}

/* Inner wrapper for the grid-rows 1fr trick — anything directly inside
   .chrono__detail must be a single child with min-height: 0 + overflow.
   v8 — 2 colonnes sur desktop (≥ 1024px), ratio 1fr/1fr, gap confortable.
   Mobile < 1024px : empilé en 1 colonne (naturel, pas de max-width). */
.chrono__detail > .chrono__detail-prose {
  min-height: 0;
  overflow: hidden;
  padding: var(--s-6) 0 var(--s-6);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
}
@media (min-width: 1024px) {
  .chrono__detail > .chrono__detail-prose {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-12);
  }
}
.detail-prose-col {
  min-width: 0;
  max-width: 65ch;
}

.detail-prose {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-text-muted);
}
.detail-prose + .detail-prose { margin-top: var(--s-3); }
.detail-prose-col + .detail-prose-col .detail-prose:first-child { margin-top: 0; }
.detail-prose strong {
  color: var(--color-text);
  font-weight: 500;
}

@media (min-width: 768px) {
  .chrono__bar {
    grid-template-columns: 80px 1fr;
    column-gap: var(--s-8);
    padding: var(--s-6) 0;
  }
  .chrono__num { width: 56px; height: 56px; font-size: 12px; }
}

/* Reduced motion : snap open/close, no rotation, no shimmer, instant fill */
@media (prefers-reduced-motion: reduce) {
  .chrono__num,
  .chrono__fill,
  .chrono__cta-chev,
  .chrono__cta-arrow {
    transition: none !important;
    animation: none !important;
    transform: none !important;
  }
  .chrono__bar:hover .chrono__num,
  .chrono__bar.is-open .chrono__num {
    transform: none !important;
    background: var(--color-text) !important;
    color: var(--color-bg) !important;
  }
  /* v4 — shimmer moved to rail ::before; stop its animation only */
  .chrono__bar--4 .chrono__track::before {
    animation: none !important;
  }
  .chrono__detail {
    transition: none !important;
    visibility: hidden;
  }
  .chrono__bar.is-open .chrono__detail {
    grid-template-rows: 1fr;
    opacity: 1;
    margin-top: var(--s-6);
    visibility: visible;
  }
}

/* ---- About — Maître d'œuvre : bande terracotta + mur en parpaings ---- */

/* v4 — cream text for high contrast on terracotta flat */
.moe-band {
  --moe-cream: #F5F1E8;
  position: relative;
  padding: var(--s-24) var(--s-6);
  background: var(--c-terracotta);
  color: var(--moe-cream);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  overflow: hidden;
}
@media (min-width: 768px) {
  .moe-band { padding: var(--s-32) var(--s-8); }
}

/* v4 — parpaing texture retirée. The .moe-band__grid node now carries a
   blueprint-style technical grid in filigrane (cream, 4% opacity) that
   prolongs the hero grid continuity across the section. Major lines
   every 120 px, minor every 24 px — same rhythm as .section--grid. The
   old .moe-band__grid::before / ::after brick verticals are cleared. */
.moe-band__grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.04;
  background-image:
    linear-gradient(to right,  #F5F1E8 1px, transparent 1px),
    linear-gradient(to bottom, #F5F1E8 1px, transparent 1px),
    linear-gradient(to right,  #F5F1E8 0.5px, transparent 0.5px),
    linear-gradient(to bottom, #F5F1E8 0.5px, transparent 0.5px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  background-repeat: repeat;
}
.moe-band__grid::before,
.moe-band__grid::after { content: none; }

.moe-wrap {
  max-width: var(--w-max);
  margin: 0 auto;
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--s-12);
  grid-template-columns: 1fr;
}
@media (min-width: 960px) {
  .moe-wrap {
    grid-template-columns: 5fr 7fr;
    gap: var(--s-16);
    align-items: start;
  }
}

.moe-prose h2 {
  font-size: clamp(2.25rem, 1.6rem + 3.4vw, 4rem);
  font-weight: 500;
  margin-top: 0;
  margin-bottom: var(--s-6);
  color: var(--moe-cream, #F5F1E8);
  max-width: 16ch;
  line-height: 1.04;
}
/* v4 — "existe." reste italique mais passe en crème pour garantir
   WCAG AA Large sur terracotta (ratio ~4.6:1). Hiérarchie via
   taille/italique, jamais via contraste réduit. */
.moe-prose h2 em {
  font-style: italic;
  color: var(--moe-cream, #F5F1E8);
}
.moe-prose .lede {
  font-size: 18px;
  line-height: 1.65;
  margin-bottom: var(--s-4);
  color: var(--moe-cream, #F5F1E8);
  max-width: 44ch;
  font-weight: 500;
}
.moe-prose .lede--muted {
  /* hierarchy via weight/size, not contrast reduction — keep cream */
  color: var(--moe-cream, #F5F1E8);
  font-weight: 400;
}
/* ---- Wall of frames (hung on the parpaing wall) ------------------- */

.moe-wall {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: auto;
  grid-template-areas:
    "a a a b b b"
    "a a a c c c";
}
@media (max-width: 720px) {
  .moe-wall {
    grid-template-columns: repeat(2, 1fr);
    grid-template-areas:
      "a a"
      "b c";
  }
}

.frame {
  margin: 0;
  background: var(--color-bg);
  padding: 10px 10px 4px;
  border: 1px solid var(--color-text);
  box-shadow:
    5px 6px 0 var(--color-text),
    0 14px 40px rgba(0,0,0,0.18);
  transition: transform 300ms var(--ease-soft), box-shadow 300ms var(--ease-soft);
  position: relative;
}
.frame__inner {
  overflow: hidden;
  background: var(--color-surface-2);
  border: 0.5px solid var(--color-text);
  aspect-ratio: 4/3;
}
.frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.frame figcaption {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-top: 6px;
  text-align: center;
}

.frame--a { grid-area: a; transform: rotate(-1.8deg); }
.frame--a .frame__inner { aspect-ratio: 3/4; }
.frame--a img { filter: grayscale(1) contrast(1.05); }
.frame--b { grid-area: b; transform: rotate(1.6deg); }
.frame--c { grid-area: c; transform: rotate(-0.8deg); }

.moe-wall { position: relative; }


.frame[data-reveal] {
  opacity: 0;
  transition:
    opacity 500ms var(--ease-soft),
    transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1),
    box-shadow 300ms var(--ease-soft);
  transition-delay: var(--stagger, 0ms);
}
.frame--a[data-reveal] { transform: rotate(-6deg) translateY(30px); }
.frame--b[data-reveal] { transform: rotate(6deg) translateY(30px); }
.frame--c[data-reveal] { transform: rotate(-4deg) translateY(30px); }

.frame[data-reveal].is-in.frame--a { opacity: 1; transform: rotate(-1.8deg); }
.frame[data-reveal].is-in.frame--b { opacity: 1; transform: rotate(1.6deg); }
.frame[data-reveal].is-in.frame--c { opacity: 1; transform: rotate(-0.8deg); }

.frame:hover {
  transform: rotate(0) translateY(-4px);
  box-shadow: 8px 10px 0 var(--color-text), 0 18px 48px rgba(0,0,0,0.24);
  z-index: 3;
}

[data-theme="dark"] .frame {
  box-shadow:
    5px 6px 0 var(--color-text),
    0 14px 40px rgba(255,255,255,0.06);
}

/* ---- Contact ------------------------------------------------------- */

/* Extra padding-top so clicking the "Contact" anchor keeps the parpaing
   band partially visible above — visual continuity with the about section. */
.section--contact {
  padding-top: var(--s-32);
  padding-bottom: var(--s-24);
}
@media (min-width: 768px) {
  .section--contact { padding-top: var(--s-40, 10rem); }
}

.form {
  max-width: 580px;
  margin: 0 auto;
  display: grid;
  gap: var(--s-5, 1.25rem);
}
.form__row {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .form__row { grid-template-columns: 1fr 1fr; }
}

.field-v4 {
  display: grid;
  gap: 6px;
  position: relative;
}
.field-v4__label {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-text-soft);
  transition: color var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
  transform-origin: left center;
}
.field-v4 input, .field-v4 textarea {
  background: transparent;
  border: 1.5px solid var(--color-border);
  padding: 12px 14px;
  font-size: 16px;
  color: var(--color-text);
  font-family: var(--font-body);
  outline: none;
  border-radius: 0;
  transition: border-color var(--dur-fast) var(--ease-soft),
              background var(--dur-fast) var(--ease-soft),
              box-shadow var(--dur-fast) var(--ease-soft);
  width: 100%;
}
.field-v4 input:hover, .field-v4 textarea:hover {
  border-color: var(--color-border-strong);
}
.field-v4 input:focus, .field-v4 textarea:focus {
  border-color: var(--color-accent);
  background: color-mix(in oklch, var(--color-surface-1) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-accent) 20%, transparent);
}
.field-v4:focus-within .field-v4__label {
  color: var(--color-accent);
  transform: translateX(2px);
}
.field-v4 textarea {
  min-height: 210px;
  resize: vertical;
  line-height: 1.6;
}

.form__actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  margin-top: var(--s-3);
  flex-wrap: wrap;
}

/* ---- Footer (restauré v8 — identité · nav · legal · contact) ------
   Spec portée depuis templates/base.html (prod) en tokens v4.
   Layout: top row = identity | nav · rule · bottom row = copy | legal.  */

.site-footer {
  /* Override shared/base.css margin-top so the footer sits flush on the
   * contact section — the 96 px body-cream strip between them was reading
   * as a chevauchement / discontinuité. */
  margin-top: 0;
  border-top: 1px solid var(--color-border);
  padding: var(--s-12) var(--s-6) var(--s-8);
  background: color-mix(in oklch, var(--color-surface-1) 60%, var(--color-bg));
  position: relative;
  z-index: 1;
}
.site-footer__inner {
  max-width: var(--w-max);
  margin: 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--color-text-soft);
}
.site-footer__top {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  align-items: flex-start;
  justify-content: space-between;
}
@media (min-width: 720px) {
  .site-footer__top {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--s-12);
  }
}
.site-footer__identity {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.site-footer__name {
  margin: 0;
  font-family: var(--font-display, var(--font-mono));
  font-size: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
}
.site-footer__tagline {
  margin: 0;
  font-size: 11px;
  color: var(--color-text-muted);
  letter-spacing: 0.06em;
  text-transform: none;
}
.site-footer__location {
  margin: 0;
  font-size: 11px;
  color: var(--color-text-soft);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4) var(--s-8);
}
.site-footer__links a {
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding-bottom: 1px;
  position: relative;
  transition: color var(--dur-fast) var(--ease-soft);
}
.site-footer__links a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-base) var(--ease-soft);
}
.site-footer__links a:hover { color: var(--color-accent); }
.site-footer__links a:hover::after { transform: scaleX(1); }

.site-footer__rule {
  height: 1px;
  background: var(--color-border);
  margin: var(--s-6) 0 var(--s-4);
  opacity: 0.8;
}

.site-footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  align-items: flex-start;
  justify-content: space-between;
}
@media (min-width: 720px) {
  .site-footer__bottom {
    flex-direction: row;
    align-items: center;
    gap: var(--s-6);
  }
}
.site-footer__copy {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--color-text-soft);
}
.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
}
.site-footer__legal a {
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding-bottom: 1px;
  position: relative;
  transition: color var(--dur-fast) var(--ease-soft);
}
.site-footer__legal a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-base) var(--ease-soft);
}
.site-footer__legal a:hover { color: var(--color-accent); }
.site-footer__legal a:hover::after { transform: scaleX(1); }

/* ---- Reveal polish ------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 700ms var(--ease-soft), transform 700ms var(--ease-soft);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: transform, opacity;
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* ---- Responsive tweaks -------------------------------------------- */

@media (min-width: 880px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1fr) clamp(400px, 46vw, 680px);
    align-items: stretch;
    gap: var(--s-12);
  }
  .hero__copy {
    padding-right: 0;
    align-self: center;
  }
  .crane {
    position: relative;
    top: auto; right: auto; bottom: auto;
    width: 100%;
    height: clamp(600px, 82vh, 880px);
    align-self: stretch;
  }
  .hero { padding-top: var(--s-20, 5rem); }
}

@media (max-width: 879px) {
  .crane {
    position: relative;
    inset: auto;
    width: min(440px, 94vw);
    height: 340px;
    margin: var(--s-6) auto 0;
  }
  .hero { min-height: auto; padding-bottom: var(--s-12); }
  .hero__title { max-width: 14ch; }
}

@media (max-width: 500px) {
  .hero { padding: var(--s-12) var(--s-4) var(--s-16); }
  .section { padding: var(--s-16) var(--s-4); }
  .hero__kicker { font-size: 10px; }
  .hero__sub { font-size: 17px; }
}

/* ---- Focus-visible everywhere ------------------------------------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
.dossier__link:focus-visible,
.stamp:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* ---- REDUCED MOTION — disable ALL animations, not just shorten ---- */

@media (prefers-reduced-motion: reduce) {
  .hero__title-lift,
  .hero__title-lift::after,
  .hero__kicker-mark,
  .ba__icon-ring,
  .ba__icon-stroke,
  .ba__bridge-rule,
  .ba__bridge-node,
  .ba__bridge-dot {
    animation: none !important;
    transition: none !important;
  }
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .btn, .btn__arrow, .dossier__link, .dossier__media img, .dossier__media video,
  .stamp, .site-nav__logo-mark, .site-nav__links a::after, .chrono__num,
  .frame, .frame img,
  .field-v4__label, .field-v4 input, .field-v4 textarea,
  .site-footer__links a::after {
    transition: none !important;
    animation: none !important;
  }
  .frame[data-reveal] {
    opacity: 1 !important;
    transition: none !important;
  }
  .frame--a[data-reveal],
  .frame[data-reveal].is-in.frame--a { transform: rotate(-1.8deg) !important; }
  .frame--b[data-reveal],
  .frame[data-reveal].is-in.frame--b { transform: rotate(1.6deg) !important; }
  .frame--c[data-reveal],
  .frame[data-reveal].is-in.frame--c { transform: rotate(-0.8deg) !important; }
  .hero__title-lift { transform: none !important; }
  .ba__icon-ring { stroke-dashoffset: 0 !important; }
  .ba__icon-stroke { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
  .ba__bridge-rule { transform: scaleX(1) !important; }
  .ba__bridge-node { transform: scale(1) !important; }
  .dossier--tilt-l, .dossier--tilt-r { transform: none !important; }
}

/* ---- Dossier media placeholder -------------------------------------- */

.dossier__media-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--color-text-muted);
}
