/* Ici se trouvait un `@import url("https://fonts.googleapis.com/...")`.
   Un @import est totalement bloquant : le navigateur ne peint RIEN tant
   qu'il n'est pas resolu. Sur un reseau ou Google Fonts ne repond pas, le
   site restait blanc douze secondes et demie — mesure, pas suppose : FCP a
   12 640 ms avec la ligne, 80 ms sans elle, toutes choses egales par
   ailleurs.

   Il annulait aussi le travail fait plus tot pour rendre la feuille de
   polices non bloquante dans le <head> : la vraie dependance etait ici, en
   ligne 1, et personne ne l'avait ouverte. Les polices sont desormais
   servies depuis /fonts/ — voir css/polices.css. */

:root {
  --ink: #0E0E0E;
  --void: #070707;
  --carbon: #121212;
  --steel: #2A2A2A;
  --ash: #6A6A6A;
  --mist: #DDDAD4;
  --bone: #F1EEE8;
  --paper: #F7F4EE;
  --red: #E10613;
  --red-deep: #B10510;
  --cut: 0px;
  --header: 64px;
  --max: 1440px;
  --read: 720px;
  --display: "Oswald", Impact, sans-serif;
  --serif: "Newsreader", "Iowan Old Style", Georgia, serif;
  --ui: "Outfit", system-ui, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
html.js-motion { scroll-behavior: auto; }
html, body { background: var(--paper); color: var(--ink); overflow-x: clip; }
body { font-family: var(--ui); line-height: 1.55; letter-spacing: 0.01em; }
img { display: block; max-width: 100%; }
button, input, textarea { font-family: inherit; border: 0; background: none; color: inherit; }
button, a { cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }

.cut { clip-path: none; }
.octa {
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}

.kicker {
  display: inline-block;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.22em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--red);
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 28px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.btn-fill { background: var(--red); color: var(--paper); }
.btn-fill:hover { background: var(--red-deep); }
.btn-line { box-shadow: inset 0 0 0 2px currentColor; }
.btn-line:hover { background: var(--paper); color: var(--ink); }

.wrap {
  width: min(100% - 80px, var(--max));
  margin: 0 auto;
}
.wrap-read {
  width: min(100% - 40px, var(--read));
  margin: 0 auto;
}

body > header {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--header);
  background: rgba(247, 244, 238, 0.86);
  backdrop-filter: blur(16px);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: height 0.45s var(--ease),
    background-color 0.45s ease,
    border-color 0.45s ease,
    box-shadow 0.45s ease;
}
body > header.is-compact {
  height: 56px;
  /* Opaque : a 94 %, le titre de la page transparaissait sous la barre en
     defilant. Une en-tete collante qui laisse lire le contenu au travers
     rend les deux illisibles. */
  background: var(--paper);
  border-bottom-color: var(--mist);
}
body.home > header {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  background: linear-gradient(180deg, rgba(7, 7, 7, 0.72) 0%, rgba(7, 7, 7, 0) 100%);
  border-bottom-color: transparent;
}
body.home > header.is-compact {
  background: rgba(247, 244, 238, 0.94);
  border-bottom-color: var(--mist);
}
body.home > header:not(.is-compact) nav.main a { color: var(--paper); opacity: 0.62; }
body.home > header:not(.is-compact) nav.main a:hover,
body.home > header:not(.is-compact) nav.main a.on { color: var(--paper); opacity: 1; }
body.home > header:not(.is-compact) .burger i { background: var(--paper); }
.header-inner {
  width: 100%;
  max-width: calc(var(--max) + 64px);
  margin: 0 auto;
  padding: 0 32px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 28px;
}
.brand img {
  height: 44px;
  width: auto;
  mix-blend-mode: multiply;
  transition: height 0.4s var(--ease), transform 0.5s ease;
}
body > header.is-compact .brand img { height: 36px; }
nav.main {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  flex-wrap: wrap;
}
nav.main a {
  position: relative;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0.45;
  transition: opacity 0.2s ease, color 0.2s ease;
}
nav.main a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -6px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
nav.main a:hover::after,
nav.main a.on::after { transform: scaleX(1); }
nav.main a:hover,
nav.main a.on { opacity: 1; color: var(--red); }

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 118px;
  height: 40px;
  padding: 0 16px;
  background: var(--red);
  color: var(--paper);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.cta:hover { background: var(--red-deep); }
.burger {
  display: none;
  width: 36px;
  height: 36px;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}
.burger i { display: block; height: 2px; background: var(--ink); }

.drawer {
  display: none;
  position: fixed;
  inset: var(--header) 0 0 0;
  z-index: 35;
  background: var(--paper);
  padding: 20px 24px 40px;
  overflow: auto;
  flex-direction: column;
  gap: 4px;
}
.drawer.open { display: flex; }
.drawer a {
  display: block;
  padding: 12px 0;
  font-family: var(--display);
  font-style: italic;
  font-size: 24px;
  text-transform: uppercase;
  border-bottom: 1px solid var(--mist);
}

.hero {
  position: relative;
  min-height: 100vh;
  background: var(--void);
  overflow: hidden;
  display: grid;
  grid-template-columns: 1.22fr 0.78fr;
}
.hero-photo {
  z-index: 0;
  opacity: 0.72;
  filter: grayscale(0.15) contrast(1.12) saturate(0.92);
}
.fighter.a .hero-photo { object-position: center 10%; }
.fighter.b .hero-photo { object-position: 50% 18%; }
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(7,7,7,0.2) 0%, transparent 30%, transparent 70%, rgba(7,7,7,0.2) 100%);
}
.hero-slash {
  position: absolute;
  top: 0;
  left: 52%;
  width: 1px;
  height: 100%;
  background: var(--paper);
  transform: none;
  z-index: 3;
  box-shadow: none;
  opacity: 0.35;
}
.fighter { position: relative; min-height: 100vh; }
.fighter.a {
  background: radial-gradient(ellipse at 38% 62%, #3a1114 0%, transparent 52%), linear-gradient(160deg, #1a1a1a 0%, #0a0a0a 100%);
}
.fighter.b {
  background: radial-gradient(ellipse at 62% 58%, #2a1012 0%, transparent 50%), linear-gradient(200deg, #141414 0%, #080808 100%);
}
.sil { display: none; }
.fighter.a .sil {
  left: 8%;
  background: linear-gradient(180deg, #2c2c2c 0%, #111 70%, #0a0a0a 100%);
  clip-path: polygon(28% 8%, 72% 0%, 100% 38%, 86% 100%, 12% 100%, 0% 42%);
}
.fighter.b .sil {
  right: 8%;
  background: linear-gradient(180deg, #323232 0%, #141414 68%, #0a0a0a 100%);
  clip-path: polygon(22% 0%, 76% 10%, 100% 44%, 88% 100%, 10% 100%, 0% 36%);
}
.corner {
  position: absolute;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: min(300px, 74%);
  color: var(--paper);
}
.fighter.a .corner { left: 48px; bottom: 88px; }
.fighter.b .corner { right: 48px; bottom: 88px; text-align: right; align-items: flex-end; }
.corner .name {
  font-family: var(--display);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(48px, 8vw, 112px);
  line-height: 0.86;
  text-transform: uppercase;
  letter-spacing: -0.03em;
}
.corner .div {
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.55;
}
.vs {
  position: absolute;
  left: 52%;
  top: 46%;
  transform: translate(-50%, -50%);
  z-index: 5;
  width: auto;
  height: auto;
  background: none;
  color: var(--paper);
  display: block;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(18px, 2vw, 28px);
  letter-spacing: 0.08em;
  mix-blend-mode: normal;
  opacity: 0.9;
  clip-path: none;
}
.cage { display: none; }
.cage svg { width: 100%; height: 100%; display: block; }
.hero-cta {
  position: absolute;
  left: auto;
  right: 48px;
  top: calc(var(--header) + 28px);
  bottom: auto;
  transform: none;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  width: auto;
  text-align: right;
}
.hero-date {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper);
  opacity: 0.7;
}
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.hero-cta .btn { min-width: 0; height: 40px; padding: 0 18px; color: var(--paper); background: transparent; box-shadow: inset 0 0 0 1px rgba(247,244,238,0.45); }
.hero-cta .btn-fill { background: var(--red); box-shadow: none; }
.hero-cta .btn-line:hover { color: var(--ink); background: var(--paper); }

.ticker {
  display: grid;
  grid-template-columns: 56px 1fr 1fr 1fr 1fr;
  background: var(--void);
  min-height: 64px;
  border-top: 1px solid rgba(247,244,238,0.08);
}
.ticker .pulse { background: var(--red); display: grid; place-items: center; }
.ticker .pulse b {
  width: 10px;
  height: 10px;
  background: var(--paper);
  border-radius: 50%;
  animation: live 1.4s ease infinite;
}
@keyframes live {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.7); }
}
.tick {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 0 24px;
  border-left: 1px solid rgba(255,255,255,0.08);
  color: var(--paper);
}
.tick strong {
  font-family: var(--display);
  font-style: italic;
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.tick span {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}

section.block { padding: 120px 0; }
section.bone { background: var(--bone); }
section.void { background: var(--void); color: var(--paper); }

.head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 56px;
  gap: 32px;
}
.head h1, .head h2 {
  margin-top: 10px;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(40px, 6vw, 76px);
  letter-spacing: -0.045em;
  line-height: 0.96;
  text-transform: none;
}
.head .more {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  white-space: nowrap;
}
.head .more:hover { color: var(--red-deep); }

.lede {
  max-width: 38ch;
  font-family: var(--serif);
  font-size: clamp(20px, 2.2vw, 28px);
  font-style: italic;
  font-weight: 300;
  line-height: 1.35;
  color: var(--ink);
  margin: 0 0 56px;
  opacity: 0.72;
}

.cards {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr;
  gap: 48px 32px;
}
.card {
  background: transparent;
  overflow: hidden;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  color: var(--ink);
  transition: none;
}
.card:hover {
  transform: none;
  box-shadow: none;
}
.card:hover .card-body h3 { color: var(--red); }
.card .media img { transition: transform 1.1s var(--ease); }
.card:hover .media img { transform: scale(1.06); }
.octa-mark { transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1); }
.card:hover .octa-mark { transform: rotate(10deg) scale(1.08); }
.media { position: relative; background: var(--carbon); overflow: hidden; min-height: 280px; }
.cards .card:first-child .media { min-height: 420px; }
.media img,
.thumb img,
.tile > img,
.split-photo,
.hero-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.media img { z-index: 0; }
.slash-art, .octa-mark { display: none; }
.tone { position: absolute; inset: 0; }
.t1 { background: radial-gradient(circle at 30% 70%, #4a1518 0%, #121212 62%); }
.t2 { background: linear-gradient(135deg, #1a1a1a 0%, #2a0e10 100%); }
.t3 { background: linear-gradient(200deg, #101010 0%, #3a1214 100%); }
.t4 { background: radial-gradient(circle at 70% 30%, #2e1518 0%, #0c0c0c 60%); }
.t5 { background: linear-gradient(18deg, #141414 40%, #5a1216 100%); }
.octa-mark {
  position: absolute;
  right: 16px;
  top: 16px;
  width: 48px;
  height: 48px;
  background: var(--red);
}
.slash-art {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(-18deg, transparent 0 28px, rgba(225,6,19,0.12) 28px 30px);
}
.card-body {
  padding: 22px 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 0;
  background: transparent;
}
.card-body h3 {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(22px, 2.4vw, 32px);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1.12;
  text-transform: none;
}
.card-body p, .meta {
  font-size: 13px;
  color: var(--ash);
  letter-spacing: 0.01em;
}
.slash-art, .octa-mark { display: none; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 48px 32px; }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 48px 32px; }
.list-cards { display: grid; gap: 0; }
.list-item {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 36px;
  background: transparent;
  box-shadow: none;
  border-bottom: 1px solid var(--mist);
  padding: 28px 0;
  align-items: center;
  transition: none;
}
.list-item .thumb { min-height: 140px; position: relative; background: var(--carbon); overflow: hidden; }
.list-item .body { padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.list-item h3 {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(22px, 2.6vw, 34px);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.03em;
}
.list-item:hover {
  transform: none;
  box-shadow: none;
}
.list-item:hover h3 { color: var(--red); }
.list-item .thumb img { transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
.list-item:hover .thumb img { transform: scale(1.05); }

.crumbs {
  display: block;
  font-size: 12px;
  letter-spacing: 0.06em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ash);
  margin: 0 0 18px;
}
.crumbs a:hover { color: var(--red); }

.article { padding: 8px 0 120px; }
.article header.ah {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 20px;
  height: auto;
  position: static;
  background: transparent;
  border: 0;
  z-index: auto;
}
.article h1 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(40px, 6.4vw, 84px);
  line-height: 0.96;
  letter-spacing: -0.045em;
  margin: 0;
  padding: 0;
  max-width: 16ch;
  overflow-wrap: break-word;
  color: var(--ink);
}
.article header.ah .kicker {
  display: block;
}
.article .byline {
  display: block;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ash);
  margin: 0;
}
.prose p { margin: 0 0 22px; font-size: 19px; line-height: 1.7; }
.prose h2 {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(26px, 3vw, 36px);
  font-weight: 400;
  margin: 56px 0 16px;
  line-height: 1.15;
  letter-spacing: -0.03em;
}
.prose h3 {
  font-family: var(--serif);
  font-style: italic;
  font-size: 20px;
  font-weight: 600;
  margin: 28px 0 10px;
  line-height: 1.25;
}
.prose ul, .prose ol { margin: 0 0 18px 1.2em; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin: 0 0 8px; font-size: 17px; line-height: 1.6; }
.prose a { color: var(--red); text-decoration: underline; text-underline-offset: 3px; }
.prose blockquote {
  border-left: 3px solid var(--red);
  padding: 8px 0 8px 18px;
  margin: 24px 0;
  font-size: 18px;
  color: var(--steel);
}
.callout {
  background: transparent;
  border-left: 0;
  padding: 32px 0 8px;
  margin: 40px 0;
  max-width: 28ch;
}
.callout p {
  margin: 0;
  font-size: 26px;
  font-family: var(--serif);
  font-style: italic;
  line-height: 1.3;
  color: var(--ink);
}
.related { margin-top: 48px; padding-top: 28px; border-top: 1px solid var(--mist); }
.related h2 { font-family: var(--serif); font-style: italic; font-size: 22px; line-height: 1.18; margin-bottom: 16px; }

table.sheet {
  width: 100%;
  border-collapse: collapse;
  font-size: 16px;
  margin: 8px 0 40px;
}
table.sheet th, table.sheet td {
  text-align: left;
  padding: 18px 12px 18px 0;
  border-bottom: 1px solid var(--mist);
  vertical-align: top;
}
table.sheet th {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash);
  font-weight: 600;
}
table.sheet .org {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 20px;
  letter-spacing: -0.02em;
}
table.sheet caption {
  text-align: left;
  font-size: 12px;
  color: var(--ash);
  margin-bottom: 10px;
}

.rank-row, .row {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 16px;
  align-items: center;
  padding: 22px 0;
  border-bottom: 1px solid rgba(7,7,7,0.1);
}
.pos {
  font-family: var(--display);
  font-style: italic;
  font-weight: 700;
  font-size: 20px;
  color: var(--red);
}
.av { display: none; }
.nm {
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: -0.02em;
}
.rec { font-size: 12px; color: var(--ash); letter-spacing: 0.1em; }

.split {
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  min-height: 640px;
  box-shadow: none;
}
.split-dark {
  background: var(--void);
  color: var(--paper);
  padding: 56px 48px 48px;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 640px;
}
.split-photo {
  z-index: 0;
  opacity: 0.55;
  filter: grayscale(0.12) contrast(1.1);
}
.split-dark > *:not(.split-photo) { position: relative; z-index: 1; }
.split-dark h2 {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(40px, 5vw, 68px);
  line-height: 0.96;
  letter-spacing: -0.04em;
  font-weight: 300;
  margin: 12px 0 18px;
}
.split-dark p { opacity: 0.72; max-width: 36ch; font-size: 17px; line-height: 1.5; }
.split-list { background: transparent; color: var(--ink); padding: 8px 8px 8px 48px; }

.page-hero {
  background: var(--void);
  color: var(--paper);
  padding: 108px 0 56px;
  position: relative;
  overflow: hidden;
}
.page-hero.has-photo {
  min-height: min(86vh, 820px);
  padding: 0;
  display: grid;
  align-items: end;
  background-color: var(--void);
  background-size: cover;
  background-position: center center;
}
.page-hero.has-photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(7,7,7,0.15) 0%, rgba(7,7,7,0.25) 42%, rgba(7,7,7,0.88) 100%);
}
.page-hero.has-photo .wrap { position: relative; z-index: 1; padding: 140px 0 72px; }
.ph-arena { background-image: url("../img/arena-exterieur.webp"); background-position: 45% 40%; }
.ph-arena2 { background-image: url("../img/octagon.webp"); background-position: center 40%; }
.ph-octagon { background-image: url("../img/octagon.webp"); background-position: center 40%; }
.ph-cage { background-image: url("../img/fight.webp"); background-position: center 48%; }
.ph-gym { background-image: url("../img/gym.webp"); background-position: 42% 38%; }
.ph-gym-paris { background-image: url("../img/gym-paris.webp"); background-position: 38% 48%; }
.ph-belt { background-image: url("../img/ceinture.webp"); background-position: center 28%; }
.ph-belt2 { background-image: url("../img/ceinture-combat.webp"); background-position: center 22%; }
.ph-paris { background-image: url("../img/arena-exterieur.webp"); background-position: 45% 40%; }
.ph-keys { background-image: url("../img/octagon.webp"); background-position: center 40%; }
.ph-micro { background-image: url("../img/combattant.webp"); background-position: 72% 28%; }
.ph-gants { background-image: url("../img/gants.webp"); background-position: 58% 16%; }
.ph-arkea { background-image: url("../img/arkea.webp"); background-position: 32% 38%; }
.page-hero h1 {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(52px, 9vw, 128px);
  font-weight: 300;
  line-height: 0.9;
  letter-spacing: -0.05em;
  margin: 12px 0 20px;
  max-width: 12ch;
  color: var(--paper);
  text-shadow: none;
}
.page-hero p {
  max-width: 36ch;
  opacity: 0.72;
  font-size: clamp(18px, 2vw, 24px);
  line-height: 1.35;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
}
.updated {
  display: inline-block;
  margin-top: 16px;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
}

.mosaic {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  grid-template-rows: 280px 280px;
  gap: 12px;
}
.tile { position: relative; background: var(--carbon); overflow: hidden; min-height: 220px; }
.tile.wide { grid-row: 1 / span 2; }
.tile > img { z-index: 0; }
.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top, rgba(7,7,7,0.82) 0%, rgba(7,7,7,0.2) 55%, rgba(7,7,7,0.3) 100%);
}
.tile .veil {
  z-index: 3;
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 18px;
  color: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.tile h3 {
  font-family: var(--serif);
  font-style: italic;
  font-size: 24px;
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.03em;
}
.tile.wide h3 { font-size: clamp(32px, 3.2vw, 48px); }

.band {
  display: grid;
  grid-template-columns: 1.4fr 0.6fr;
}
.band .left {
  background: var(--void);
  color: var(--paper);
  padding: 80px 64px;
}
.band .left h2 {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(40px, 6vw, 80px);
  font-weight: 300;
  margin: 12px 0 16px;
  line-height: 0.94;
  letter-spacing: -0.045em;
}
.band .right {
  background: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 36px;
}
.field {
  width: min(280px, 70%);
  height: 48px;
  background: var(--steel);
  color: var(--paper);
  padding: 0 16px;
}
.field::placeholder { color: rgba(255,255,255,0.35); }
.go {
  width: 48px;
  height: 48px;
  background: var(--red);
  color: var(--paper);
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  cursor: pointer;
  transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1), background-color 0.25s ease;
}
.go:hover {
  background: var(--red-deep);
  transform: scale(1.06) translateX(3px);
}

.note {
  font-size: 13px;
  color: var(--ash);
  margin-top: 12px;
}

footer.site {
  background: var(--paper);
  border-top: 0;
  padding: 80px 0 0;
}
.foot {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 32px 48px;
  padding-bottom: 28px;
  align-items: start;
}
.foot img { height: 36px; width: auto; }
.foot-cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.foot-cols h3 {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 10px;
}
.foot-cols a {
  display: inline-block;
  position: relative;
  font-size: 13px;
  padding: 4px 0;
  opacity: 0.55;
  transition: opacity 0.2s ease, color 0.2s ease, transform 0.25s ease;
}
.foot-cols a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 2px;
  width: 100%;
  height: 1px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}
.foot-cols a:hover {
  opacity: 1;
  color: var(--red);
  transform: translateX(4px);
}
.foot-cols a:hover::after { transform: scaleX(1); }
.legal {
  background: var(--ink);
  color: rgba(255,255,255,0.55);
  font-size: 12px;
  padding: 16px 0;
}
.legal .wrap { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.legal strong { color: var(--paper); font-weight: 600; }

.forum-box {
  background: transparent;
  padding: 0;
  box-shadow: none;
  border-top: 1px solid var(--mist);
  padding-top: 32px;
}
.forum-box h3 {
  font-family: var(--display);
  font-style: italic;
  text-transform: uppercase;
  font-size: 22px;
  line-height: 1.18;
  margin-bottom: 10px;
}

.figure { margin: 28px 0 48px; background: var(--carbon); position: relative; overflow: hidden; }
.figure img {
  position: relative;
  inset: auto;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  max-height: min(78vh, 760px);
  min-height: 320px;
  object-fit: cover;
  object-position: center center;
}

/* Cadrage par visuel : le sujet reste dans le cadre (cover) */
.figure img[src$="parnasse.webp"],
img[src$="parnasse.webp"] { object-position: center 12%; }
.figure img[src$="parnasse-cage.webp"],
img[src$="parnasse-cage.webp"] { object-position: center 28%; }
.figure img[src$="hooker.webp"],
img[src$="hooker.webp"] { object-position: 50% 42%; }
.figure img[src$="sola.webp"],
img[src$="sola.webp"] { object-position: center 12%; }
.figure img[src$="gane.webp"],
img[src$="gane.webp"] { object-position: center 18%; }
.figure img[src$="gane.webp"] {
  aspect-ratio: 4 / 5;
  min-height: 420px;
  object-position: center 12%;
}
.figure img[src$="charriere.webp"],
img[src$="charriere.webp"] { object-position: center 8%; }
.figure img[src$="imavov.webp"],
img[src$="imavov.webp"] { object-position: center 6%; }
.figure img[src$="saint-denis.webp"],
img[src$="saint-denis.webp"] { object-position: center 16%; }
.figure img[src$="duclos.webp"],
img[src$="duclos.webp"] { object-position: center 8%; }
.figure img[src$="ziam.webp"],
img[src$="ziam.webp"] { object-position: center 8%; }
.figure img[src$="zebo.webp"],
img[src$="zebo.webp"] { object-position: center 18%; }
.figure img[src$="sy.webp"],
img[src$="sy.webp"] { object-position: center 8%; }
.figure img[src$="cornolle.webp"],
img[src$="cornolle.webp"] { object-position: 38% 18%; }
.figure img[src$="aljarouj.webp"],
img[src$="aljarouj.webp"] { object-position: center 10%; }
.figure img[src$="benouaich.webp"],
img[src$="benouaich.webp"] { object-position: center 10%; }
.figure img[src$="gym.webp"],
img[src$="gym.webp"] { object-position: 22% 40%; }
.figure img[src$="gym-paris.webp"],
img[src$="gym-paris.webp"] { object-position: 38% 48%; }
.figure img[src$="gants.webp"],
img[src$="gants.webp"] { object-position: 58% 16%; }
.figure img[src$="ceinture.webp"],
img[src$="ceinture.webp"] { object-position: center 22%; }
.figure img[src$="ceinture-combat.webp"],
img[src$="ceinture-combat.webp"] { object-position: center 22%; }
.figure img[src$="arena-exterieur.webp"],
img[src$="arena-exterieur.webp"] { object-position: 45% 40%; }
.figure img[src$="octagon.webp"],
img[src$="octagon.webp"] { object-position: center 48%; }
.figure img[src$="fight.webp"],
img[src$="fight.webp"] { object-position: center 48%; }
.figure img[src$="grappling.webp"],
img[src$="grappling.webp"] { object-position: 32% 40%; }
.figure img[src$="clinch.webp"],
img[src$="clinch.webp"] { object-position: 58% 42%; }
.figure img[src$="combattant.webp"],
img[src$="combattant.webp"] { object-position: 78% 30%; }
.figure img[src$="pesee.webp"],
img[src$="pesee.webp"] { object-position: 42% 26%; }
.figure img[src$="victoire.webp"],
img[src$="victoire.webp"] { object-position: center 48%; }
.figure img[src$="arkea.webp"],
img[src$="arkea.webp"] { object-position: 28% 36%; }
.figure img[src$="organisations.webp"],
img[src$="organisations.webp"] {
  object-position: center center;
}
.figure img[src$="organisations.webp"] {
  object-fit: contain;
  aspect-ratio: auto;
  max-height: 520px;
  min-height: 0;
  background: #111;
}

.hero .fighter.a .hero-photo { object-position: center 6%; }
.hero .fighter.b .hero-photo { object-position: 50% 0%; }
.legal a { color: inherit; text-decoration: underline; opacity: 0.85; }
.caption {
  font-size: 12px;
  color: var(--ash);
  padding: 8px 0 0;
  letter-spacing: 0.02em;
}
.badge {
  display: inline-block;
  background: var(--red);
  color: var(--paper);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 4px 10px;
  margin-bottom: 10px;
}
.badge.wait { background: var(--ink); }
.checks { margin: 0 0 24px; }
.checks li {
  padding: 8px 0 8px 28px;
  position: relative;
  border-bottom: 1px solid var(--mist);
  font-size: 15px;
}
.checks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  width: 12px;
  height: 12px;
  background: var(--red);
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
.timeline { border-left: 2px solid var(--red); margin: 20px 0 32px; padding-left: 20px; }
.timeline .t-item { margin: 0 0 22px; }
.timeline .t-item strong { display: block; font-family: var(--display); font-style: italic; text-transform: uppercase; }
.code {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 13px;
  background: var(--bone);
  padding: 16px;
  overflow: auto;
  margin: 0 0 20px;
}
.status-ok { color: var(--red); font-weight: 700; }

@media (max-width: 980px) {
  .header-inner { padding: 0 20px; gap: 12px; }
  nav.main { display: none; }
  header .cta { display: none; }
  .burger { display: flex; }
  .hero { grid-template-columns: 1fr; min-height: auto; }
  .fighter { min-height: 70vh; }
  .hero-slash, .cage { display: none; }
  .fighter.a { order: 1; }
  .vs { order: 2; position: relative; left: auto; top: auto; transform: none; text-align: center; padding: 14px 0; background: var(--void); width: 100%; }
  .fighter.b { order: 3; }
  .hero-cta { order: 4; }
  .hero-cta {
    position: relative;
    left: auto;
    top: auto;
    bottom: auto;
    transform: none;
    justify-content: flex-start;
    padding: 24px 20px 32px;
    background: var(--void);
    width: 100%;
    flex-wrap: wrap;
  }
  .fighter.a .corner, .fighter.b .corner { left: 24px; right: auto; bottom: 28px; }
  .ticker { grid-template-columns: 56px 1fr 1fr; }
  .ticker .tick:nth-child(n+4) { display: none; }
  .wrap { width: calc(100% - 40px); }
  .cards, .split, .mosaic, .band, .grid-2, .grid-3, .foot, .foot-cols, .list-item,
  .ed-week-grid, .ed-aside, .ed-keys-grid, .ed-bercy-row, .ed-club, .ed-club-full-grid, .roster, .org-lead { grid-template-columns: 1fr; }
  .mosaic { grid-template-rows: none; }
  .tile.wide { grid-row: auto; min-height: 280px; }
  section.block { padding: 72px 0; }
  .fighter.b .corner { align-items: flex-start; text-align: left; }
  .band .left { padding: 48px 24px; }
  .list-item .body { padding: 0; }
  .list-item .thumb { min-height: 180px; }
  .page-hero.has-photo { min-height: 70vh; }
  .page-hero.has-photo .wrap { padding: 100px 0 48px; }
  .split-list { padding: 32px 0 0; }
  .ed-lead-copy,
  .ed-bleed-copy,
  .ed-portrait-copy { width: calc(100% - 40px); margin-left: auto; margin-right: auto; }
  .ed-bercy-row { width: calc(100% - 40px); margin-top: 0; padding: 28px 0 64px; }
  .ed-shot { aspect-ratio: 16 / 10; }
  .ed-club-full { min-height: 0; }
  .ed-club-full-grid { min-height: 0; padding: 72px 0 48px; gap: 40px; }
  .ed-club-full::after {
    background: linear-gradient(180deg, rgba(7,7,7,0.55) 0%, rgba(7,7,7,0.78) 100%);
  }
  .ed-aside-item { grid-template-columns: 1fr; }
  .ed-aside-item img { height: 240px; }
  .ed-index { grid-template-columns: 1fr; }
  .ed-keys-photo { aspect-ratio: 4 / 3; margin-top: 28px; }
  .roster a.lead { grid-row: auto; min-height: 70vh; }
  .hub-index a,
  .hub-index .row-static { grid-template-columns: 48px 1fr; }
  .hub-index a em,
  .hub-index .row-static em { grid-column: 2; }
  .org-lead { width: auto; margin-left: 0; padding-right: 0; }
  .org-lead-photo { aspect-ratio: 16 / 10; }
  body.home > header { position: sticky; }
  body.home > header:not(.is-compact) {
    background: rgba(247, 244, 238, 0.92);
    border-bottom-color: transparent;
  }
  body.home > header:not(.is-compact) .burger i { background: var(--ink); }
}

/* ——— Composition éditoriale ——— */
.ed-lead {
  display: block;
  position: relative;
  color: var(--paper);
  min-height: 86vh;
  overflow: hidden;
}
.ed-lead-media,
.ed-bleed-media,
.ed-portrait-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.ed-lead-media img,
.ed-bleed-media img,
.ed-portrait-media img {
  position: absolute;
  inset: -8% 0;
  width: 100%;
  height: 116%;
  object-fit: cover;
}
.ed-portrait-media img {
  inset: 0;
  height: 100%;
}
.ed-bleed-media img {
  inset: 0;
  height: 100%;
  object-position: center 58%;
}
.ed-lead::after,
.ed-bleed::after,
.ed-portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(7,7,7,0.08) 0%, rgba(7,7,7,0.2) 40%, rgba(7,7,7,0.88) 100%);
  pointer-events: none;
}
.ed-lead-copy,
.ed-bleed-copy {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: inherit;
  width: min(100% - 80px, var(--max));
  margin: 0 auto;
  padding: 120px 0 72px;
}
.ed-lead-copy h2,
.ed-lead-copy h3,
.ed-bleed-copy h2 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(42px, 7vw, 96px);
  line-height: 0.92;
  max-width: 14ch;
  letter-spacing: -0.045em;
  margin: 10px 0 16px;
}
.ed-lead-copy p { font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.65; }
.ed-week { padding: 0 0 80px; }
.ed-week .wrap.ed-head { padding: 88px 0 0; }
.ed-head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px 48px;
  align-items: end;
  margin-bottom: 0;
}
section.block.ed-club { padding: 0; }
.ed-club .btn-line { color: var(--paper); }
.ed-club .btn-line:hover { color: var(--ink); background: var(--paper); }
.ed-head h2,
.ed-keys h2 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(40px, 6vw, 76px);
  letter-spacing: -0.045em;
  line-height: 0.96;
  margin: 0;
}
.ed-head .kicker { grid-column: 1; grid-row: 1; }
.ed-head h2 { grid-column: 1; grid-row: 2; }
.ed-head .lede { grid-column: 1; grid-row: 3; }
.ed-head .more { grid-column: 2; grid-row: 2; align-self: end; }

.ed-aside {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px 40px;
  padding: 40px 0 72px;
}
.ed-aside-item {
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: stretch;
  padding: 0;
  color: var(--ink);
}
.ed-aside-item img {
  width: 100%;
  height: min(38vh, 340px);
  object-fit: cover;
  display: block;
}
.ed-aside-item img[src$="parnasse.webp"] { object-position: center 10%; }
.ed-aside-item img[src$="zebo.webp"] { object-position: center 24%; }
.ed-aside-item h3 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(22px, 2.2vw, 30px);
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin: 4px 0 6px;
}
.ed-aside-item p { font-size: 13px; color: var(--ash); }

.ed-club {
  display: grid;
  grid-template-columns: 1.35fr 0.65fr;
  min-height: 72vh;
  align-items: stretch;
}
.ed-club .split-dark { padding: 80px 8% 64px; min-height: 72vh; }
.ed-club .split-list { display: flex; flex-direction: column; justify-content: center; }
.ed-club .row {
  grid-template-columns: 56px 1fr auto;
  padding: 22px 0;
  border-bottom: 1px solid var(--mist);
}
.ed-club .av { display: none; }

.ed-club-full {
  position: relative;
  min-height: 88vh;
  overflow: hidden;
  color: var(--paper);
  background: var(--void);
}
.ed-club-full > .split-photo {
  z-index: 0;
  left: 38%;
  width: 62%;
  opacity: 0.95;
  object-position: 20% 30%;
  filter: grayscale(0.1) contrast(1.08);
}
.ed-club-full::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(90deg, #070707 0%, #070707 32%, rgba(7,7,7,0.35) 52%, rgba(7,7,7,0.55) 100%),
    linear-gradient(180deg, rgba(7,7,7,0.2) 0%, transparent 30%, rgba(7,7,7,0.65) 100%);
}
.ed-club-full-grid {
  position: relative;
  z-index: 2;
  min-height: 88vh;
  display: flex;
  align-items: end;
  padding: 120px 0 80px;
}
.ed-club-full-copy { width: min(100%, 460px); }
.ed-club-full h2 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(40px, 5.4vw, 72px);
  line-height: 0.96;
  letter-spacing: -0.04em;
  margin: 12px 0 18px;
  max-width: 12ch;
}
.ed-club-full p { opacity: 0.78; max-width: 36ch; font-size: 17px; line-height: 1.5; }
.ed-club-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 28px; }
.ed-club-full .btn-line { color: var(--paper); }
.ed-club-full .btn-line:hover { color: var(--ink); background: var(--paper); }
.ed-club-full .split-list { padding: 28px 0 0; color: var(--paper); }
.ed-club-full .row { border-bottom-color: rgba(247,244,238,0.16); }
.ed-club-full .rec { color: rgba(247,244,238,0.55); }

.ed-bercy { padding: 0; background: var(--void); }
.ed-bleed {
  position: relative;
  min-height: 78vh;
  color: var(--paper);
  overflow: hidden;
}
.ed-bleed-copy .more { color: var(--paper); opacity: 0.7; }
.ed-bleed-copy .more:hover { opacity: 1; color: var(--paper); }

.ed-bercy-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 20px;
  align-items: start;
  width: min(100% - 80px, var(--max));
  margin: 0 auto;
  padding: 36px 0 88px;
  position: relative;
  z-index: 3;
}
.ed-shot {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  min-height: 0;
  overflow: hidden;
  color: var(--paper);
  background: var(--carbon);
}
.ed-shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease);
}
.ed-shot[href*="combattants"] img { object-position: center 12%; }
.ed-shot[href*="analyse"] img { object-position: center 42%; }
.ed-shot:hover img { transform: scale(1.06); }
.ed-shot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(7,7,7,0.82) 0%, rgba(7,7,7,0.1) 55%);
}
.ed-shot .veil {
  position: absolute;
  left: 20px;
  right: 20px;
  top: auto;
  bottom: 18px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 6px;
  pointer-events: none;
}
.ed-shot h3 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(18px, 1.8vw, 26px);
  line-height: 1.08;
  letter-spacing: -0.03em;
}
.ed-shot.shift { transform: none; }
.ed-index {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0 32px;
  padding: 12px 0 0;
}
.ed-index a {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: 16px;
  padding: 18px 0;
  border-bottom: 1px solid rgba(247,244,238,0.12);
  color: var(--paper);
  align-items: baseline;
}
.ed-index a span { font-family: var(--display); font-style: italic; color: var(--red); font-size: 14px; }
.ed-index a strong {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 20px;
  letter-spacing: -0.02em;
}

.ed-keys { overflow: hidden; }
.ed-keys-grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 48px 56px;
  align-items: start;
}
.ed-keys-list { list-style: none; margin: 36px 0 0; }
.ed-keys-list a {
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 20px;
  padding: 22px 0;
  border-top: 1px solid var(--mist);
  align-items: baseline;
}
.ed-keys-list a em {
  font-family: var(--display);
  font-style: italic;
  color: var(--red);
  font-size: 15px;
}
.ed-keys-list a strong {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(22px, 2.4vw, 30px);
  letter-spacing: -0.03em;
}
.ed-keys-list a b { display: block; font-weight: 400; font-size: 14px; color: var(--ash); margin-top: 6px; font-style: normal; font-family: var(--ui); }
.ed-keys-photo {
  position: relative;
  height: auto;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  margin-right: 0;
  background: var(--carbon);
}
.ed-keys-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

.ed-portrait {
  position: relative;
  min-height: 92vh;
  color: var(--paper);
  overflow: hidden;
}
.ed-portrait-media {
  overflow: hidden;
}
.ed-portrait-copy {
  position: relative;
  z-index: 2;
  width: min(100% - 80px, var(--max));
  margin: 0 auto;
  min-height: 92vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 100px 0 72px;
}
.ed-portrait-copy h2 {
  font-family: var(--display);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(36px, 6.4vw, 88px);
  line-height: 0.9;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  margin: 8px 0 20px;
  max-width: 16ch;
}
.ed-portrait-copy p {
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  max-width: 28ch;
  opacity: 0.8;
  margin-bottom: 28px;
}
.ed-portrait-copy .more { color: var(--paper); }
.ed-portrait-media img[src$="parnasse.webp"] { object-position: center 6%; }

.roster {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  grid-auto-rows: 280px;
  gap: 10px;
}
.roster a {
  position: relative;
  overflow: hidden;
  color: var(--paper);
  background: var(--carbon);
  display: block;
}
.roster a.lead { grid-row: span 2; min-height: 570px; }
.roster img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.2s var(--ease);
}
.roster a:hover img { transform: scale(1.07); }
.roster a::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(7,7,7,0.86) 0%, rgba(7,7,7,0.05) 55%);
}
.roster .meta {
  position: absolute;
  left: 20px;
  right: 20px;
  bottom: 20px;
  z-index: 2;
}
.roster .meta h3 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 24px;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
.roster .lead .meta h3 { font-size: clamp(32px, 3vw, 48px); }

.hub-index { margin-top: 56px; }
.hub-index a,
.hub-index .row-static {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: 24px;
  padding: 28px 0;
  border-top: 1px solid var(--mist);
  align-items: baseline;
}
.hub-index a span,
.hub-index .row-static span {
  font-family: var(--display);
  font-style: italic;
  color: var(--red);
  font-size: 16px;
}
.hub-index a strong,
.hub-index .row-static strong {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(24px, 3vw, 36px);
  letter-spacing: -0.03em;
}
.hub-index a em,
.hub-index .row-static em { font-style: normal; font-size: 13px; color: var(--ash); letter-spacing: 0.08em; text-transform: uppercase; }
.hub-index .row-static p {
  grid-column: 2 / -1;
  font-size: 15px;
  color: var(--ash);
  font-style: normal;
  max-width: 52ch;
  margin: 8px 0 0;
  line-height: 1.5;
}

.org-lead {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 40px 56px;
  align-items: center;
  width: auto;
  margin-left: 0;
  margin-bottom: 8px;
  padding-right: 0;
}
.org-lead-photo {
  position: relative;
  height: auto;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--carbon);
}
.org-lead-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 48%;
}
.org-lead h2 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(36px, 5vw, 64px);
  letter-spacing: -0.04em;
  line-height: 0.95;
  margin: 10px 0 18px;
}
.org-lead p { font-size: 17px; line-height: 1.55; max-width: 42ch; opacity: 0.82; }
.ed-graphic {
  background: var(--void);
  padding: 56px 0;
}
.ed-graphic img {
  width: min(100% - 80px, var(--max));
  margin: 0 auto;
  height: auto;
  max-height: 420px;
  object-fit: contain;
}

.article .figure {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  max-width: 100vw;
}
.article .caption {
  width: min(100% - 40px, var(--read));
  margin: 12px auto 0;
}
@media (min-width: 981px) {
  .article > .wrap-read:has(> header.ah) {
    width: min(100% - 80px, var(--max));
    max-width: var(--max);
    display: grid;
    grid-template-columns: minmax(280px, 0.4fr) minmax(0, 1fr);
    column-gap: 48px;
    align-items: end;
  }
  .article .crumbs { grid-column: 1 / -1; }
  .article header.ah {
    grid-column: 1;
    grid-row: 2;
    padding-bottom: 8px;
    /* La taille minimale automatique d'un element de grille est celle de son
       contenu : un mot plus large que la piste ne s'y repliait pas, il en
       sortait — et la photo de la colonne voisine le recouvrait. « Ultimate
       Fighting Championship », « Dovletdzhan Yagshimuradov » et les six
       pages organisation etaient coupes net. */
    min-width: 0;
  }
  .article .figure {
    grid-column: 2;
    grid-row: 2;
    width: auto;
    max-width: none;
    margin: 0;
    margin-right: calc((100% - 100vw) / 2);
  }
  .article .figure img {
    aspect-ratio: 4 / 5;
    max-height: min(86vh, 820px);
    min-height: 520px;
  }
  .article .caption {
    width: auto;
    margin: 12px 0 0;
  }
  .article .prose,
  .article .related {
    grid-column: 1 / -1;
    max-width: var(--read);
  }
}
.wrap-read > .figure:first-child {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  max-width: 100vw;
  margin-bottom: 40px;
}
.prose > p:first-of-type::first-letter {
  font-family: var(--serif);
  font-style: italic;
  font-size: 4.6em;
  float: left;
  line-height: 0.78;
  padding: 10px 12px 0 0;
  color: var(--ink);
}

.tile > img { transition: transform 1.1s var(--ease); }
.tile:hover > img { transform: scale(1.06); }
.split-dark { isolation: isolate; }
.figure { isolation: isolate; }

@media (prefers-reduced-motion: no-preference) {
  html.js-motion:not(.motion-ready) body > header {
    opacity: 0;
  }
  html.js-motion:not(.motion-ready) .hero .corner,
  html.js-motion:not(.motion-ready) .hero .hero-cta,
  html.js-motion:not(.motion-ready) .hero .vs {
    opacity: 0;
  }
  html.js-motion:not(.motion-ready) .hero .hero-photo {
    transform: scale(1.08);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ticker .pulse b { animation: none; }
  .card:hover,
  .list-item:hover,
  .tile:hover > img,
  .card:hover .media img,
  .ed-shot:hover img,
  .roster a:hover img,
  .go:hover,
  .foot-cols a:hover {
    transform: none;
  }
  body > header,
  .brand img,
  nav.main a::after {
    transition: none;
  }
}

@media (max-width: 980px) {
  .ed-aside,
  .ed-keys-grid,
  .ed-bercy-row,
  .ed-club,
  .ed-club-full-grid,
  .roster,
  .org-lead,
  .ed-index {
    grid-template-columns: 1fr;
  }
  .ed-shot {
    aspect-ratio: 16 / 10;
  }
  .ed-shot h3 { font-size: 22px; }
  .org-lead {
    gap: 28px;
    align-items: start;
  }
  .org-lead-photo {
    width: 100%;
    aspect-ratio: 16 / 10;
  }
  .ed-club-full { min-height: 0; }
  .ed-club-full-grid { min-height: 0; padding: 72px 0 48px; display: block; }
  .ed-club-full-copy { width: 100%; }
  .ed-club-full > .split-photo {
    left: 0;
    width: 100%;
    object-position: 22% 28%;
  }
}

/* =========================================================================
   Composants ajoutés par le générateur.
   Rangés en fin de feuille pour rester lisibles comme un bloc, et écrits
   avec les mêmes jetons que le reste : aucune nouvelle couleur, aucune
   nouvelle famille. Un composant qui introduit sa propre palette est la
   première marche vers un site qui ressemble à un thème.
   ========================================================================= */

/* Lien d'évitement : invisible tant qu'on ne tabule pas, indispensable dès
   qu'on navigue au clavier. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 18px;
  font-family: var(--ui);
  font-size: 13px;
}
.skip:focus { left: 8px; top: 8px; }

/* Sortie du tiroir. Son absence était le défaut : le menu s'ouvrait en plein
   écran sans qu'aucun signe ne dise comment en sortir. */
.drawer-close {
  position: absolute;
  top: 14px;
  right: 18px;
  width: 44px;
  height: 44px;
  border: 1px solid var(--mist);
  background: transparent;
  color: var(--ink);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.drawer-close:hover,
.drawer-close:focus-visible { background: var(--ink); color: var(--paper); }
.drawer { position: fixed; }
.drawer nav { display: flex; flex-direction: column; gap: 4px; }

/* Rail de rubriques. Remplace le filtre JavaScript du CMS par des liens
   réels : un robot les suit, un visiteur peut les partager. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 26px 0 40px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--mist);
}
.filters a {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--mist);
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease);
}
.filters a b { font-size: 11px; font-weight: 600; color: var(--ash); }
.filters a:hover { border-color: var(--ink); }
.filters a.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.filters a.on b { color: var(--red); }

/* Suite de lecture en fin d'article. */
.related-list { list-style: none; margin: 14px 0 0; padding: 0; }
.related-list li { border-top: 1px solid var(--mist); }
.related-list a {
  display: block;
  padding: 14px 0;
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.35;
  color: var(--ink);
  transition: color 0.25s var(--ease), padding-left 0.35s var(--ease);
}
.related-list a:hover { color: var(--red); padding-left: 10px; }

/* Image d'ouverture d'article. */
.figure.lead { margin: 0 0 34px; }
.figure.lead img { width: 100%; height: auto; display: block; }

@media (max-width: 980px) {
  .filters { gap: 6px; margin: 20px 0 28px; }
  .filters a { padding: 7px 11px; font-size: 12px; }
  .related-list a { font-size: 17px; }
}

/* =========================================================================
   Mouvement.
   L'état masqué n'existe que sous `html.motion`, classe posée par le script
   lui-même. Sans JavaScript, aucune de ces règles ne s'applique et la page
   est intégralement lisible — le mouvement est un supplément, jamais une
   condition.
   ========================================================================= */

/* Les blocs ne s'estompent pas, ils montent.
 *
 * Le devoilement se faisait par `clip-path: inset()`, pour dire « ceci etait
 * la, tu y arrives » plutot que « ceci apparait ». L'intention etait juste,
 * son cout ne l'etait pas : `clip-path` ne s'anime pas sur le compositeur,
 * chaque trame repeint l'element entier. Mesure sur un defilement de vingt
 * crans, processeur divise par quatre : 25 trames longues sur 123 avec, 6
 * sur 135 sans. C'est la moitie du hachage que le defilement donnait a voir.
 *
 * `transform` et `opacity` sont les deux seules proprietes que le navigateur
 * anime sans repasser par la mise en page. La montee dit la meme chose — le
 * bloc vient d'en bas, on descend vers lui — et elle ne coute rien. */
html.motion [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  transition:
    opacity 0.55s var(--ease),
    transform 0.72s var(--ease);
}
html.motion [data-reveal].shown {
  opacity: 1;
  transform: none;
}

/* Le heros s'ouvre au defilement : les deux combattants s'ecartent, la
   couture laisse voir le noir. Les transformations sont posees par le
   script ; ici on ne fait qu'annoncer au navigateur ce qui va bouger. */
/* `will-change` etait pose pour l'ancien effet en JavaScript. Il promeut la
   couche en memoire video ; laisse en permanence sur deux grandes images, il
   coute plus qu'il ne rapporte. Les animations de defilement ci-dessous
   tournent deja sur le compositeur. */

/* Le compteur : chiffre en display, aligne sur la ligne de base du libelle,
   pour que la montee ne fasse pas sauter la mise en page. */
.compteur {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  font-variant-numeric: tabular-nums;
}
.compteur b {
  font-family: var(--display);
  font-size: clamp(30px, 3.4vw, 54px);
  font-weight: 600;
  line-height: 1;
  color: var(--red);
}
.compteur span {
  font-family: var(--ui);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
}
.chiffres {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(26px, 5vw, 72px);
  padding: clamp(30px, 5vh, 52px) 0 0;
  border-top: 1px solid var(--mist);
  margin-top: clamp(30px, 5vh, 52px);
}

/* L'image se pose : elle arrive légèrement trop grande et se cale. Le cadre
   masque le débord, donc rien ne saute dans la mise en page. */
html.motion [data-reveal-media] { overflow: hidden; }
html.motion [data-reveal-media] img {
  transform: scale(1.06);
  transition: transform 1.15s var(--ease);
  /* `will-change` seulement ici, et seulement le temps du mouvement : ces
     images sont grandes, et promouvoir une couche en permanence coute de la
     memoire video pour rien une fois l'animation finie. */
  will-change: transform;
}
html.motion [data-reveal-media].shown img { will-change: auto; }
html.motion [data-reveal-media].shown img { transform: scale(1); }

/* Le titre d'article arrive seul, sans attendre le reste : c'est la première
   chose qu'on lit, elle ne doit jamais être en file d'attente. */
html.motion .ah [data-reveal] { transition-duration: 0.72s; }

@media (prefers-reduced-motion: reduce) {
  html.motion [data-reveal],
  html.motion [data-reveal-media] img {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* =========================================================================
   La carte de combats.
   Une soirée de MMA a un ordre : on ouvre sur les préliminaires et on finit
   par le main event. Un tableau écrase cet ordre en quatorze lignes égales.
   Ici chaque combat occupe sa place dans la descente, et l'octogone au fond
   se referme au fur et à mesure — c'est le seul indicateur de progression,
   et il appartient au sujet.
   ========================================================================= */

.card-page { background: var(--void); color: var(--paper); }

.card-hero {
  position: relative;
  padding: clamp(90px, 14vh, 160px) 0 clamp(50px, 8vh, 90px);
  border-bottom: 1px solid rgba(247, 244, 238, 0.12);
}
.card-hero .crumbs { color: var(--ash); margin-bottom: 26px; }
.card-hero .crumbs a { color: var(--ash); }
.card-hero .crumbs a:hover { color: var(--paper); }
.card-hero h1 {
  font-family: var(--display);
  font-size: clamp(44px, 9vw, 128px);
  line-height: 0.88;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  margin: 14px 0 26px;
}
.card-hero .lede { color: var(--mist); max-width: 54ch; font-size: 17px; }
.card-count { margin-top: 22px; font-family: var(--ui); font-size: 13px; letter-spacing: 0.06em; color: var(--ash); }
.card-count b { color: var(--red); font-size: 17px; font-weight: 600; }

.card-scrollhint {
  position: absolute;
  right: 24px;
  bottom: 26px;
  font-family: var(--ui);
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ash);
  writing-mode: vertical-rl;
}

/* NB : cette classe s'appelait .card-body et ecrasait le bloc texte des
   cartes d'article, qui portait deja ce nom. Toutes les pages de liste du
   site en sont sorties disloquees. Les classes de la page carte sont
   desormais prefixees `carte-` : un prefixe par surface, pas de nom
   generique reutilise. */
.carte-corps {
  position: relative;
  display: grid;
  grid-template-columns: minmax(240px, 34%) 1fr;
  gap: clamp(24px, 5vw, 80px);
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 clamp(18px, 4vw, 56px);
}

/* L'octogone tient l'écran pendant toute la descente. */
.cage {
  position: sticky;
  top: calc(var(--header) + 8vh);
  align-self: start;
  height: min(46vh, 420px);
  display: grid;
  place-items: center;
  padding-top: 8vh;
}
.cage svg { width: 100%; height: 100%; overflow: visible; }
.cage-bg { fill: none; stroke: rgba(247, 244, 238, 0.09); stroke-width: 1.5; }
.cage-line {
  fill: none;
  stroke: var(--red);
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  /* Rempli par le script au fil du défilement. Valeur de départ : le cadre
     est vide tant que la première station n'est pas atteinte. */
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 0.45s var(--ease);
}
.cage-count {
  position: absolute;
  display: flex;
  align-items: baseline;
  gap: 3px;
  font-family: var(--display);
}
.cage-count b { font-size: clamp(34px, 5vw, 64px); color: var(--paper); font-weight: 600; }
.cage-count i { font-size: 15px; color: var(--ash); font-style: normal; }

.card-rail { padding: clamp(40px, 8vh, 100px) 0 clamp(60px, 12vh, 140px); }

.card-part {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 8px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(247, 244, 238, 0.16);
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
}
.card-part + .bout { border-top: 0; }
.card-part:not(:first-child) { margin-top: clamp(50px, 9vh, 110px); }

/* Une station. Le combat français est le seul à porter une marque : c'est
   la promesse éditoriale du site, elle mérite d'être lisible d'un coup d'œil. */
.bout {
  position: relative;
  padding: clamp(30px, 5vh, 54px) 0 clamp(26px, 4vh, 44px);
  border-top: 1px solid rgba(247, 244, 238, 0.12);
}
.bout[data-fr="1"]::before {
  content: "";
  position: absolute;
  left: -14px;
  top: clamp(30px, 5vh, 54px);
  width: 3px;
  height: 34px;
  background: var(--red);
}
.bout-rank {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-family: var(--ui);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--ash);
  margin-bottom: 14px;
}
.bout-rank span { color: var(--mist); }
.bout-rank i { font-style: normal; }

.bout-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(12px, 3vw, 36px);
  align-items: center;
}
.bout-side h3 {
  font-family: var(--display);
  font-size: clamp(20px, 3.1vw, 42px);
  line-height: 1;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  margin: 0;
}
.bout-side.b { text-align: right; }
.bout-meta { margin: 8px 0 0; font-family: var(--ui); font-size: 12px; color: var(--ash); }
.bout-mid { display: grid; justify-items: center; gap: 6px; text-align: center; }
.bout-vs {
  font-family: var(--serif);
  font-style: italic;
  font-size: 14px;
  color: var(--ash);
}
.bout-div {
  font-family: var(--ui);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mist);
  white-space: nowrap;
}
.bout-tag {
  font-family: var(--ui);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--void);
  background: var(--red);
  padding: 3px 8px;
}
.bout.is-main h3 { font-size: clamp(26px, 4.4vw, 62px); }

.bout-state {
  margin: 18px 0 0;
  font-family: var(--ui);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
}
.card-page[data-etat="termine"] .bout-state { color: var(--paper); }
.bout-reserve {
  margin: 10px 0 0;
  font-family: var(--ui);
  font-size: 13px;
  color: var(--mist);
  border-left: 2px solid rgba(225, 6, 19, 0.5);
  padding-left: 12px;
}
.bout-reserve a { color: var(--red); text-decoration: underline; text-underline-offset: 3px; }

/* La station active se détache pendant la descente. */
.bout { transition: opacity 0.5s var(--ease); }
html.motion .card-rail .bout { opacity: 0.42; }
html.motion .card-rail .bout.near { opacity: 1; }

.card-outro { background: var(--void); border-top: 1px solid rgba(247, 244, 238, 0.12); }
.card-outro .related-list a { color: var(--paper); }
.card-outro .related-list li { border-color: rgba(247, 244, 238, 0.14); }
.card-honest {
  margin-top: 30px;
  padding-top: 18px;
  border-top: 1px solid rgba(247, 244, 238, 0.14);
  font-family: var(--ui);
  font-size: 13px;
  color: var(--ash);
  max-width: 62ch;
}

@media (max-width: 980px) {
  /* Le téléphone reçoit le même récit, pas une version amputée : l'octogone
     passe en bandeau collé en haut au lieu de disparaître. */
  .carte-corps { grid-template-columns: 1fr; gap: 0; }
  /* Le bandeau doit etre opaque : en degrade, le texte des combats passait au
     travers et se melangeait au compteur. Un repere de progression qu'on lit
     par-dessus l'information qu'il repere ne repere plus rien. */
  .cage {
    position: sticky;
    top: var(--header);
    height: 64px;
    padding: 0 4px;
    z-index: 20;
    background: var(--void);
    border-bottom: 1px solid rgba(247, 244, 238, 0.16);
    box-shadow: 0 14px 22px rgba(7, 7, 7, 0.92);
    grid-template-columns: 52px 1fr;
    place-items: center start;
    display: grid;
  }
  .cage svg { width: 42px; height: 42px; }
  /* Sur 42 px, un trait de 2,5 unites SVG disparait : on l'epaissit et on le
     rend independant de l'echelle. */
  .cage .cage-line { stroke-width: 7; vector-effect: non-scaling-stroke; }
  .cage .cage-bg { stroke-width: 4; vector-effect: non-scaling-stroke; }
  /* Le premier combat passait sous le bandeau au chargement et a chaque
     ancre. */
  .bout { scroll-margin-top: calc(var(--header) + 76px); }
  .card-rail { padding-top: 18px; }
  .cage-count { position: static; }
  .cage-count b { font-size: 26px; }
  .bout-grid { grid-template-columns: 1fr; gap: 10px; text-align: left; }
  .bout-side.b { text-align: left; }
  .bout-mid { justify-items: start; text-align: left; flex-direction: row; }
  .bout[data-fr="1"]::before { left: -12px; }
  .card-scrollhint { display: none; }
}

/* =========================================================================
   LES VISAGES D'ARTICLE
   Cinq formats, cinq mises en page. Un portrait est une personne, un
   resultat est une chronologie, un reportage est un lieu, des citations
   sont une voix. Les servir dans le meme gabarit, c'est ce qui fait dire
   « site genere » — et c'est exactement ce qu'on refuse ici.
   ========================================================================= */

/* --- PORTRAIT
   La feuille portait deja, depuis l'origine, une mise en page d'article en
   deux colonnes au-dessus de 981 px : titre a gauche, photo a droite en 4/5
   qui deborde du cadre, texte pleine largeur en dessous. C'est une bonne
   mise en page editoriale, et elle etait la.

   Mes premieres regles la combattaient — ratio impose, marges remises a
   zero, enfants recentres — et disloquaient la page. Elles sont retirees.
   Un visage d'article ajoute des distinctions ; il ne refait pas la mise en
   page qui existe. */
.face-portrait .ah h1 { font-size: clamp(30px, 3.6vw, 52px); line-height: 0.98; }
.face-portrait .ah .kicker { color: var(--red); }

/* --- LIEU — la salle porte. Le trait rouge sous le titre signale la
   rubrique sans toucher a la grille, et les intertitres deviennent des
   reperes plutot que des titres de recit. */
.face-lieu .ah::after {
  content: "";
  display: block;
  width: 54px;
  height: 3px;
  background: var(--red);
  margin-top: 18px;
}
.face-lieu .prose h2 {
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  border-top: 1px solid var(--mist);
  padding-top: 16px;
  margin-top: 44px;
}

/* --- RESULTAT — une chronologie. Le texte se resserre, les tableaux
       respirent, et chaque intertitre est un moment de la soiree. */
.face-resultat .prose { font-size: 17px; }
.face-resultat .prose h2 {
  font-family: var(--display);
  font-size: clamp(20px, 2.4vw, 30px);
  text-transform: uppercase;
  letter-spacing: -0.005em;
  margin-top: 48px;
  padding-left: 16px;
  border-left: 3px solid var(--red);
}
.face-resultat .prose table { font-family: var(--ui); font-size: 14px; }
.face-resultat .prose table th {
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
}

/* --- CITATIONS — c'est une voix. Le texte cite prend la taille du titre,
       parce que c'est lui l'article. */
.face-citations .prose blockquote,
.face-citations .prose p:has(> em:only-child) {
  font-family: var(--serif);
  font-size: clamp(22px, 3vw, 34px);
  font-style: italic;
  line-height: 1.28;
  margin: 40px 0;
  padding-left: 24px;
  border-left: 2px solid var(--red);
  color: var(--ink);
}
.face-citations .prose blockquote p { font-size: inherit; font-style: inherit; margin: 0 0 12px; }

/* --- RECIT — la colonne de lecture classique, deja en place. */
.face-recit .prose > p:first-of-type::first-letter {
  font-family: var(--display);
  float: left;
  font-size: 4.2em;
  line-height: 0.78;
  padding: 6px 12px 0 0;
  color: var(--red);
}

/* =========================================================================
   TRANSITIONS DE PAGE
   L'API native : aucune bibliotheque, aucun routeur, et les navigateurs qui
   ne la connaissent pas naviguent normalement. Le mouvement est court —
   une transition de page qu'on remarque est une transition ratee.
   ========================================================================= */
@view-transition { navigation: auto; }

::view-transition-old(root) { animation: vt-out 0.18s var(--ease) both; }
::view-transition-new(root) { animation: vt-in 0.32s var(--ease) both; }
@keyframes vt-out { to { opacity: 0; transform: translate3d(0, -8px, 0); } }
@keyframes vt-in { from { opacity: 0; transform: translate3d(0, 12px, 0); } }

/* L'en-tete ne doit pas clignoter entre deux pages : il est le point fixe. */
body > header { view-transition-name: entete; }
::view-transition-group(entete) { animation-duration: 0.001s; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* =========================================================================
   SURVOLS QUI INFORMENT
   Un survol decoratif deplace des pixels. Un survol utile dit ce qui va se
   passer si on clique : ou on va, et ce qu'on y trouvera.
   ========================================================================= */

.card { position: relative; }
.card .media { overflow: hidden; }
.card .media img { transition: transform 0.9s var(--ease), filter 0.6s var(--ease); }
.card:hover .media img { transform: scale(1.045); }
.card .carte-corps h3 {
  background-image: linear-gradient(var(--red), var(--red));
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 0 100%;
  transition: background-size 0.5s var(--ease), color 0.3s var(--ease);
}
.card:hover .carte-corps h3 { background-size: 100% 1px; color: var(--red); }
.card .carte-corps time {
  display: block;
  margin-top: 10px;
  font-family: var(--ui);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
  transition: color 0.3s var(--ease);
}
.card:hover .carte-corps time { color: var(--ink); }

/* Le roster : le nom monte a la rencontre du curseur, l'image se desature
   pour que le nom reste lisible. */
.roster a { position: relative; overflow: hidden; }
.roster a img { transition: transform 0.85s var(--ease), filter 0.5s var(--ease); }
.roster a:hover img { transform: scale(1.06); filter: saturate(0.55) contrast(1.05); }
.roster a .meta { transition: transform 0.45s var(--ease); }
.roster a:hover .meta { transform: translateY(-4px); }

/* Etat de focus visible partout : c'est la meme information que le survol,
   pour qui navigue au clavier. */
a:focus-visible,
button:focus-visible,
.filters a:focus-visible,
.card:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
}

/* =========================================================================
   RUPTURES REELLES
   Un iPhone SE, un grand telephone, une tablette et un portable ne sont pas
   le meme appareil. Les regles ci-dessous ne touchent jamais au bureau :
   elles sont toutes plafonnees.
   ========================================================================= */

/* Portable et petite tablette. */
@media (max-width: 900px) {
  .ed-keys-grid { grid-template-columns: 1fr; gap: 34px; }
  .cards.grid-3 { grid-template-columns: repeat(2, 1fr); }
  .roster { grid-template-columns: repeat(3, 1fr); }
  .face-portrait .figure.lead { aspect-ratio: 4 / 3; }
}

/* Grand telephone. La lecture prime : on passe en colonne unique et on
   redescend les titres d'un cran, sans jamais casser la hierarchie. */
@media (max-width: 600px) {
  .cards.grid-3, .cards.grid-2 { grid-template-columns: 1fr; gap: 30px; }
  .roster { grid-template-columns: repeat(2, 1fr); }
  .ah h1, .face-portrait .ah h1 { font-size: clamp(28px, 8vw, 40px); }
  .prose { font-size: 17px; }
  .face-recit .prose > p:first-of-type::first-letter { font-size: 3.4em; }
  .filters { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .filters::-webkit-scrollbar { display: none; }
  .filters a { flex: 0 0 auto; }
  .face-portrait .lead-org { font-size: clamp(30px, 12vw, 54px); }
}

/* Petit telephone. Rien ne disparait : on resserre les marges et on reduit
   l'echelle typographique. Couper une section ici serait un echec. */
@media (max-width: 400px) {
  :root { --header: 56px; }
  .wrap, .wrap-read { padding-left: 16px; padding-right: 16px; }
  .roster { grid-template-columns: 1fr 1fr; gap: 10px; }
  .bout-side h3 { font-size: 22px; }
  .bout.is-main h3 { font-size: 27px; }
  .card-hero h1 { font-size: clamp(34px, 12vw, 46px); }
  .drawer a { font-size: 20px; padding: 10px 0; }
}

/* =========================================================================
   LE HEROS — L'OCTOGONE COMME SIGNATURE
   La forme vient de la page carte. La reutiliser ici n'est pas une economie :
   c'est ce qui fait qu'un visiteur reconnait le site d'une page a l'autre.
   Une identite, c'est une forme qu'on retrouve, pas un logo qu'on repete.
   ========================================================================= */

.hero-cage {
  position: relative;
  min-height: min(100svh, 900px);
  background: var(--void);
  color: var(--paper);
  display: grid;
  grid-template-rows: 1fr auto;
  overflow: hidden;
  isolation: isolate;
}

/* Le cadre. `preserveAspectRatio="none"` etire volontairement l'octogone a la
   forme de l'ecran : ce n'est pas un logo centre, c'est une arene dans
   laquelle la page se tient. */
.cage-frame { position: absolute; inset: clamp(14px, 3vw, 40px); z-index: 2; pointer-events: none; }
.cage-frame svg { width: 100%; height: 100%; }
.cage-frame .cage-bg { stroke: rgba(247, 244, 238, 0.14); stroke-width: 0.6; vector-effect: non-scaling-stroke; }
.cage-frame .cage-line {
  stroke: var(--red);
  stroke-width: 1.6;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
/* Le trace se referme au chargement — une seule fois, en une seconde et
   demie. Assez pour etre vu, trop court pour retarder la lecture. */
html.motion .cage-frame .cage-draw { animation: cage-close 1.5s var(--ease) 0.15s forwards; }
@keyframes cage-close { to { stroke-dashoffset: 0; } }

.hero-duel {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  z-index: 1;
}
.hero-man { position: relative; margin: 0; overflow: hidden; }
.hero-man img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 18%;
  filter: grayscale(1) contrast(1.12) brightness(0.78);
  transition: filter 0.9s var(--ease), transform 1.4s var(--ease);
}
/* La couleur revient sur celui qu'on regarde : le survol dit qui on a
   choisi, sans deplacer quoi que ce soit. */
.hero-man:hover img { filter: grayscale(0) contrast(1.05) brightness(0.92); transform: scale(1.03); }
.hero-man::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(7, 7, 7, 0.92) 0%, rgba(7, 7, 7, 0.1) 46%);
}
.hero-man figcaption {
  position: absolute;
  left: clamp(20px, 4vw, 54px);
  bottom: clamp(26px, 6vh, 68px);
  z-index: 2;
  display: grid;
  gap: 8px;
}
.hero-man.b figcaption { left: auto; right: clamp(20px, 4vw, 54px); text-align: right; }
.hero-name {
  font-family: var(--display);
  font-size: clamp(38px, 7.4vw, 122px);
  line-height: 0.84;
  letter-spacing: -0.025em;
  text-transform: uppercase;
}

/* Le « contre » est pose sur la couture, pas dans une colonne : c'est le
   point de contact des deux images. */
.hero-vs {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(15px, 1.7vw, 23px);
  color: var(--paper);
  background: var(--void);
  padding: 9px 17px;
  border: 1px solid rgba(247, 244, 238, 0.2);
}

.hero-foot {
  position: relative;
  z-index: 3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: clamp(20px, 4vh, 40px) clamp(28px, 6vw, 76px) clamp(28px, 5vh, 54px);
}
.hero-when {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  font-family: var(--ui);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mist);
}
/* Le compte a rebours est une information, pas un ornement : a trois jours
   de l'evenement, c'est ce que le visiteur veut savoir en premier.

   Il echappe aux majuscules du bloc parent : « 46H00 » n'existe pas en
   francais, le symbole de l'heure est minuscule et le reste — J−2 — porte
   deja sa propre casse. */
.hero-when b {
  text-transform: none;
  font-family: var(--display);
  font-size: clamp(19px, 2.3vw, 30px);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--red);
}
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.hero-cage .btn-fill { background: var(--red); color: var(--paper); border-color: var(--red); }
.hero-cage .btn-fill:hover { background: var(--paper); color: var(--void); border-color: var(--paper); }
.hero-cage .btn-line { color: var(--paper); border-color: rgba(247, 244, 238, 0.42); }
.hero-cage .btn-line:hover { background: var(--paper); color: var(--void); border-color: var(--paper); }

@media (max-width: 900px) {
  .hero-cage { min-height: min(92svh, 760px); }
  .hero-name { font-size: clamp(30px, 9vw, 62px); }
}
@media (max-width: 600px) {
  /* Le telephone garde les deux combattants : c'est l'affiche. On empile au
     lieu de couper — supprimer l'un des deux serait perdre le sujet. */
  .hero-duel { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .hero-man.b figcaption { left: clamp(20px, 4vw, 54px); right: auto; text-align: left; }
  .hero-man figcaption { bottom: clamp(16px, 3vh, 28px); }
  .hero-vs { font-size: 13px; padding: 7px 13px; }
  .hero-foot { flex-direction: column; align-items: flex-start; }
  .cage-frame { inset: 10px; }
}

/* =========================================================================
   CORRECTIFS — constates en ouvrant les pages, pas en lisant le code.
   Chacun est note ici avec sa cause, parce qu'un correctif sans cause
   revient toujours.
   ========================================================================= */

/* 1. Le heros etait ecrase.
   `.hero-cage` porte aussi `.hero`, dont la regle historique impose
   `grid-template-columns: 1.22fr 0.78fr`. Le duel se retrouvait comprime
   dans la premiere colonne, le pied de heros ejecte dans la seconde, et les
   deux noms se chevauchaient faute de place. Une colonne unique, et la
   grille des rangees reprend la main. */
.hero-cage {
  grid-template-columns: 1fr;
  grid-template-rows: 1fr auto;
  min-height: min(100svh, 880px);
}
.hero-duel { width: 100%; min-height: 0; }
.hero-man { min-width: 0; }

/* Le nom reste dans sa colonne, quelle que soit la police effectivement
   chargee : en repli, une graisse large deborde la ou Oswald condense. Se
   fier a la police distante pour tenir une mise en page est un pari. */
.hero-man figcaption {
  right: clamp(20px, 4vw, 54px);
  max-width: 100%;
}
.hero-man.b figcaption { left: clamp(20px, 4vw, 54px); }
.hero-name {
  display: block;
  font-size: clamp(26px, 4.6vw, 76px);
  max-width: 100%;
  overflow-wrap: anywhere;
  hyphens: none;
}
.hero-man .kicker { color: var(--mist); }

/* 2. L'en-tete clair sur une page sombre.
   Le bandeau et le logo gardaient leur fond papier au-dessus du noir : une
   barre blanche et une vignette blanche posees sur l'arene. L'en-tete doit
   appartenir a la page qu'il coiffe. */
body:has(.card-page) > header,
body:has(.hero-cage) > header {
  background: linear-gradient(rgba(7, 7, 7, 0.88), rgba(7, 7, 7, 0));
  backdrop-filter: none;
  border-bottom-color: transparent;
}
/* Opaque, pas 95 % : le nom du combat qui defile dessous transparaissait. */
body:has(.card-page) > header.is-compact,
body:has(.hero-cage) > header.is-compact {
  background: var(--void);
  border-bottom-color: rgba(247, 244, 238, 0.14);
}
body:has(.card-page) nav.main a,
body:has(.hero-cage) nav.main a { color: var(--mist); }
body:has(.card-page) nav.main a:hover,
body:has(.hero-cage) nav.main a:hover,
body:has(.card-page) nav.main a.on,
body:has(.hero-cage) nav.main a.on { color: var(--paper); }
body:has(.card-page) .burger i,
body:has(.hero-cage) .burger i { background: var(--paper); }

/* 3. Le logo a fond blanc.
   Le fichier historique est un JPEG : son fond est cuit dans l'image et
   forme une vignette claire sur fond noir. La mediatheque contient la marque
   en PNG detoure — c'est elle qu'on sert sur les pages sombres, sans
   redessiner quoi que ce soit. */
body:has(.card-page) .brand img,
body:has(.hero-cage) .brand img { visibility: hidden; }
body:has(.card-page) .brand,
body:has(.hero-cage) .brand {
  background: url("/media/brand/marque.png") left center / contain no-repeat;
  width: 42px;
  height: 42px;
  display: block;
}
body:has(.card-page) .brand img,
body:has(.hero-cage) .brand img { width: 42px; height: 42px; }

/* 4. Le trace de l'octogone depassait en bas a gauche : le point de depart
   du polygone et celui du trace ne coincidaient pas visuellement. On arrondit
   les jonctions pour que la fermeture se lise comme un cadre continu. */
.cage-line { stroke-linecap: round; }

/* 5. Le cadre-octogone du heros : supprime.
   Deux tentatives, deux echecs. En SVG etire, ses diagonales traversaient les
   photos ; en CSS, le remplissage interieur formait un panneau noir opaque
   par-dessus tout le heros — un clip-path ne perce pas de trou.
   La bonne decision n'etait pas une troisieme technique : c'etait de
   constater que cet ornement ne portait aucune information. L'octogone garde
   sa place sur la page carte, ou il dit ou l'on en est dans la soiree. */

/* 6. La marque sur fond sombre.
   Le PNG detoure est un pictogramme carre : seul, il flotte et ne dit pas le
   nom du media. On le double du mot-symbole compose — la typographie du site
   fait le travail, sans dependre d'un fichier image qui n'existe pas. */
body:has(.card-page) .brand,
body:has(.hero-cage) .brand {
  width: auto;
  height: auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: none;
}
body:has(.card-page) .brand::before,
body:has(.hero-cage) .brand::before {
  content: "";
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  background: url("/media/brand/marque.png") center / contain no-repeat;
}
body:has(.card-page) .brand::after,
body:has(.hero-cage) .brand::after {
  content: "UFC.FR";
  font-family: var(--display);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--paper);
}
body:has(.card-page) .brand img,
body:has(.hero-cage) .brand img { display: none; }

/* 7. L'en-tete sombre etait un degrade gris, ni transparent ni opaque. Il
   devient franc : rien en haut de page, plein des qu'on defile. */
body:has(.card-page) > header:not(.is-compact),
body:has(.hero-cage) > header:not(.is-compact) { background: transparent; }
/* Des qu'on defile, l'en-tete redevient une surface : une barre transparente
   posee sur du contenu rend son propre contenu illisible. */
body:has(.hero-cage) > header.is-compact {
  background: rgba(247, 244, 238, 0.96);
  border-bottom-color: var(--mist);
}
body:has(.hero-cage) > header.is-compact nav.main a { color: var(--ink); }
body:has(.hero-cage) > header.is-compact nav.main a.on,
body:has(.hero-cage) > header.is-compact nav.main a:hover { color: var(--red); }
body:has(.hero-cage) > header.is-compact .burger i { background: var(--ink); }
body:has(.hero-cage) > header.is-compact .brand::after { color: var(--ink); }

/* 8. Le pied de heros respirait mal : la date collee a gauche, les boutons
   colles a droite, une bande noire vide entre les deux. On le ramene dans la
   largeur de lecture et on rapproche les deux blocs. */
.hero-foot {
  max-width: var(--max);
  width: 100%;
  margin: 0 auto;
  justify-content: space-between;
  align-items: flex-end;
}
.hero-when { gap: 14px; }
.hero-man.b figcaption { align-items: flex-end; justify-items: end; }
.hero-man.b .kicker { text-align: right; }

/* Le bandeau defilant.
   Un ticker qui ne defile pas n'est pas un ticker. Le contenu est double
   dans le balisage et la piste se translate de la moitie de sa largeur : la
   boucle se ferme sans saut, parce que la seconde copie occupe exactement la
   place de la premiere au moment ou celle-ci sort. La duplication est
   masquee aux lecteurs d'ecran. */
.ticker { grid-template-columns: 56px 1fr; overflow: hidden; }
.ticker-rail { overflow: hidden; display: flex; align-items: center; }
.ticker-run {
  display: flex;
  align-items: center;
  gap: 0;
  white-space: nowrap;
  animation: defile 46s linear infinite;
}
/* Le survol suspend : on ne peut pas lire une information qui fuit. */
.ticker:hover .ticker-run { animation-play-state: paused; }
@keyframes defile { to { transform: translate3d(-50%, 0, 0); } }

.ticker .tick {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 0 clamp(20px, 3vw, 44px);
  border-right: 1px solid rgba(247, 244, 238, 0.1);
  font-family: var(--ui);
}
.ticker .tick strong {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper);
}
.ticker .tick > span { font-size: 12px; color: var(--ash); }

@media (prefers-reduced-motion: reduce) {
  .ticker-run { animation: none; }
}

/* L'en-tete de section place ses quatre enfants explicitement.
   Sans placement, la grille `1fr auto` les distribue en serpentin : le
   sur-titre et le titre sur la premiere rangee, l'accroche et le lien sur la
   seconde — ce qui envoyait le titre dans la colonne de droite. Le probleme
   est apparu en passant de h2 a h1 : la feuille ne stylait que h2, et rien
   ne placait quoi que ce soit. */
.ed-head > .kicker { grid-column: 1; grid-row: 1; }
.ed-head > h1,
.ed-head > h2 { grid-column: 1; grid-row: 2; }
.ed-head > .lede { grid-column: 1; grid-row: 3; align-self: start; max-width: 46ch; }
.ed-head > .more { grid-column: 2; grid-row: 3; justify-self: end; align-self: end; }

/* Le titre de l'accueil est un h1 pour l'indexation, et doit se lire comme
   le h2 des autres sections : meme famille, meme graisse, meme rythme. */
.ed-head h1 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(40px, 6vw, 76px);
  letter-spacing: -0.045em;
  line-height: 0.96;
  margin: 0;
}

/* L'en-tete collante doit etre opaque, y compris sur les pages a heros
   sombre : a 96 %, le bas du heros transparaissait pendant le defilement. */
body:has(.hero-cage) > header.is-compact { background: var(--paper); }

@media (max-width: 900px) {
  /* En colonne unique, le lien « tout le fil » passe sous l'accroche plutot
     que de comprimer le titre. */
  .ed-head { grid-template-columns: 1fr; }
  .ed-head > .more { grid-column: 1; grid-row: 4; justify-self: start; margin-top: 14px; }
}

/* La recherche.
   Le champ est le sujet de la page : il occupe la largeur de lecture et se
   lit a la taille d'un titre. Un champ de recherche discret sur une page qui
   ne sert qu'a chercher est une contradiction. */
.recherche { margin: 34px 0 8px; }
.recherche input {
  width: 100%;
  padding: 18px 0;
  border: 0;
  border-bottom: 2px solid var(--ink);
  background: transparent;
  font-family: var(--serif);
  font-size: clamp(24px, 3.4vw, 40px);
  font-style: italic;
  color: var(--ink);
  outline: none;
}
.recherche input::placeholder { color: var(--mist); }
.recherche input:focus-visible { border-bottom-color: var(--red); outline: none; }
.recherche-etat {
  margin: 12px 0 0;
  min-height: 1.2em;
  font-family: var(--ui);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
}

.recherche-resultats { display: grid; gap: 0; margin-top: 26px; }
.resultat {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "kicker kicker" "titre date" "resume resume";
  gap: 4px 24px;
  padding: 26px 0;
  border-top: 1px solid var(--mist);
  color: var(--ink);
  transition: padding-left 0.4s var(--ease);
}
.resultat:hover { padding-left: 12px; }
.resultat .kicker { grid-area: kicker; }
.resultat h2 {
  grid-area: titre;
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(20px, 2.2vw, 28px);
  line-height: 1.15;
  transition: color 0.3s var(--ease);
}
.resultat:hover h2 { color: var(--red); }
.resultat time {
  grid-area: date;
  font-family: var(--ui);
  font-size: 12px;
  color: var(--ash);
  font-variant-numeric: tabular-nums;
}
.resultat p { grid-area: resume; margin: 6px 0 0; color: var(--ash); font-size: 15px; max-width: 70ch; }

.visuallyhidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

@media (max-width: 600px) {
  .resultat { grid-template-columns: 1fr; grid-template-areas: "kicker" "titre" "resume" "date"; }
  .resultat time { margin-top: 8px; }
}

/* ------------------------------------------------------------------ eases
   Le tiroir s'ouvre, il n'apparait pas.
   Il etait pilote par l'attribut `hidden` seul : aucune transition possible,
   le menu surgissait et disparaissait d'un cadre a l'autre. Il est desormais
   toujours dans le flux quand il s'anime, et ce sont l'opacite, l'echelle et
   le decoupage qui font l'ouverture — jamais `display`, qui ne s'anime pas.

   Les liens entrent en cascade : c'est ce qui distingue un panneau qui
   s'ouvre d'un panneau qui clignote. */
.drawer {
  display: flex;
  visibility: hidden;
  opacity: 0;
  clip-path: inset(0 0 100% 0);
  transition:
    opacity 0.34s var(--ease),
    clip-path 0.52s var(--ease),
    visibility 0s linear 0.52s;
}
.drawer.open {
  visibility: visible;
  opacity: 1;
  clip-path: inset(0 0 0 0);
  transition:
    opacity 0.26s var(--ease),
    clip-path 0.52s var(--ease),
    visibility 0s;
}
.drawer[hidden] { display: none; }

.drawer nav a {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
  transition: opacity 0.42s var(--ease), transform 0.42s var(--ease), color 0.25s var(--ease);
}
.drawer.open nav a { opacity: 1; transform: none; }
/* Chaque lien part 34 ms apres le precedent : la cascade se lit, elle ne
   traine pas. Quinze liens tiennent en un demi-quart de seconde. */
.drawer.open nav a:nth-child(1) { transition-delay: 0.08s; }
.drawer.open nav a:nth-child(2) { transition-delay: 0.114s; }
.drawer.open nav a:nth-child(3) { transition-delay: 0.148s; }
.drawer.open nav a:nth-child(4) { transition-delay: 0.182s; }
.drawer.open nav a:nth-child(5) { transition-delay: 0.216s; }
.drawer.open nav a:nth-child(6) { transition-delay: 0.25s; }
.drawer.open nav a:nth-child(7) { transition-delay: 0.284s; }
.drawer.open nav a:nth-child(8) { transition-delay: 0.318s; }
.drawer.open nav a:nth-child(9) { transition-delay: 0.352s; }
.drawer.open nav a:nth-child(10) { transition-delay: 0.386s; }
.drawer.open nav a:nth-child(n + 11) { transition-delay: 0.42s; }

/* Le bouton devient une croix. Les trois barres pivotent, celle du milieu
   s'efface : le geste dit ce que le clic fera. */
.burger i {
  transition: transform 0.36s var(--ease), opacity 0.2s var(--ease);
  transform-origin: center;
}
.burger[aria-expanded="true"] i:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.burger[aria-expanded="true"] i:nth-child(2) { opacity: 0; transform: scaleX(0.4); }
.burger[aria-expanded="true"] i:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

.drawer-close { transition: background 0.25s var(--ease), color 0.25s var(--ease), transform 0.3s var(--ease); }
.drawer-close:hover { transform: rotate(90deg); }

/* ---------------------------------------------------------------- cadrage
   Les vignettes coupaient les visages.
   `object-fit: cover` centre le cadrage : sur une photo verticale posee dans
   une boite horizontale, le centre tombe sur le torse et la tete sort. On
   remonte le point d'interet — un portrait se cadre sur le regard, pas sur
   les abdominaux. */
/* Le cadrage part du haut, pas d'un pourcentage arbitraire.
   Une photo de combattant est verticale, la vignette est horizontale : a 18 %
   le visage sortait encore par le haut. Sur ce type d'image, ce qui compte
   est toujours dans le premier tiers — on cale donc le cadrage sur le bord
   superieur, ou se trouve la tete, plutot que de chercher un reglage moyen
   qui coupe tout le monde un peu. */
.media img,
.thumb img { object-position: 50% 0%; }
/* Les vues d'arene et de salle n'ont pas de visage a preserver : elles se
   cadrent au centre, ou leur sujet se trouve. */
.media img[src*="arena"],
.media img[src*="octagon"],
.media img[src*="cage"],
.media img[src*="gym"],
.media img[src*="accor"] { object-position: 50% 50%; }

/* ------------------------------------------------- en-tete sur telephone
   Trois defauts constates le tiroir ouvert.

   1. Deux croix. Le burger devenu croix et le bouton de fermeture du tiroir
      proposaient la meme action a dix pixels l'un de l'autre. Le burger
      gagne : il est la ou le pouce vient de cliquer. */
@media (max-width: 980px) {
  .drawer-close { display: none; }

  /* 2. Le burger tombait au centre : la navigation est masquee et l'appel a
        l'action aussi, il ne restait que la marque et lui dans un conteneur
        centre. On force les deux extremites. */
  .header-inner { justify-content: space-between; }
  .header-inner .cta { display: none; }
  .burger { margin-left: auto; }
}

/* 3. Le mot-symbole etait blanc sur creme, donc invisible, des que le tiroir
      s'ouvrait en haut de page — l'en-tete y est transparente, mais le
      tiroir derriere est clair. Tiroir ouvert, la marque redevient encre. */
body:has(.drawer.open) > header .brand::after { color: var(--ink) !important; }
body:has(.drawer.open) > header .burger i { background: var(--ink) !important; }
body:has(.drawer.open) > header { background: var(--paper) !important; }

/* ---------------------------------------------------------------- entree
   L'ecran d'entree. Toutes ces regles ne s'appliquent que si le script a
   pose l'element : rien ici ne peut cacher la page a quelqu'un dont le
   JavaScript n'a pas repondu. */
.entree {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--void);
  display: grid;
  place-items: center;
  /* La sortie se fait par le haut, dans le sens de la lecture qui commence :
     le voile se leve, il ne s'evapore pas. */
  clip-path: inset(0 0 0 0);
  transition: clip-path 0.72s var(--ease);
}
.entree.partie { clip-path: inset(0 0 100% 0); }

.entree-corps {
  display: grid;
  justify-items: center;
  gap: 14px;
  text-align: center;
  padding: 24px;
}
.entree-marque {
  font-family: var(--display);
  font-size: clamp(30px, 5vw, 52px);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--paper);
}
.entree-compte {
  font-family: var(--display);
  font-size: clamp(52px, 12vw, 132px);
  font-weight: 600;
  line-height: 0.86;
  letter-spacing: -0.02em;
  color: var(--red);
}
.entree-lieu {
  font-family: var(--ui);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ash);
}
/* La barre se remplit sur la duree exacte de l'entree : elle ne simule pas
   un chargement, elle annonce la fin de l'attente. */
.entree-barre {
  width: min(220px, 52vw);
  height: 2px;
  margin-top: 10px;
  background: rgba(247, 244, 238, 0.16);
  overflow: hidden;
}
.entree-barre i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--red);
  transform-origin: left center;
  transform: scaleX(0);
  animation: entree-barre 1.1s var(--ease) forwards;
}
@keyframes entree-barre { to { transform: scaleX(1); } }

/* Le defilement est bloque tant que le voile est la, et rendu ensuite. */
html.entree-active, html.entree-active body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) { .entree { display: none; } }

/* --------------------------------------------------------------- pied de page
   Les liens s'empilent. `.foot-cols a` est en `inline-block` : avec un seul
   mot par lien ils tenaient sur une ligne, mais « Calendrier MMA France » et
   ses voisins se suivaient a la queue leu leu dans la meme colonne. Chaque
   lien prend sa ligne, et la grille passe a cinq colonnes puisqu'il y en a
   cinq — a quatre, la cinquieme retombait seule sur une deuxieme rangee. */
.foot-cols { grid-template-columns: repeat(5, 1fr); }
.foot-cols > div { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
.foot-cols a { display: block; }

@media (max-width: 980px) { .foot-cols { grid-template-columns: repeat(2, 1fr); gap: 30px 20px; } }
@media (max-width: 480px) { .foot-cols { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ roster
   Le roster d'une page organisation sort de la colonne de lecture.
   Il est rendu dans `.prose`, plafonnee a la largeur de lecture (720 px) :
   cinq portraits se serraient donc dans le tiers gauche d'un ecran de 1440,
   laissant les deux tiers vides. Une galerie n'est pas du texte, elle prend
   la page. */
.article .prose .roster {
  /* Debordement pleine largeur, la formule classique : 100vw de large, tire
     vers la gauche de la moitie de l'ecart entre le parent et la fenetre. Ma
     premiere version calculait l'ecart depuis la largeur du parent, ce qui
     laissait la galerie coincee dans la colonne de lecture. */
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  margin-top: 26px;
  padding: 0 clamp(18px, 4vw, 56px);
  box-sizing: border-box;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  grid-auto-rows: 300px;
}
/* Le nom debordait de son cadre par la gauche : il etait pose sans limite de
   largeur sur une vignette etroite. Il se replie desormais, et se resserre
   quand il est long. */
.article .prose .roster .meta h3 {
  font-size: clamp(15px, 1.4vw, 22px);
  line-height: 1.12;
  overflow-wrap: anywhere;
}
.article .prose h2 + .roster { margin-top: 18px; }

@media (max-width: 900px) {
  .article .prose .roster {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 240px;
    padding: 0 18px;
  }
}

/* Le bloc roster d'une page organisation.
   Il vit hors de `.prose` : une galerie n'est pas du texte et n'a pas a tenir
   dans une colonne de lecture. Le nombre de colonnes suit la largeur reelle
   au lieu d'etre fige a trois. */
.roster-bloc { margin: clamp(40px, 6vh, 72px) auto clamp(20px, 4vh, 40px); }
.roster-bloc h2 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(24px, 3vw, 38px);
  margin: 0 0 22px;
}
.roster-bloc .roster {
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  grid-auto-rows: 290px;
  gap: 12px;
}
.roster-bloc .roster .meta h3 {
  font-size: clamp(15px, 1.3vw, 21px);
  line-height: 1.12;
  overflow-wrap: anywhere;
}
@media (max-width: 600px) {
  .roster-bloc .roster { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 220px; }
}

/* Le conteneur rouvert apres le bloc roster reste vide quand la page n'a pas
   de suite de lecture : il laissait deux cents pixels de blanc avant le pied
   de page. */
.wrap-read-vide { display: none; }

/* ------------------------------------------------- article sur telephone
   1. La photo d'ouverture debordait a droite.
      La mise en page de bureau la fait deliberement sortir du cadre
      (`margin-right: calc((100% - 100vw) / 2)`), ce qui est juste sur large
      et faux des que la colonne occupe tout l'ecran : l'image partait hors
      champ sans que rien ne la ramene. */
@media (max-width: 900px) {
  .article .figure,
  .article .figure.lead {
    width: auto;
    max-width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
  .article .figure img,
  .article .figure.lead img {
    width: 100%;
    height: auto;
    max-height: 62vh;
    object-fit: cover;
    aspect-ratio: auto;
    min-height: 0;
  }

  /* 2. Le fil d'Ariane reprenait le titre complet, en majuscules, sur trois
        lignes, juste au-dessus du titre lui-meme. Sur un ecran etroit, un
        chemin de navigation sert a remonter, pas a redire ou l'on est. Le
        dernier maillon disparait ; les precedents restent cliquables. */
  .crumbs { font-size: 11px; }
  .crumbs .crumb-actuel { display: none; }
  .crumbs a:last-of-type + .crumb-sep { display: none; }
}

/* =========================================================================
   LES SALLES
   La seule rubrique ou le site parle de lieux ou l'on peut se rendre. Elle
   passe sur fond sombre : dans une page claire, c'est ce qui lui donne le
   poids d'une destination plutot que d'une liste de plus.
   ========================================================================= */

.salles {
  background: var(--void);
  color: var(--paper);
  padding: clamp(64px, 11vh, 128px) 0 clamp(70px, 12vh, 140px);
}

.salles-tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  margin-bottom: clamp(34px, 6vh, 62px);
  padding-bottom: 26px;
  border-bottom: 1px solid rgba(247, 244, 238, 0.16);
}
.salles-tete h2 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(34px, 5.2vw, 66px);
  letter-spacing: -0.04em;
  line-height: 0.98;
  margin: 8px 0 0;
}
.salles-tete .lede { color: var(--mist); margin: 14px 0 0; max-width: 44ch; }
.salles-tete .more { color: var(--paper); border-bottom-color: rgba(247, 244, 238, 0.4); }
.salles-tete .more:hover { color: var(--red); border-bottom-color: var(--red); }

.salles-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: clamp(22px, 3vw, 44px);
}

.salle { display: flex; flex-direction: column; }
.salle-media {
  display: block;
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--carbon);
}
.salle-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Le sujet d'une photo de salle est l'equipement — ring, cage, tapis — et
     il occupe le haut du cadre. Un cadrage centre ne montrerait que le sol.
     La desaturation reste legere : a 0,35 la salle de Ramonville virait au
     monochrome a cote de ses voisines. */
  object-position: 50% 34%;
  filter: grayscale(0.12) contrast(1.04);
  transition: transform 1s var(--ease), filter 0.6s var(--ease);
}
.salle-media:hover img { transform: scale(1.045); filter: grayscale(0) contrast(1); }

/* La carte occupe toute la hauteur de sa cellule et le corps prend le reste :
   c'est ce qui permet aux rangees de liens de s'aligner d'une fiche a
   l'autre. Sans cela, un titre sur deux lignes decalait ses liens vers le bas
   et la grille perdait sa ligne de base. */
.salle { height: 100%; }
.salle-corps { padding: 20px 0 0; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.salle-ville {
  font-family: var(--ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--red);
}
.salle h3 {
  font-family: var(--display);
  font-size: clamp(19px, 1.9vw, 26px);
  font-weight: 600;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  line-height: 1.06;
  margin: 0;
}
/* Le composant est neutre : il sert la bande sombre de l'accueil et
   l'annuaire, qui est sur fond clair. Tant qu'il ecrivait « paper » en dur,
   les noms de salles etaient blancs sur creme — donc absents. Les couleurs
   du fond sombre sont declarees plus bas, sous `.salles`. */
.salle h3 a { color: var(--ink); }
.salle h3 a:hover { color: var(--red); }
.salle p { margin: 0; color: var(--ash); font-size: 15px; line-height: 1.45; }

.salle-liens {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  margin-top: auto !important;
  padding-top: 14px;
  border-top: 1px solid rgba(14, 14, 14, 0.14);
}
.salle-lire,
.salle-site {
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.salle-lire { color: var(--ink); }
.salle-lire:hover { color: var(--red); }
/* Le lien sortant se distingue du lien interne : le lecteur doit savoir qu'il
   quitte le site avant de cliquer, pas apres. */
.salle-site { color: var(--ash); display: inline-flex; align-items: center; gap: 6px; }
.salle-site i { font-style: normal; font-size: 11px; transition: transform 0.3s var(--ease); }
.salle-site:hover { color: var(--ink); }
.salle-site:hover i { transform: translate(2px, -2px); }

/* Sur la bande sombre de l'accueil, le composant s'inverse. Un seul endroit,
   et les deux surfaces restent d'accord. */
.salles .salle h3 a,
.salles .salle-lire { color: var(--paper); }
.salles .salle h3 a:hover,
.salles .salle-lire:hover { color: var(--red); }
.salles .salle-liens { border-top-color: rgba(247, 244, 238, 0.14); }
.salles .salle-site:hover { color: var(--paper); }

@media (max-width: 600px) {
  .salles-tete { flex-direction: column; align-items: flex-start; }
  .salles-grille { gap: 34px; }
  .salle-media { aspect-ratio: 16 / 10; }
}

/* =========================================================================
   L'ANNUAIRE DES SALLES — page « Les clubs de MMA français »

   La page tenait sa liste en texte : douze puces, un nom, une adresse. Un
   annuaire de salles est pourtant la seule page du site dont le lecteur
   attend qu'elle montre — il cherche un endroit ou aller, pas une reference
   a citer. Les fiches reprennent le composant `.salle` de l'accueil : meme
   objet, deux surfaces, une seule definition.
   ========================================================================= */

/* Un bloc pleine largeur au milieu d'un article. Il sort de la colonne de
   lecture (720 px) parce qu'une grille n'a pas de mesure de lecture. Le
   generateur ferme `.wrap-read` et ouvre celui-ci : c'est la structure qui
   le permet, pas une regle de debordement. */
.bloc-large {
  margin: clamp(46px, 7vh, 88px) auto clamp(44px, 6vh, 80px);
}

.annuaire-tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px 44px;
  flex-wrap: wrap;
  padding-bottom: 22px;
  margin-bottom: clamp(30px, 4vh, 48px);
  border-bottom: 2px solid var(--ink);
}
.annuaire-tete h2 {
  font-family: var(--display);
  font-size: clamp(26px, 3.4vw, 44px);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1;
  margin: 6px 0 0;
}
.annuaire-note {
  font-family: var(--ui);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ash);
  max-width: 38ch;
  margin: 0;
}

/* Quatorze fiches. `auto-fill` plutot qu'`auto-fit` : avec `auto-fit`, une
   derniere ligne d'une seule fiche s'etirait sur toute la largeur et cette
   fiche-la devenait une banniere. On garde la colonne. */
.annuaire-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: clamp(30px, 3.4vw, 52px) clamp(20px, 2.6vw, 38px);
}

/* Un filet sous chaque fiche : c'est ce qui fait lire la grille comme un
   annuaire et non comme une suite de cartes flottantes. */
.annuaire .salle-corps { padding-top: 16px; }
.annuaire .salle-media { aspect-ratio: 4 / 3; }
.annuaire .salle h3 { font-size: clamp(17px, 1.5vw, 21px); }
.annuaire .salle p { font-size: 14px; }

/* Une fiche sans photo. Elle ne se cache pas : le cadre reste, et il dit
   pourquoi il est vide. C'est une information — le club n'en publie pas —
   et c'est plus honnete qu'un cliche generique emprunte a un autre. */
.salle-media-vide {
  display: flex;
  align-items: flex-end;
  background:
    repeating-linear-gradient(135deg, transparent 0 11px, rgba(14, 14, 14, 0.045) 11px 12px),
    var(--bone);
  border: 1px solid rgba(14, 14, 14, 0.12);
}
.salle-media-vide span {
  display: block;
  padding: 16px 16px 15px;
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ash);
}
.salle-media-vide b { display: block; font-weight: 400; font-size: 11px; opacity: 0.72; margin-top: 3px; }
.salles .salle-media-vide {
  background:
    repeating-linear-gradient(135deg, transparent 0 11px, rgba(247, 244, 238, 0.05) 11px 12px),
    var(--carbon);
  border-color: rgba(247, 244, 238, 0.12);
}

/* Le bloc « autour des clubs » : quatre reperes, pas des salles. */
.rubrique-suite { margin-top: clamp(50px, 7vh, 96px); }
.rubrique-suite .ed-head { margin-bottom: clamp(26px, 3.5vh, 44px); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 40px 26px; }
.grid-4 .card h3 { font-size: clamp(16px, 1.4vw, 19px); }

/* Le credit d'une photo qui n'est pas la notre. Discret, jamais absent. */
.lead-credit {
  font-family: var(--ui);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ash);
  padding: 9px 0 0;
}

@media (max-width: 900px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); gap: 34px 22px; }
}
@media (max-width: 600px) {
  .annuaire-grille { grid-template-columns: 1fr; gap: 34px; }
  .annuaire .salle-media { aspect-ratio: 16 / 10; }
  .annuaire-tete { border-bottom-width: 1px; }
  .grid-4 { grid-template-columns: 1fr; gap: 30px; }
}

/* =========================================================================
   LE CORPS DU TITRE SUIT SA LONGUEUR

   `.article h1` compose en 84 px dans une boite de 16 caracteres. C'est une
   manchette, et c'est juste tant que le titre en est une. Passe cinquante
   signes — quarante documents sur cent neuf — le meme reglage donne cinq ou
   six lignes de trois mots, une colonne etroite a cote d'une photo pleine
   hauteur, et un titre qu'on lit en descendant.

   Le generateur pose le palier ; ici on ne fait que composer. Les titres
   courts ne sont pas touches : la manchette reste une manchette.
   ========================================================================= */

.article.t-long .ah h1 {
  font-size: clamp(30px, 4.2vw, 56px);
  max-width: 21ch;
  line-height: 1.02;
  letter-spacing: -0.035em;
}
.article.t-tres-long .ah h1 {
  font-size: clamp(27px, 3.4vw, 44px);
  max-width: 26ch;
  line-height: 1.08;
  letter-spacing: -0.025em;
}

/* Le mot le plus long decide aussi. Un titre de trente signes tient dans la
   mesure d'une manchette, mais pas si l'un de ses mots fait a lui seul la
   largeur de la colonne : il faudrait alors le couper en deux, et on ne
   coupe pas « Championship » au milieu pour tenir une taille. */
.article.t-mot-long .ah h1 { font-size: clamp(30px, 4.6vw, 62px); line-height: 1; }
.article.t-mot-tres-long .ah h1 { font-size: clamp(28px, 3.6vw, 48px); line-height: 1.04; }

/* =========================================================================
   LES TROIS PARAGRAPHES QUI NE SONT PAS DU CORPS

   Un article maison ouvre sur un chapo, se ferme sur un renvoi vers le site
   du sujet et sur la mention de ses sources. Les trois etaient rendus comme
   du texte courant : trois fonctions editoriales distinctes, une seule
   apparence, donc aucune. Un lecteur doit voir au premier coup d'oeil ou
   commence l'article et ou finit ce que nous avons verifie.
   ========================================================================= */

/* Le chapeau. Il resume et il annonce le ton — il se lit avant de decider
   de lire. Serif, plus grand que le corps, plus clair que le titre. */
.prose .chapo {
  font-family: var(--serif);
  font-size: clamp(20px, 1.7vw, 24px);
  line-height: 1.45;
  letter-spacing: -0.012em;
  color: var(--steel);
  margin: 0 0 34px;
  padding-bottom: 26px;
  border-bottom: 1px solid rgba(14, 14, 14, 0.12);
}

/* Le renvoi vers le site du club. C'est une recommandation editoriale, pas
   une publicite : elle se distingue du corps sans se deguiser en encart
   sponsorise. Le filet vertical est reserve aux citations, celui-ci prend
   un fond — sinon les deux se confondraient. */
.prose .renvoi {
  background: var(--bone);
  padding: 18px 22px;
  margin: 34px 0 0;
  font-size: 16px;
  line-height: 1.55;
  color: var(--steel);
}
.prose .renvoi a { font-weight: 600; }

/* La mention de source. Elle doit etre lisible et discrete : c'est ce qui
   permet a un lecteur de verifier, et ce qui nous engage. */
.prose .source-note {
  margin: 22px 0 0;
  padding-top: 16px;
  border-top: 1px solid rgba(14, 14, 14, 0.14);
  font-family: var(--ui);
  font-size: 13px;
  line-height: 1.55;
  color: var(--ash);
}

@media (max-width: 600px) {
  .prose .chapo { font-size: 19px; padding-bottom: 20px; margin-bottom: 26px; }
  .prose .renvoi { padding: 16px 18px; font-size: 15px; }
}

/* =========================================================================
   L'OUVERTURE D'UNE PAGE DE LISTE

   Quinze pages de rubrique s'ouvraient sur six cent vingt pixels de vide
   pour annoncer « UFC / 27 articles dans cette rubrique ». Le titre tenait
   seul a gauche d'une page de 1440, la moitie droite ne portait rien, et la
   phrase sous le titre ne disait que ce que la pastille active disait deja.

   Le CMS contenait pourtant, pour chaque rubrique, une ligne ecrite : ce que
   la rubrique couvre et comment on la tient. Elle passe a l'ecran, le
   chiffre passe a droite, et l'ouverture reprend la hauteur qu'elle merite.
   ========================================================================= */

/* Une page de liste s'ouvre sur elle-meme, pas apres une autre section :
   les 120 px qui aerent l'accueil ne separent ici rien de rien. */
section.block-liste { padding-top: 60px; }
section.block > .wrap > .tete-liste { margin-bottom: 40px; }
.tete-liste .lede { max-width: 52ch; margin-top: 16px; }

/* Le compte. En chiffres tabulaires : sur quinze rubriques, les nombres
   s'alignent d'une page a l'autre au lieu de danser. */
.tete-compte {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  margin: 0;
  padding-bottom: 6px;
  flex: 0 0 auto;
}
.tete-compte b {
  font-family: var(--display);
  font-size: clamp(48px, 6vw, 88px);
  font-weight: 600;
  line-height: 0.82;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.tete-compte span {
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
}

@media (max-width: 1100px) {
  section.block-liste { padding-top: 44px; }
}
@media (max-width: 900px) {
  /* Le chiffre passe au-dessus du titre : a droite, il se retrouverait seul
     sur une ligne, et un nombre isole ne veut rien dire. */
  .tete-liste { flex-direction: column-reverse; align-items: flex-start; gap: 18px; }
  .tete-compte { flex-direction: row; align-items: baseline; gap: 9px; padding: 0; }
  .tete-compte b { font-size: 34px; line-height: 1; }
}

/* =========================================================================
   L'OUVERTURE D'UNE PAGE ORGANISATION

   Les sept pages s'ouvraient sur le meme montage : les sept logotypes colles
   cote a cote sur un fond de banque d'images. Sur la page KSW, la premiere
   chose que voyait le lecteur, c'etaient les logos de l'UFC, de ONE et de la
   PFL — l'image mettait en avant les concurrents du sujet.

   Faute de photographie propre a chaque organisation, l'ouverture se compose
   au lieu de s'illustrer. Le sigle occupe la place de la photo, a la meme
   echelle, et porte dessous les trois seuls reperes que le site tient
   vraiment. C'est un choix, pas un manque : un bloc typographique assume dit
   mieux « KSW » qu'une photo qui ne parle pas d'elle.
   ========================================================================= */

.org-ouverture {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: clamp(26px, 4vh, 46px);
  min-height: min(64vh, 560px);
  padding: clamp(34px, 5vw, 62px);
  background: var(--void);
  color: var(--paper);
  overflow: hidden;
}

/* Le sigle est traite comme une marque, pas comme un titre : il est cadre au
   plus juste, et il deborde volontiers la mesure — c'est ce qui lui donne son
   echelle. `min(...)` le ramene dans le cadre quand le mot est long
   (« HEXAGONE » contre « CW »), sans qu'on ait a chiffrer chaque cas. */
.org-sigle {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: min(clamp(60px, 14vw, 190px), 24vw);
  line-height: 0.82;
  letter-spacing: -0.045em;
  color: var(--paper);
  overflow-wrap: anywhere;
}

.org-reperes {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 44px;
  margin: 0;
  padding-top: clamp(20px, 3vh, 32px);
  border-top: 1px solid rgba(247, 244, 238, 0.18);
}
.org-reperes dt {
  font-family: var(--ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 5px;
}
.org-reperes dd {
  margin: 0;
  font-family: var(--ui);
  font-size: clamp(15px, 1.3vw, 18px);
  font-weight: 500;
  color: var(--mist);
  font-variant-numeric: tabular-nums;
}

@media (min-width: 981px) {
  /* Elle prend la place exacte de la photo : meme colonne, meme rangee, et
     la meme sortie de cadre par la droite. */
  .article .org-ouverture {
    grid-column: 2;
    grid-row: 2;
    margin-right: calc((100% - 100vw) / 2);
    padding-right: max(clamp(34px, 5vw, 62px), calc((100vw - 100%) / 2 + 34px));
  }
}
@media (max-width: 980px) {
  .org-ouverture {
    width: min(100% - 40px, var(--read));
    margin: 0 auto 40px;
    min-height: 0;
  }
}

/* =========================================================================
   LA PHOTO D'OUVERTURE SORT DU CADRE — POUR DE BON

   La mise en page de bureau demande depuis le debut que la photo d'article
   deborde par la droite jusqu'au bord de l'ecran : `.article .figure` porte
   un `margin-right: calc((100% - 100vw) / 2)` ecrit pour ca. Il n'a jamais
   rien fait. Deux cents lignes plus bas, `.figure.lead { margin: 0 0 34px }`
   — meme specificite, plus tard dans la feuille — remettait la marge droite
   a zero, et la photo s'arretait pile au bord de la colonne.

   C'est la faute que la regle 26 du registre decrit mot pour mot : une regle
   ecrite sans lire celles qui portent deja le meme selecteur. La marge est
   donc redonnee ici, apres tout le monde, avec de quoi la reconnaitre.

   L'ouverture des pages organisation suit le meme trace : les deux gabarits
   occupent la meme case de la grille, ils doivent finir au meme endroit.
   ========================================================================= */

@media (min-width: 981px) {
  .article > .wrap-read > .figure.lead,
  .article > .wrap-read > .org-ouverture {
    margin-right: calc((100% - 100vw) / 2);
  }
}

/* =========================================================================
   LE BANDEAU DE FRAICHEUR

   Trente-sept fiches de combattant portent en tete « Mise a jour 31 aout
   2026 — statut titre. Cette fiche date de 2025. » C'est exactement ce qu'un
   lecteur veut savoir sur un site de resultats : une ceinture a pu changer
   de proprietaire depuis. Pose dans le fil du texte, en corps 19, il se
   lisait pourtant comme la premiere phrase de l'article.

   Il devient un element de service : filet rouge a gauche, corps reduit,
   sur un fond qui le detache sans crier. Le lecteur voit en un coup d'oeil
   que c'est le site qui parle, pas l'article.
   ========================================================================= */

.prose .maj {
  border-left: 2px solid var(--red);
  background: var(--bone);
  padding: 14px 18px;
  margin: 0 0 30px;
  font-family: var(--ui);
  font-size: 14px;
  line-height: 1.55;
  color: var(--steel);
}
.prose .maj strong {
  display: block;
  font-family: var(--ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 5px;
}
.prose .maj a { font-weight: 600; }

@media (max-width: 600px) {
  .prose .maj { padding: 12px 14px; font-size: 13px; }
}

/* =========================================================================
   LE BOUTON D'EFFACEMENT DU CHAMP DE RECHERCHE

   `<input type="search">` porte une croix dessinee par le navigateur, dans
   sa propre couleur : bleue dans Chrome. Sur une page qui n'a que de l'encre,
   de la creme et du rouge, c'etait le seul objet etranger de tout le site.

   On ne la supprime pas — elle efface le champ et declenche l'evenement que
   la recherche ecoute, gratuitement. On la repeint : le masque remplace son
   image par la notre, et la couleur vient des variables comme le reste.
   ========================================================================= */

.recherche input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  cursor: pointer;
  background-color: var(--ash);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M4 4 L16 16 M16 4 L4 16' stroke='black' stroke-width='2' fill='none' stroke-linecap='round'/></svg>") center / 100% no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M4 4 L16 16 M16 4 L4 16' stroke='black' stroke-width='2' fill='none' stroke-linecap='round'/></svg>") center / 100% no-repeat;
  transition: background-color 0.25s var(--ease);
}
.recherche input[type="search"]:hover::-webkit-search-cancel-button,
.recherche input[type="search"]::-webkit-search-cancel-button:hover {
  background-color: var(--red);
}

/* =========================================================================
   LE DEFILEMENT EST CELUI DU NAVIGATEUR

   Le site embarquait un defilement « lisse » maison : il interceptait la
   molette (`preventDefault`), accumulait une cible et interpolait vers elle
   a 11 % par trame. Mesure sur vingt crans de molette — 2 400 px demandes :
   la page en parcourait 300. Puis la boucle rattrapait d'un coup.

   C'est exactement ce qu'on ressentait : sec au depart, tres lent ensuite,
   et une ruee vers le bas de la page. Le pavé tactile aggravait tout, chaque
   geste envoyant des dizaines d'evenements qui s'additionnaient.

   Aucune interpolation maison ne bat l'inertie que le systeme calcule : elle
   connait la vitesse du geste, le materiel, les reglages d'accessibilite.
   On la rend au navigateur. Le seul lissage qu'on garde est celui des ancres
   internes, qui tient en une ligne — et qui se tait si le lecteur a demande
   moins de mouvement.
   ========================================================================= */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* =========================================================================
   L'OUVERTURE DU DUEL, SUR LA LIGNE DE TEMPS DU DEFILEMENT

   Les deux combattants s'ecartent quand la lecture quitte le heros, et la
   couture s'efface : c'est le geste du debut de soiree. Il etait calcule en
   JavaScript, dans un ecouteur de defilement qui lisait la geometrie puis
   ecrivait un `transform` a chaque trame — le schema exact qui force le
   navigateur a recalculer la mise en page en plein defilement, et qui
   donnait des images « qui bougent bizarrement ».

   `animation-timeline: scroll()` confie la meme chose au compositeur : la
   progression est liee au defilement, pas au fil principal, et rien ne peut
   plus saccader. La ou la propriete n'existe pas encore, la regle entiere
   est ignoree : le heros reste immobile, ce qui est une mise en page — pas
   un defaut.

   L'ecartement est volontairement faible (3,5 % de part et d'autre). Un
   effet qu'on remarque est un effet rate ; celui-ci doit se sentir.
   ========================================================================= */

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes duel-gauche { to { transform: translate3d(-3.5%, 0, 0); } }
    @keyframes duel-droite { to { transform: translate3d(3.5%, 0, 0); } }
    @keyframes duel-couture {
      to { opacity: 0; transform: translate(-50%, -50%) scale(0.88); }
    }

    .hero-cage .hero-man.a,
    .hero-cage .hero-man.b,
    .hero-cage .hero-vs {
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: scroll(root block);
      /* La course se joue sur la premiere hauteur d'ecran : au-dela, le
         heros est hors champ et l'effet n'a plus de spectateur. */
      animation-range: 0 100vh;
    }
    .hero-cage .hero-man.a { animation-name: duel-gauche; }
    .hero-cage .hero-man.b { animation-name: duel-droite; }
    .hero-cage .hero-vs { animation-name: duel-couture; }
  }
}

/* La profondeur des images d'ouverture — le parallaxe — a ete retiree, pas
   deplacee. Elle deplacait l'image de 6 % de sa hauteur pendant le
   defilement, ce qui, additionne au defilement maison, se lisait comme un
   glissement parasite. Une image d'article n'a rien a gagner a flotter. */

/* =========================================================================
   LES LONGUES LISTES NE PEIGNENT QUE CE QU'ON REGARDE

   Le fil complet fait quatre-vingt-douze cartes et dix-sept mille pixels de
   haut. Le navigateur en calculait la mise en page et la peinture en entier,
   y compris les quatre-vingts cartes qu'on ne verra jamais sans defiler :
   22 trames longues sur 136 pendant un defilement, dont cinq au-dela de
   50 ms.

   `content-visibility: auto` laisse le navigateur sauter le travail d'un
   element hors champ. `contain-intrinsic-size` lui donne la hauteur a
   reserver en attendant, sans quoi la barre de defilement sauterait a chaque
   carte qui entre — le remede serait pire que le mal.

   La valeur vient de la mesure : une carte du fil fait 430 px de haut, une
   fiche d'annuaire 390.
   ========================================================================= */

@supports (content-visibility: auto) {
  .cards .card,
  .annuaire .salle,
  .roster > a {
    content-visibility: auto;
  }
  .cards .card { contain-intrinsic-size: auto 430px; }
  .annuaire .salle { contain-intrinsic-size: auto 390px; }
  .roster > a { contain-intrinsic-size: auto 260px; }
  /* La premiere carte porte l'image que le navigateur mesure comme le plus
     grand element de l'ecran : elle ne se saute jamais. */
  .cards .card:first-child { content-visibility: visible; }
}

/* =========================================================================
   RESPONSIVE — affinage telephone / tablette
   Corrige debordements, hauteurs trop hautes, et titres illisibles.
   ========================================================================= */

@media (max-width: 980px) {
  .ed-lead {
    min-height: min(78svh, 720px);
  }
  .ed-lead-copy,
  .ed-bleed-copy {
    padding: 96px 0 48px;
  }
  .ed-lead-copy h2,
  .ed-lead-copy h3,
  .ed-bleed-copy h2 {
    font-size: clamp(30px, 8.4vw, 56px);
    max-width: 18ch;
  }
  .ed-lead-media img {
    object-position: center 22%;
  }
  .ed-aside {
    gap: 36px;
    padding: 28px 0 56px;
  }
  .chiffres {
    gap: 22px 28px;
  }
  .chiffres .compteur b {
    font-size: clamp(28px, 8vw, 44px);
  }
  .salles {
    padding: 56px 0 64px;
  }
  .salles-tete h2 {
    font-size: clamp(28px, 7vw, 48px);
  }
  .hero-foot {
    gap: 16px;
    padding: 18px 20px 24px;
  }
  .hero-actions {
    width: 100%;
  }
  .hero-actions .btn {
    flex: 1 1 auto;
    min-width: 140px;
    justify-content: center;
  }
}

@media (max-width: 600px) {
  .wrap {
    width: calc(100% - 32px);
  }
  .ed-lead {
    min-height: min(72svh, 640px);
  }
  .ed-lead-copy,
  .ed-bleed-copy {
    width: calc(100% - 32px);
    padding: 88px 0 36px;
  }
  .ed-lead-copy p {
    font-size: 12px;
    letter-spacing: 0.1em;
    line-height: 1.45;
  }
  .ed-week .wrap.ed-head {
    padding-top: 56px;
  }
  .ed-head h1,
  .ed-head h2 {
    font-size: clamp(28px, 9vw, 42px);
  }
  .ed-aside-item img {
    height: 200px;
  }
  .ticker {
    grid-template-columns: 44px 1fr;
    min-height: 56px;
  }
  .ticker .tick:nth-child(n+3) {
    display: none;
  }
  .hero-cage {
    min-height: auto;
  }
  .hero-duel {
    min-height: 78svh;
  }
  .hero-man {
    min-height: 39svh;
  }
  .hero-name {
    font-size: clamp(28px, 11vw, 48px);
  }
  .hero-vs {
    top: 50%;
  }
  .hero-foot {
    flex-direction: column;
    align-items: stretch;
  }
  .hero-actions {
    flex-direction: column;
  }
  .hero-actions .btn {
    width: 100%;
  }
  .salle-liens {
    gap: 10px 14px;
  }
  .salle-lire,
  .salle-site {
    font-size: 11px;
  }
  .split-list .row {
    grid-template-columns: 40px 1fr;
    gap: 12px;
  }
  .split-list .rec {
    grid-column: 2;
    margin-top: 4px;
  }
  .roster {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
}

@media (max-width: 400px) {
  .wrap {
    width: calc(100% - 28px);
  }
  .ed-lead-copy h2,
  .ed-lead-copy h3 {
    font-size: clamp(26px, 9vw, 34px);
  }
  .salles-grille,
  .annuaire-grille {
    grid-template-columns: 1fr;
  }
}
