/* ==========================================================================
   Fler — coach de recherche olfactive
   Surcouche applicative du design system Nocturne.
   Nocturne est sombre par défaut ; les maquettes transposent ses jetons sur
   un fond clair. On refait ici la même transposition, puis on rétablit la
   version sombre quand le système de l'utilisateur la demande.
   ========================================================================== */

/* — thème clair (celui des maquettes) — */
:root {
  --color-text: #2a2c34;
  --color-bg: #f4f4f9;
  --color-surface: #ffffff;
  --color-divider: rgba(41, 43, 49, .14);

  --color-accent: #6f61b8;
  --color-accent-400: #a99cf0;
  --color-accent-600: #6f61b8;
  --color-accent-700: #584b9c;
  --color-accent-800: #e6e2fa;
  --color-accent-100: #4a3f86;

  --color-neutral-100: #f4f4f9;
  --color-neutral-700: #595d6c;
  --color-neutral-800: #33353f;

  /* rôles propres à l'app, extraits des valeurs littérales des maquettes */
  --muted: #8d91a3;
  --line: rgba(41, 43, 49, .11);
  --line-soft: rgba(41, 43, 49, .05);
  --fill-soft: rgba(41, 43, 49, .035);
  --fill-bar: rgba(41, 43, 49, .12);
  --chrome: rgba(41, 43, 49, .028);
  --accent-tint: #e9e5fb;
  --accent-line: #796cbf;
  --accent-pale: #cfc9f4;
  --accent-edge: rgba(121, 108, 191, .3);
  --accent-rule: rgba(121, 108, 191, .5);
  --mission-wash: radial-gradient(120% 90% at 15% 0%, #ece9fb 0%, #f6f5fc 62%, #f7f7fb 100%);
  --card-wash: linear-gradient(150deg, #eeebfb, #f7f7fb);
  --shadow-screen: 0 16px 40px rgba(41, 43, 49, .13);
  --veil-top: rgba(244, 244, 249, .55);
  --veil-mid: rgba(244, 244, 249, .15);
  --veil-deep: rgba(244, 244, 249, .92);
  --veil-solid: #f4f4f9;
  /* Issue d'une séance. Nocturne n'a pas de couleur sémantique : ces deux-là
     sont désaturées pour tenir dans une palette de violets doux, un vert et
     une terre cuite plutôt qu'un vert/rouge de signalisation qui jurerait. */
  --ok-fg: #3f7d5a;
  --ok-bg: #e4f0e9;
  --moyen-fg: #8a6d3b;
  --moyen-bg: #f4ecdd;
  --ko-fg: #a8544a;
  --ko-bg: #f6e6e3;
  color-scheme: light;
}

/* — version sombre : on revient aux jetons natifs de Nocturne — */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-text: #e9e9ed;
    --color-bg: #161826;
    --color-surface: #232532;
    --color-divider: color-mix(in srgb, #e9e9ed 16%, transparent);

    --color-accent: #9184d9;
    --color-accent-400: #b5abfc;
    --color-accent-600: #9184d9;
    --color-accent-700: #b5abfc;
    --color-accent-800: #423a6a;
    --color-accent-100: #f5f4ff;

    --color-neutral-100: #f3f5fe;
    --color-neutral-700: #b2b6ca;
    --color-neutral-800: #cfd3e5;

    --muted: #8f93a8;
    --line: rgba(233, 233, 237, .13);
    --line-soft: rgba(233, 233, 237, .07);
    --fill-soft: rgba(233, 233, 237, .045);
    --fill-bar: rgba(233, 233, 237, .14);
    --chrome: rgba(233, 233, 237, .03);
    --accent-tint: #2f2a4d;
    --accent-line: #9184d9;
    --accent-pale: #4a4276;
    --accent-edge: rgba(145, 132, 217, .34);
    --accent-rule: rgba(145, 132, 217, .5);
    --mission-wash: radial-gradient(120% 90% at 15% 0%, #262242 0%, #1d1f30 62%, #1a1c2b 100%);
    --card-wash: linear-gradient(150deg, #232043, #1c1e2d);
    --shadow-screen: 0 16px 40px rgba(0, 0, 0, .55);
    --veil-top: rgba(22, 24, 38, .5);
    --veil-mid: rgba(22, 24, 38, .12);
    --veil-deep: rgba(22, 24, 38, .93);
    --veil-solid: #161826;
    /* Mêmes trois issues, remontées en clarté et posées sur un fond translucide :
       les pastels du thème clair disparaîtraient sur #161826. */
    --ok-fg: #86c8a4;
    --ok-bg: rgba(134, 200, 164, .14);
    --moyen-fg: #d6b681;
    --moyen-bg: rgba(214, 182, 129, .14);
    --ko-fg: #dd9086;
    --ko-bg: rgba(221, 144, 134, .14);
    color-scheme: dark;
  }
}

/* ── ossature ────────────────────────────────────────────────────────── */

html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  font-size: 15px;
  overscroll-behavior-y: none;
}

.app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* La colonne d'écran reprend la largeur des maquettes (390 px) et s'étire
   sur les petits écrans réels. */
.screen {
  flex: 1;
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
  padding: 14px 20px calc(84px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.screen--flush { padding-left: 0; padding-right: 0; }
.screen--flush > *:not(.bleed) { padding-left: 20px; padding-right: 20px; }

/* ── barre d'onglets ─────────────────────────────────────────────────── */

.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: flex;
  padding: 10px 8px calc(14px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: blur(12px);
}
.tabbar a {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 2px 0;
  color: var(--muted);
  text-decoration: none;
  font-size: 9.5px;
  border-radius: 10px;
}
.tabbar a[aria-current="page"] { color: var(--color-accent-600); font-weight: 500; }
.tabbar svg { width: 21px; height: 21px; }

/* ── éléments récurrents ─────────────────────────────────────────────── */

.kicker {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .085em;
  text-transform: uppercase;
  color: var(--color-accent-600);
}
.kicker--muted { color: var(--muted); letter-spacing: .075em; }

.h-screen {
  font-size: 25px;
  font-weight: 500;
  letter-spacing: -.02em;
  margin: 0;
}
.sub { font-size: 12px; color: var(--muted); margin: 4px 0 0; }

.row { display: flex; align-items: center; gap: 10px; }
.row--between { justify-content: space-between; }
.spread { display: flex; justify-content: space-between; align-items: baseline; }
.stack { display: flex; flex-direction: column; gap: 14px; }
.grow { flex: 1; }
.muted { color: var(--muted); }
.tnum { font-variant-numeric: tabular-nums; }

.box {
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 12px 13px;
  background: var(--fill-soft);
}
.box--plain { background: none; }
.box--dashed { border-style: dashed; border-color: var(--accent-edge); background: none; }

/* Filet d'accent : le « conseil du coach » et ses cousins. */
.aside-rule {
  border-left: 2px solid var(--accent-rule);
  padding-left: 13px;
}
.aside-rule--neutral { border-left-color: var(--line); }
.aside-rule p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--color-neutral-800); text-wrap: pretty; }

/* jauges */
.bar {
  height: 4px;
  border-radius: 2px;
  background: var(--fill-bar);
  overflow: hidden;
}
.bar > i { display: block; height: 100%; background: var(--color-accent-600); border-radius: inherit; }
.bar--thin { height: 3px; }
.bar--gradient > i { background: linear-gradient(to right, var(--color-accent-400), var(--color-accent-700)); }

/* listes de compétences */
.skill { display: flex; align-items: center; gap: 10px; }
.skill > span:first-child { width: 126px; font-size: 12px; color: var(--color-neutral-800); }
.skill .bar { flex: 1; }
.skill > span:last-child { width: 26px; text-align: right; font-size: 11.5px; color: var(--muted); }

/* photos : le dégradé du dessous reste visible tant que le JPG est absent,
   ce qui évite toute image cassée avant la livraison des visuels. */
.photo {
  background-repeat: no-repeat;
  background-position: 50% 55%;
  background-size: cover;
  background-color: #ded9f2;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .photo { background-color: #2b2743; }
}
.photo--avatar {
  border-radius: 50%;
  border: 1px solid var(--line);
  flex: none;
  background-image: var(--src), linear-gradient(155deg, var(--accent-pale), var(--color-accent-600));
}
/* Repli en l'absence de photo. Il reste très proche du fond de page : en
   pleine largeur sur mobile, ce bandeau couvre plus d'un tiers de l'écran,
   et un dégradé soutenu y teinterait toute l'interface — alors que sur
   bureau, contenu dans une carte, il passerait inaperçu. Discret des deux
   côtés, donc, pour que la teinte générale soit la même. */
.photo--fill {
  background-image: var(--src),
    radial-gradient(120% 90% at 30% 12%, color-mix(in srgb, var(--accent-pale) 34%, var(--color-bg)) 0%,
      color-mix(in srgb, var(--color-accent-600) 20%, var(--color-bg)) 58%,
      color-mix(in srgb, var(--color-accent-700) 26%, var(--color-bg)) 100%);
}

/* Le voile qui assoit les photos sur le fond — les maquettes le décrivent
   explicitement : pas de mélange lighten, un dégradé sombre à la place. */
.veil { position: absolute; inset: 0; }
.veil--hero {
  background: linear-gradient(to bottom,
    var(--veil-top) 0%, var(--veil-mid) 32%, var(--veil-deep) 82%, var(--veil-solid) 100%);
}
.veil--card { background: linear-gradient(to top, var(--veil-deep) 4%, var(--veil-mid) 62%); }
.veil--tile { background: linear-gradient(to top, var(--veil-deep) 6%, var(--veil-mid) 70%); }
.veil--mission { background: linear-gradient(100deg, var(--veil-deep) 0%, var(--veil-deep) 62%, var(--veil-mid) 78%, transparent 100%); }

/* ── accueil bureau (1o) : la mission prend la place du bandeau chien ──── */
.mission-hero {
  position: relative;
  border: 1px solid var(--accent-edge);
  border-radius: 20px;
  overflow: hidden;
  display: flex;
  min-height: 250px;
}
.mission-hero .photo { position: absolute; inset: 0; }
.mission-hero-body { position: relative; padding: 24px 26px; display: flex; flex-direction: column; gap: 14px; max-width: 560px; }
.mission-hero-title { font-size: 32px; font-weight: 500; letter-spacing: -.025em; line-height: 1.08; }

/* ── accueil ─────────────────────────────────────────────────────────── */

/* Même traitement du bandeau en mobile et en bureau : une carte contenue,
   pas un aplat pleine largeur d'un côté et une vignette de l'autre. */
.hero {
  position: relative;
  height: 300px;
  flex: none;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.hero .photo, .mission-hero .photo { animation: om-kb 26s cubic-bezier(.45,0,.55,1) infinite alternate; will-change: transform; }
.hero .photo { position: absolute; inset: 0; }
.hero-body { position: absolute; left: 20px; right: 20px; bottom: 16px; display: flex; align-items: flex-end; gap: 14px; }
/* Sans photo, le bandeau est un aplat vide sur un tiers du premier écran :
   autant y proposer l'ajout, l'envoi existe déjà sur « Mes chiens ». */
.hero-photo-vide {
  position: absolute; top: 12px; right: 12px;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 11px; border-radius: 999px;
  background: var(--color-bg); border: 1px solid var(--accent-edge);
  color: var(--color-accent-700); font-size: 11.5px; text-decoration: none;
}
.hero-name { font-size: 38px; font-weight: 500; letter-spacing: -.03em; line-height: 1; margin: 6px 0 0; }
.hero-meta { font-size: 12.5px; color: var(--color-neutral-800); margin-top: 6px; }

.stat-strip { display: flex; gap: 8px; }
.stat-strip > div {
  flex: 1;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 11px 6px;
  transition: transform .35s cubic-bezier(.22,.8,.28,1), box-shadow .35s ease;
}
.stat-strip > div:hover { transform: translateY(-3px); box-shadow: 0 8px 18px rgba(41, 43, 49, .09); }
.stat-strip b { display: block; font-size: 19px; font-weight: 500; }
.stat-strip span { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }

.mission-card {
  border: 1px solid var(--accent-edge);
  border-radius: 20px;
  padding: 17px;
  background: var(--mission-wash);
  position: relative;
  overflow: hidden;
  animation: om-fu .8s cubic-bezier(.22,.8,.28,1) .1s both;
}
.mission-title { font-size: 21px; font-weight: 500; letter-spacing: -.02em; margin: 8px 0 0; }

/* CTA de la mission : respiration douce + reflet qui balaie, pour rester
   l'action la plus visible de l'accueil sans clignoter. */
.cta-breathe {
  position: relative; overflow: hidden;
  animation: om-breathe 3.4s cubic-bezier(.4,0,.6,1) 1.4s infinite;
  transition: transform .3s cubic-bezier(.22,.8,.28,1), filter .3s ease;
}
.cta-breathe:hover { transform: translateY(-1px) scale(1.012); filter: brightness(1.06); }
.cta-breathe:active { transform: scale(.985); }
.cta-sweep {
  position: absolute; top: 0; bottom: 0; left: 0; width: 38%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.42), transparent);
  animation: om-sweep 5.4s cubic-bezier(.4,0,.5,1) 2s infinite;
  pointer-events: none;
}

.challenge {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px dashed var(--accent-edge);
  border-radius: 13px;
  padding: 13px 15px;
  color: inherit;
  text-decoration: none;
  transition: border-color .4s ease, background .4s ease, transform .4s cubic-bezier(.22,.8,.28,1);
  animation: om-fu .8s cubic-bezier(.22,.8,.28,1) .2s both;
}
.challenge:hover { border-color: rgba(121, 108, 191, .62); background: rgba(121, 108, 191, .05); transform: translateY(-2px); }
.challenge > svg:first-child { animation: om-float 3.2s cubic-bezier(.4,0,.6,1) infinite; }
.challenge > svg:last-child { animation: om-nudge 2.6s cubic-bezier(.4,0,.6,1) infinite; }

/* ── fiche mission ───────────────────────────────────────────────────── */

.spec { border: 1px solid var(--line); border-radius: 13px; background: var(--fill-soft); overflow: hidden; }
.spec > div {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 14px;
  font-size: 12.5px;
}
.spec > div + div { border-top: 1px solid var(--line-soft); }
.spec dt, .spec > div > span:first-child { color: var(--color-neutral-700); }
.spec > div > span:last-child { font-weight: 500; text-align: right; }
.spec em { font-style: normal; color: var(--color-accent-600); font-weight: 400; }
.spec-label { display: flex; align-items: center; gap: 8px; }
.spec-icon {
  width: 20px; height: 20px; flex: none;
  border-radius: 6px;
  background: var(--accent-tint);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-600);
}

.steps { display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; line-height: 1.5; color: var(--color-neutral-800); }
.steps > div { display: flex; gap: 10px; }
.steps b { color: var(--color-accent-600); font-weight: 400; font-variant-numeric: tabular-nums; }

/* ── séance en cours ─────────────────────────────────────────────────── */

.timer-wrap { display: flex; justify-content: center; margin: 24px 0 8px; }
.timer { position: relative; width: min(264px, 72vw); aspect-ratio: 1; }
.timer svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.timer-face {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
}
.timer-value { font-size: clamp(44px, 15vw, 60px); font-weight: 500; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.chrono-colon { animation: om-blink 1s steps(1,end) infinite; }
.timer-unit { font-size: 11px; letter-spacing: .075em; text-transform: uppercase; color: var(--muted); }

.pulse-status { position: relative; display: inline-flex; width: 10px; height: 10px; flex: none; }
.pulse-dot { position: absolute; inset: 0; border-radius: 50%; background: var(--color-accent-600); }
.pulse-status::before {
  content: ''; position: absolute; inset: 0;
  border-radius: 50%;
  background: var(--color-accent-600);
  animation: pulse-ring 1.8s cubic-bezier(.4, 0, .6, 1) infinite;
}
.pulse-status.is-paused .pulse-dot { background: var(--color-neutral-700); }
.pulse-status.is-paused::before { display: none; }

.mark-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.mark-grid .btn { height: 50px; font-size: 12.5px; border-color: var(--color-divider); }
.mark-grid .btn.is-found { border-color: var(--color-accent-700); color: var(--color-accent-700); }

/* Marquage rapide pendant une recherche extérieure géolocalisée : trois
   marqueurs seulement (pas de bouton « trouvé » dedans, celui-là reste seul
   mis en avant juste en dessous, voir ecranRechercheCarte). */
.mark-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.mark-grid-3 .btn.mark {
  min-height: 44px; height: auto; padding: 6px 4px; font-size: 10.5px; font-weight: 500;
  line-height: 1.25; text-align: center; letter-spacing: 0; border-color: var(--color-divider);
}

.timeline { display: flex; flex-direction: column; }
.timeline-item { position: relative; display: flex; align-items: baseline; gap: 10px; padding: 0 0 14px 21px; }
.timeline-item:last-child { padding-bottom: 0; }
.timeline-item::before {
  content: ''; position: absolute; left: 4px; top: 7px; bottom: -7px; width: 1px;
  background: var(--line);
}
.timeline-item:last-child::before { display: none; }
.timeline-dot {
  position: absolute; left: 0; top: 3px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--color-neutral-700);
}
.timeline-dot.is-found { background: var(--color-accent-600); }
.timeline-time { flex: none; width: 32px; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.timeline-label { font-size: 12.5px; color: var(--color-neutral-800); }

/* ── recherche extérieure géolocalisée ──────────────────────────────────
   Carte plein écran (voir ecranRechercheCarte dans app.js) : bandeau haut
   et fiche flottante, marqueurs Leaflet en L.divIcon pour rester dans le
   même langage visuel que le reste de l'appli plutôt que les pins par
   défaut de Leaflet. */

.live-dot {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500; font-variant-numeric: tabular-nums;
  background: var(--color-surface); padding: 6px 11px; border-radius: 999px; flex: none;
  box-shadow: 0 2px 8px rgba(41,43,49,.14);
}

.pin { position: absolute; transform: translate(-50%, -100%); display: flex; flex-direction: column; align-items: center; gap: 4px; }
.pin-badge {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-accent-600); color: #fff;
  box-shadow: 0 4px 10px rgba(41,43,49,.25);
}
.pin-label {
  font-size: 9.5px; font-weight: 600; color: var(--color-neutral-800);
  background: var(--color-surface); padding: 2px 7px; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 1px 4px rgba(41,43,49,.14);
}
.moi { position: relative; width: 20px; height: 20px; display: grid; place-items: center; }
.moi::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: var(--color-accent-600); opacity: .28;
  animation: pulse-ring 1.8s cubic-bezier(.4, 0, .6, 1) infinite;
}
.moi i {
  width: 13px; height: 13px; border-radius: 50%; background: var(--color-accent-600);
  border: 2px solid var(--color-surface); box-shadow: 0 1px 5px rgba(41,43,49,.3);
}

/* Leaflet est stylé clair par défaut : on aligne ses contrôles sur les
   jetons de l'appli plutôt que de laisser un carré blanc jurer en thème
   sombre. Cible large des boutons de zoom (44px), cohérent avec le reste
   de l'appli tenue à une main dehors, voir plus bas « retour au toucher ». */
.leaflet-bar, .leaflet-bar a {
  background: var(--color-surface); border-color: var(--line) !important; color: var(--color-text);
}
.leaflet-bar a { width: 40px !important; height: 40px !important; line-height: 40px !important; }
.leaflet-bar a:hover { background: var(--fill-soft); }
.leaflet-control-attribution {
  background: color-mix(in srgb, var(--color-surface) 85%, transparent) !important;
  color: var(--muted) !important; font-size: 10px !important;
}
.leaflet-control-attribution a { color: var(--color-accent-600) !important; }

/* ── compte-rendu ────────────────────────────────────────────────────── */

.choice-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.choice {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 12px;
  font-size: 12.5px;
  color: var(--color-neutral-800);
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.choice[aria-pressed="true"] {
  border-color: var(--color-accent-600);
  background: var(--accent-tint);
  color: var(--color-accent-700);
}
.choice svg { width: 15px; height: 15px; flex: none; color: var(--color-accent-600); opacity: 0; }
.choice[aria-pressed="true"] svg { opacity: 1; }

.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  font: inherit;
  font-size: 11px;
  letter-spacing: .02em;
  padding: 3px 10px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
  background: none;
}
.chip[aria-pressed="true"] {
  background: var(--color-accent-800);
  color: var(--color-accent-100);
  border-color: transparent;
}

.stars { display: flex; gap: 5px; background: none; border: 0; padding: 0; cursor: pointer; color: var(--color-accent-600); }
.stars svg { width: 17px; height: 17px; }
.stars .off { color: var(--color-neutral-700); opacity: .5; }

/* ── recommandation ──────────────────────────────────────────────────── */

.reco-card { border: 1px solid var(--accent-edge); border-radius: 20px; overflow: hidden; background: var(--card-wash); }
.reco-head { padding: 16px 17px 14px; border-bottom: 1px solid var(--accent-edge); }
.reco-delta > div {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 17px;
  font-size: 13px;
}
.reco-delta > div + div { border-top: 1px solid var(--line-soft); }
.reco-delta .op { width: 22px; text-align: center; color: var(--color-accent-600); font-size: 15px; }
.reco-delta .same { color: var(--muted); }
.reco-delta .same .op { color: inherit; }
.reco-delta small { font-size: 11.5px; color: var(--muted); }

.medal-badge {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  border: 1px solid var(--color-accent-600);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-600);
  box-shadow: 0 0 22px rgba(121, 108, 191, .22);
}

/* ── historique ──────────────────────────────────────────────────────── */

.entry {
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 13px 15px;
  width: 100%;
  background: none;
  font: inherit;
  color: inherit;
  /* Ces lignes sont des liens : sans cette annulation, tout leur texte est
     souligné, et une suite de libellés soulignés se lit comme un listing de
     fichiers plutôt que comme un journal de séances. */
  text-decoration: none;
  text-align: left;
  cursor: pointer;
}
.entry-title { font-size: 13.5px; margin-top: 2px; }
.entry-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
/* La date passait en gris clair au milieu de la ligne de détails, derrière le
   titre : c'était la seule information qu'on venait chercher et la dernière
   qu'on trouvait. Elle prend la première ligne, en pleine encre. */
.entry-date { font-size: 11.5px; font-weight: 600; letter-spacing: .01em; }
.entry-date .heure { font-weight: 400; color: var(--muted); }

/* Issue d'une séance : « Réussite complète » et « Échec » étaient deux
   libellés de plus dans une ligne qui en portait déjà quatre, donc illisibles
   d'un coup d'œil. Couleur + icône se trient sans lecture ; le libellé reste
   dans title/aria-label, et en toutes lettres sur la fiche de séance. */
.issue {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--issue-bg);
  color: var(--issue-fg);
}
.issue--ok { --issue-fg: var(--ok-fg); --issue-bg: var(--ok-bg); }
.issue--moyen { --issue-fg: var(--moyen-fg); --issue-bg: var(--moyen-bg); }
.issue--ko { --issue-fg: var(--ko-fg); --issue-bg: var(--ko-bg); }
.issue-tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px 4px 7px;
  border-radius: 999px;
  font-size: 11px; font-weight: 500;
  background: var(--issue-bg);
  color: var(--issue-fg);
}

/* Série d'échecs : dit avant la liste, avec la sortie de secours. */
.alerte-echecs {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--ko-fg) 34%, transparent);
  border-radius: 13px;
  background: var(--ko-bg);
  text-decoration: none;
  color: inherit;
}
.alerte-echecs p { margin: 0; font-size: 12.5px; line-height: 1.5; text-wrap: pretty; }
.alerte-echecs strong { font-weight: 600; color: var(--ko-fg); }
.alerte-echecs .suite { display: block; margin-top: 3px; font-size: 11.5px; color: var(--muted); }
.entry--open {
  display: block;
  border-color: var(--accent-edge);
  background: var(--card-wash);
  padding: 0;
  cursor: default;
}
.entry--open .entry-head { padding: 14px 15px 12px; }
.entry--open .entry-body { padding: 0 15px 14px; display: flex; flex-direction: column; gap: 11px; }
.quote {
  font-size: 12px; line-height: 1.5;
  color: var(--color-neutral-800);
  border-left: 2px solid var(--line);
  padding-left: 11px;
}

/* ── apprendre ───────────────────────────────────────────────────────── */

.feature { border: 1px solid var(--line); border-radius: 13px; overflow: hidden; background: var(--fill-soft); }
.feature-media { position: relative; height: 140px; }
.feature-media .photo { position: absolute; inset: 0; }
.feature-text { position: absolute; left: 15px; right: 15px; bottom: 13px; }
.feature-title { font-size: 17px; font-weight: 500; margin-top: 4px; text-wrap: pretty; }

.listrow {
  display: flex; gap: 12px; align-items: center;
  border: 1px solid var(--line);
  border-radius: 13px;
  padding: 12px 13px;
  color: inherit; text-decoration: none;
}
.listrow-icon {
  width: 38px; height: 38px; flex: none;
  border-radius: 9px;
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-600);
}
.listrow svg.chev { width: 16px; height: 16px; color: var(--muted); flex: none; }

/* ── mode ludique ────────────────────────────────────────────────────── */

.segmented {
  display: flex;
  padding: 4px;
  border-radius: 14px;
  background: var(--fill-soft);
  font-size: 12.5px;
}
.segmented a {
  flex: 1; text-align: center; padding: 9px 0;
  border-radius: 11px;
  color: var(--color-neutral-700);
  text-decoration: none;
}
.segmented a[aria-current="page"] { background: var(--accent-tint); color: var(--color-accent-700); }

.play-hero {
  border-radius: 20px;
  padding: 20px 18px;
  background: radial-gradient(130% 100% at 12% 0%, rgba(121, 108, 191, .13) 0%, var(--fill-soft) 60%, var(--fill-soft) 100%);
}
.game {
  display: flex; align-items: center; gap: 13px;
  border-radius: 16px;
  padding: 14px 15px;
  background: var(--fill-soft);
  width: 100%;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.game-icon {
  width: 40px; height: 40px; flex: none;
  border-radius: 13px;
  background: rgba(121, 108, 191, .1);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-700);
}

/* ── écran badge ─────────────────────────────────────────────────────── */

.badge-veil {
  position: fixed; inset: 0; z-index: 60;
  background: color-mix(in srgb, var(--color-bg) 72%, transparent);
  backdrop-filter: blur(3px);
  display: grid; place-items: center;
  padding: 26px;
  animation: fade .28s ease both;
}
.badge-card {
  width: min(360px, 100%);
  border: 1px solid var(--color-divider);
  border-radius: 20px;
  background: var(--color-bg);
  box-shadow: 0 20px 48px rgba(41, 43, 49, .18);
  padding: 26px 22px;
  text-align: center;
  animation: om-pop .75s cubic-bezier(.2, 1.1, .3, 1) .12s both;
}
.badge-medal {
  width: 88px; height: 88px; margin: 0 auto 16px;
  border-radius: 50%;
  border: 1px solid var(--color-accent-600);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-600);
  background: radial-gradient(circle, var(--accent-tint), transparent 70%);
  box-shadow: 0 0 46px rgba(121, 108, 191, .24);
  animation: om-pop .8s cubic-bezier(.2, 1.15, .3, 1) .3s both, om-float 4s cubic-bezier(.4,0,.6,1) 1.1s infinite;
}
.badge-medal svg { animation: om-shine 3s ease-in-out 1.2s infinite; }
.badge-strip { display: flex; justify-content: center; gap: 8px; margin: 18px 0 20px; }
.badge-strip span {
  width: 44px; height: 44px;
  border-radius: 13px;
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--muted);
  font-size: 11px;
}
.badge-strip span.won { border-color: var(--color-accent-700); color: var(--color-accent-600); }
.badge-strip span.rest { border-style: dashed; color: var(--color-neutral-700); }

/* ── écran changement de palier ──────────────────────────────────────── */

.palier-card {
  width: min(360px, 100%);
  border: 1px solid var(--color-accent-700);
  border-radius: 22px;
  background: linear-gradient(160deg, var(--accent-tint), var(--color-bg) 60%);
  box-shadow: 0 24px 56px rgba(41, 43, 49, .22);
  padding: 30px 22px 26px;
  text-align: center;
  animation: om-pop .75s cubic-bezier(.2, 1.1, .3, 1) .1s both;
}
.palier-burst { position: relative; width: 108px; height: 108px; margin: 0 auto 14px; }
.palier-medal {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1px solid var(--color-accent-600);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-600);
  background: radial-gradient(circle, var(--accent-tint), transparent 70%);
  box-shadow: 0 0 52px rgba(121, 108, 191, .32);
  animation: om-pop .8s cubic-bezier(.2, 1.15, .3, 1) .28s both, om-float 4s cubic-bezier(.4,0,.6,1) 1.1s infinite;
}
.palier-medal svg { animation: om-shine 2.6s ease-in-out 1.1s infinite; }
.confetti {
  position: absolute; top: 50%; left: 50%; width: 7px; height: 7px; border-radius: 2px;
  background: var(--accent-line);
  transform: translate(-50%, -50%) rotate(var(--a)) translateY(0) rotate(calc(var(--a) * -1));
  opacity: 0;
  animation: om-confetti var(--t, 1.1s) cubic-bezier(.18,.72,.32,1) .15s both;
}
.confetti:nth-child(3n) { background: var(--color-accent-400); width: 6px; height: 6px; }
.confetti:nth-child(4n) { background: var(--accent-pale); width: 5px; height: 9px; border-radius: 3px; }

@keyframes om-confetti {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(var(--a)) translateY(0) rotate(calc(var(--a) * -1)) scale(.4); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--r) * -1)) rotate(calc(var(--a) * -1)) scale(1); }
}

@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes rise { from { opacity: 0; transform: translateY(14px) scale(.97) } to { opacity: 1; transform: none } }

/* Animations de la maquette « Recherche olfactive » (accueil, chronos,
   badge débloqué) — voir jauge()/anneau()/carteMission() dans app.js. */
@keyframes om-kb { from { transform: scale(1) translateY(0) } to { transform: scale(1.08) translateY(-1.5%) } }
@keyframes om-fu { from { opacity: 0; transform: translateY(16px) } to { opacity: 1; transform: none } }
@keyframes om-draw { from { stroke-dashoffset: var(--dash, 340) } to { stroke-dashoffset: 0 } }
@keyframes om-grow { from { transform: scaleX(0) } to { transform: scaleX(1) } }
@keyframes om-pulse { 0%, 100% { transform: scale(1) } 50% { transform: scale(1.14) } }
@keyframes om-breathe { 0%, 100% { box-shadow: 0 0 0 0 rgba(121,108,191,.26) } 50% { box-shadow: 0 0 0 9px rgba(121,108,191,0) } }
@keyframes om-sweep { 0% { transform: translateX(-130%) } 45%, 100% { transform: translateX(240%) } }
@keyframes om-nudge { 0%, 100% { transform: translateX(0) } 50% { transform: translateX(5px) } }
@keyframes om-ring { 0% { transform: scale(.85); opacity: .45 } 100% { transform: scale(2.1); opacity: 0 } }
@keyframes om-pop { 0% { transform: scale(.55); opacity: 0 } 62% { transform: scale(1.07); opacity: 1 } 100% { transform: scale(1); opacity: 1 } }
@keyframes om-blink { 0%, 45% { opacity: 1 } 55%, 100% { opacity: .25 } }
@keyframes om-float { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-5px) } }
@keyframes om-shine { 0%, 100% { opacity: .35 } 50% { opacity: .9 } }
@keyframes pulse-ring { 0% { transform: scale(1); opacity: .55 } 100% { transform: scale(2.6); opacity: 0 } }

/* ── entrée d'écran ──────────────────────────────────────────────────── */
/* `rise` existait sans avoir jamais été branchée : c'est elle qui donne son
   liant à la navigation, jusqu'ici sèche d'un écran à l'autre.
   Le conteneur `.screen` n'est délibérément pas animé lui-même : une
   transformation sur un ancêtre redéfinit le référentiel des descendants
   `position:fixed`, et la barre d'action basse sauterait pendant toute la
   transition. Ce sont donc les blocs de contenu qui entrent, ce qui se lit
   d'ailleurs mieux qu'un plan entier qui glisse d'un bloc.
   La classe n'est posée que sur une vraie navigation (voir `rendre()`), pas
   sur les re-rendus du même écran comme le tick du chrono. */
.screen--entree > *:not(.actionbar) {
  animation: rise .34s cubic-bezier(.22, .8, .28, 1) both;
}
.screen--entree > *:nth-child(2) { animation-delay: .04s; }
.screen--entree > *:nth-child(3) { animation-delay: .08s; }
.screen--entree > *:nth-child(n+4) { animation-delay: .11s; }

/* Les huit barres de compétences arrivaient d'un bloc, déjà remplies, sur un
   écran qui ne bouge pas : elles se dessinent maintenant en cascade, avec la
   même `om-grow` que la barre de difficulté de la mission. Le décalage par
   barre est posé en ligne, à la construction de la liste. */
.skill .bar > i { transform-origin: left; }

/* Retour au toucher : l'app se tient à une main, dehors, souvent avec des
   gants ; un enfoncement franc vaut mieux qu'un simple survol, qui n'existe
   pas là-bas. `.cta-breathe` avait déjà ce traitement, il est généralisé. */
.btn, .chip, .listrow, .seg-opt, .tabbar a, .card-tap {
  transition: transform .16s cubic-bezier(.22, .8, .28, 1);
}
.btn:active, .chip:active, .listrow:active, .seg-opt:active, .card-tap:active { transform: scale(.972); }
.tabbar a:active { transform: scale(.93); }

/* L'onglet qui devient actif marque le coup, brièvement. */
.tabbar a[aria-current="page"] svg { animation: om-pop .34s cubic-bezier(.2, 1.1, .3, 1) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
}

/* ── barre d'action basse ────────────────────────────────────────────── */

.actionbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 45;
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 14px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--color-bg) 94%, transparent);
  backdrop-filter: blur(12px);
}
.actionbar > .btn { min-height: 46px; }
.actionbar .btn-primary { flex: 1; letter-spacing: .05em; }
.has-actionbar .screen { padding-bottom: calc(104px + env(safe-area-inset-bottom, 0px)); }
.has-actionbar .tabbar { display: none; }
@media (min-width: 1100px) {
  .actionbar { position: static; border: 0; background: none; backdrop-filter: none; padding: 0; }
  .has-actionbar .screen { padding-bottom: 40px; }
}

/* Cas particulier : certains écrans avec barre d'action gardent quand même
   les onglets visibles (ex. « Créer ma séance », pour rester cohérent avec
   ses deux écrans voisins du même groupe segmenté qui les montrent). La
   barre d'action remonte au-dessus de la barre d'onglets plutôt que de la
   recouvrir. */
/* La hauteur de la barre d'onglets était estimée ici à 84 px alors qu'elle en
   fait 69 : la barre d'action flottait 15 px trop haut et le contenu défilait
   à nu dans la bande ainsi ouverte entre les deux. Elle est donc mesurée à
   l'exécution (`majHauteurOnglets`), ce qui suit aussi la zone sûre de
   l'appareil et la taille de police système. La valeur de repli ne sert qu'au
   premier rendu, avant la première mesure.
   La mesure inclut déjà `env(safe-area-inset-bottom)`, présent dans le
   padding de la barre : le rajouter reviendrait à le compter deux fois, ce
   que faisait l'ancien calcul de remplissage. */
@media (max-width: 1099px) {
  .has-actionbar.tabs-avec-actionbar .tabbar { display: flex; }
  .has-actionbar.tabs-avec-actionbar .actionbar { bottom: var(--h-tabbar, 69px); }
  .has-actionbar.tabs-avec-actionbar .screen { padding-bottom: calc(104px + var(--h-tabbar, 69px)); }
}

/* Les boutons de Nocturne sont en contour ; on garde le contour et on
   élargit seulement la surface tactile. */
.btn { min-height: 40px; }
.btn-block { padding: 13px; font-size: 13px; letter-spacing: .06em; }

/* ── écrans nus (connexion, premier chien) ───────────────────────────── */
/* Pas d'onglets ni de barre latérale tant qu'il n'y a pas de compte. */

body.nu .tabbar,
body.nu .sidebar,
body.nu .topbar { display: none; }
/* La barre d'onglets est masquée ici : sa réserve de place en bas laissait
   le formulaire collé en haut avec la moitié de l'écran vide en dessous,
   sur le tout premier écran que voit un visiteur. `safe` évite de rogner le
   haut du formulaire quand il dépasse la hauteur disponible (clavier ouvert,
   écran court) ; les moteurs qui ne le connaissent pas gardent l'alignement
   en haut, c'est-à-dire le comportement actuel. */
/* `.screen` porte `flex:1`, mais son parent `.main` n'est pas lui-même un
   conteneur flex extensible : sans ces deux lignes la colonne ne fait que la
   hauteur de son contenu, et le centrage ci-dessous n'a rien à centrer.
   `align-items: center` est nécessaire pour le centrage horizontal sur grand
   écran : les marges auto de `.screen` ne suffisent pas dans un conteneur en
   colonne (sur PC, le formulaire de connexion restait collé à gauche).
   Cantonné aux écrans nus pour ne rien changer à la mise en page connectée. */
body.nu .main { flex: 1; display: flex; flex-direction: column; align-items: center; }
body.nu .screen {
  max-width: 430px;
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  justify-content: safe center;
}
/* « Nouveau chien » est un écran nu QUI A AUSSI une barre d'action fixe (le
   bouton « Créer le profil ») : sans ce correctif, le padding-bottom de 24px
   ci-dessus ne réservait pas la place de cette barre (104px, voir
   `.has-actionbar .screen` plus haut), et les dernières puces du formulaire
   (Objectif) se retrouvaient invisibles ET inatteignables au scroll, cachées
   sous le bouton — vérifié en conditions réelles (Playwright, la puce
   « Découverte » n'était ni visible ni cliquable au scroll maximum). */
body.nu.has-actionbar .screen {
  padding-bottom: calc(104px + env(safe-area-inset-bottom, 0px));
}

/* ── bandeau d'information ───────────────────────────────────────────── */

#bandeau {
  position: fixed;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 12px);
  z-index: 70;
  max-width: min(380px, calc(100vw - 32px));
  padding: 11px 16px;
  border-radius: 12px;
  background: var(--color-neutral-900);
  color: var(--color-neutral-100);
  font-size: 12.5px;
  line-height: 1.45;
  text-align: center;
  box-shadow: 0 10px 30px rgba(41, 43, 49, .28);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
}
#bandeau.visible { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #bandeau { background: #e9e9ed; color: #161826; }
}

/* ── mise à jour disponible ──────────────────────────────────────────── */
/* Contrairement au bandeau ci-dessus, reste affiché tant qu'on n'a pas
   actualisé : une nouvelle version silencieusement active en arrière-plan
   sans qu'on le sache mène à une interface incohérente (JS neuf, CSS ancien
   ou l'inverse selon ce qui était en cache au moment de la bascule). */
#maj-dispo {
  position: fixed; left: 0; right: 0; top: 0;
  z-index: 80;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 10px 16px;
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
  background: var(--color-accent-600);
  color: #fff;
  font-size: 12.5px;
}
#maj-dispo[hidden] { display: none; }
#maj-dispo button {
  border: 1px solid rgba(255, 255, 255, .55);
  background: none;
  color: #fff;
  border-radius: 8px;
  padding: 5px 13px;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}

/* ── curseurs de réglage ─────────────────────────────────────────────── */

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 26px;
  background: none;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: var(--fill-bar);
}
input[type="range"]::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--fill-bar);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -9px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 2px solid var(--color-accent-600);
  box-shadow: 0 1px 4px rgba(41, 43, 49, .2);
}
input[type="range"]::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 2px solid var(--color-accent-600);
}
input[type="range"]:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* ── barre d'état simulée ────────────────────────────────────────────── */
/* Les maquettes montrent 9:41 / 84 % : c'est le chrome de l'iPhone, pas de
   l'app. On ne le rejoue pas dans le navigateur. */

/* ── version bureau (écran 1o) ───────────────────────────────────────── */

.sidebar { display: none; }
.topbar { display: none; }

@media (min-width: 1100px) {
  .app { flex-direction: row; }

  .sidebar {
    display: flex;
    flex-direction: column;
    gap: 26px;
    width: 240px;
    flex: none;
    padding: 22px 16px;
    border-right: 1px solid var(--line-soft);
    background: var(--chrome);
    position: sticky;
    top: 0;
    height: 100dvh;
  }
  .brand { display: flex; align-items: center; gap: 9px; padding-left: 6px; }
  .brand-mark {
    width: 26px; height: 26px;
    border-radius: 7px;
    border: 1px solid var(--color-accent-600);
    display: flex; align-items: center; justify-content: center;
    color: var(--color-accent-600);
  }
  .brand-name { font-size: 14px; font-weight: 500; letter-spacing: -.01em; }

  .sidenav { display: flex; flex-direction: column; gap: 3px; }
  .sidenav a {
    display: flex; align-items: center; gap: 11px;
    padding: 9px 11px;
    border-radius: 13px;
    color: var(--color-neutral-700);
    text-decoration: none;
    font-size: 13px;
  }
  .sidenav a:hover { background: var(--fill-soft); }
  .sidenav a[aria-current="page"] { background: var(--accent-tint); color: var(--color-accent-700); }
  .sidenav svg { width: 17px; height: 17px; }

  .side-dogs { margin-top: auto; display: flex; flex-direction: column; gap: 9px; }
  .side-dog {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px;
    border-radius: 13px;
    color: inherit; text-decoration: none;
  }
  .side-dog.is-active { border: 1px solid var(--line); }
  .side-dog:not(.is-active) { opacity: .55; }

  .tabbar { display: none; }

  .main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
  .topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 18px 30px;
    border-bottom: 1px solid var(--line-soft);
  }
  .topbar h1 { font-size: 22px; font-weight: 500; letter-spacing: -.02em; margin: 3px 0 0; }
  .pill {
    display: flex; align-items: center; gap: 6px;
    padding: 7px 12px;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 12.5px;
  }
  .pill--accent { color: var(--color-accent-600); }

  .screen {
    max-width: 1180px;
    margin: 0;
    padding: 22px 30px 40px;
    gap: 18px;
  }
  .screen--flush > *:not(.bleed) { padding-left: 0; padding-right: 0; }

  /* L'accueil passe en deux colonnes : la mission garde la vedette,
     le contexte (conseil, dernières séances) se déplie à droite. Les deux
     colonnes s'étirent à la même hauteur (comme dans 1o) : la paire de
     cartes grandit pour combler l'espace, et le dernier bloc de la colonne
     de droite se cale en bas plutôt que de laisser un vide sous une
     colonne plus courte. */
  .desk { display: grid; grid-template-columns: minmax(0, 1.55fr) 300px; gap: 22px; align-items: stretch; }
  .desk-side { display: flex; flex-direction: column; gap: 16px; }
  .desk-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; flex: 1; }
  .desk-side .challenge { margin-top: auto; }
  .desk-hide { display: none; }

  .hero { height: 260px; }
}

@media (max-width: 1099px) {
  .desk-side .desk-only { display: none; }
  .desk-mobile-hide { display: none; }
  /* Sur mobile, seul le défi "Envie de jouer ?" reste visible dans
     .desk-side : sans marge, il colle directement sous le bouton
     "Commencer l'entraînement" de la carte mission. */
  .desk-side { margin-top: 18px; }
}
