/* === TI'ZOR Design System v2.0 — phygital treasure hunt (La Réunion) === */

/* ── Palette TI'ZOR (default · "lagon") ──
   Brand: teal/green gradient + coral accent + gold highlights.
   Existing semantic tokens (--bg/--ink/--canopy/--ember…) are remapped to
   TI'ZOR values so every legacy page adopts the new look automatically,
   while raw brand colors live under --tz-*. */
:root {
  /* Brand ramp */
  --tz-teal-d:  #0b4f5a;   /* deep teal (nav, headings) */
  --tz-teal:    #0c7a72;   /* primary teal */
  --tz-green:   #16a06a;   /* fresh green (success / publish) */
  --tz-green-d: #0b6b45;   /* dark green (paired nav items: carte/collection) */
  --tz-coral:   #f2543d;   /* coral (primary CTA) */
  --tz-coral-d: #d8432d;
  --tz-gold:    #ffc53d;   /* gold (score / logo) */
  --tz-amber:   #e89622;   /* amber (partner "rencontre") */
  --tz-purple:  #7c4dd1;   /* purple (énigme) */
  --tz-sky:     #0ea5be;

  /* Surfaces */
  --bg:         #e9f5f0;
  --bg-soft:    #f1f7ec;
  --bg-card:    #ffffff;

  /* Ink / text */
  --ink:        #13343b;
  --ink-soft:   #37565c;
  --muted:      #5e7a80;
  --muted-2:    #90a4a8;

  /* Lines */
  --line:        #eef1ec;
  --line-strong: #cfe3dc;

  /* Semantic accents (legacy aliases) */
  --canopy:      #0c7a72;
  --canopy-soft: #e7f2ef;
  --ember:       #f2543d;
  --ember-soft:  #fdeeea;

  /* Typography */
  --font-sans:  'Nunito', system-ui, -apple-system, sans-serif;
  --font-serif: 'Fredoka', 'Nunito', system-ui, sans-serif;  /* display */
  --font-mono:  'Nunito', system-ui, sans-serif;             /* labels */

  /* Radii — TI'ZOR is very rounded */
  --r-sm: 10px;
  --r:    14px;
  --r-lg: 20px;
  --r-xl: 26px;

  /* Elevation */
  --tz-shadow:    0 12px 28px -20px rgba(11,79,90,.4);
  --tz-shadow-lg: 0 18px 40px -18px rgba(11,79,90,.45);
  --tz-grad-brand: linear-gradient(110deg,#0b4f5a 0%,#0c7a72 55%,#16a06a 100%);
  --tz-grad-page:  linear-gradient(165deg,#e9f7f4 0%,#f3f8ed 45%,#fdf5e8 100%);
}

/* ── Palette Cirques (cooler / bluer accent) ── */
[data-palette="cirques"] {
  --bg:         #e7f1f6;
  --bg-soft:    #eef5f9;
  --canopy:     #0e6f86;
  --canopy-soft:#e4f0f5;
  --ember:      #0ea5be;
  --ember-soft: #e3f4f8;
  --tz-grad-page: linear-gradient(165deg,#e8f4f8 0%,#eef6f4 45%,#f3f8ed 100%);
}

/* ── Palette Volcan (warmer / coral accent) ── */
[data-palette="volcan"] {
  --bg:         #fbeee7;
  --bg-soft:    #fdf3ec;
  --canopy:     #c2541a;
  --canopy-soft:#fcefe2;
  --ember:      #f2543d;
  --ember-soft: #fdeeea;
  --tz-grad-page: linear-gradient(165deg,#fdf0e6 0%,#fef6ed 45%,#f3f8ed 100%);
}

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

body {
  background: var(--tz-grad-page) 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(--tz-teal) !important; }

/* ── Typography ──
   .display now renders Fredoka (rounded display). Legacy <em> emphasis is
   shown in teal rather than italic, since Fredoka has no true italic. */
.display {
  font-family: var(--font-serif);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.05;
  color: var(--tz-teal-d);
}
.display em { font-style: normal; color: var(--canopy); }

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

.eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  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; }
}

/* ── Bottom nav mobile ── */
.th-bottombar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: none;
  background: color-mix(in oklch, var(--bg) 96%, transparent);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  padding: 8px 6px calc(8px + env(safe-area-inset-bottom));
}
@media (max-width: 900px) { .th-bottombar { display: flex; } }

/* ── 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); }
}

/* ── Scrollbar ── */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(11,79,90,.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;
}

/* ── 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 : 45 % du corps (50 % - 10 %), overlays (bandeau, chips, boussole) confinés */
.th-play2-map {
  position: relative;
  flex: 0 0 45%;
  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);
}

/* ══════════════════════════════════════════════════════════════════════
   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); }
.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 (Fredoka) */
.tz-display { font-family: var(--font-serif); font-weight: 600; line-height: 1.05; color: var(--tz-teal-d); letter-spacing: -0.005em; }

/* 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;
}
