/* === En Zistoir Design System v5.0 — « Kolaz Vakans » (La Réunion) ===
   Direction « carnet de vacances / scrapbook » : papier kraft #f3e9d7 à texture
   pointillée, encre brun chaud #33302a, accent rouge (rouge dominant du logo) #a02a1a + jaune washi #ffe082.
   Photos « scotchées » légèrement inclinées, ruban adhésif (washi tape), bords
   pointillés, notes manuscrites (Caveat), ombres DOUCES (pas d'ombre dure). Typo :
   Bricolage Grotesque (titres/corps) + Caveat (accents manuscrits : notes, CTA, scores).

   ┌─────────────────────────────────────────────────────────────────────┐
   │  FICHIER DE THÈME — ne pas éditer la copie active `css/app.css`.     │
   │  Source de vérité : `css/themes/kolaz-vakans/app.css`.               │
   │  Bascule / retour arrière :  scripts/switch-theme.sh <thème>         │
   │  Thèmes archivés : arcade-tropikal · zournal-kreol (Web) · tizor (Maui) │
   └─────────────────────────────────────────────────────────────────────┘

   Architecture de tokens conservée : les noms existants (--bg/--ink/--ember/--tz-*…)
   sont remis à la palette Kolaz Vakans → propagation automatique. Couleurs de marque
   brutes sous --tz-* ; tokens spécifiques Kolaz sous --kv-* ; traitements de surface
   des primitives sous --ui-*. */

/* ── Palette Kolaz Vakans (default) ── */
:root {
  /* Brand ramp — accent rouge (rouge dominant du logo) + jaune washi, secondaires pastel/sauge */
  --tz-teal-d:  #5b7a6e;   /* sauge profonde */
  --tz-teal:    #7a8f85;   /* sauge (tampons « VALIDÉ ») */
  --tz-green:   #2e5243;   /* vert profond (rareté « commune ») */
  --tz-green-d: #2e5243;
  --tz-coral:   #a02a1a;   /* ROUGE (logo) — accent primaire : CTA, liens, scores */
  --tz-coral-d: #7c1c14;
  --tz-gold:    #ffe082;   /* JAUNE washi tape / surligneur */
  --tz-amber:   #e0a54d;
  --tz-purple:  #5b3f6e;   /* prune (rareté « épique ») */
  --tz-sky:     #6aa9c0;

  /* Surfaces — papier kraft + cartes/photos blanches */
  --bg:         #f3e9d7;
  --bg-soft:    #ede1cb;
  --bg-card:    #ffffff;

  /* Ink / text — brun chaud */
  --ink:        #33302a;
  --ink-soft:   #6b6559;   /* corps */
  --muted:      #a39a87;   /* notes manuscrites, méta discrète */
  --muted-2:    #b8ae99;

  /* Lines — filets kraft & bords pointillés */
  --line:        #efe6d2;
  --line-strong: #d9cbb2;  /* couleur des bords pointillés */

  /* Semantic accents (legacy aliases) */
  --canopy:      #7a8f85;
  --canopy-soft: #e5ede9;
  --ember:       #a02a1a;  /* rouge (logo) — accent signature */
  --ember-soft:  #f4e0da;

  /* Typography — Kolaz Vakans */
  --font-sans:  'Bricolage Grotesque', system-ui, -apple-system, sans-serif; /* corps 500, titres 800 */
  --font-serif: 'Bricolage Grotesque', system-ui, sans-serif;                /* display = grotesque gras */
  --font-hand:  'Caveat', 'Bricolage Grotesque', cursive;                    /* accents manuscrits */
  --font-mono:  ui-monospace, 'Spline Sans Mono', SFMono-Regular, monospace; /* data légère */

  /* Radii — Kolaz est « papier découpé » : coins nets */
  --r-sm: 3px;
  --r:    4px;
  --r-lg: 5px;
  --r-xl: 6px;

  /* Elevation — ombres DOUCES (photo soulevée), teintées encre chaude */
  --tz-shadow:    0 14px 32px -16px rgba(51,48,42,.45);
  --tz-shadow-lg: 0 18px 44px -20px rgba(51,48,42,.55);
  --tz-grad-brand: linear-gradient(120deg,#a02a1a,#c04a34);
  --tz-grad-page:  #f3e9d7;  /* fond uni ; la texture pointillée est posée sur <body> */

  /* ── Tokens spécifiques Kolaz Vakans (--kv-*) ── */
  --kv-paper:   #f3e9d7;
  --kv-ink:     #33302a;
  --kv-rose:    #a02a1a;
  --kv-jaune:   #ffe082;
  --kv-sage:    #7a8f85;
  --kv-dash:    #d9cbb2;
  --kv-note:    #a39a87;   /* gris des notes manuscrites */
  /* Ruban adhésif (washi tape) — rectangles semi-transparents posés sur les cartes */
  --kv-tape-jaune: rgba(255,224,130,.85);
  --kv-tape-rose:  rgba(160,42,26,.40);
  --kv-tape-mint:  rgba(205,228,218,.90);
  /* Aplats pastel des vignettes/photos (dégradés hachurés posés en ligne dans les pages) */
  --kv-mint:    #cde4da;
  --kv-peach:   #f4d9c2;
  --kv-lavender:#e4d2ec;
  --kv-aqua:    #c9e6ef;
  /* Ombres */
  --kv-shadow-photo: 0 18px 38px -16px rgba(51,48,42,.55);
  --kv-shadow-soft:  0 12px 28px -12px rgba(51,48,42,.40);
  --kv-shadow-tab:   3px 3px 0 rgba(51,48,42,.20);   /* petite ombre nette des chips/icônes bordées */
  /* Texture pointillée du papier */
  --kv-dots: radial-gradient(rgba(51,48,42,.05) 1.2px, transparent 1.2px);

  /* ── Traitements de surface consommés par les primitives (--ui-*) ──
     En Kolaz, les éléments bordés portent une fine bordure encre + une petite
     ombre nette (3px), pas l'ombre dure décalée d'Arcade. Repli = rendu legacy. */
  --ui-stroke:            var(--kv-ink);
  --ui-btn-border:        2px solid var(--kv-ink);
  --ui-btn-shadow:        var(--kv-shadow-tab);
  --ui-btn-shadow-active: 1px 1px 0 rgba(51,48,42,.20);
  --ui-chip-border:       2px solid var(--kv-ink);
  --ui-chip-shadow:       3px 3px 0 rgba(51,48,42,.16);
  --ui-badge-border:      none;
  --ui-badge-shadow:      0 4px 10px -6px rgba(51,48,42,.4);
}

/* ── Palette Cirques (variante fraîche) ── */
[data-palette="cirques"] {
  --canopy:     #5b7a86;
  --canopy-soft:#e2edf0;
  --ember:      #6aa9c0;
  --ember-soft: #e4f1f5;
}

/* ── Palette Volcan (variante chaude) ── */
[data-palette="volcan"] {
  --canopy:     #c2694a;
  --canopy-soft:#f6e3d8;
  --ember:      #a02a1a;
  --ember-soft: #f4e0da;
}

/* ── Reset & Base ── */
*, *::before, *::after { box-sizing: border-box; }
html, body, #root { height: 100%; }

body {
  background-color: var(--bg);
  background-image: var(--kv-dots);
  background-size: 22px 22px;
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  margin: 0;
  padding: 0;
}

button { font: inherit; color: inherit; cursor: pointer; }
a { color: inherit; }
input, textarea, select { font: inherit; color: inherit; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--ember) !important; }

/* ── Typography ──
   .display rend Bricolage Grotesque (gras 800, serré). L'emphase <em> devient un
   surlignage jaune washi (façon feutre), sans italique. Un utilitaire .hand rend
   les accents manuscrits en Caveat. */
.display {
  font-family: var(--font-serif);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.03;
  color: var(--ink);
}
.display em {
  font-style: normal;
  background: var(--kv-jaune);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  padding: 0 .16em;
}

.hand { font-family: var(--font-hand); font-weight: 700; color: var(--kv-rose); }

.mono {
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.hairline { background: var(--line); height: 1px; width: 100%; }

/* ── Responsive visibility ── */
.th-hide-desktop { display: none; }
.th-hide-mobile { display: initial; }
.th-brand-sub { display: inline; }
@media (max-width: 1180px) { .th-brand-sub { display: none; } }
@media (max-width: 1024px) { .th-conn-label { display: none; } }

/* ── Page sections fill the column-flex <main> ──
   MainLayout's <main> is a column flex container (display:flex; flex-direction:column).
   Page section wrappers use `max-width:…; margin:0 auto` to cap-and-center their content.
   In flexbox, horizontal `auto` margins disable the default `align-items:stretch`, so such
   a wrapper collapses to its content's max-content width instead of spanning the row — e.g.
   the home "À la une" flex card (flex bases 280px + 320px) shrank to ~600px and centered,
   while the 3 concept cards above it (a grid with wide text) stayed near full width, leaving
   them visibly misaligned. The same caused the Pro "formules" grid to shrink under its hero.
   Forcing width:100% restores full-width behavior — still capped by each wrapper's own
   max-width and centered by its margin:auto. Targets only MainLayout (AuthLayout uses a div). */
main > * { width: 100%; }

/* ── Layout utilities ── */
.th-row-stack { display: grid; gap: 64px; align-items: end; }
.th-row-stack.cols-58 { grid-template-columns: 1.4fr 1fr; }
.th-row-stack.cols-eq { grid-template-columns: 1fr 1fr; }

.th-stats { display: grid; gap: 24px; }
.th-stats.cols-5 { grid-template-columns: repeat(5, 1fr); }
.th-stats.cols-4 { grid-template-columns: repeat(4, 1fr); }

.th-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.th-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 640px) { .th-grid-3 { grid-template-columns: 1fr; } }
.th-grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; }
.th-home-popular { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
@media (max-width: 900px) { .th-home-popular { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .th-home-popular { grid-template-columns: 1fr; } }
.th-editor-split { display: grid; grid-template-columns: 380px 1fr 320px; flex: 1; min-height: 0; }
.th-recap-grid { display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr; }
.th-recap-bottom { display: grid; grid-template-columns: 1.2fr 1fr; gap: 24px; }
.th-pad-page { padding: 0 28px 80px; }

/* ── Fluid headline sizes ── */
.th-hero-headline { font-size: clamp(36px, 6.4vw, 64px); }
.th-detail-headline { font-size: clamp(32px, 5.5vw, 56px); }
.th-section-headline { font-size: clamp(26px, 3.6vw, 48px); }
.th-play-headline { font-size: clamp(26px, 3.6vw, 42px); }
.th-recap-headline { font-size: clamp(34px, 5.6vw, 64px); }
/* Page indice mobile : titre d'étape un peu plus discret que le clamp desktop ci-dessus. */
@media (max-width: 900px) {
  .th-play-headline { font-size: clamp(19px, 5.2vw, 24px); }
}

/* ── Shell row ── */
.th-shell-row {
  max-width: 1440px;
  margin: 0 auto;
  height: 60px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  gap: 16px;
}

/* ── Chasse "mode jeu" (mobile) ──
   /chasse/{id} une fois la session du joueur démarrée : la mise en page desktop reste
   inchangée, mais sous 900px elle cède la place à un shell dédié carte/collection/photo
   (voir GameModeState + ChasseDetail.razor). Volontairement sans `display: initial`
   pour ne jamais affecter le rendu desktop, contrairement à .th-hide-mobile. */
.th-game-hide-mobile { }
@media (max-width: 900px) {
  .th-game-hide-mobile { display: none !important; }
}
.th-game-shell {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
@media (max-width: 900px) {
  /* Verrouillage de la racine à 100dvh (voir .th-game-root) : le header/footer/barre du bas
     globaux sont masqués sur mobile pendant le jeu, le shell remplit donc tout l'écran. Une
     hauteur *définitive* remonte ainsi la chaîne flex (root → main → .th-game-shell →
     .th-play2-shell → conteneur carte), ce qui permet à la carte Leaflet de prendre
     MapHeight="100%" sans rester à hauteur 0. */
  .th-game-root { height: 100dvh; overflow: hidden; }
  .th-game-shell { display: flex; flex: 1; min-height: 0; }
}

/* ── Menu mobile : bouton hamburger + tiroir latéral ──
   Remplace l'ancienne barre de navigation du bas. Hors jeu, la navigation mobile
   passe désormais par un tiroir classique qui s'ouvre/se ferme (menu à trois barres).
   Le bouton (.th-burger) et le tiroir (.th-drawer) n'apparaissent que sur mobile
   (≤ 900px) ; sur desktop la nav horizontale de l'en-tête reste seule (.th-hide-mobile). */
.th-burger {
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--bg-soft);
  border: 1px solid var(--line-strong);
  color: var(--ink);
  cursor: pointer;
  padding: 9px;
  border-radius: 10px;
  flex-shrink: 0;
}

/* Tiroir : toujours présent dans le DOM (pour animer l'ouverture/fermeture),
   masqué sur desktop, hors écran tant qu'il n'est pas ouvert (.th-drawer--open). */
.th-drawer { display: none; }

@media (max-width: 900px) {
  .th-burger { display: inline-flex; }

  .th-drawer { display: block; }

  .th-drawer__scrim {
    position: fixed;
    inset: 0;
    z-index: 300;
    background: color-mix(in oklch, var(--ink) 45%, transparent);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
  }

  /* position:fixed → le panneau hors écran (translateX(100%)) ne crée pas de
     débordement horizontal : il est borné par le viewport. */
  .th-drawer__panel {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    z-index: 301;
    width: min(84vw, 340px);
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    border-left: 1px solid var(--line-strong);
    box-shadow: -18px 0 44px -22px rgba(36, 28, 18, .5);
    transform: translateX(100%);
    transition: transform .24s ease;
    padding-bottom: env(safe-area-inset-bottom);
    overflow-y: auto;
  }

  .th-drawer--open .th-drawer__scrim { opacity: 1; pointer-events: auto; }
  .th-drawer--open .th-drawer__panel { transform: translateX(0); }

  .th-drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 16px 12px;
    border-bottom: 1px solid var(--line);
  }
  .th-drawer__title {
    font-family: var(--font-serif);
    font-weight: 700;
    font-size: 17px;
    color: var(--ink);
  }
  .th-drawer__close {
    display: flex;
    background: var(--bg-soft);
    border: 1px solid var(--line-strong);
    color: var(--ink);
    cursor: pointer;
    padding: 8px;
    border-radius: 10px;
  }
  .th-drawer__links {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px;
  }
  .th-drawer__link {
    display: flex;
    align-items: center;
    gap: 13px;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 13px 14px;
    border-radius: 12px;
    color: var(--ink-soft);
    font-family: var(--font-sans);
    font-weight: 800;
    font-size: 15px;
    transition: background .15s ease, color .15s ease;
  }
  .th-drawer__link:hover { background: var(--bg-soft); }
  .th-drawer__link.is-active {
    background: var(--ember-soft);
    color: var(--ember);
  }
}

/* ── Tabbed editor mobile ── */
.th-editor-pane-map { min-height: 360px; }


@media (max-width: 900px) {
  .th-editor-split[data-active-tab="list"] .th-editor-pane-map,
  .th-editor-split[data-active-tab="list"] .th-editor-pane-inspect { display: none !important; }
  .th-editor-split[data-active-tab="map"] .th-editor-pane-list,
  .th-editor-split[data-active-tab="map"] .th-editor-pane-inspect { display: none !important; }
  .th-editor-split[data-active-tab="inspect"] .th-editor-pane-list,
  .th-editor-split[data-active-tab="inspect"] .th-editor-pane-map { display: none !important; }
  .th-editor-pane-list, .th-editor-pane-inspect { border: none !important; }
  .th-editor-pane-map { min-height: calc(100vh - 220px); }
}

/* ── Editor toolbar ── */
.th-editor-toolbar {
  padding: 12px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* ── Editor tabs mobile ── */
.th-editor-tabs {
  display: flex;
  border-bottom: 1px solid var(--line);
  background: var(--bg-soft);
}

/* ── Modal bottom-sheet mobile ── */
@media (max-width: 640px) {
  .th-modal-overlay { align-items: flex-end !important; }
  .th-modal {
    width: 100% !important;
    max-width: 100% !important;
    border-radius: 16px 16px 0 0 !important;
    animation: th-slide-up 0.22s ease-out;
  }
}

/* ── Animations ── */
@keyframes th-pulse {
  0%, 100% { transform: scale(1); opacity: 0.18; }
  50% { transform: scale(1.8); opacity: 0; }
}
@keyframes th-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes th-slide-up {
  from { transform: translateY(24px); opacity: 0.5; }
  to { transform: translateY(0); opacity: 1; }
}
@keyframes th-pulse-ring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0.45); }
  50% { box-shadow: 0 0 0 14px rgba(255, 59, 48, 0); }
}
/* Éclair de déclencheur : flash blanc bref au moment où l'on prend la photo,
   pour un retour visuel immédiat pendant que la capture haute qualité se traite. */
@keyframes th-shutter-flash {
  0% { opacity: 0.85; }
  100% { opacity: 0; }
}
@keyframes th-spin {
  to { transform: rotate(360deg); }
}

/* ── Scrollbar ── */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(36,28,18,.22);
  border-radius: 9px;
}

/* ── Responsive breakpoints ── */
@media (max-width: 900px) {
  .th-row-stack.cols-58,
  .th-row-stack.cols-eq { grid-template-columns: 1fr; gap: 28px; }
  .th-stats.cols-5 { grid-template-columns: repeat(3, 1fr); }
  .th-stats.cols-4 { grid-template-columns: repeat(2, 1fr); }
  .th-grid-2 { grid-template-columns: 1fr; }
  .th-editor-split { grid-template-columns: 1fr; }
  .th-recap-grid { grid-template-columns: repeat(2, 1fr); }
  .th-recap-bottom { grid-template-columns: 1fr; }
  .th-pad-page { padding: 0 18px 96px; }
  .th-hide-mobile { display: none !important; }
  .th-hide-desktop { display: initial; }
}

@media (max-width: 640px) {
  .th-stats.cols-5,
  .th-stats.cols-4 { grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .th-grid-cards { grid-template-columns: 1fr; gap: 16px; }
  .th-pad-page { padding: 0 14px 96px; }
}

/* ── Accessibility ── */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ── Legacy compat shim (form-control for InputText in auth pages) ── */
.form-control { width: 100%; }

/* ── Play page — mode jeu (/jeu/{id}) : menu à 4 éléments fixes (boussole,
   points, temps + étapes, action de validation), en bas de page. Un seul menu,
   quelle que soit la taille d'écran — remplace l'ancienne sub-bar desktop et la
   barre du bas mobile à onglets (voir MainLayout.IsGameRoute, qui masque la nav
   globale sur cette route, et JeuSession.razor). ── */
.th-play-menu {
  display: flex;
  align-items: stretch;
  flex: 0 0 auto;
  border-top: 1px solid var(--line);
  background: var(--bg);
  /* Pas de padding-bottom safe-area ici : <main> (MainLayout) le fournit déjà
     via son propre padding-bottom, et ce menu est un enfant de flux normal
     (contrairement à l'ancienne .th-play-gamebar, position:fixed). */
}
.th-play-menu > *:not(:last-child) { border-right: 1px solid var(--line); }
.th-play-menu-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  padding: 10px 6px;
  border: none;
  background: none;
  color: var(--ink);
  font-family: var(--font-sans);
  cursor: default;
}
button.th-play-menu-item { cursor: pointer; }
button.th-play-menu-item:disabled { cursor: default; opacity: .55; }
.th-play-menu-value {
  font-size: 15px;
  font-weight: 700;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.th-play-menu-label { font-size: 9.5px; }
.th-play-compass { display: flex; align-items: center; justify-content: center; color: var(--ember); }
.th-play-compass svg { transition: transform .25s ease; }
.th-play-menu-cta {
  flex: 1.15;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 10px 6px;
  border: none;
  background: var(--ember);
  color: #fff;
  font-family: var(--font-sans);
  cursor: pointer;
}
.th-play-menu-cta .th-play-menu-value { color: #fff; font-size: 12px; font-weight: 800; white-space: normal; text-align: center; }

/* ── Corps de jeu : carte (2/6 de la hauteur) fusionnée à l'indice (4/6) —
   toujours affichées ensemble, quelle que soit la taille d'écran (plus de
   bascule carte/indice mobile). ── */
.th-play-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.th-play-clue-panel {
  flex: 4 1 0%;
  min-height: 0;
  overflow-y: auto;
  padding: 20px clamp(16px, 4vw, 32px) 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ── Titre de l'étape — au-dessus de la carte (voir JeuSession.razor). ── */
.th-play-title-bar {
  flex: 0 0 auto;
  padding: 16px clamp(16px, 4vw, 32px) 4px;
}

/* ── Badges (type/points/zone/hors-ligne) — overlay en haut de la carte, plutôt
   que dans l'indice (voir JeuSession.razor). Fond translucide flouté : certains
   badges (Tone="outline") ont un fond transparent, illisible sur les tuiles de
   la carte sans ce bandeau. Leaflet garde son control de zoom en bottomright et
   son attribution désactivée (voir leaflet-route-map.js) : rien en haut ne peut
   entrer en conflit avec ce bandeau. ── */
.th-play-map-badges {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: color-mix(in oklch, var(--bg-card) 85%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  pointer-events: none;
}

/* ── Indice principal — pleine largeur, sans encadré ni libellé. ── */
.th-play-clue-text {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(17px, 2.6vw, 20px);
  color: var(--ink);
  margin: 0;
  line-height: 1.55;
}

/* ── Bouton média — incite au clic (pulsation tz-pulse), ouvre le média en
   grand (lightbox plein écran, voir JeuSession.razor) plutôt que de l'intégrer
   directement dans l'indice. ── */
.th-play-media-btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border: none;
  border-radius: 999px;
  background: var(--ember);
  color: #fff;
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: 13.5px;
  cursor: pointer;
  animation: tz-pulse 2.4s infinite;
}

/* ── Objectif de l'étape — fixe juste au-dessus du menu, ne défile jamais avec
   l'indice (contrairement au reste du contenu de .th-play-clue-panel). ── */
.th-play-objective {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px clamp(16px, 4vw, 32px);
  border-top: 1px solid var(--line);
  background: var(--bg-soft);
}
.th-play-objective-icon {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-card);
  border: 1px solid var(--line-strong);
  color: var(--tz-teal-d);
}
.th-play-objective-title { font-size: 12.5px; font-weight: 800; color: var(--ink); }
.th-play-objective-desc { font-size: 12.5px; color: var(--ink-soft); font-weight: 600; line-height: 1.45; margin-top: 3px; }

/* ══════════════════════════════════════════════════════════════════════
   RÈGLE GLOBALE — Leaflet ne doit JAMAIS passer au-dessus du menu/header
   ou des fenêtres modales. Ce bug est revenu à CHAQUE nouvelle intégration
   Leaflet (voir CLAUDE.md, section "Bugs UI résolus") car le correctif était
   appliqué au cas par cas sur certains composants (isolation:isolate en
   inline style) et oublié sur d'autres.
   `.leaflet-container` est la classe posée PAR Leaflet lui-même sur le div
   de la carte (L.map(...)) : cette règle protège donc AUTOMATIQUEMENT toute
   nouvelle carte Leaflet ajoutée à l'app, sans qu'il soit nécessaire d'y
   penser composant par composant. Ne pas retirer, ne pas la limiter à une
   classe de wrapper spécifique. ── */
.leaflet-container {
  isolation: isolate;
}

/* ══════════════════════════════════════════════════════════════════════
   Cartes d'ÉDITION (créateur) — les contrôles Leaflet des coins HAUT ne
   doivent jamais passer sous les pastilles flottantes de l'éditeur.
   Bug : sur l'éditeur de quête, la pastille « Vue parcours » (coin haut
   gauche) recouvrait le zoom +/- et la pastille « Étape N » / « Départ »
   (coin haut droit) recouvrait le sélecteur de calques (Plan / Satellite /
   Repères) — les deux contrôles devenaient inaccessibles au clic.
   Ces pastilles sont posées en position:absolute (inset 14px, z-index 500)
   PAR-DESSUS la carte, hors du contexte d'empilement de `.leaflet-container`
   (isolation:isolate ci-dessus) : elles gagnent donc toujours.
   Correctif : décaler les DEUX coins hauts de la carte sous la rangée de
   pastilles (pastille ≈ 33px + inset 14px ≈ 47px ; marge Leaflet 10px déjà
   comprise dans le total). Appliqué via la classe `.th-editor-map` posée par
   le composant de carte lui-même, donc valable pour tous ses usages
   (desktop étape 1 / étape 2, et carte plein écran mobile). ── */
.th-editor-map .leaflet-top.leaflet-left,
.th-editor-map .leaflet-top.leaflet-right {
  margin-top: 48px;
}

/* ══════════════════════════════════════════════════════════════════════
   Appareil photo plein écran (joueur) — mise en page PAYSAGE.
   Bug : sur mobile web, une fois le téléphone tourné en paysage, la barre
   de titre, le curseur « Qualité » et la barre de déclenchement s'empilent
   verticalement et écrasent l'aperçu caméra en une fine bande — on ne voit
   plus ce qu'on photographie, quelle que soit l'activité (traversée, quête
   ET collection).
   Correctif GLOBAL (comme la règle Leaflet ci-dessus) : en paysage sur écran
   bas (téléphones), on sort ces éléments de « chrome » du flux vertical et on
   les superpose en overlay. L'aperçu (flex:1, seul enfant restant dans le
   flux) reprend alors tout l'écran. Toute future page caméra qui réutilise
   ces classes en hérite automatiquement.
   Les styles inline des composants l'emportant sur la feuille de style, les
   surcharges sont marquées !important.
   Composants : MediaValidator.razor (photo/vidéo d'étape) et
   SpotCaptureModal.razor (collection). Seuil ~600px : les tablettes en
   paysage (hauteur > 600px) gardent la mise en page verticale normale. ── */
@media (orientation: landscape) and (max-height: 600px) {
  /* Barre de titre : overlay en haut, largeur réduite pour ne pas passer
     sous la colonne de contrôles ancrée à droite. */
  .th-cam-head {
    position: absolute !important;
    top: 0;
    left: 0;
    right: 116px;
    z-index: 3;
    padding-top: calc(6px + env(safe-area-inset-top)) !important;
    padding-bottom: 8px !important;
    background: linear-gradient(to bottom, rgba(0, 0, 0, .6), transparent) !important;
  }

  /* Colonne de contrôles (déclencheur, valider, compteur…) : bande verticale
     ancrée à droite, plutôt qu'une barre horizontale en bas. */
  .th-cam-controls {
    position: absolute !important;
    top: 0;
    bottom: 0;
    right: 0;
    left: auto !important;
    flex-direction: column !important;
    gap: 18px !important;
    width: auto;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom)) !important;
    background: linear-gradient(to left, rgba(0, 0, 0, .55), transparent) !important;
    z-index: 3;
  }

  /* Curseur qualité (avant capture) et champs titre/commentaire (après
     capture, collection) : overlay en bas à gauche, dégagé de la colonne de
     droite. Les deux sont mutuellement exclusifs (qualité si aucune photo,
     champs sinon), ils peuvent donc partager la même zone. */
  .th-cam-quality,
  .th-cam-fields {
    position: absolute !important;
    left: 0;
    right: 116px;
    bottom: 0;
    z-index: 3;
    background: linear-gradient(to top, rgba(0, 0, 0, .6), transparent) !important;
  }

  .th-cam-fields {
    max-height: 42vh !important;
  }
}

/* ── Lien e-mail protégé contre le moissonnage (spam / phishing) ──────────
   Composant EmailLink.razor. Le « @ » n'est pas dans le texte du DOM :
   il est injecté ici via ::before, donc absent du textContent lu par les
   robots collecteurs. Utiliser l'échappement Unicode \0040 pour ne pas
   écrire non plus le caractère « @ » littéral dans la feuille de style. ── */
.th-eml {
  cursor: pointer;
  white-space: nowrap;
}
.th-eml__at::before {
  content: "\0040"; /* @ */
}

/* ── Impression de la fiche QR Code (ParcoursEditor) ──────────────────────
   Isole #qr-fiche-print du reste de la page à l'impression via `visibility`
   (préserve la mise en page, contrairement à `display:none`). ── */
@media print {
  body * {
    visibility: hidden;
  }
  #qr-fiche-print,
  #qr-fiche-print * {
    visibility: visible;
  }
  #qr-fiche-print {
    position: fixed;
    inset: 0;
    margin: auto;
    box-shadow: none !important;
  }
  .qr-fiche-no-print {
    display: none !important;
  }
}

/* ── Impression de la fiche parcours (ParcoursPrintSheet) ─────────────────
   Même principe que la fiche QR Code ci-dessus : isole #parcours-print-sheet
   du reste de la page à l'impression via `visibility`. ── */
@media print {
  body * {
    visibility: hidden;
  }
  #parcours-print-sheet,
  #parcours-print-sheet * {
    visibility: visible;
  }
  #parcours-print-sheet {
    position: absolute;
    inset: 0;
    margin: 0;
  }
  /* La zone de défilement de l'écran ne doit plus rien rogner à l'impression. */
  .th-print-scroll {
    overflow: visible !important;
  }
  .th-print-no-print {
    display: none !important;
  }
}

/* La route /creator/parcours/{id}/imprimer est une « editor route » : le shell
   (MainLayout) fige la hauteur à 100dvh avec overflow:hidden. Sans conteneur de
   défilement dédié, une fiche plus haute que l'écran est tronquée et impossible à
   faire défiler. On reproduit donc le patron de l'éditeur : colonne flex, barre
   d'outils figée en haut, fiche dans une zone qui scrolle. */
.th-print-page {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.th-print-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.th-print-toolbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 20px;
  border-bottom: 1.5px solid var(--line);
  background: var(--bg-card);
}

.th-print-mode-toggle {
  display: inline-flex;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r);
  overflow: hidden;
}

.th-print-mode-toggle button {
  border: none;
  background: transparent;
  padding: 8px 16px;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 800;
  color: var(--muted);
  cursor: pointer;
}

.th-print-mode-toggle button.is-active {
  background: var(--tz-teal);
  color: #fff;
}

#parcours-print-sheet {
  max-width: 900px;
  margin: 0 auto;
  padding: 24px;
  background: #fff;
  color: #111;
}

.th-print-header h1 {
  font-size: 24px;
  margin: 0 0 4px;
}

.th-print-lieu {
  margin: 0 0 8px;
  color: #555;
  font-weight: 700;
}

.th-print-mode-banner {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 800;
  margin-bottom: 16px;
}

.th-print-mode-banner.is-organisateur {
  background: #fde8e4;
  color: #b3392a;
}

.th-print-mode-banner.is-joueur {
  background: #e2f4ef;
  color: #0b4f5a;
}

.th-print-map {
  border: 1.5px solid #ccc;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 24px;
  break-inside: avoid;
}

.th-print-etape {
  display: flex;
  gap: 14px;
  padding: 16px 0;
  border-top: 1.5px solid #e5e5e5;
  break-inside: avoid;
}

.th-print-etape-num {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #1a1a1a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 14px;
}

.th-print-etape-body h2 {
  margin: 0 0 8px;
  font-size: 16px;
}

.th-print-media-badge {
  display: inline-block;
  padding: 5px 10px;
  border-radius: 8px;
  background: #fff6e0;
  color: #7a5a00;
  font-weight: 800;
  font-size: 12.5px;
  margin-bottom: 8px;
}

.th-print-photo {
  max-width: 260px;
  max-height: 200px;
  object-fit: cover;
  border-radius: 8px;
  border: 1.5px solid #ddd;
  display: block;
  margin-bottom: 8px;
}

.th-print-qr {
  width: 90px;
  height: 90px;
}

.th-print-qr-caption {
  font-size: 11.5px;
  color: #777;
  margin: 4px 0 8px;
}

.th-print-indice-texte {
  margin: 0 0 10px;
  font-size: 14px;
  line-height: 1.5;
}

.th-print-lettres {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.th-print-mot {
  display: flex;
  gap: 5px;
}

.th-print-case {
  width: 28px;
  height: 34px;
  border: 1.5px solid #999;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 15px;
}

.th-print-consigne {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: #333;
}

/* ── Livret plié A4 (ParcoursBookletSheet) ────────────────────────────────────
   Une feuille A4 (210×297mm) recto/verso pliée en quatre = 8 panneaux A6
   (105×148,5mm). Chaque face A4 porte une grille 2×2 ; la rangée haute est
   pivotée de 180° pour se lire dans l'ordre une fois la feuille pliée.
   Le format de page A4 est confiné aux feuilles du livret via une page nommée
   (`@page booklet`), pour ne pas affecter les autres impressions de l'app. ── */
@page booklet {
  size: A4 portrait;
  margin: 0;
}

.th-bk-toolbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 20px;
  border-bottom: 1.5px solid var(--line);
  background: var(--bg-card);
}

.th-bk-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.th-bk-instructions {
  max-width: 900px;
  margin: 16px auto 0;
  padding: 14px 18px;
  background: #eef7f4;
  border: 1.5px solid #bfe3da;
  border-radius: 12px;
  color: #0b4f5a;
  font-size: 13.5px;
}

.th-bk-instructions p {
  margin: 0 0 6px;
}

.th-bk-instructions ol {
  margin: 0;
  padding-left: 20px;
}

.th-bk-instructions li {
  margin: 2px 0;
  line-height: 1.45;
}

#parcours-booklet {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  padding: 24px 12px 48px;
  background: var(--bg);
}

.th-bk-sheet {
  page: booklet;
  position: relative;
  box-sizing: border-box;
  width: 210mm;
  height: 297mm;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  background: #fff;
  color: #111;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.18);
}

.th-bk-sheet-label {
  position: absolute;
  top: -22px;
  left: 0;
  font-size: 12px;
  font-weight: 800;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.th-bk-panel {
  box-sizing: border-box;
  width: 105mm;
  height: 148.5mm;
  overflow: hidden;
  border: 1px dashed #cfcfcf; /* repères de pli / découpe */
}

.th-bk-panel.is-rotated {
  transform: rotate(180deg);
}

/* Mode paysage : A4 couché (297 × 210 mm), zones A6 larges (148,5 × 105 mm). */
.th-bk-landscape .th-bk-sheet {
  width: 297mm;
  height: 210mm;
}

.th-bk-landscape .th-bk-panel {
  width: 148.5mm;
  height: 105mm;
}

/* Pages blanches : lignes espacées pour l'écriture (notes des enfants). */
.th-bk-notes-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #b8b8b8;
  margin-bottom: 4mm;
}

.th-bk-notes-lines {
  flex: 1;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 10mm,
    #d6d6d6 10mm,
    #d6d6d6 calc(10mm + 1px)
  );
}

.th-bk-fin-site {
  margin: 6px 0 0;
  font-size: 11px;
  color: #777;
  text-align: center;
  word-break: break-all;
}

.th-bk-page {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: 10mm 9mm;
  display: flex;
  flex-direction: column;
  position: relative;
}

.th-bk-page-num {
  position: absolute;
  top: 4px;
  right: 6px;
  font-size: 10px;
  font-weight: 800;
  color: #b8b8b8;
}

/* Couverture & fin — centrées */
.th-bk-cover,
.th-bk-fin {
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 8px;
}

.th-bk-cover-emoji {
  font-size: 52px;
  line-height: 1;
}

.th-bk-cover h1,
.th-bk-fin h1 {
  margin: 4px 0;
  font-size: 21px;
  line-height: 1.2;
}

.th-bk-cover-lieu {
  margin: 0;
  font-weight: 700;
  color: #555;
  font-size: 13px;
}

.th-bk-cover-lore {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #444;
  display: -webkit-box;
  -webkit-line-clamp: 8;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.th-bk-cover-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 12px;
  font-weight: 800;
  font-size: 13px;
  color: #0b4f5a;
}

.th-bk-fin-message {
  margin: 4px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: #444;
}

.th-bk-fin-score {
  margin-top: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 800;
  font-size: 14px;
}

.th-bk-fin-box {
  width: 46px;
  height: 34px;
  border: 1.5px solid #999;
  border-radius: 6px;
}

.th-bk-fin-total {
  color: #777;
}

/* Étape */
.th-bk-etape-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.th-bk-etape-num {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #1a1a1a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 13px;
}

.th-bk-etape-head h2 {
  margin: 0;
  font-size: 15px;
  line-height: 1.2;
}

.th-bk-media-badge {
  align-self: flex-start;
  padding: 4px 8px;
  border-radius: 8px;
  background: #fff6e0;
  color: #7a5a00;
  font-weight: 800;
  font-size: 11px;
  margin-bottom: 6px;
}

.th-bk-qr {
  width: 96px;
  height: 96px;
  align-self: center;
}

.th-bk-qr-caption {
  font-size: 10.5px;
  color: #777;
  text-align: center;
  margin: 4px 0 6px;
}

.th-bk-photo {
  max-width: 100%;
  max-height: 46mm;
  object-fit: cover;
  border-radius: 8px;
  border: 1.5px solid #ddd;
  display: block;
  margin-bottom: 6px;
}

.th-bk-indice {
  margin: 0 0 8px;
  font-size: 13px;
  line-height: 1.5;
}

.th-bk-consigne {
  margin: 0 0 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: #333;
}

.th-bk-lettres {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
}

.th-bk-mot {
  display: flex;
  gap: 4px;
}

.th-bk-case {
  width: 22px;
  height: 28px;
  border: 1.5px solid #999;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 800;
  font-size: 13px;
}

/* Impression : n'afficher que le livret ; chaque feuille A4 sur une page. */
@media print {
  body * {
    visibility: hidden;
  }
  #parcours-booklet,
  #parcours-booklet * {
    visibility: visible;
  }
  #parcours-booklet {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    gap: 0;
    background: #fff;
  }
  #parcours-booklet .th-print-no-print {
    display: none !important;
  }
  .th-bk-sheet {
    box-shadow: none;
    margin: 0;
    break-after: page;
  }
  .th-bk-sheet:last-child {
    break-after: auto;
  }
  .th-bk-panel {
    border-color: #e6e6e6;
  }
}

/* ── Map panel (mode jeu) — 2/6 de la hauteur du corps, voir .th-play-body. ── */
.th-play-map-panel {
  flex: 2 1 0%;
  /* Filet de sécurité : garantit une hauteur visible même si un ancêtre venait à
     perdre sa hauteur définitive (voir MainLayout.IsGameRoute → height:100dvh),
     sans quoi ce panneau flex (flex-basis:0%, sans contenu en flux normal —
     PlayerPlayMap est en position:absolute) s'effondre à 0px et la carte disparaît. */
  min-height: 140px;
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  /* Confine les z-index internes de Leaflet (tuiles, marqueurs, contrôles ~1000)
     dans un contexte d'empilement local, sinon la carte passe AU-DESSUS des
     fenêtres modales (overlay z-index 1000+). */
  isolation: isolate;
}
/* Filet de sécurité : borne les z-index des panes/contrôles Leaflet afin
   qu'ils restent toujours sous les fenêtres modales du jeu. */
.th-play-map-panel .leaflet-pane,
.th-play-map-panel .leaflet-top,
.th-play-map-panel .leaflet-bottom,
.th-play-map-panel .leaflet-control { z-index: 1 !important; }

/* ══════════════════════════════════════════════════════════════════════
   Écran de jeu — template "2a" (import Claude Design, ADR-0004,
   docs/adr/0004-templates-ux-jeu-session.md). Colonne pleine hauteur :
   en-tête d'étape pleine largeur (aide « ? » + quitter), carte GPS sur la
   moitié du corps (boussole chaud/froid en overlay), corps défilant pour
   l'indice/consigne, barre d'actions fixe en bas (média, indice
   supplémentaire, CTA de validation).
   Classes distinctes (.th-play2-*) du template figé .th-play-* utilisé par
   JeuSessionInitial.razor (/jeu/{id}/initial) — ne jamais faire converger
   les deux jeux de classes, elles partagent la même feuille de style
   globale mais doivent pouvoir évoluer indépendamment.
   ══════════════════════════════════════════════════════════════════════ */

.th-play2-shell {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
@media (min-width: 640px) {
  .th-play2-shell {
    width: 100%;
    max-width: 560px;
    margin: 0 auto;
    box-shadow: 0 0 0 1px var(--line), 0 30px 70px -30px rgba(11, 79, 90, 0.35);
  }
}

/* Carte GPS : 52 % du corps (itération 2a « la carte respire ») ; overlays (chips, polaroid,
   boussole minimaliste) confinés */
.th-play2-map {
  position: relative;
  flex: 0 0 52%;
  min-height: 0;
  overflow: hidden;
  isolation: isolate; /* confine les z-index Leaflet, comme .th-play-map-panel */
}
.th-play2-map .leaflet-pane,
.th-play2-map .leaflet-top,
.th-play2-map .leaflet-bottom,
.th-play2-map .leaflet-control { z-index: 1 !important; }

/* ── En-tête d'étape — pleine largeur, en flux au-dessus de la carte ── */
.th-play2-objective {
  position: relative;
  z-index: 25;
  flex-shrink: 0;
  width: 100%;
  background: var(--bg-card);
  border-bottom: 1.5px solid var(--line);
  box-shadow: 0 14px 30px -20px rgba(11, 79, 90, 0.5);
  padding: 5px 12px 6px;
  animation: tz-pop 0.3s ease;
}
.th-play2-objective-btns {
  display: inline-flex;
  gap: 8px;
  margin-left: auto;
}
.th-play2-icon-btn {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  background: var(--bg-soft);
  color: var(--tz-teal-d);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  padding: 0;
}
.th-play2-objective-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}
.th-play2-objective-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 800 12px var(--font-sans);
  color: var(--ink);
  white-space: nowrap;
}
/* Titre de l'étape + boutons (aide « ? », quitter « × ») sur la même ligne,
   sans zone blanche : header compact. */
.th-play2-objective-titlerow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 2px;
}
.th-play2-objective-title {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: clamp(16px, 4vw, 19px);
  line-height: 1.15;
  color: var(--tz-teal-d);
  min-width: 0;
  flex: 1;
}

/* ── Légende zone / hors-ligne (chips flottants) ── */
.th-play2-zone-chip {
  position: absolute;
  left: 16px;
  z-index: 24;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: 800 10px var(--font-sans);
  letter-spacing: 0.04em;
  color: var(--tz-teal-d);
  background: color-mix(in oklch, var(--bg-card) 92%, transparent);
  padding: 4px 9px;
  border-radius: 7px;
  box-shadow: 0 6px 14px -10px rgba(11, 79, 90, 0.5);
}

/* ── Boussole chaud/froid — en overlay au bas de la carte ── */
.th-play2-compass-float {
  position: absolute;
  bottom: 14px;
  left: 14px;
  z-index: 26;
  display: flex;
  align-items: center;
  gap: 10px;
}
.th-play2-dial {
  width: 96px;
  height: 96px;
  min-width: 96px;
  position: relative;
  display: block;
  filter: drop-shadow(0 12px 22px rgba(11, 79, 90, 0.35));
}
.th-play2-dial:disabled { cursor: default; }
.th-play2-dial-ring {
  position: absolute; inset: 0; border-radius: 50%;
  background: var(--bg-card); border: 2px solid var(--line);
}
.th-play2-dial-ring2 { position: absolute; inset: 11px; border-radius: 50%; border: 2px solid var(--line); }
.th-play2-dial-ring3 { position: absolute; inset: 23px; border-radius: 50%; border: 2px solid var(--line); }
.th-play2-dial-arc {
  position: absolute; inset: -1px; border-radius: 50%;
  -webkit-mask: radial-gradient(circle, transparent 44px, #000 46px);
  mask: radial-gradient(circle, transparent 44px, #000 46px);
  transition: background 0.4s ease;
}
.th-play2-dial-sweep {
  position: absolute;
  top: 2px; left: 50%;
  width: 2px; height: 46px;
  transform-origin: bottom center;
  animation: tz-spin 4s linear infinite;
  transition: opacity 0.4s ease;
}
.th-play2-dial-needle {
  position: absolute;
  left: 50%; top: 50%;
  transform-origin: bottom center;
  height: 38px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  transition: transform 0.4s ease;
}
.th-play2-dial-center {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 11px; height: 11px;
  border-radius: 50%;
  border: 2px solid var(--bg-card);
  transition: background 0.4s ease;
}
.th-play2-proximity-card {
  background: var(--bg-card);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  box-shadow: 0 12px 24px -16px rgba(11, 79, 90, 0.5);
  padding: 9px 13px;
  min-width: 0;
  transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
/* Signalisation d'approche « Tu brûles » : le bloc « Proximité » remplace l'ancien
   bandeau — fond dégradé corail/ambre + textes blancs (voir ProximityAccentColor). */
.th-play2-proximity-card--hot {
  background: linear-gradient(120deg, var(--tz-coral), var(--tz-amber));
  border-color: transparent;
  box-shadow: 0 14px 28px -14px rgba(242, 84, 61, 0.7);
  animation: tz-pop 0.3s ease;
}

/* Boussole matérielle : bouton d'activation (permission device) + état actif.
   L'aiguille pointe alors la cible relativement à l'orientation réelle du téléphone. */
.th-play2-compass-enable {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--ink-soft);
  font: 800 10px var(--font-sans);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.th-play2-compass-enable:hover {
  background: var(--bg-card);
  border-color: var(--line-strong);
}
.th-play2-compass-state {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: 800 10px var(--font-sans);
}
.th-play2-compass-state--on {
  color: var(--canopy);
}

/* ── Corps défilant (indice, consigne, feedback) — sous la carte ── */
.th-play2-sheet {
  position: relative;
  z-index: 30;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--bg-card);
  box-shadow: 0 -14px 34px -22px rgba(11, 79, 90, 0.5);
  padding: 14px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.th-play2-clue-box {
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ember);
  background: var(--bg-soft);
  border-radius: var(--r);
  box-shadow: 0 10px 24px -20px rgba(11, 79, 90, 0.4);
}
.th-play2-clue-box--clickable { cursor: pointer; }
.th-play2-clue-box p {
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
  /* Tronque au-delà de 4 lignes — la zone devient alors cliquable et ouvre
     l'indice complet en modale (voir th.isTextClamped / JeuSession.razor). */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}
.th-play2-clue-more {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 6px;
  font: 800 11px var(--font-sans);
  color: var(--ember);
}

/* ── Encart « Objectif » de la chasse — sous la carte, dans le style du bloc « indice » du mode
   parcours (.th-play2-clue-box) : liseré ambre à gauche + fond doux + texte serif (voir
   ChasseDetail.razor, shell immersif du mode jeu chasse). ── */
.th-play2-chasse-objective {
  flex-shrink: 0;
  z-index: 20;
  margin: 10px 16px 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ember);
  background: var(--bg-soft);
  border-radius: var(--r);
  box-shadow: 0 10px 24px -20px rgba(11, 79, 90, 0.4);
}
.th-play2-chasse-objective-text {
  font-family: var(--font-serif);
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--ink);
  /* Deux lignes max : l'objectif reste un rappel compact, le détail complet vit dans l'aide « ? ». */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.th-play2-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.th-play2-action-btn {
  flex: 1 1 140px;
  min-height: 42px;
  border-radius: 12px;
  border: 1.5px solid var(--line-strong);
  background: var(--bg-card);
  color: var(--tz-teal-d);
  font: 800 12px var(--font-sans);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  padding: 8px 10px;
}
/* Onglet actif (Carte / Collection) de la barre d'actions du mode jeu chasse : seul le
   contour est mis en évidence (liseré teal + texte teal), le fond reste clair — un remplissage
   plein contrastait trop avec le bouton inactif. */
.th-play2-action-btn--active {
  border-color: var(--tz-teal-d);
  color: var(--tz-teal-d);
  box-shadow: inset 0 0 0 1px var(--tz-teal-d);
}
.th-play2-hint-btn {
  border-style: dashed;
  background: var(--bg-soft);
  color: var(--ink-soft);
}
.th-play2-media-btn { animation: tz-pulse 2.4s infinite; }

.th-play2-cta {
  width: 100%;
  min-height: 52px;
  border: none;
  border-radius: 16px;
  background: var(--ember);
  color: #fff;
  font: 800 15.5px var(--font-sans);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  box-shadow: 0 14px 26px -12px rgba(242, 84, 61, 0.55);
  cursor: pointer;
}

/* ── Barre d'actions — fixe en bas de l'écran, jamais sous le pli ── */
.th-play2-actionbar {
  flex-shrink: 0;
  z-index: 31;
  background: var(--bg-card);
  border-top: 1.5px solid var(--line);
  box-shadow: 0 -14px 34px -22px rgba(11, 79, 90, 0.5);
  padding: 10px 16px calc(12px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ── Lightbox audio : gros bouton lecture/pause centré ── */
.th-play2-audio-toggle {
  width: 92px;
  height: 92px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  background: var(--ember);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 18px 40px -14px rgba(242, 84, 61, 0.7);
}

/* ══════════════════════════════════════════════════════════════════════
   Écran de jeu — itération 2a « Polaroid + boussole minimaliste » (ADR-0004).
   Le cadran à 3 anneaux + la grosse carte « Proximité » sont remplacés par une
   boussole minimaliste (pastille flèche + pilule distance) ; l'indice photo est
   « scotché » en polaroid sur la carte ; l'indice texte défile dans sa carte
   (fondu de débordement) au lieu d'ouvrir une modale.
   Classes ADDITIVES : les anciennes (.th-play2-dial*, .th-play2-proximity-card*)
   restent définies — encore utilisées par la coque Maui et les thèmes archivés.
   ══════════════════════════════════════════════════════════════════════ */

/* Conteneur boussole : pile verticale (pastille au-dessus, pilule distance dessous) */
.th-play2-compass-float--mini {
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

/* Pastille flèche — 58 px, fond clair, repère N discret, flèche orientée vers la cible */
.th-play2-mini-pastille {
  width: 58px;
  height: 58px;
  min-width: 58px;
  border-radius: 50%;
  background: color-mix(in oklch, var(--bg-card) 96%, transparent);
  border: 1.5px solid var(--line);
  box-shadow: 0 10px 20px -10px rgba(11, 79, 90, 0.45);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  transition: border-color 0.4s ease, box-shadow 0.4s ease;
}
.th-play2-mini-pastille:disabled { cursor: default; }
.th-play2-mini-pastille--hot {
  border-color: transparent;
  box-shadow: 0 12px 24px -10px rgba(242, 84, 61, 0.6);
}
.th-play2-mini-n {
  position: absolute;
  top: 3px;
  left: 50%;
  transform: translateX(-50%);
  font: 800 8px var(--font-sans);
  color: var(--muted);
}
.th-play2-mini-needle {
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.4s ease;
}

/* Pilule distance — libellé « Proximité » + valeur + précision GPS + tendance chaud/froid */
.th-play2-dist-pill {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--bg-card);
  border: 1.5px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 10px 20px -10px rgba(11, 79, 90, 0.45);
  padding: 5px 12px 6px;
  white-space: nowrap;
  transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
/* Approche « Tu brûles » : la pilule passe au dégradé corail/ambre, textes en blanc. */
.th-play2-dist-pill--hot {
  background: linear-gradient(120deg, var(--tz-coral), var(--tz-amber));
  border-color: transparent;
  box-shadow: 0 14px 28px -14px rgba(242, 84, 61, 0.7);
  animation: tz-pop 0.3s ease;
}
.th-play2-dist-eyebrow { font-size: 8.5px; margin: 0; }
.th-play2-dist-row { display: inline-flex; align-items: baseline; gap: 5px; }
.th-play2-dist-value { font-size: 15px; line-height: 1; }
.th-play2-dist-unit { font-size: 10px; }
.th-play2-dist-acc { font: 700 10px var(--font-sans); color: var(--ink-soft); }
.th-play2-dist-trend { font: 700 10px var(--font-sans); color: var(--muted); }
.th-play2-dist-pill--hot .th-play2-dist-eyebrow,
.th-play2-dist-pill--hot .th-play2-dist-acc,
.th-play2-dist-pill--hot .th-play2-dist-trend { color: rgba(255, 255, 255, 0.9); }

/* Polaroid « scotché » — indice photo épinglé en haut à droite de la carte, incliné,
   ruban washi jaune, légende manuscrite ; un toucher l'agrandit (lightbox). */
.th-play2-polaroid {
  position: absolute;
  top: 12px;
  right: 14px;
  /* Largeur de la photo = source unique : le cadre (photo + 2×8px de padding) et la légende
     en dérivent, pour qu'un agrandissement responsive (desktop → 180px) ne puisse pas
     désynchroniser les trois largeurs et faire déborder la photo hors du cadre photomaton. */
  --th-polaroid-photo-w: 128px;
  width: calc(var(--th-polaroid-photo-w) + 16px);
  box-sizing: border-box;
  z-index: 26;
  transform: rotate(-4deg);
  background: #fff;
  padding: 8px 8px 6px;
  border: none;
  cursor: pointer;
  box-shadow: 0 18px 38px -16px rgba(51, 48, 42, 0.55);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.th-play2-polaroid:hover { transform: rotate(-2deg) scale(1.02); }
.th-play2-polaroid-tape {
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%) rotate(3deg);
  width: 64px;
  height: 18px;
  background: color-mix(in oklch, var(--tz-gold) 85%, transparent);
  box-shadow: 0 1px 3px rgba(51, 48, 42, 0.15);
}
.th-play2-polaroid-photo {
  display: block;
  position: relative;
  width: var(--th-polaroid-photo-w);
  height: 104px;
  overflow: hidden;
  background: var(--bg-soft);
}
.th-play2-polaroid-photo img,
.th-play2-polaroid-photo video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Tuile média (audio, ou vidéo embarquée sans vignette exploitable) : icône centrée sur fond papier. */
.th-play2-polaroid-mediaicon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--ember);
  background: var(--bg-soft);
}
/* Pastille « lecture » en superposition (coin bas-droit) pour l'indice audio/vidéo. */
.th-play2-polaroid-playbadge {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ember);
  color: #fff;
  box-shadow: 0 2px 6px rgba(51, 48, 42, 0.35);
}
.th-play2-polaroid-caption {
  display: block;
  width: var(--th-polaroid-photo-w);
  text-align: center;
  padding-top: 4px;
  font: 700 16px var(--font-hand, cursive);
  color: var(--ink);
}

/* Carte d'indice — en-tête « Indice », corps défilant, fondu de débordement en bas */
.th-play2-clue-card {
  position: relative;
  flex: 1 1 auto;
  min-height: 96px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ember);
  background: var(--bg-soft);
  border-radius: var(--r);
  box-shadow: 0 10px 24px -20px rgba(11, 79, 90, 0.4);
  overflow: hidden;
}
.th-play2-clue-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 12px 16px 0;
  font: 800 10px var(--font-sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tz-coral-d);
}
.th-play2-clue-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 16px 12px;
}
.th-play2-clue-scroll p {
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
}
.th-play2-clue-fade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 22px;
  background: linear-gradient(to bottom, transparent, var(--bg-soft));
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════════════════
   Parcours editor — TI'ZOR (assistant 2 étapes · desktop 3-pane · mobile)
   Step 1 « Le parcours » (identité + départ) → Step 2 « Les étapes »
   ══════════════════════════════════════════════════════════════════════ */

/* Shell */
.tz-ed-root {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  background: var(--tz-grad-page);
}

/* Wizard top bar (shared by both steps) */
.tz-ed-bar {
  flex-shrink: 0;
  display: flex; align-items: center; gap: 14px;
  padding: 10px clamp(13px, 3vw, 24px);
  background: var(--bg-card);
  border-bottom: 1.5px solid var(--line);
  box-shadow: 0 8px 22px -20px rgba(11,79,90,.65);
  flex-wrap: wrap;
}
.tz-ed-back {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px 8px 11px;
  background: var(--bg-soft);
  border: 1.5px solid var(--line-strong); border-radius: 999px;
  color: var(--tz-teal-d); font-weight: 800; font-size: 12.5px;
  cursor: pointer; transition: background .15s ease, transform .15s ease;
}
.tz-ed-back:hover { background: var(--canopy-soft); transform: translateX(-2px); }
.tz-ed-titlewrap { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tz-ed-eyebrow {
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted-2);
  display: inline-flex; align-items: center; gap: 5px;
}
.tz-ed-title {
  width: 100%;
  border: 1.5px solid transparent; background: transparent;
  border-radius: 11px; padding: 3px 9px; margin-left: -2px;
  font-family: var(--font-serif); font-weight: 600; font-size: 21px;
  color: var(--tz-teal-d); outline: none;
}
.tz-ed-title::placeholder { color: var(--muted-2); }
.tz-ed-title:hover { background: var(--bg-soft); }
.tz-ed-title:focus { background: var(--bg-soft); border-color: var(--line-strong); }
.tz-ed-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }

/* Stepper */
.tz-stepper { display: inline-flex; align-items: center; gap: 8px; }
.tz-step {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px 6px 7px; border-radius: 999px;
  border: 1.5px solid var(--line-strong); background: var(--bg-card);
  color: var(--ink-soft); font-weight: 800; font-size: 12.5px;
  cursor: pointer; transition: all .15s ease; white-space: nowrap;
}
.tz-step:hover:not(:disabled):not(.is-active) { background: var(--bg-soft); }
.tz-step:disabled { opacity: .5; cursor: not-allowed; }
.tz-step.is-active { background: var(--tz-teal); border-color: var(--tz-teal); color: #fff; box-shadow: 0 11px 22px -13px rgba(12,122,114,.85); }
.tz-step-num {
  width: 23px; height: 23px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 800;
  background: var(--canopy-soft); color: var(--tz-teal);
}
.tz-step.is-active .tz-step-num { background: rgba(255,255,255,.24); color: #fff; }
.tz-step.is-done .tz-step-num { background: #e7f7ee; color: var(--tz-green); }
.tz-step-sep { width: 22px; height: 2.5px; border-radius: 2px; background: var(--line-strong); }
@media (max-width: 760px) { .tz-step-label { display: none; } .tz-step { padding: 6px; } .tz-step-sep { width: 12px; } }

/* ── Step 1 — identité & point de départ ── */
.tz-ed-step1 { flex: 1; min-height: 0; overflow-y: auto; }
.tz-ed-step1-inner {
  max-width: 1180px; margin: 0 auto;
  padding: clamp(16px,3vw,28px) clamp(14px,4vw,28px) 44px;
  display: grid; grid-template-columns: 1.02fr 0.98fr; gap: 22px; align-items: start;
}
.tz-ed-panel { padding: clamp(16px,2vw,22px); }
.tz-ed-panel-map { padding: 0; overflow: hidden; display: flex; flex-direction: column; min-height: 480px; }
.tz-ed-panel-maphd { padding: 13px 16px; border-bottom: 1.5px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tz-ed-maptall { position: relative; flex: 1; min-height: 420px; }
@media (max-width: 1024px) { .tz-ed-step1-inner { grid-template-columns: 1fr; } .tz-ed-panel-map { min-height: 360px; } .tz-ed-maptall { min-height: 300px; } }

/* ── Step 2 — desktop 3-pane ── */
.tz-ed-grid {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: 344px minmax(0,1fr) 398px; gap: 0;
}
@media (max-width: 1180px) { .tz-ed-grid { grid-template-columns: 300px minmax(0,1fr) 360px; } }
.tz-ed-col { min-height: 0; min-width: 0; display: flex; flex-direction: column; }
.tz-ed-col-list { background: var(--bg-card); border-right: 1.5px solid var(--line); }
.tz-ed-col-map  { background: var(--bg-soft); position: relative; }
.tz-ed-col-insp { background: var(--bg-card); border-left: 1.5px solid var(--line); }
.tz-ed-listhead { flex-shrink: 0; padding: 16px 16px 11px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tz-ed-list { flex: 1; min-height: 0; overflow-y: auto; padding: 2px 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.tz-ed-row {
  display: flex; gap: 11px; align-items: center;
  padding: 11px 12px; width: 100%; text-align: left;
  background: var(--bg-card); border: 1.5px solid var(--line-strong); border-radius: var(--r);
  cursor: pointer; box-shadow: 0 8px 18px -17px rgba(11,79,90,.55);
  transition: background .12s ease, border-color .12s ease, transform .12s ease;
}
.tz-ed-row:hover { background: var(--bg-soft); transform: translateY(-1px); }
.tz-ed-row.is-active { border-color: var(--tz-teal); background: var(--canopy-soft); }

/* ── Éditeur de spots d'une collection (/creator/collections) ──────────────
   Desktop : carte à gauche, sélecteur d'affichage + liste à droite.
   Mobile  : la carte passe en PREMIER en pleine largeur (elle ne doit jamais
   sortir de l'écran ni être côte à côte avec la liste), suivie du sélecteur
   « Tous / Dans la carte » puis de la liste — cf. bug récurrent des cartes
   Leaflet et exigence UX mobile. */
.th-spots-editor {
  display: grid;
  grid-template-columns: minmax(300px, 1.4fr) minmax(260px, 1fr);
  gap: 16px;
  align-items: start;
}
.th-spots-editor-map { position: relative; height: 440px; }
.th-spots-editor-side {
  display: flex; flex-direction: column; gap: 10px; min-width: 0;
  /* Conteneur de requête : les lignes de spot s'adaptent à la largeur RÉELLE de
     la colonne liste (et non à celle de l'écran), donc le repli des boutons
     fonctionne aussi bien en portrait empilé qu'en paysage côte à côte. */
  container-type: inline-size;
}
.th-spots-filter {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.th-spots-filter-label {
  font-size: 11px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .05em;
}
.th-spots-editor-list {
  max-height: 386px; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 8px; padding-right: 2px;
}
/* Quand la colonne liste est trop étroite pour tenir « nom + coordonnées +
   boutons » sur une ligne, on fait passer les boutons Modifier/Supprimer SOUS le
   texte (ligne dédiée, alignée à droite). Le texte récupère toute la largeur et
   la ligne ne déborde plus — vrai en portrait (empilé) comme en paysage. */
@container (max-width: 440px) {
  .th-spots-editor-list .tz-ed-row { flex-wrap: wrap; }
  .th-spots-editor-list .tz-ed-row > span:last-child {
    flex-basis: 100%; justify-content: flex-end;
  }
}
@media (max-width: 720px) {
  /* align-items: stretch est OBLIGATOIRE ici. La règle de base ci-dessus pose
     `align-items: start` (utile pour le layout grid desktop). En repassant en
     flex COLONNE, cet `align-items: start` s'applique à l'axe transversal
     (= largeur) et empêche les enfants de s'étirer : ils prennent alors la
     largeur de leur CONTENU. La carte, dont l'unique enfant est en
     position:absolute (donc 0 largeur intrinsèque), se réduisait à 0 px de
     LARGE → carte blanche (impossible de peindre des tuiles sur 0 px), et la
     colonne liste se tassait à la largeur des boutons. C'était LA cause du bug
     « pas de carte en portrait » (indépendant de toute logique JS Leaflet). */
  .th-spots-editor { display: flex; flex-direction: column; align-items: stretch; }
  .th-spots-editor-map { height: 320px; }
  .th-spots-editor-list { max-height: 340px; }
}
/* Écran très bas (téléphone en paysage) : la carte ne doit pas monopoliser toute
   la hauteur visible. */
@media (max-height: 520px) {
  .th-spots-editor-map { height: 240px; }
  .th-spots-editor-list { max-height: 240px; }
}

.tz-ed-quickadd {
  padding: 13px; border: 1.5px dashed var(--line-strong); border-radius: var(--r);
  background: transparent; color: var(--tz-teal); font-weight: 800; font-size: 13px; width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer;
  transition: background .15s ease;
}
.tz-ed-quickadd:hover { background: var(--canopy-soft); }

/* Map overlay pills */
.tz-ed-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px; border-radius: 999px;
  background: var(--bg-card); border: 1.5px solid var(--line-strong);
  color: var(--tz-teal-d); font-weight: 800; font-size: 12px;
  cursor: pointer; box-shadow: var(--tz-shadow);
}
.tz-ed-pill:hover { background: var(--bg-soft); }
.tz-ed-pill.is-on-teal  { background: var(--tz-teal);  border-color: var(--tz-teal);  color: #fff; }
.tz-ed-pill.is-on-coral { background: var(--tz-coral); border-color: var(--tz-coral); color: #fff; }

/* Inspector (step 2 right pane / mobile step) */
.tz-ed-insp-head { flex-shrink: 0; padding: 15px 18px 13px; border-bottom: 1.5px solid var(--line); display: flex; align-items: center; gap: 12px; }
.tz-ed-insp-body { flex: 1; overflow-y: auto; min-height: 0; padding: 17px 18px 26px; display: flex; flex-direction: column; gap: 16px; }
.tz-ed-insp-foot { flex-shrink: 0; padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); border-top: 1.5px solid var(--line); background: var(--bg-card); display: flex; gap: 8px; align-items: center; }

/* ── Rubriques de l'éditeur d'étape : chaque bloc de données est nettement
      séparé, avec une couleur d'accent différente par rubrique. ── */
.th-ed-sec {
  border: 1.5px solid var(--th-sec-accent, var(--line-strong));
  border-left-width: 5px;
  border-radius: var(--r-lg);
  padding: 14px 16px;
  background: var(--th-sec-soft, var(--bg-card));
  display: flex;
  flex-direction: column;
  gap: 13px;
}
.th-ed-sec > .eyebrow { color: var(--th-sec-accent); margin: 0; }
/* Le trait de séparation interne (bordures top des sous-blocs) suit l'accent. */
.th-ed-sec .th-ed-subrule { border-top: 1.5px solid var(--th-sec-accent); opacity: .5; }

.th-ed-sec--capture    { --th-sec-accent: var(--tz-teal);   --th-sec-soft: var(--canopy-soft); border-style: dashed; }
.th-ed-sec--general    { --th-sec-accent: var(--tz-sky);    --th-sec-soft: #e6f5f9; }
.th-ed-sec--indice     { --th-sec-accent: var(--tz-purple); --th-sec-soft: #f1ebfb; }
.th-ed-sec--validation { --th-sec-accent: var(--tz-green);  --th-sec-soft: #e6f5ec; }
.th-ed-sec--fin        { --th-sec-accent: var(--tz-amber);  --th-sec-soft: #fdf3e3; }

/* Number pip */
.tz-pip {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 12.5px;
  background: var(--canopy-soft); color: var(--tz-teal);
}
.tz-pip.is-active { background: var(--tz-coral); color: #fff; }

/* Waypoint type selector chips */
.tz-wtype {
  height: 34px; padding: 0 12px; display: inline-flex; align-items: center; gap: 6px;
  border-radius: 999px; font-size: 12.5px; font-weight: 800; cursor: pointer;
  border: 1.5px solid var(--line-strong); background: var(--bg-card); color: var(--ink-soft);
  transition: all .14s ease;
}
.tz-wtype:hover { background: var(--bg-soft); }
.tz-wtype.is-active { border-color: var(--tz-teal); background: var(--tz-teal); color: #fff; }

/* Reorder buttons */
.tz-ed-ord {
  width: 30px; height: 30px; border-radius: 9px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line-strong); background: var(--bg-card); color: var(--tz-teal-d);
}
.tz-ed-ord:disabled { opacity: .4; cursor: not-allowed; }
.tz-ed-ord:hover:not(:disabled) { background: var(--bg-soft); }

/* Inline message banner */
.tz-ed-msg { font-size: 12.5px; font-weight: 700; padding: 10px 13px; border-radius: 11px; }
.tz-ed-msg-ok  { background: #e7f7ee; color: #0b6b39; }
.tz-ed-msg-err  { background: var(--ember-soft); color: var(--tz-coral-d); }
.tz-ed-msg-warn { background: #fef9e7; color: #7a5c00; }

/* ── Mobile drill-down ── */
.tz-em-stage { position: relative; flex: 1; min-height: 0; width: 100%; overflow: hidden; display: flex; flex-direction: column; background: var(--bg); }
.tz-em-slide {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  background: var(--tz-grad-page); overflow: hidden;
  transition: transform .3s cubic-bezier(.32,.72,.36,1), opacity .22s ease;
}
.tz-em-slide.is-active { transform: translateX(0); opacity: 1; pointer-events: auto; }
.tz-em-slide.out-left  { transform: translateX(-12%); opacity: 0; pointer-events: none; }
.tz-em-slide.out-right { transform: translateX(100%); opacity: 0; pointer-events: none; }
.tz-em-head {
  flex-shrink: 0; min-height: 56px; padding: 10px 12px;
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-card); border-bottom: 1.5px solid var(--line);
}
.tz-em-iconbtn {
  width: 38px; height: 38px; border-radius: 12px; flex-shrink: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-soft); border: 1.5px solid var(--line-strong); color: var(--tz-teal-d);
}
.tz-em-iconbtn:disabled { opacity: .4; cursor: not-allowed; }
.tz-em-card {
  display: flex; gap: 12px; align-items: center; padding: 12px 14px; width: 100%; text-align: left;
  background: var(--bg-card); border: 1.5px solid var(--line-strong); border-radius: var(--r);
  cursor: pointer; box-shadow: 0 8px 18px -17px rgba(11,79,90,.55);
}
@keyframes tz-em-sheet-up { from { transform: translateY(16px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* ══════════════════════════════════════════════════════════════════════
   TI'ZOR — motion + reusable component layer
   ══════════════════════════════════════════════════════════════════════ */

@keyframes tz-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(242,84,61,.5); } 50% { box-shadow: 0 0 0 13px rgba(242,84,61,0); } }
@keyframes tz-pop   { from { transform: translateY(10px) scale(.99); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes tz-float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes tz-bar   { 0%,100% { transform: scaleY(.3); } 50% { transform: scaleY(1); } }
@keyframes tz-shine { 0% { background-position: -120% 0; } 100% { background-position: 220% 0; } }
@keyframes tz-fade  { from { opacity: 0; } to { opacity: 1; } }
@keyframes tz-spin  { to { transform: rotate(360deg); } }
@keyframes tz-banner-in { from { transform: translateY(-104%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

.tz-pop   { animation: tz-pop .3s ease; }
.tz-fade  { animation: tz-fade .2s ease; }
.tz-float { animation: tz-float 3s ease-in-out infinite; }

/* Page shell */
.tz-page { max-width: 1180px; margin: 0 auto; padding: clamp(24px,4vw,44px) clamp(16px,4vw,40px) 54px; }
.tz-page-narrow { max-width: 860px; }

/* Display heading helper (Spectral, éditorial) */
.tz-display { font-family: var(--font-serif); font-weight: 700; line-height: 1.05; color: var(--ink); letter-spacing: -0.01em; }
.tz-display em { font-style: italic; color: var(--ember); }

/* Card */
.tz-card {
  background: var(--bg-card);
  border: 1.5px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--tz-shadow);
}
.tz-card-sm { border-radius: var(--r-lg); }
.tz-hover-rise { transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.tz-hover-rise:hover { transform: translateY(-3px); box-shadow: var(--tz-shadow-lg); }

/* Pills / badges */
.tz-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 999px;
  font-weight: 800; font-size: 12.5px; line-height: 1;
  white-space: nowrap;
}
.tz-pill-teal   { background: var(--canopy-soft); color: var(--tz-teal); }
.tz-pill-coral  { background: var(--ember-soft);  color: var(--tz-coral-d); }
.tz-pill-gold   { background: #fff3e0;            color: #c2641a; }
.tz-pill-green  { background: #e7f7ee;            color: #0b6b39; }
.tz-pill-purple { background: #f3f0fb;            color: #5b3aa0; }

/* Buttons */
.tz-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: none; cursor: pointer;
  font-family: var(--font-sans); font-weight: 800; font-size: 15px;
  padding: 14px 22px; border-radius: var(--r);
  transition: transform .15s ease, filter .15s ease, background .15s ease;
  white-space: nowrap; user-select: none;
}
.tz-btn:disabled { opacity: .5; cursor: not-allowed; }
.tz-btn-sm  { padding: 9px 15px; font-size: 13.5px; border-radius: 12px; }
.tz-btn-lg  { padding: 15px 26px; font-size: 15.5px; border-radius: var(--r-lg); }
.tz-btn-coral { background: var(--tz-coral); color: #fff; box-shadow: 0 12px 24px -12px rgba(242,84,61,.55); }
.tz-btn-coral:hover:not(:disabled) { transform: translateY(-2px); }
.tz-btn-teal  { background: var(--tz-teal); color: #fff; }
.tz-btn-teal:hover:not(:disabled)  { filter: brightness(1.06); }
.tz-btn-green { background: linear-gradient(135deg,#16a06a,#0c7a72); color: #fff; box-shadow: 0 8px 18px -8px rgba(22,160,106,.6); }
.tz-btn-green:hover:not(:disabled) { transform: translateY(-2px); }
.tz-btn-ghost { background: var(--bg-card); color: var(--tz-teal-d); border: 1.5px solid var(--line-strong); }
.tz-btn-ghost:hover:not(:disabled) { transform: translateY(-2px); }

/* Form controls */
.tz-label {
  display: block; font-weight: 800; font-size: 12.5px;
  color: var(--ink-soft); margin-bottom: 7px; letter-spacing: .2px;
}
.tz-input, .tz-select, .tz-textarea {
  width: 100%; box-sizing: border-box;
  border: 1.5px solid var(--line-strong); border-radius: var(--r);
  padding: 12px 14px; background: #fbfdfc;
  font-family: var(--font-sans); font-weight: 700; font-size: 14px; color: var(--ink);
}
.tz-textarea { min-height: 74px; resize: vertical; line-height: 1.45; }

/* Faux map canvas (grid texture) used by player + editor */
.tz-map {
  position: relative; overflow: hidden;
  background: linear-gradient(135deg,#bfe6df,#dcefcf);
  border: 1.5px solid var(--line-strong);
}
.tz-map::before {
  content: ""; position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(90deg, rgba(255,255,255,.45) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(0deg,  rgba(255,255,255,.45) 0 1px, transparent 1px 28px);
}

/* Ghost button for use on the brand gradient (hero band, etc.) */
.tz-hero-ghost {
  display: inline-flex; align-items: center; gap: 8px;
  height: 50px; padding: 0 24px;
  background: rgba(255,255,255,.15); border: 1.5px solid rgba(255,255,255,.45);
  border-radius: var(--r-lg); color: #fff;
  font-family: var(--font-sans); font-weight: 800; font-size: 15.5px;
  cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.tz-hero-ghost:hover { background: rgba(255,255,255,.24); border-color: rgba(255,255,255,.65); }

/* Brand logo tile */
.tz-logo {
  display: flex; align-items: center; justify-content: center;
  border-radius: 14px;
/*  background: linear-gradient(135deg,#ffc53d,#f2543d);
  box-shadow: 0 4px 12px rgba(242,84,61,.4);
*/
  font-family: var(--font-serif); font-weight: 700; color: #fff;
  flex: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   Kolaz Vakans — surfaces & interactions
   Présent uniquement dans le thème Kolaz Vakans (n'affecte pas un thème
   réactivé au retour arrière). Donne aux primitives Razor partagées
   (Button → .th-btn, Chip → .th-chip) et aux cartes (.tz-card) le rendu
   « scrapbook » : coins nets, ombres douces, léger soulèvement/inclinaison
   au survol. Les !important ne priment que sur les états :hover/:active.
   ═══════════════════════════════════════════════════════════════════════ */

/* Boutons — appui doux (petit décalage, ombre nette réduite). */
.th-btn { transition: transform .14s ease, box-shadow .14s ease, filter .14s ease, background .14s ease; }
.th-btn:hover:not([disabled]):not(:active) { transform: translateY(-1px); filter: brightness(1.02); }
.th-btn:active:not([disabled]) {
  transform: translate(1px,1px) !important;
  box-shadow: var(--ui-btn-shadow-active, 1px 1px 0 rgba(51,48,42,.2)) !important;
}

/* Chips / filtres — micro-appui. */
.th-chip { transition: transform .14s ease, box-shadow .14s ease, background .14s ease; }
.th-chip:hover:not(:active) { transform: translateY(-1px); }
.th-chip:active { transform: translate(1px,1px) !important; }

/* Cartes — blanc net, ombre douce ; au survol, la « photo » se soulève et se
   redresse légèrement (comme collée de travers dans un album). */
.tz-card { border: none; box-shadow: var(--kv-shadow-soft); }
.tz-card-sm { border-radius: var(--r-lg); }
.tz-hover-rise { transition: transform .18s ease, box-shadow .18s ease; }
.tz-hover-rise:hover { transform: translateY(-4px) rotate(-.5deg); box-shadow: var(--kv-shadow-photo); }

/* Emphase surlignée jaune (comme .display em). */
.tz-display em { font-style: normal; background: var(--kv-jaune); padding: 0 .16em;
                 box-decoration-break: clone; -webkit-box-decoration-break: clone; }

/* ── Helpers scrapbook réutilisables ── */
.kv-hand { font-family: var(--font-hand); font-weight: 700; }              /* note manuscrite (Caveat) */
.kv-photo { background: var(--bg-card); box-shadow: var(--kv-shadow-photo); } /* carte-photo « polaroid » */
.kv-dashed { border: 2px dashed var(--kv-ink); }
.kv-dashed-soft { border: 3px dashed var(--kv-dash); }
/* Ruban adhésif (washi tape) posé en haut d'un conteneur en position:relative */
.kv-tape { position: relative; }
.kv-tape::before { content:""; position:absolute; top:-11px; left:50%; width:98px; height:25px;
                   transform:translateX(-50%) rotate(-4deg); background:var(--kv-tape-jaune);
                   box-shadow:0 2px 6px rgba(0,0,0,.12); }

@keyframes kv-wiggle { 0%,100% { transform:rotate(-2deg); } 50% { transform:rotate(1deg); } }
.kv-wiggle { animation: kv-wiggle 5s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .th-btn, .th-chip, .tz-hover-rise, .kv-wiggle { transition: none; animation: none; }
  .th-btn:hover, .th-chip:hover, .tz-hover-rise:hover { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   Écran de jeu — design « 2a affiné » (import Claude Design, Ecran Jeu 2a.dc.html).
   Évolution du template 2a « Polaroid + boussole minimaliste » :
   - panneau « Objectif » REPLIABLE (chevron) : replié, la carte respire plein écran ;
   - chips chrono / étape / tendance chaud-froid en haut de la carte (bandeau de titre épuré) ;
   - pilule de proximité HORIZONTALE consolidée (flèche + distance) en haut à gauche.
   Classes ADDITIVES : les anciennes (.th-play2-sheet, .th-play2-clue-card, .th-play2-mini-*,
   .th-play2-dist-*, .th-play2-zone-chip) restent définies (coque MAUI + thèmes archivés).
   Toutes les couleurs passent par les variables de thème → un seul bloc convient aux 3 thèmes.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Rangée de chips en haut de la carte (zone, chrono, étape, tendance, hors-ligne) ── */
.th-play2-topchips {
  position: absolute;
  top: 10px;
  left: 12px;
  right: 172px;
  z-index: 24;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  pointer-events: none; /* laisse la carte draggable entre les chips */
}
.th-play2-chip {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: 800 10.5px var(--font-sans);
  letter-spacing: 0.03em;
  color: var(--ink);
  background: color-mix(in oklch, var(--bg-card) 97%, transparent);
  padding: 5px 9px;
  border-radius: 7px;
  border: 1.5px solid var(--line);
  white-space: nowrap;
  box-shadow: 0 6px 14px -10px rgba(11, 79, 90, 0.5);
}
.th-play2-chip--step {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
/* Chip de tendance « Tu brûles / Tu chauffes » : fond corail plein quand ça chauffe. */
.th-play2-trend-chip--hot {
  color: #fff;
  background: var(--ember);
  border-color: var(--ember);
  box-shadow: 0 8px 18px -8px rgba(242, 84, 61, 0.6);
}

/* ── Pilule de proximité horizontale (bas-gauche de la carte) — consolide pastille flèche + distance ── */
.th-play2-compass-float--pill {
  top: auto;
  bottom: 14px;
  left: 12px;
  right: auto;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  max-width: 62%;
}
.th-play2-prox-pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: color-mix(in oklch, var(--bg-card) 97%, transparent);
  border: 1.5px solid var(--line);
  border-radius: 10px;
  padding: 4px 10px;
  box-shadow: 0 10px 20px -10px rgba(11, 79, 90, 0.45);
  cursor: pointer;
  transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
.th-play2-prox-pill:disabled { cursor: default; }
/* Approche « Tu brûles » : dégradé corail/ambre, textes en blanc. */
.th-play2-prox-pill--hot {
  background: linear-gradient(120deg, var(--tz-coral), var(--tz-amber));
  border-color: transparent;
  box-shadow: 0 14px 28px -14px rgba(242, 84, 61, 0.7);
  animation: tz-pop 0.3s ease;
}
.th-play2-prox-dial {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
}
.th-play2-prox-pill--hot .th-play2-prox-dial { border-color: rgba(255, 255, 255, 0.6); }
.th-play2-prox-needle {
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.4s ease;
}
.th-play2-prox-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.05;
}
.th-play2-prox-eyebrow {
  font: 800 8.5px var(--font-sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.th-play2-prox-row {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  white-space: nowrap;
}
.th-play2-prox-value { font: 800 15px var(--font-sans); line-height: 1; }
.th-play2-prox-unit { font-size: 10px; }
.th-play2-prox-acc { font: 700 10px var(--font-sans); color: var(--ink-soft); }
.th-play2-prox-pill--hot .th-play2-prox-eyebrow,
.th-play2-prox-pill--hot .th-play2-prox-acc { color: rgba(255, 255, 255, 0.9); }

/* ── Panneau « Objectif » repliable (remplace .th-play2-sheet dans le design 2a affiné) ── */
.th-play2-panel {
  position: relative;
  z-index: 30;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border-top: 1.5px solid var(--line);
  box-shadow: 0 -14px 34px -22px rgba(11, 79, 90, 0.5);
  overflow: hidden;
}
/* Replié : le panneau se réduit à son en-tête, la carte prend tout l'espace. */
.th-play2-shell--panel-collapsed .th-play2-panel { flex: 0 0 auto; }
.th-play2-shell--panel-collapsed .th-play2-map { flex: 1 1 auto; }
.th-play2-shell--panel-collapsed .th-play2-panel-head { border-bottom: none; }

.th-play2-panel-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px 9px 18px;
  border-bottom: 1.5px solid var(--line);
}
.th-play2-panel-eyebrow {
  flex-shrink: 0;
  font: 800 10px var(--font-sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tz-teal-d);
}
.th-play2-panel-objective {
  flex: 1;
  min-width: 0;
  font: 700 13.5px var(--font-sans);
  line-height: 1.3;
  color: var(--ink);
}
.th-play2-panel-toggle { flex-shrink: 0; margin-left: auto; }
.th-play2-panel-chev {
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease;
}

.th-play2-panel-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  scrollbar-width: thin;
  scrollbar-color: var(--tz-coral) transparent;
}
.th-play2-panel-body::-webkit-scrollbar { width: 11px; }
.th-play2-panel-body::-webkit-scrollbar-track { background: transparent; }
.th-play2-panel-body::-webkit-scrollbar-thumb {
  background: var(--tz-coral);
  border-radius: 7px;
  border: 3px solid var(--bg-card);
}
/* Indice — préfixe « L'indice · » coloré + corps serif (esprit carnet). */
.th-play2-clue-text {
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--ink);
  margin: 0;
}
.th-play2-clue-prefix {
  font: 800 12px var(--font-sans);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tz-coral-d);
}
/* Fondu de débordement en bas du panneau (signal « défile pour lire »). */
.th-play2-panel-fade {
  position: absolute;
  left: 0;
  right: 11px; /* laisse voir la barre de défilement */
  bottom: 0;
  height: 22px;
  background: linear-gradient(to bottom, transparent, var(--bg-card));
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════════════════
   Écran de jeu — mode DESKTOP / tablette large (design « Ecran Jeu Desktop.dc.html »).
   Le même écran « 2a affiné » bascule, à partir de 1024 px, d'une colonne empilée vers une
   carte PLEIN ÉCRAN surmontée d'un VOLET FLOTTANT (bas-droite) réunissant objectif, indice
   et actions. Piloté uniquement par media-query : markup partagé, le « dock » (.th-play2-dock)
   passe de display:contents (mobile) à carte flottante (desktop). Additif — aucune classe
   mobile n'est modifiée hors media-query.
   PORTÉE : toutes les règles desktop sont limitées à l'écran de jeu (.th-play2-jeu), car
   .th-play2-shell / .th-play2-objective / .th-play2-icon-btn sont AUSSI réutilisés par
   ChasseDetail.razor (mode chasse) — il ne faut surtout pas les toucher hors du jeu.
   ══════════════════════════════════════════════════════════════════════ */

/* Mobile (base) : le dock s'efface (panneau + barre d'actions empilés comme avant), le
   sous-titre d'en-tête est masqué. Ces deux classes sont propres à l'écran de jeu (absentes
   de ChasseDetail) : sûres même hors portée .th-play2-jeu. */
.th-play2-dock { display: contents; }
.th-play2-objective-sub { display: none; }

@media (min-width: 1024px) {
  /* La coque de jeu cesse d'être une colonne « téléphone » centrée (règle ≥ 640 px) : plein écran.
     Compound .th-play2-jeu.th-play2-shell = le même élément (le shell du jeu), pas la chasse. */
  .th-play2-jeu.th-play2-shell {
    max-width: none;
    margin: 0;
    box-shadow: none;
  }

  /* En-tête plus ample + sous-titre « jeu en cours » visible à côté du titre. */
  .th-play2-jeu .th-play2-objective { padding: 11px 24px 12px; }
  .th-play2-jeu .th-play2-objective-title { flex: 0 0 auto; white-space: nowrap; font-size: 22px; }
  .th-play2-jeu .th-play2-objective-sub {
    display: inline-flex;
    align-items: center;
    font: 800 11px var(--font-sans);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
  }
  .th-play2-jeu .th-play2-icon-btn { width: 34px; height: 34px; }

  /* La carte occupe tout le corps sous l'en-tête (le dock flottant est hors-flux). */
  .th-play2-jeu .th-play2-map { flex: 1 1 auto; }
  /* Overlays légèrement agrandis / repositionnés comme le mock desktop. */
  .th-play2-jeu .th-play2-topchips { top: 16px; left: 16px; right: auto; }
  .th-play2-jeu .th-play2-chip { font-size: 12px; padding: 7px 13px; }
  .th-play2-jeu .th-play2-compass-float--pill { bottom: 24px; left: 24px; top: auto; max-width: 340px; }
  .th-play2-jeu .th-play2-polaroid { top: 16px; right: 24px; --th-polaroid-photo-w: 180px; }
  .th-play2-jeu .th-play2-polaroid-photo { height: 150px; }
  .th-play2-jeu .th-play2-polaroid-caption { font-size: 18px; }
  .th-play2-jeu .th-play2-polaroid-tape { width: 74px; height: 20px; }

  /* Volet flottant : panneau « Objectif » + barre d'actions réunis en une carte ancrée en
     bas à droite, superposée à la carte. Repli du panneau → la carte se réduit à son en-tête
     « Objectif » + la barre d'actions (le CTA « J'y suis » reste accessible). */
  .th-play2-jeu .th-play2-dock {
    display: flex;
    flex-direction: column;
    position: absolute;
    right: 24px;
    bottom: 24px;
    width: min(430px, calc(100% - 48px));
    max-height: calc(100% - 32px);
    background: var(--bg-card);
    border: 2px solid var(--line-strong);
    border-radius: 16px;
    box-shadow: 0 30px 60px -25px rgba(11, 79, 90, 0.5);
    overflow: hidden;
    z-index: 40;
  }
  /* Panneau et barre vivent DANS la carte flottante : pas de bordure/ombre propre, fond
     transparent (la carte porte le fond et l'ombre). */
  .th-play2-jeu .th-play2-dock .th-play2-panel {
    flex: 0 1 auto;
    min-height: 0;
    border-top: none;
    box-shadow: none;
    background: transparent;
  }
  .th-play2-jeu .th-play2-dock .th-play2-panel-body { max-height: 34vh; }
  .th-play2-jeu .th-play2-dock .th-play2-panel-fade {
    background: linear-gradient(to bottom, transparent, var(--bg-card));
  }
  .th-play2-jeu .th-play2-dock .th-play2-actionbar {
    background: transparent;
    border-top: 1.5px solid var(--line);
    box-shadow: none;
    padding: 10px 16px 12px;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   Correctifs 2a affiné (revue rendu mobile).
   ══════════════════════════════════════════════════════════════════════ */

/* Barre d'actions : « Indice supp. » et le CTA de validation CÔTE À CÔTE (mockup 2a),
   au lieu d'être empilés pleine largeur. Le média audio/vidéo garde sa propre rangée au-dessus.
   Sans indice supplémentaire, seul le CTA occupe la rangée (donc pleine largeur). */
.th-play2-actionrow {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.th-play2-actionrow > .th-play2-hint-btn {
  flex: 1 1 0;
  min-width: 0;
  flex-direction: column;
  gap: 1px;
  line-height: 1.15;
}
.th-play2-hint-main { display: inline-flex; align-items: center; gap: 5px; }
.th-play2-hint-pts { font: 700 10px var(--font-sans); color: var(--muted); }
/* Le CTA prend 2 parts (le double de l'indice supp.) et abandonne son width:100% en rangée. */
.th-play2-actionrow > .th-play2-cta { flex: 2 1 0; width: auto; }

/* ── Overlay carte EN COLONNE : chips au-dessus de la pilule de proximité ──
   Robuste anti-chevauchement : quel que soit le nombre de chips (zone/chrono/étape/tendance/
   hors-ligne) ou la largeur d'écran, la pilule suit toujours SOUS les chips (flux vertical),
   au lieu d'être positionnée en absolu et de passer derrière une 2ᵉ ligne de chips.
   Le polaroid reste indépendant (absolu, haut-droite). */
.th-play2-map-overlay {
  position: absolute;
  top: 10px;
  left: 12px;
  right: 12px;
  z-index: 26;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  pointer-events: none; /* laisse la carte draggable ; seuls les chips/pilule captent le pointeur */
}
.th-play2-map-overlay > * { pointer-events: auto; max-width: 100%; }
/* Chips + pilule repassent EN FLUX dans la colonne (annule leur ancienne position absolue). */
.th-play2-map-overlay .th-play2-topchips {
  position: static;
  top: auto;
  left: auto;
  right: auto;
  z-index: auto;
  width: 100%;
}
.th-play2-map-overlay .th-play2-compass-float--pill {
  position: static;
  top: auto;
  left: auto;
  right: auto;
  bottom: auto;
}

@media (min-width: 1024px) {
  /* Desktop : l'overlay se cale en haut à gauche, un peu plus grand (comme le mock desktop). */
  .th-play2-jeu .th-play2-map-overlay {
    top: 16px;
    left: 16px;
    right: auto;
    max-width: 60%;
    gap: 10px;
  }
}
