/* ==========================================================================
   Orvane Research — one stylesheet, no build step, no framework.

   How it is laid out
     0.  Reset
     1.  Tokens — every value that changes between breakpoints lives here
     2.  Breakpoints — the same token block, restated four times
     3.  Base and typography
     4.  Shared pieces
     5.  Background field and pointer
     6.  Header
     7.  Hero
     8.  Statement
     9.  About
     10. Archive
     11. Conditions
     12. Manifesto
     13. Footer
     14. Motion — reveals, typing, page-load fades
     15. Reduced motion

   The rule that keeps this readable: no heading, no section ever carries its
   own media query. Changing --t-heros in part 2 is enough to resize the hero
   title everywhere it appears. If you catch yourself writing @media further
   down this file, the value you want probably belongs in part 1.

   The four breakpoints are the four widths the design was drawn at:
   1440, 1024, 768 and 375. They switch at 1200, 851 and 451.
   ========================================================================== */

/* ==========================================================================
   0. Reset
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* clip, not hidden: hidden would turn the root into a scroll container and
     break every position:sticky further down the page. The archive cards
     slide in from off-screen, so something has to clip them. */
  overflow-x: clip;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body,
h1,
h2,
h3,
p,
ul,
ol,
li,
figure,
blockquote {
  margin: 0;
  padding: 0;
}

/* Headings inherit their size instead of taking the browser's default.
   Without this a <h2> inside a 40px block silently renders at 60px, because
   the UA stylesheet says 1.5em — and the block, not the heading, is where
   this design sets type size. */
h1,
h2,
h3 {
  font-size: inherit;
  font-weight: inherit;
}

ul,
ol {
  list-style: none;
}

img,
svg,
canvas {
  display: block;
  max-width: 100%;
}

button,
input {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

/* ==========================================================================
   1. Tokens — the 1440 px design
   ========================================================================== */

:root {
  /* --- Colour ---------------------------------------------------------- */
  --encre: #0c0c0d; /* page background, and type on the light section */
  --papier: #f2f2f2; /* the one light section, and the archive cards */
  --texte: #ffffff;
  --accent: rgb(218, 132, 10); /* the pointer dot */
  --focus: #f5e100; /* focus ring on dark ground */
  --focus-clair: #0c0c0d; /* focus ring on the light section */
  --erreur: #ff3c2b;
  --succes: #2bff9c;
  --filet-clair: rgba(12, 12, 13, 0.23); /* column rules on the light section */
  --filet-sombre: rgba(255, 255, 255, 0.16); /* the manifesto underline */
  --champ-fond: rgba(255, 255, 255, 0.1);
  --champ-fond-actif: rgba(255, 255, 255, 0.2);
  --champ-fond-faux: rgba(255, 60, 43, 0.2);

  /* Three opacities, not three greys — the ground is always --encre.
     0.5 is the floor: below that, 12px type drops under 4.5:1. */
  --voile-fort: 0.8;
  --voile: 0.6;
  --voile-faible: 0.5;

  /* --- Type ------------------------------------------------------------ */
  --font-display: "Funnel Display", "Funnel Display Fallback", system-ui, sans-serif;
  --font-mono: "Space Mono", "Space Mono Fallback", ui-monospace, monospace;

  --t-heros: 164px; /* h1, and only the h1 */
  --t-heros-ls: -6.56px;
  --t-section: 48px; /* statement, about */
  --t-section-ls: -1.44px;
  --t-large: 40px; /* conditions intro */
  --t-large-ls: -1.2px;
  --t-manifeste: 40px; /* manifesto — same until 451, then it holds at 32 */
  --t-manifeste-ls: -1.2px;
  --t-condition: 48px; /* the three condition names */
  --t-condition-ls: -1.44px;
  --t-carte: 40px; /* archive card titles */
  --t-carte-ls: -1.2px;
  --t-pied: 120px; /* the footer wordmark */
  --t-pied-ls: -4.8px;

  --t-mono-l: 16px; /* section labels, hero standfirst */
  --t-mono: 12px; /* everything else */
  --t-mono-ls: -0.36px; /* only the clock, the scroll hint and the credit */
  --t-carte-note: 12px;

  /* --- Layout ---------------------------------------------------------- */
  --marge-page: 40px;
  --colonne-large: 725px; /* hero block, statement, conditions intro */
  --colonne-enonce: 645px; /* the statement sentence inside that block */
  --colonne-moyenne: 538px; /* about */
  --colonne-accroche: 391px; /* hero standfirst */
  --colonne-pied: 723px;
  --colonne-pied-contact: 585px;

  --logo-l: 271px;
  --logo-h: 41px;
  --entete-marque-l: 455px;
  --entete-ecart: 207px;
  --entete-droite-l: auto;

  --heros-h: 900px;
  --heros-ecart: 260px;
  --section-h: 800px; /* statement and about */

  --archive-h: 3200px; /* scroll length of the pinned scene */
  --archive-scene-h: 800px; /* height of the pinned scene itself */
  --archive-liste-ecart: 80px; /* the fallback vertical list */
  --carte-l: 650px;
  --carte-h: 534px;
  --carte-y: 133px;
  --carte-pas: 710px; /* how far a card travels to reach the stack */

  --conditions-ecart: 180px;
  --conditions-colonnes-ecart: 60px;
  --conditions-pt: 120px;
  --conditions-pb: 160px;

  --manifeste-y: 140px;

  --pied-h: 660px;
  --pied-y: 80px;
  --pied-ecart: 60px;
  --pied-mention-mt: 0px;

  /* --- Motion ---------------------------------------------------------- */
  --reveal-duree: 900ms;
  --reveal-courbe: cubic-bezier(0.16, 1, 0.3, 1);
  --reveal-decalage: 90ms; /* between one revealed line and the next */
}

/* ==========================================================================
   2. Breakpoints — the same tokens, restated
   --------------------------------------------------------------------------
   Written widest-first and each block only overrides what actually moves, so
   at 375 px all three blocks apply, in order.
   ========================================================================== */

/* --- Below 1200 px: the 1024 design ------------------------------------- */
@media (width < 1200px) {
  :root {
    --t-heros: 120px;
    --t-heros-ls: -4.8px;
    --t-section: 40px;
    --t-section-ls: -1.2px;
    --t-large: 32px;
    --t-large-ls: -0.96px;
    --t-manifeste: 32px;
    --t-manifeste-ls: -0.96px;
    --t-condition: 32px;
    --t-condition-ls: -0.96px;
    --t-pied: 100px;
    --t-pied-ls: -4px;

    --colonne-large: 517px;
    --colonne-pied: 517px;

    --logo-l: 221px;
    --logo-h: 33px;
    --entete-marque-l: 299px;
    --entete-ecart: 51px;

    --heros-h: 768px;
    --heros-ecart: 240px;

    --carte-l: 520px;
    --carte-h: 427px;
    --carte-y: 186px;
    --carte-pas: 568px;

    --conditions-colonnes-ecart: 30px;
  }
}

/* --- Below 851 px: the 768 design --------------------------------------- */
@media (width < 851px) {
  :root {
    --colonne-large: 100%;
    --colonne-enonce: 100%;
    --colonne-moyenne: 100%;
    --colonne-accroche: auto;
    --colonne-pied: 100%;
    --colonne-pied-contact: 100%;

    --logo-l: 217px;
    --logo-h: 33px;
    --entete-marque-l: 217px;
    --entete-ecart: 0px;
    --entete-droite-l: 217px;

    --heros-h: 950px;
    --section-h: 1024px;

    --conditions-ecart: 60px;
    --manifeste-y: 80px;

    --pied-h: auto;
    --pied-mention-mt: 100px;
  }
}

/* --- Below 451 px: the 375 design --------------------------------------- */
@media (width < 451px) {
  :root {
    --t-heros: 80px;
    --t-heros-ls: -3.2px;
    --t-section: 32px;
    --t-section-ls: -0.96px;
    --t-large: 28px;
    --t-large-ls: -0.84px;
    --t-carte: 28px;
    --t-carte-ls: -0.84px;
    --t-pied: 56px;
    --t-pied-ls: -2.24px;
    --t-carte-note: 11px;

    --marge-page: 20px;

    --logo-l: 177px;
    --logo-h: 27px;

    --heros-h: 730px;
    --section-h: 812px;

    --archive-liste-ecart: 60px;
    --carte-l: 100%; /* the list version goes full width, it never stacks here */
    --conditions-ecart: 140px;

    --pied-y: 60px;
    --pied-ecart: 24px;
    --pied-mention-mt: 80px;
  }
}

/* ==========================================================================
   3. Base and typography
   ========================================================================== */

body {
  background: var(--encre);
  color: var(--texte);
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  line-height: 1.2;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1;
}

a {
  color: inherit;
  text-decoration: none;
}

::selection {
  color: var(--encre);
  background: var(--focus);
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

/* The light section — and the header while it floats over it — need a dark
   ring, because the yellow one sits at 1.2:1 against #f2f2f2. */
.conditions :focus-visible,
.entete.est-sombre :focus-visible {
  outline-color: var(--focus-clair);
}

/* ==========================================================================
   4. Shared pieces
   ========================================================================== */

.lecteur-seul {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.evitement {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--texte);
  color: var(--encre);
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  text-transform: uppercase;
  transform: translateY(-200%);
  transition: transform 150ms ease;
}

.evitement:focus-visible {
  transform: none;
}

/* Every small caps line on the page: the clock, the section labels, the
   card notes, the credit. */
.etiquette {
  font-family: var(--font-mono);
  font-size: var(--t-mono-l);
  line-height: 1.2;
  text-transform: uppercase;
  white-space: nowrap;
}

/* A <br> that only exists on narrow screens. */
.saut-etroit {
  display: none;
}

/* Labels that type themselves in. inline-block is what lets the script pin a
   min-width on them before it empties them out — min-width does nothing to a
   plain inline box, and the line would jiggle one character at a time. */
[data-type] {
  display: inline-block;
}

.contenu {
  position: relative;
  z-index: 1; /* above the canvas, which sits at 0 */
}

/* ==========================================================================
   5. Background field and pointer
   ========================================================================== */

.champ {
  position: fixed;
  inset: 0;
  z-index: 0;
  animation: or-zoom-fade 1s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.champ-toile {
  width: 100%;
  height: 100%;
}

/* A 10px dot standing in for the cursor. The script only shows it on wide
   screens with a fine pointer, and the rule below only hides the real cursor
   under the same conditions — a touch device keeps its own. */
.curseur {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%);
  pointer-events: none;
  will-change: left, top;
  display: none;
}

.js .curseur.est-actif {
  display: block;
}

@media (width >= 1200px) and (pointer: fine) {
  .js body.curseur-cache * {
    cursor: none;
  }
}

/* ==========================================================================
   6. Header
   ========================================================================== */

.entete {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  width: 100%;
  padding: 30px var(--marge-page) 0;
  color: var(--texte);
  transition: color 250ms ease;
  animation: or-fade 600ms ease 400ms both;
  /* The header is a thin band over the whole page. Only its links should
     swallow clicks. */
  pointer-events: none;
}

.entete a {
  pointer-events: auto;
}

/* Set by the script while the light section is behind the header. */
.entete.est-sombre {
  color: var(--encre);
}

.entete-rang {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.entete-marque {
  flex-shrink: 0;
  width: var(--entete-marque-l);
}

.entete-lien-marque {
  display: block;
  line-height: 0;
}

/* One file, two colours. brightness(0) crushes the artwork — white letters,
   gold gradient and all — down to flat black; invert(1) then flips it to flat
   white. That is the whole trick, and it means the header can tint its own
   logo without shipping a second SVG.

   mask-image would read better, but Chromium treats a CSS mask as a CORS
   fetch, and a CORS fetch from file:// always fails. This template has to
   survive being double-clicked off a desktop. */
.logo-mot {
  width: var(--logo-l);
  height: var(--logo-h);
  object-fit: contain;
  object-position: left center;
  filter: brightness(0) invert(1);
  transition: filter 250ms ease;
}

.entete.est-sombre .logo-mot {
  filter: brightness(0);
}

.entete-heure {
  flex-shrink: 0;
  font-size: var(--t-mono);
  letter-spacing: var(--t-mono-ls);
  text-transform: uppercase;
}

.entete-heure-sep {
  transition: opacity 120ms linear;
}

.entete-heure-sep.est-eteint {
  opacity: 0;
}

.entete-droite {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--entete-ecart);
  width: var(--entete-droite-l);
}

.entete-statuts {
  font-size: var(--t-mono);
  text-transform: uppercase;
}

.entete-cle {
  opacity: var(--voile);
}

.entete-nav {
  display: flex;
  flex-direction: column;
  width: 80px;
  font-size: var(--t-mono);
  text-transform: uppercase;
}

.entete-nav a:hover {
  opacity: var(--voile);
}

/* Below 851 the three status lines go, and the nav slides right to keep the
   row balanced. Below 451 there is no room for either, so the header is
   reduced to the wordmark and the clock. */
@media (width < 851px) {
  .entete-statuts {
    display: none;
  }

  .entete-nav {
    margin-left: 151px;
  }
}

@media (width < 451px) {
  .entete-droite {
    display: none;
  }
}

/* ==========================================================================
   7. Hero
   ========================================================================== */

.heros {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--heros-ecart);
  height: var(--heros-h);
  padding: 30px var(--marge-page) 0;
  overflow: hidden;
}

/* Holds the space the fixed header floats over. */
.heros-vide {
  flex-shrink: 0;
  height: 40px;
}

.heros-bas {
  display: flex;
  flex-shrink: 0;
  align-items: flex-end;
  justify-content: space-between;
}

.heros-invite {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 6px;
  animation: or-fade 600ms ease 400ms both;
}

.heros-invite p {
  width: 129px;
  font-size: var(--t-mono);
  letter-spacing: var(--t-mono-ls);
  line-height: 1.2;
  text-transform: uppercase;
  opacity: var(--voile);
}

.heros-bloc {
  display: flex;
  flex-shrink: 0;
  flex-direction: column;
  align-items: flex-end;
  gap: 48px;
  width: var(--colonne-large);
}

.heros-titre {
  width: 100%;
  font-weight: 500;
  font-size: var(--t-heros);
  line-height: 0.79;
  letter-spacing: var(--t-heros-ls);
}

.heros-accroche {
  width: var(--colonne-accroche);
  font-size: var(--t-mono-l);
  text-transform: uppercase;
  animation: or-fade 500ms ease 1400ms both;
}

@media (width < 851px) {
  .heros {
    gap: 0;
    justify-content: space-between;
    padding-bottom: 40px;
  }

  .heros-invite {
    display: none;
  }

  .heros-bloc {
    align-items: flex-start;
  }

  .saut-etroit {
    display: block;
  }
}

@media (width < 451px) {
  .heros {
    padding-bottom: 60px;
  }
}

/* ==========================================================================
   8. Statement
   ========================================================================== */

.declaration {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: var(--section-h);
  padding: 100px var(--marge-page);
  overflow: hidden;
}

.declaration-bloc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 48px;
  width: var(--colonne-large);
}

.declaration-texte {
  width: var(--colonne-enonce);
  font-family: var(--font-display);
  font-size: var(--t-section);
  line-height: 1;
  letter-spacing: var(--t-section-ls);
}

@media (width < 851px) {
  .declaration {
    align-items: flex-end;
    padding-bottom: 60px;
  }
}

@media (width < 451px) {
  .declaration {
    padding-top: 60px;
  }
}

/* ==========================================================================
   9. About
   ========================================================================== */

.apropos {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  height: var(--section-h);
  padding: 0 var(--marge-page);
  overflow: hidden;
}

.apropos-bloc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 40px;
  width: var(--colonne-moyenne);
}

.apropos-texte {
  font-family: var(--font-display);
  font-size: var(--t-section);
  line-height: 1;
  letter-spacing: var(--t-section-ls);
}

.apropos-prose {
  font-size: var(--t-mono);
  text-transform: uppercase;
}

.apropos-prose p + p {
  margin-top: 12px;
}

.apropos-principes {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 40px;
  padding-left: 80px;
}

.apropos-principes ul {
  padding-left: 18px;
  font-size: var(--t-mono);
  text-transform: uppercase;
  white-space: nowrap;
  list-style: disc;
}

@media (width < 851px) {
  .apropos {
    justify-content: flex-end;
    padding-bottom: 60px;
  }

  .apropos-detail {
    display: flex;
    gap: 30px;
  }

  .apropos-prose,
  .apropos-principes {
    flex: 1;
  }

  .apropos-principes {
    margin-top: 0;
    padding-left: 0;
  }
}

@media (width < 451px) {
  .apropos-detail {
    flex-direction: column;
    gap: 24px;
  }

  .apropos-principes {
    flex: none;
    padding-left: 80px;
  }
}

/* ==========================================================================
   10. Archive
   --------------------------------------------------------------------------
   Default state — and the state with JavaScript off — is a plain vertical
   list of three cards. The pinned, scroll-driven version is opt-in: it needs
   both .js on <html> and a viewport wide enough to hold a 650px card.
   ========================================================================== */

.archive {
  padding: 60px var(--marge-page) 100px;
  /* Cards 2 and 3 wait off-screen to the right, so this section is wider
     than the window for most of its life. Clipping it here, rather than
     leaning on the root, keeps documentElement.scrollWidth honest — and clip
     (unlike hidden) does not turn this into a scroll container, which would
     break the sticky scene inside it. */
  overflow-x: clip;
}

.archive-scene {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--archive-liste-ecart);
}

.archive-titre {
  align-self: flex-start;
}

.archive-pile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--archive-liste-ecart);
}

.carte {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: var(--carte-l);
  max-width: 100%;
  height: var(--carte-h);
  padding: 10px 10px 20px;
  background: var(--papier);
  color: var(--encre);
}

.carte-vue {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: #fff;
}

.carte-vue img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.carte-code {
  position: absolute;
  top: 0;
  left: 0;
  min-width: 5ch;
  padding: 10px;
  background: var(--papier);
  font-size: var(--t-mono-l);
  letter-spacing: var(--t-mono-ls);
  line-height: 1.2;
  text-transform: uppercase;
  white-space: nowrap;
}

.carte-corps {
  display: flex;
  flex-shrink: 0;
  flex-direction: column;
  align-items: flex-start;
  gap: 36px;
  padding: 0 10px;
}

.carte-corps h3 {
  font-size: var(--t-carte);
  letter-spacing: var(--t-carte-ls);
}

.carte-notes {
  display: flex;
  gap: 20px;
  width: 100%;
  font-size: var(--t-carte-note);
  text-transform: uppercase;
}

.carte-notes p {
  flex: 1;
  opacity: var(--voile-fort);
}

@media (width < 451px) {
  .archive {
    padding-bottom: 200px;
  }

  .carte {
    gap: 16px;
    padding: 8px 8px 16px;
  }

  .carte-corps {
    gap: 30px;
    padding: 0 8px;
  }

  .carte-notes {
    flex-direction: column;
  }
}

/* --- The pinned version ------------------------------------------------- */
@media (width >= 851px) {
  .js .archive {
    height: var(--archive-h);
    padding: 0;
  }

  .js .archive-scene {
    display: block;
    position: sticky;
    top: 0;
    height: var(--archive-scene-h);
  }

  .js .archive-titre {
    position: absolute;
    top: calc(var(--carte-y) + 14px);
    left: var(--marge-page);
  }

  .js .archive-pile {
    display: block;
    position: relative;
    height: 100%;
  }

  .js .carte {
    position: absolute;
    top: var(--carte-y);
    left: 50%;
    margin-left: calc(var(--carte-l) / -2);
    will-change: transform;
  }

  /* Card 1 is the one already on screen, so it sits at the bottom of the
     stack and each later card lands on top of it. */
  .js .carte:nth-child(1) {
    z-index: 1;
  }
  .js .carte:nth-child(2) {
    z-index: 2;
  }
  .js .carte:nth-child(3) {
    z-index: 3;
  }
}

/* ==========================================================================
   11. Conditions — the light section
   ========================================================================== */

.conditions {
  position: relative;
  z-index: 10; /* it has to cover the archive scene on the way out */
  display: flex;
  flex-direction: column;
  gap: var(--conditions-ecart);
  padding: var(--conditions-pt) var(--marge-page) var(--conditions-pb);
  background: var(--papier);
  color: var(--encre);
}

/* Only the pinned archive needs covering. In list mode there is nothing to
   pull up over. */
@media (width >= 851px) {
  .js .conditions {
    margin-top: calc(-1 * var(--archive-scene-h));
  }
}

.conditions-intro {
  display: flex;
  align-items: baseline;
  gap: 60px;
}

.conditions-intro .etiquette {
  flex: 1;
  min-width: 0;
}

.conditions-enonce {
  display: flex;
  flex-shrink: 0;
  flex-direction: column;
  gap: 48px;
  width: var(--colonne-large);
  font-family: var(--font-display);
  font-size: var(--t-large);
  line-height: 1;
  letter-spacing: var(--t-large-ls);
}

.conditions-liste {
  display: flex;
  gap: var(--conditions-colonnes-ecart);
}

.colonne {
  display: flex;
  flex: 1;
  min-width: 0; /* grid and flex children need this, never rely on 1fr alone */
  flex-direction: column;
  gap: 82px;
  padding-left: 20px;
  border-left: 1px solid var(--filet-clair);
  will-change: transform;
}

.colonne-entete {
  display: flex;
  justify-content: space-between;
  font-size: var(--t-mono);
  text-transform: uppercase;
  white-space: nowrap;
}

.colonne-entete span {
  opacity: var(--voile-fort);
}

.colonne-corps {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.colonne-corps h3 {
  font-size: var(--t-condition);
  letter-spacing: var(--t-condition-ls);
}

.colonne-vue {
  position: relative;
  width: 100%;
  aspect-ratio: 393 / 237;
  overflow: hidden;
}

.colonne-vue img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.colonne-notes {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: var(--t-mono);
  text-transform: uppercase;
}

.colonne-notes p {
  opacity: var(--voile-fort);
}

@media (width < 851px) {
  .conditions-intro {
    flex-direction: column;
    gap: 24px;
  }

  .conditions-liste {
    flex-direction: column;
    gap: 80px;
  }

  .colonne {
    flex: none;
    width: 100%;
    padding-left: 0;
    padding-top: 20px;
    border-left: 0;
    border-top: 1px solid var(--filet-clair);
  }
}

@media (width < 451px) {
  .conditions-liste {
    gap: 60px;
  }
}

/* ==========================================================================
   12. Manifesto
   ========================================================================== */

.manifeste {
  padding: var(--manifeste-y) var(--marge-page);
  border-bottom: 1px solid var(--filet-sombre);
}

.manifeste-texte {
  font-family: var(--font-display);
  font-size: var(--t-manifeste);
  line-height: 1;
  letter-spacing: var(--t-manifeste-ls);
}

/* The original spaces these three blocks with a bottom margin rather than a
   gap, because the reveal wrapper has to stay a plain block. */
.bloc-ligne {
  margin-bottom: 20px;
}

/* ==========================================================================
   13. Footer
   ========================================================================== */

.pied {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: var(--pied-h);
  padding: var(--pied-y) var(--marge-page) 30px;
}

.pied-haut {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  width: 100%;
}

.pied-embleme {
  flex-shrink: 0;
  width: 90px;
  height: 90px;
}

.pied-bloc {
  display: flex;
  flex-direction: column;
  gap: var(--pied-ecart);
  width: var(--colonne-pied);
}

.pied-titre {
  font-weight: 500;
  font-size: var(--t-pied);
  line-height: 0.79;
  letter-spacing: var(--t-pied-ls);
}

.pied-contact {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: var(--colonne-pied-contact);
}

.pied-prose {
  font-size: var(--t-mono);
  text-transform: uppercase;
}

.pied-prose p + p {
  margin-top: 12px;
}

.pied-forme {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
}

/* The original draws this box 32px tall. 44px is the smallest target that
   passes WCAG 2.5.8, and twelve extra pixels inside a 660px footer are not
   something you can spot side by side. */
.pied-champ {
  display: flex;
  align-items: center;
  height: 44px;
  padding: 0 20px;
  background: var(--champ-fond);
  transition: background-color 150ms ease;
}

.pied-champ:focus-within {
  background: var(--champ-fond-actif);
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

.pied-champ input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  line-height: 1.2;
  text-transform: uppercase;
  outline: none;
}

.pied-champ input::placeholder {
  color: rgba(255, 255, 255, var(--voile-fort));
}

.pied-forme.est-faux .pied-champ {
  background: var(--champ-fond-faux);
}

/* Empty until the form has something to say. Without this it would still
   eat one of the column's 24px gaps and push the button down. */
.pied-message:empty {
  display: none;
}

.pied-message {
  font-size: var(--t-mono);
  text-transform: uppercase;
}

/* Full strength, no veil: at 80% this red lands at 3.8:1 on #0c0c0d, which
   is not enough for the one line that tells you what went wrong. */
.pied-forme.est-faux .pied-message {
  color: var(--erreur);
}

.pied-forme.est-envoye .pied-message {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--succes);
  font-weight: 700;
  white-space: nowrap;
}

/* The tick only exists in the success state, so it belongs to the state, not
   to the markup. background-image rather than mask-image: a mask is fetched
   under CORS rules and would fail when the page is opened over file://. */
.pied-forme.est-envoye .pied-message::before {
  content: "";
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  background: url("../img/check.svg") no-repeat center / contain;
}

/* The button holds three copies of its own label stacked on top of each
   other: an invisible one that sets the width, and two that slide sideways
   on hover so the arrow appears to swap sides. */
.pied-bouton {
  position: relative;
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 4px;
  height: 30px;
  padding: 0;
  overflow: hidden;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--t-mono);
  line-height: 1.2;
  text-transform: uppercase;
}

/* 30px of type, 44px of target — the extra reach is invisible and costs the
   layout nothing. */
.pied-bouton::after {
  content: "";
  position: absolute;
  inset: -7px 0;
}

.pied-bouton-gabarit {
  display: flex;
  align-items: center;
  gap: 4px;
  visibility: hidden;
  pointer-events: none;
  user-select: none;
}

.pied-bouton-place {
  width: 20px;
  height: 20px;
}

.pied-bouton-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
}

.pied-bouton-face-doublure {
  transform: translateX(-100%);
}

.pied-bouton:hover .pied-bouton-face {
  transform: translateX(100%);
}

.pied-bouton:hover .pied-bouton-face-doublure {
  transform: translateX(0);
}

.pied-forme.est-envoye .pied-bouton {
  display: none;
}

.pied-mention {
  margin-top: var(--pied-mention-mt);
  font-size: var(--t-mono);
  letter-spacing: var(--t-mono-ls);
  text-transform: uppercase;
  opacity: var(--voile-faible);
}

@media (width < 851px) {
  .pied-haut {
    flex-direction: column;
    gap: 40px;
  }
}

@media (width < 451px) {
  .pied-embleme {
    width: 64px;
    height: 64px;
  }
}

/* ==========================================================================
   14. Motion
   ========================================================================== */

@keyframes or-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes or-zoom-fade {
  from {
    opacity: 0;
    transform: scale(1.05);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* --- Line reveal ---------------------------------------------------------
   The hidden state lives on .ligne-interieur, an element only the script
   creates. Nothing is hidden until something exists to unhide it, so a broken
   or blocked main.js leaves every heading plainly readable.

   padding-bottom / negative margin: descenders like the "g" in "designing"
   hang below the line box, and a plain overflow:hidden would shave them off.
   ------------------------------------------------------------------------ */

.ligne {
  display: block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
}

.ligne-interieur {
  display: block;
  transform: translateY(110%);
  transition: transform var(--reveal-duree) var(--reveal-courbe);
  transition-delay: calc(var(--retard, 0ms) + var(--rang, 0) * var(--reveal-decalage));
  will-change: transform;
}

[data-reveal].est-vu .ligne-interieur {
  transform: none;
}

/* ==========================================================================
   15. Reduced motion
   --------------------------------------------------------------------------
   Everything lands on its final state at once. A delay is movement spread
   over time, so the delays go to zero too — otherwise a "reduced" page still
   spends two seconds assembling itself.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }

  .ligne-interieur {
    transform: none;
  }
}
