/* intro.css — l'introduction : une cité se bâtit, puis elle devient le seuil.
   La scène reprend la géométrie exacte du seuil (même largeur --hero-arch-w, même arche 100 × 72, mêmes assises,
   même porte que celle du nom) : à la relève, intro.js mesure le seuil et chaque pièce y voyage par transform.
   Sans JS (pas de html.intro-on), le recouvrement reste display:none et ne bloque rien.
   Chronologie (ms) : sol 0–600 · briques 250–1100 · ville lointaine 450–1350, proche 650–1500 · porte 900–1700 ·
   arche 1250–2050 · fenêtres 1400–2100 · soleil 1500–2500 · battants 1900–2500 · mortier 2250–2500 ·
   relève 2500 → +1000 (voir dna/MOTION.md). Mouvement réduit : l'image finale seule, en fondu. */

.intro {
  display: none;
}

.intro-on .intro {
  /* même géométrie que .seuil (seuil.css) */
  --w: var(--hero-arch-w);
  --bar: calc(var(--w) * 0.04);
  --gap: calc(var(--w) * 0.05);
  --lift: calc(var(--w) * 0.025);
  --lead: calc((100% - var(--w)) / 2);
  --hand: 1000ms;
  --hand-ease: cubic-bezier(0.62, 0.02, 0.22, 1);
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  align-content: center;
  justify-items: center;
  overflow: hidden;
  cursor: pointer;
  color: var(--c-ink);
}

html.intro-on {
  overflow: hidden;
  scrollbar-gutter: stable;
}

/* ── Les battants : le papier de l'introduction, fendu au milieu, s'ouvre comme la porte ── */
.intro__leaf {
  position: absolute;
  inset-block: 0;
  inline-size: calc(50% + 1px);
  background-color: var(--c-paper);
  transform-origin: left center;
}

.intro__leaf--start {
  inset-inline-start: 0;
}

.intro__leaf--end {
  inset-inline-end: 0;
  transform-origin: right center;
}

:root[dir="rtl"] .intro__leaf--start {
  transform-origin: right center;
}

:root[dir="rtl"] .intro__leaf--end {
  transform-origin: left center;
}

/* l'ombre de la charnière grandit quand le battant tourne */
.intro__leaf::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(to var(--hinge, left), color-mix(in srgb, var(--c-ink) 14%, transparent), transparent 60%);
  opacity: 0;
}

.intro__leaf--end {
  --hinge: right;
}

:root[dir="rtl"] .intro__leaf--start {
  --hinge: right;
}

:root[dir="rtl"] .intro__leaf--end {
  --hinge: left;
}

/* ── L'aube derrière l'arche ── */
.intro__glow {
  position: absolute;
  grid-row: 1 / 3;
  inset-block-start: calc(var(--w) * 0.332 - var(--w) * 0.75);
  inset-inline-start: calc(50% - var(--w) * 0.75);
  inline-size: calc(var(--w) * 1.5);
  aspect-ratio: 1;
  border-radius: 50%;
  background-image: radial-gradient(closest-side, color-mix(in srgb, var(--c-sun) 42%, transparent), color-mix(in srgb, var(--c-sun) 12%, transparent) 55%, transparent);
}

/* ── La ville : deux plans, posés sur le sol (bas des assises), coupés par lui ── */
.intro__city {
  position: absolute;
  grid-row: 1 / 3;
  inset-block-end: 0;
  inset-inline-start: calc(50% - var(--w) * 2);
  inline-size: calc(var(--w) * 4);
  max-inline-size: none;
  aspect-ratio: 400 / 60;
  overflow: hidden;
}

.i-far,
.i-near,
.i-b,
.i-fw {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

.i-fw {
  fill: var(--c-paper-3);
  opacity: 0.7;
}

.i-wall {
  fill: var(--c-paper-2);
  stroke: var(--c-ink-3);
  stroke-width: 0.4;
}

.i-lit {
  fill: var(--c-sun);
}

/* ── L'arche et le soleil : le dessin du seuil, à l'identique ── */
.intro__crest {
  position: relative;
  grid-row: 1;
  inline-size: var(--w);
  aspect-ratio: 100 / 72;
  overflow: hidden;
  transform-origin: 0 0;
}

.i-arch {
  fill: none;
  stroke: var(--c-ink);
  stroke-width: var(--stroke-display);
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
}

.i-orbit {
  transform-box: view-box;
  transform-origin: 50px 50px;
}

.i-sun {
  fill: var(--hand-sun, var(--c-sun));
}

/* ── Les assises : briques posées depuis la porte vers le large, puis jointoyées en deux courses ── */
.intro__ground {
  position: relative;
  grid-row: 2;
  justify-self: stretch;
  display: grid;
  grid-template-columns:
    calc(var(--lead) + var(--w) * 0.14)
    calc(var(--w) * 0.72)
    minmax(0, 1fr);
  block-size: calc(2 * var(--bar) + var(--gap));
  margin-block-start: calc(-1 * var(--lift));
}

/* la ligne du sol */
.intro__ground::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(-0.5 * max(1.5px, var(--w) * 0.006));
  block-size: max(1.5px, var(--w) * 0.006);
  background-color: var(--c-ink);
}

/* l'ombre portée sous la porte */
.intro__ground::before {
  content: "";
  position: absolute;
  inset-inline-start: calc(50% - var(--w) * 0.3);
  inset-block-end: calc(var(--w) * -0.035);
  inline-size: calc(var(--w) * 0.6);
  block-size: calc(var(--w) * 0.07);
  background-image: radial-gradient(closest-side, color-mix(in srgb, var(--c-ink) 22%, transparent), transparent);
}

.intro__course {
  display: grid;
  grid-template-rows: var(--bar) var(--gap) var(--bar);
  transform-origin: 0 0;
}

.intro__course--start {
  grid-column: 1;
}

.intro__course--end {
  grid-column: 3;
}

/* le mortier : la course pleine, identique à celle du seuil */
.intro__course::before {
  content: "";
  grid-row: 1 / -1;
  grid-column: 1;
  border-block: var(--bar) solid var(--c-terra);
  opacity: 0;
}

.intro__course b {
  grid-row: 1;
  grid-column: 1;
  display: flex;
  column-gap: calc(var(--w) * 0.012);
  min-inline-size: 0;
}

.intro__course b + b {
  grid-row: 3;
}

/* côté départ : la première brique touche le passage */
.intro__course--start b {
  flex-direction: row-reverse;
}

.intro__course i {
  flex: none;
  inline-size: calc(var(--w) * 0.085);
  background-color: var(--c-terra);
  transform-origin: 50% 100%;
}

/* ── La porte de la ville (châtelet) : elle monte du sol ── */
.intro__gate {
  position: absolute;
  grid-row: 1 / 3;
  inset-block-end: 0;
  inset-inline-start: calc(50% - var(--w) * 0.15);
  inline-size: calc(var(--w) * 0.3);
  block-size: calc(var(--w) * 0.375);
  overflow: hidden;
}

.intro__gate svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
}

.i-gatewall {
  fill: var(--c-ink);
}

/* ── Le passage : la porte du nom, à l'échelle de la ville ── */
.intro__door {
  position: absolute;
  grid-row: 1 / 3;
  inset-block-end: 0;
  inset-inline-start: calc(50% - var(--w) * 0.06);
  inline-size: calc(var(--w) * 0.12);
  aspect-ratio: 16 / 34;
  transform-origin: 0 0;
}

.intro__tag {
  position: relative;
  grid-row: 3;
  margin-block-start: var(--s-6);
  padding-inline: var(--margin);
  font-family: var(--f-title);
  font-size: var(--t-lg);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-title);
  text-align: center;
  color: var(--c-ink-2);
  text-wrap: balance;
}

/* ordre de pose : de la porte vers le large, la rangée basse d'abord */
.intro__course i:nth-child(2) { --n: 1; }
.intro__course i:nth-child(3) { --n: 2; }
.intro__course i:nth-child(4) { --n: 3; }
.intro__course i:nth-child(5) { --n: 4; }
.intro__course i:nth-child(6) { --n: 5; }
.intro__course i:nth-child(7) { --n: 6; }
.intro__course i:nth-child(8) { --n: 7; }
.intro__course b:first-child { --row: 1; }
.b0 { --b: 0; } .b1 { --b: 1; } .b2 { --b: 2; } .b3 { --b: 3; } .b4 { --b: 4; }
.b5 { --b: 5; } .b6 { --b: 6; } .b7 { --b: 7; } .b8 { --b: 8; }
.f0 { --b: 0; } .f1 { --b: 1; } .f2 { --b: 2; } .f3 { --b: 3; } .f4 { --b: 4; } .f5 { --b: 5; }

/* ── Mouvement : seulement si le visiteur l'accepte ──────────── */
@media (prefers-reduced-motion: no-preference) {
  @keyframes i-draw {
    from { scale: 0 1; }
  }

  /* la brique tombe, s'écrase d'un rien, se tasse */
  @keyframes i-lay {
    0% { opacity: 0; translate: 0 -160%; scale: 1 1; }
    50% { opacity: 1; translate: 0 6%; scale: 1.03 0.86; }
    72% { translate: 0 -5%; scale: 0.99 1.04; }
    100% { opacity: 1; translate: 0 0; scale: 1 1; }
  }

  @keyframes i-up {
    from { translate: 0 102%; }
  }

  /* la porte monte, dépasse d'un cheveu, se pose */
  @keyframes i-gate {
    0% { translate: 0 102%; }
    78% { translate: 0 -2.5%; }
    100% { translate: 0 0; }
  }

  @keyframes i-show {
    from { opacity: 0; }
  }

  @keyframes i-hide {
    to { opacity: 0; }
  }

  @keyframes i-mortar {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  @keyframes i-light {
    0% { opacity: 0; }
    40% { opacity: 0.95; }
    55% { opacity: 0.45; }
    100% { opacity: 1; }
  }

  @keyframes i-stroke {
    from { stroke-dashoffset: 1; }
  }

  /* le soleil sort de derrière la porte (caché tant qu'elle n'est pas levée) et monte jusqu'à sa place dans l'arche */
  @keyframes i-sunrise {
    from { translate: 0 21px; }
  }

  @keyframes i-wait {
    from, to { opacity: 0; }
  }

  @keyframes i-dawn {
    0% { opacity: 0; scale: 0.6; }
    35% { opacity: 0.35; }
    100% { opacity: 1; scale: 1; }
  }

  @keyframes i-ajar {
    from { scale: 1 1; }
  }

  @keyframes i-tag {
    from { opacity: 0; translate: 0 0.5rem; }
  }

  .intro__glow { animation: i-dawn 2400ms var(--ease-veille) both; }
  .intro__ground::after { animation: i-draw 600ms var(--ease-course) both; }
  .intro__ground::before { animation: i-show 600ms ease-out 1300ms both; }
  .intro__course i {
    animation:
      i-lay 440ms var(--ease-assise) calc(250ms + var(--row, 0) * 280ms + var(--n, 0) * 55ms) both,
      i-hide 240ms ease-in 2260ms forwards;
  }
  .intro__course::before { animation: i-mortar 240ms ease-out 2260ms both; }
  .i-fw { animation: i-up 900ms var(--ease-lever) calc(450ms + var(--b) * 70ms) both; }
  .i-b { animation: i-up 850ms var(--ease-lever) calc(650ms + var(--b) * 80ms) both; }
  /* la montée est portée par le dessin, l'enfoncement (relève) par le svg : les deux ne se marchent pas dessus */
  .intro__gate svg > * {
    transform-box: view-box;
    animation: i-gate 800ms var(--ease-ouverture) 900ms both;
  }
  .intro__gate .i-lit {
    animation:
      i-gate 800ms var(--ease-ouverture) 900ms both,
      i-light 520ms ease-out 1400ms both;
  }
  .i-lit { animation: i-light 520ms ease-out calc(1400ms + var(--b, 0) * 80ms) both; }
  .i-arch { animation: i-stroke 800ms var(--ease-course) 1250ms both; }
  .i-rise {
    animation:
      i-wait 1500ms linear backwards,
      i-sunrise 1000ms cubic-bezier(0.22, 0.8, 0.3, 1) 1500ms both;
  }
  .intro__door { animation: i-show 200ms linear 1500ms both; }
  .intro__door .door__lit,
  .intro__door .door__sun { animation: i-show 600ms ease-out 1900ms both; }
  .intro__door .door__leaf { animation: i-ajar 600ms var(--ease-ouverture) 1900ms both; }
  .intro__tag { animation: i-tag 700ms ease-out 700ms both; }

  /* ── Relève : chaque pièce voyage jusqu'à son double du seuil (intro.js pose --fx/--fy/--fsx/--fsy) ── */
  .intro-open .intro__crest,
  .intro-open .intro__door,
  .intro-open .intro__course {
    transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(var(--fsx, 1), var(--fsy, 1));
    transition: transform var(--hand) var(--hand-ease);
  }

  /* le soleil glisse sur son orbite jusqu'à l'heure du seuil, et en prend la couleur */
  .intro-open .i-orbit {
    rotate: var(--hand-turn, 0deg);
    transition: rotate var(--hand) var(--hand-ease);
  }

  .intro-open .i-sun {
    transition: fill var(--hand) var(--hand-ease);
  }

  /* la ville s'enfonce : le plan proche d'abord, le lointain plus lentement */
  .intro-open .i-near {
    translate: 0 102%;
    transition: translate calc(var(--hand) * 0.6) cubic-bezier(0.5, 0, 0.75, 0);
  }

  .intro-open .i-far {
    translate: 0 102%;
    opacity: 0;
    transition: translate calc(var(--hand) * 0.8) cubic-bezier(0.5, 0, 0.75, 0) calc(var(--hand) * 0.08), opacity calc(var(--hand) * 0.8) ease-in;
  }

  .intro-open .intro__gate svg {
    translate: 0 102%;
    transition: translate calc(var(--hand) * 0.5) cubic-bezier(0.4, 0, 0.9, 0.5);
  }

  /* leurs animations de chantier finissent sur la valeur de base : une nouvelle animation prend le relais sans saut */
  .intro-open .intro__glow,
  .intro-open .intro__ground::before,
  .intro-open .intro__ground::after,
  .intro-open .intro__tag {
    animation: i-hide calc(var(--hand) * 0.45) ease-out forwards;
  }

  .intro-open .intro__leaf {
    scale: 0 1;
    transition: scale calc(var(--hand) * 0.8) var(--ease-ouverture) calc(var(--hand) * 0.1);
  }

  .intro-open .intro__leaf::after {
    opacity: 1;
    transition: opacity calc(var(--hand) * 0.4) ease-out calc(var(--hand) * 0.1);
  }

  .intro-open .intro {
    pointer-events: none;
  }

  /* passer : même relève, plus vive */
  .intro-fast .intro {
    --hand: 560ms;
  }

  /* seuil hors de l'écran (page rechargée plus bas) : les pièces s'effacent sur place */
  .intro-away .intro__crest,
  .intro-away .intro__door,
  .intro-away .intro__course {
    opacity: 0;
    transition: opacity calc(var(--hand) * 0.5) ease-out;
  }

  /* le seuil attend ses pièces : arche, soleil, assises, porte du nom et halo n'apparaissent qu'au retrait */
  html.intro-on .seuil__sky,
  html.intro-on .seuil__ground,
  html.intro-on .seuil__title .split__door,
  html.intro-on .seuil__halo,
  html.intro-on .seuil__rail {
    opacity: 0;
  }

  /* l'introduction a déjà levé le soleil, posé les assises et la porte : le seuil ne les rejoue pas */
  .intro-ran .seuil {
    --d-lever: 1ms;
    --d-lever-delay: 0ms;
  }
}

/* ── Mouvement réduit : image fixe, puis fondu ───────────── */
@media (prefers-reduced-motion: reduce) {
  .intro-open .intro {
    opacity: 0;
    transition: opacity 300ms linear;
    pointer-events: none;
  }
}
