
/* Phase 2 — variables locales surchargeables par composant. */
:root {
  --component-card-radius: var(--radius-md);
  --component-card-gap: var(--grid-gap);
  --component-panel-shadow: 0 12px 35px rgba(0,0,0,.08);
  --component-overlay-duration: var(--transition-overlay);
}
/**
 * components.css — Composants réutilisables multi-pages
 * =====================================================
 * Styles de composants utilisables sur toutes les pages
 * du site (badges de statut, skeleton screens, boutons filtre,
 * barre de recherche, état vide…).
 *
 * À charger APRÈS base.css. Pour une page, charger ensuite
 * son fichier pages/XXX.css spécifique.
 *
 * NOTE : les sélecteurs de filtres (#search-input, .filters…)
 * sont ici car partageables (page projets ET page relevés
 * par exemple). Ils utilisent des variables de tokens.css.
 */


/* ── Section éditoriale générique (titre + corps) ── */
.section-lede__title {
  font-family: var(--font-family);
  font-weight: var(--font-weight-semibold);
  font-size: var(--fs-2xl);
  line-height: var(--line-height-tight);
  color: var(--color-primary);
  letter-spacing: var(--letter-spacing-meta);
  margin: 0 0 var(--space-2xl);
  text-wrap: balance;   /* évite les lignes orphelines dans le titre */
  text-align:     center;
}




/* ═══ Média + texte (bloc éditorial 2 colonnes) ═══ */
.media-text {
  display: grid;
  /* Colonnes purement proportionnelles : aucun plafond interne,
     donc aucun espace résiduel dans la gouttière.
     minmax(0, …) évite le débordement des médias à taille intrinsèque. */
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--media-ratio-cols, 1.618fr));
  gap: var(--space-2xl);          /* gouttière constante */
  align-items: start;             /* le texte ne s'étire pas verticalement */

  /* Seul et unique plafond de largeur + centrage */
  max-width: var(--content-max-width, 1200px);
  margin-inline: auto;
}

/* Colonne texte : hérite de la typo titres/corps de base.css.
   Plus de max-width ici — c'est le plafond du bloc qui borne la mesure. */
.media-text__body > :first-child {
  margin-top: 0;
}

/* Colonne média */
.media-text__figure {
  margin: 0;                   /* reset <figure> */
  align-self: start;           /* l'image garde son ratio */
  display: flex;
  flex-direction: column;
}

.media-text__figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--media-ratio, 4 / 3);   /* ratio maîtrisé, surchargeable */
  object-fit: var(--fit, cover);             /* cover par défaut si non défini */
  object-position: var(--pos, center);   /* ← à ajouter */
}


.media-text__caption {
  font-size:      var(--fs-sm);
  color:          var(--color-muted);
  line-height:    var(--line-height-snug);
  margin-top:     var(--space-sm);
  letter-spacing: var(--letter-spacing-meta);
}

/* Par défaut : texte à gauche (étroit), média à droite (large) */

/* Mode reverse : on inverse les proportions… */
.media-text--reverse {
  grid-template-columns: minmax(0, var(--media-ratio-cols, 1.618fr)) minmax(0, 1fr);
}

/* …et on repositionne explicitement chaque enfant */
.media-text--reverse .media-text__figure {
  grid-column: 1;   /* média dans la 1ʳᵉ colonne (large, à gauche) */
  grid-row: 1;      /* force la même rangée */
}
.media-text--reverse .media-text__body {
  grid-column: 2;   /* texte dans la 2ᵉ colonne (étroite, à droite) */
  grid-row: 1;      /* idem */
}

/* Embed 3D / vidéo : ratio propre, indépendant des images */
.media-text__embed {
  position: relative;
  width: 100%;
  aspect-ratio: var(--embed-ratio, 1 / 1);   /* carré par défaut ; 16/9 possible */
  min-height: 100px;
}
.media-text__embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
}

/* Rythme vertical entre blocs consécutifs */
.media-text + .media-text {
  margin-block-start: var(--space-media-gap, var(--space-4xl));
}

@media (max-width: 900px) {
  .media-text,
  .media-text--reverse {
    grid-template-columns: 1fr;
    gap: var(--space-xl);
  }
  .media-text--reverse .media-text__figure,
  .media-text--reverse .media-text__body {
    grid-column: 1;      /* une seule colonne */
    grid-row: auto;      /* on rend la main au placement auto */
  }
}

/* ═══════════════════════════════════════════════
   RÉVÉLATION AU SCROLL
   Piloté par initTextScrollReveal() (main.js)
   ═══════════════════════════════════════════════ */

/* État initial : invisible + légèrement décalé.
   Appliqué uniquement si JS est actif (classe .js sur <html>)
   → sans JS, le contenu reste visible et indexable. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition:
    opacity   var(--reveal-duration) var(--reveal-easing),
    transform var(--reveal-duration) var(--reveal-easing);
  will-change: opacity, transform;
}

/* État révélé */
.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* Nettoyage : on libère le compositeur après l'animation */
.js [data-reveal].is-revealed {
  will-change: auto;
}

/* ── Stagger interne au bloc media-text ── */
/* La figure arrive en premier, le texte suit légèrement après.
   Le parent .media-text ne subit AUCUN transform : on évite
   de créer un contexte d'empilement qui gênerait les embeds. */
.js .media-text[data-reveal] .media-text__figure,
.js .media-text[data-reveal] .media-text__body {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition:
    opacity   var(--reveal-duration) var(--reveal-easing),
    transform var(--reveal-duration) var(--reveal-easing);
}

.js .media-text[data-reveal] {
  opacity: 1;
  transform: none;
}

.js .media-text[data-reveal].is-visible .media-text__figure {
  opacity: 1;
  transform: none;
}
.js .media-text[data-reveal].is-visible .media-text__body {
  opacity: 1;
  transform: none;
  transition-delay: var(--reveal-stagger);
}

/* Sécurité : si l'utilisateur refuse les animations, on neutralise
   complètement les états initiaux (sans dépendre du JS). */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js .media-text[data-reveal] .media-text__figure,
  .js .media-text[data-reveal] .media-text__body {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}



/* ═══════════════════════════════════════════════
   BADGES DE STATUT
   ═══════════════════════════════════════════════ */

.status-badge {
  font-family:    var(--font-family);
  font-size:      var(--fs-3xs);
  font-weight:    var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-status);
  text-transform: uppercase;
  color:          #ffffff;
  background:     var(--status-default);
  padding:        var(--status-badge-padding);
  border-radius:  var(--radius-sm);
  line-height:    var(--line-height-tight);
  white-space:    nowrap;
  box-shadow:     var(--shadow-badge);
}

.status-badge.status-pro        { background: var(--status-pro); }
.status-badge.status-chantier   { background: var(--status-chantier); }
.status-badge.status-diagnostic { background: var(--status-diagnostic); }
.status-badge.status-releve     { background: var(--status-releve); }
.status-badge.status-avant      { background: var(--status-avant); }
.status-badge.status-esquisse   { background: var(--status-esquisse); }
.status-badge.status-termine    { background: var(--status-termine); }


/* ═══════════════════════════════════════════════
   BOUTONS FILTRE
   ═══════════════════════════════════════════════ */

.filters {
  display:         flex;
  flex-wrap:       wrap;
  justify-content: center;
  gap:             var(--filter-gap);
  margin-bottom:   var(--filter-margin-bottom);
}

.filter-btn {
  font-family:      var(--font-family);
  font-size:        var(--fs-2xs);
  font-weight:      var(--font-weight-semibold);
  letter-spacing:   var(--letter-spacing-filter);
  text-transform:   uppercase;
  color:            var(--filter-btn-text);
  background-color: var(--filter-btn-bg);
  border:           var(--border-width) solid var(--filter-btn-border);
  border-radius:    var(--filter-btn-radius);
  padding:          var(--filter-btn-padding);
  cursor:           pointer;
  transition:       background-color var(--transition-filter),
                    color            var(--transition-filter);
}

.filter-btn:hover               { background-color: var(--filter-btn-bg-hover); }
.filter-btn.active             { background-color: var(--filter-btn-bg-active);
                                 color:            var(--filter-btn-text-active); }
.filter-btn[data-hidden="true"] { display: none; }

.filter-btn:focus-visible {
  outline:        2px solid var(--color-primary);
  outline-offset: 3px;
}


/* ═══════════════════════════════════════════════
   BARRE DE RECHERCHE
   ═══════════════════════════════════════════════ */

.search-wrap {
  display:         flex;
  justify-content: center;
  margin-bottom:   28px;
}


/* ═══ HEADER ═══ */
.site-header {
  position: fixed; top: 0; left: 0; width: 100%; z-index: 100;
  transition: background-color .35s ease, box-shadow .35s ease;
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem clamp(1rem, 4vw, 3rem); gap: 2rem;
}
.site-header__logo { display: block; height: clamp(40px, 6vw, 64px); }
.site-header__logo .logo { height: 100%; width: auto; display: block; transition: opacity .35s ease; }

/* Par défaut (hero sombre) : logo clair visible, foncé caché */
.logo--dark  { position: absolute; top: 0; left: 0; opacity: 0; }
.site-header__logo { position: relative; }

/* Header "scrollé" ou pages sans hero → fond blanc + logo foncé */
.site-header.is-scrolled,
body:not([data-page="home"]) .site-header {
  background: #fff; box-shadow: 0 2px 12px rgba(0,0,0,.08);
}
.site-header.is-scrolled .logo--light,
body:not([data-page="home"]) .site-header .logo--light { opacity: 0; }
.site-header.is-scrolled .logo--dark,
body:not([data-page="home"]) .site-header .logo--dark  { opacity: 1; }

/* Le header flotte au-dessus du hero, sans décaler le contenu */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  background: transparent;      /* transparent sur le hero */
  transition: background .3s ease;
}

/* Par défaut sur pages à hero : logo clair visible, foncé caché */
.site-header .logo--light { display: block; }
.site-header .logo--dark  { display: none; }

/* Au scroll (ou header opaque) : fond blanc + logo foncé */
.site-header.is-scrolled {
  background: #fff;
  box-shadow: 0 2px 12px rgba(0,0,0,.08);
}
.site-header.is-scrolled .logo--light { display: none; }
.site-header.is-scrolled .logo--dark  { display: block; }

/* Le hero passe SOUS le header : pas de padding-top, il occupe le viewport */
.page-hero {
  position: relative;
  min-height: 60vh;             /* hero secondaire, moins haut que la home */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hero-img) center/cover no-repeat;
}
.page-hero__overlay {
  position: absolute; inset: 0;
  background: rgba(0,0,0,.35);  /* assombrit pour lisibilité du logo/titre */
}
.page-hero__title {
  position: relative;
  color: #fff;
  font-size: clamp(2rem, 5vw, 3.5rem);
  font-weight: 300;
  letter-spacing: .04em;
}


/* ═══ NAV ═══ */
.site-nav ul { display: flex; gap: clamp(1rem, 2.5vw, 2.5rem); list-style: none; margin: 0; padding: 0; }
.site-nav a {
  text-decoration: none; color: currentColor; font-size: .95rem;
  letter-spacing: .02em; padding: .4rem 0; position: relative; white-space: nowrap;
}
.site-nav a::after {
  content: ''; position: absolute; left: 0; bottom: 0; width: 0; height: 2px;
  background: currentColor; transition: width .3s ease;
}
.site-nav a:hover::after,
body[data-page="projets"]  a[data-navlink="projets"]::after,
body[data-page="agence"]   a[data-navlink="agence"]::after,
body[data-page="histoire"] a[data-navlink="histoire"]::after,
body[data-page="releves"]  a[data-navlink="releves"]::after,
body[data-page="contact"]  a[data-navlink="contact"]::after { width: 100%; }

/* Couleur du texte nav : clair sur hero, foncé sinon */
.site-header { color: #fff; }
.site-header.is-scrolled,
body:not([data-page="home"]) .site-header { color: #1a1a1a; }

/* ═══ BURGER (mobile) ═══ */
.site-header__burger { display: none; flex-direction: column; gap: 5px; background: none; border: 0; cursor: pointer; padding: 8px; }
.site-header__burger span { width: 26px; height: 2px; background: currentColor; transition: transform .3s, opacity .3s; }

@media (max-width: 860px) {
  .site-header__burger { display: flex; }
  .site-nav {
    position: fixed; inset: 0 0 0 auto; width: min(80vw, 340px);
    background: #fff; color: #1a1a1a; transform: translateX(100%);
    transition: transform .35s ease; padding: 6rem 2rem 2rem; box-shadow: -4px 0 20px rgba(0,0,0,.15);
  }
  .site-nav.is-open { transform: translateX(0); }
  .site-nav ul { flex-direction: column; gap: 1.5rem; }
  [data-burger][aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  [data-burger][aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  [data-burger][aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

/* ═══ PAGE HERO (bannière secondaire) ═══ */
.page-hero {
  position: relative; height: clamp(280px, 45vh, 460px);
  display: flex; align-items: center; justify-content: center;
  background: var(--hero-img) center/cover no-repeat; color: #fff; text-align: center;
}
.page-hero__overlay { position: absolute; inset: 0; background: rgba(0,0,0,.35); }
.page-hero__title { position: relative; font-size: clamp(2rem, 5vw, 3.5rem); font-weight: 300; letter-spacing: .04em; margin: 0; }

/* ═══ FOOTER ═══ */
.site-footer {
  background: var(--color-secondary-blue);            /* ← bleu secondaire */
  color: #cfcfcf;
  padding: clamp(2.5rem, 6vw, 5rem) clamp(1rem, 4vw, 3rem);
  text-align: right;                            /* ← alignement à droite */
  margin-top: var(--space-xl);
}
.site-footer__inner {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
  align-items: flex-start;
  justify-content: space-between;   /* ← logo à gauche, texte à droite */
}
.site-footer__logo { height: 90px; width: auto; }
.site-footer__info {
  font-style: normal;
  line-height: 1.9;
  font-size: .9rem;
  text-align: right;
}
.site-footer__info a { color: #fff; text-decoration: none; }
.site-footer__info a:hover { text-decoration: underline; }
.site-footer__copy {
  width: 100%;
  margin: 1.5rem 0 0;
  font-size: .8rem;
  color: #b8c4cd;                               /* ← éclairci pour rester lisible sur bleu */
}

/* Décale le contenu sous le header fixe (sauf home où le hero passe dessous) */
body:not([data-page="home"]) main { padding-top: 0; }


.equipe__role {
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted, #6b6b6b);
  margin-block: -0.5rem 1.5rem;
}


/* ─── Lien partenaire (logo + libellé) ─── */
.partner-link {
  display: flex;                /* au lieu de inline-flex */
  flex-direction: column;
  align-items: center;          /* au lieu de flex-start */
  width: fit-content;           /* le cadre reste ajusté au contenu */
  margin-inline: auto;          /* ← le centrage */
  margin-block-start: 2.5rem;
  gap: 0.9rem;
  padding: 1.4rem 1.8rem;
  border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
  border-radius: 2px;
  text-decoration: none;
  color: inherit;
  background: transparent;
  text-align: center;
  transition: border-color .35s ease, background-color .35s ease, transform .35s ease;
  position: relative;
  z-index: 1;
  pointer-events: auto;
  min-height: 1px;
}

.partner-link:hover,
.partner-link:focus-visible {
  border-color: color-mix(in srgb, currentColor 45%, transparent);
  background: color-mix(in srgb, currentColor 4%, transparent);
  transform: translateY(-2px);
}

.partner-link__logo {
  width: clamp(160px, 22vw, 230px);
  height: auto;
  display: block;
  transition: opacity .35s ease;
  opacity: .85;
}

.partner-link:hover .partner-link__logo,
.partner-link:focus-visible .partner-link__logo {
  opacity: 1;
}

.partner-link__label {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-muted, #6b6b6b);
  transition: color .35s ease;
}

.partner-link:hover .partner-link__label,
.partner-link:focus-visible .partner-link__label {
  color: inherit;
}

.partner-link__arrow {
  width: 1em;
  height: 1em;
  transition: transform .35s ease;
}

.partner-link:hover .partner-link__arrow,
.partner-link:focus-visible .partner-link__arrow {
  transform: translate(2px, -2px);
}

.partner-link__logo,
.partner-link__label,
.partner-link__arrow {
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .partner-link,
  .partner-link__logo,
  .partner-link__label,
  .partner-link__arrow { transition: none; }
  .partner-link:hover { transform: none; }
}




#search-input {
  font-family:    var(--font-family);
  font-size:      var(--fs-xs);
  font-weight:    var(--font-weight-regular);
  letter-spacing: var(--letter-spacing-meta);
  color:          var(--color-text);
  background:     transparent;
  border:         var(--border-width) solid var(--color-input-border);
  border-radius:  0;
  padding:        var(--input-padding);
  width:          280px;
  max-width:      100%;
  outline:        none;
  transition:     border-color var(--transition-fast);
}

#search-input::placeholder { color: var(--color-input-placeholder); }
#search-input:focus        { border-color: var(--color-primary); }


/* ═══════════════════════════════════════════════
   COMPTEUR DE RÉSULTATS
   ═══════════════════════════════════════════════ */

#result-count {
  display:         flex;
  justify-content: center;
  font-size:       var(--fs-2xs);
  font-weight:     var(--font-weight-light);
  letter-spacing:  var(--letter-spacing-status);
  color:           var(--color-taupe);
  margin-bottom:   var(--space-xl);
  min-height:      1.2em;
}


/* ═══════════════════════════════════════════════
   ÉTAT VIDE (aucun résultat)
   ═══════════════════════════════════════════════ */

#no-results {
  display:        none;
  text-align:     center;
  padding:        var(--space-2xl) var(--space-md);
  font-size:      var(--fs-sm);
  font-weight:    var(--font-weight-regular);
  letter-spacing: var(--letter-spacing-meta);
  color:          var(--color-muted-light);
}

#no-results button {
  margin-top:     var(--space-md);
  font-family:    var(--font-family);
  font-size:      var(--fs-2xs);
  font-weight:    var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-wide);
  text-transform: uppercase;
  color:          var(--color-primary);
  background:     transparent;
  border:         var(--border-width) solid var(--color-primary);
  padding:        var(--space-sm) 22px;
  cursor:         pointer;
}

#no-results button:hover { background: var(--color-primary-tint); }


    #cesiumContainer {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }

    #customToolbar {
      position: absolute;
      top: 10px;
      left: 10px;
      z-index: 1000;
      display: flex;
      gap: 8px;
      align-items: center;
      flex-wrap: wrap;
    }
    #customToolbar button {
      padding: 6px 12px;
      background: var(--color-primary);
      color: white;
      border: 1px solid #444;
      border-radius: 4px;
      cursor: pointer;
      font-family: var(--font-family);
      font-size: 13px;
    }
    #customToolbar button.active {
      background: var(--color-primary);
      border-color: var(--color-primary);
    }
    #customToolbar .clip-control {
      color: white;
      font-family: var(--font-family);
      font-size: 13px;
    }

/* ============================================================
   CESIUM VIEWER - TOOLBAR & UI (Superposition / Overlay)
   ============================================================ */

/* S'assure que le conteneur parent sert de repère absolu */
/* ============================================================
   CESIUM VIEWER — BARRE D'OUTILS
   ============================================================ */
#cesiumContainer, .cesium-viewer-wrapper { position: relative !important; }

.cv-toolbar {
  /* Palette locale : gris transparent, rouge réservé à l'état actif */
  --cv-bg:          rgba(25, 25, 25, 0.88);
  --cv-btn-bg:      rgba(255, 255, 255, 0.06);
  --cv-btn-bg-hov:  rgba(255, 255, 255, 0.16);
  --cv-btn-border:  rgba(255, 255, 255, 0.28);
  --cv-sep:         rgba(255, 255, 255, 0.12);
  --cv-text:        #f0f0f0;
  --cv-text-sub:    #b5b5b5;
  --cv-input-bg:    #2b2b2b;

  position: absolute !important;
  top: var(--space-sm); left: var(--space-sm);
  z-index: 9999;
  display: flex; flex-direction: column;
  box-sizing: border-box;
  width: 270px; min-width: 200px;
  max-width: min(520px, calc(100% - var(--space-md)));
  max-height: calc(100% - var(--space-md));
  resize: both; overflow: hidden;
  padding: var(--space-xs) var(--space-sm);
  background: var(--cv-bg);
  backdrop-filter: blur(4px);
  color: var(--cv-text);
  border: var(--border-width) solid var(--cv-sep);
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
  font-family: var(--font-family);
  font-size: 11px; line-height: 1.35;
  color-scheme: dark;              /* listes déroulantes et barres de défilement sombres */
}

/* En-tête */
.cv-header { display:flex; align-items:center; justify-content:space-between; gap:var(--space-xs); flex:none; user-select:none; }
.cv-main-title, .cv-section-title { font-weight:var(--font-weight-semibold); text-transform:uppercase; letter-spacing:.05em; }
.cv-main-title { font-size:10px; color:var(--cv-text-sub); }
.cv-toggle-btn {
  width:20px; height:20px; display:inline-grid; place-items:center;
  border:0; border-radius:var(--radius-sm); padding:0;
  background:transparent; color:var(--cv-text-sub); cursor:pointer; font-size:11px; line-height:1;
}
.cv-toggle-btn:hover, .cv-toggle-btn:focus-visible { background:var(--cv-btn-bg-hov); color:var(--cv-text); }

/* Corps : la barre de défilement n'apparaît que si le contenu déborde */
.cv-body {
  display:flex; flex-direction:column; flex:1 1 auto; min-height:0;
  margin-top:var(--space-xs);
  overflow-y:auto; overflow-x:hidden;
  scrollbar-width:thin;
}

/* Barre repliée : il ne reste qu'un carré avec la flèche */
.cv-toolbar.collapsed {
  width:auto !important; height:auto !important;
  min-width:0; min-height:0; padding:3px; resize:none;
}
.cv-toolbar.collapsed .cv-main-title,
.cv-toolbar.collapsed .cv-body { display:none !important; }

/* Sections et lignes : espacement plus aéré */
.cv-section { display:flex; flex-direction:column; gap:8px; padding-bottom:10px; margin-bottom:10px; border-bottom:var(--border-width) solid var(--cv-sep); }
.cv-section:last-child { padding-bottom:0; margin-bottom:0; border-bottom:0; }
.cv-section-title { margin:0; font-size:9px; color:var(--cv-text-sub); }
.cv-section-content { display:flex; flex-direction:column; gap:8px; }
.cv-section-title { margin:0; }   /* neutralise la marge par défaut du <h2> */
.cv-row, .cv-row-between { display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.cv-row-between { justify-content:space-between; width:100%; }

/* Boutons : gris par défaut, éclaircis au survol, rouge seulement si actifs */
.cv-btn {
  padding:3px 7px;
  border:var(--border-width) solid var(--cv-btn-border); border-radius:var(--radius-sm);
  background:var(--cv-btn-bg); color:var(--cv-text);
  font:inherit; font-size:11px; cursor:pointer; user-select:none;
  transition:background-color var(--transition-fast), border-color var(--transition-fast);
}
.cv-btn:hover, .cv-btn:focus-visible { background:var(--cv-btn-bg-hov); }
.cv-btn.active, .cv-btn.active:hover { background:var(--color-primary); border-color:var(--color-primary); }
.cv-btn-primary { font-weight:var(--font-weight-semibold); }
.cv-btn-sm { padding:2px 5px; font-size:10px; }
.cv-btn:disabled { opacity:.45; cursor:wait; }

/* Champs lisibles sur fond gris */
.cv-toolbar label, .cv-view-label { color:var(--cv-text-sub); font-size:10px; }
.cv-toolbar select, .cv-num-input {
  box-sizing:border-box; padding:2px 4px;
  border:var(--border-width) solid var(--cv-btn-border); border-radius:var(--radius-sm);
  background:var(--cv-input-bg); color:var(--cv-text); font:inherit; font-size:11px;
}
.cv-toolbar select option { background:var(--cv-input-bg); color:var(--cv-text); }
.cv-toolbar select { width:auto; flex:1 1 auto; min-width:0; }
.cv-num-input { width:52px; text-align:right; }
.cv-toolbar input[type=range] { width:100%; margin:0; accent-color:var(--color-primary); cursor:pointer; }

/* Vues enregistrées : libellé de largeur fixe + boutons sur une grille commune */
.cv-row:has(> .cv-view-label) { display:grid; grid-template-columns:44px 1fr; align-items:start; gap:6px; }
.cv-view-label { padding-top:4px; font-weight:var(--font-weight-semibold); }
.cv-view-buttons { display:grid; grid-template-columns:repeat(auto-fill, minmax(38px, 1fr)); gap:4px; }
.cv-view-buttons .cv-btn { padding:3px 2px; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* Coupe : angle + presets sur une ligne, masquée si inutile */
.cv-angle-row { display:flex; align-items:center; gap:4px; flex-wrap:wrap; }
.cv-angle-row label { margin-right:auto; }

/* Infobulles : retirées du rendu tant qu'elles sont invisibles (pas de faux défilement) */
[data-tooltip] { position:relative; }
[data-tooltip]::after { content:none; }
[data-tooltip]:hover::after, [data-tooltip]:focus-visible::after {
  content:attr(data-tooltip);
  position:absolute; left:0; top:calc(100% + 4px); z-index:5;
  width:max-content; max-width:200px;
  padding:4px 6px; border:var(--border-width) solid var(--cv-btn-border); border-radius:var(--radius-sm);
  background:#111; color:var(--cv-text); font-size:10px; font-weight:normal; line-height:1.3;
  white-space:normal; text-transform:none; pointer-events:none;
}

/* Statut de la coupe */
.cv-status { display:flex; align-items:center; gap:6px; font-size:10px; color:var(--cv-text-sub); }
.cv-status[hidden] { display:none; }
.cv-status.ready { color:#7fd49b; } .cv-status.error { color:#ff8a80; }
.cv-spinner { width:9px; height:9px; flex:none; border:2px solid rgba(255,255,255,.25); border-top-color:#fff; border-radius:50%; animation:cv-spin .8s linear infinite; }
.cv-status.ready .cv-spinner, .cv-status.error .cv-spinner { display:none; }
@keyframes cv-spin { to { transform:rotate(360deg); } }

/* ============================================================
   MODALE D'EXPORTATION HD
   ============================================================ */
.cv-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cv-modal-window {
  background: #222;
  color: #eee;
  border-radius: 8px;
  width: 320px;
  padding: 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7);
  font: 12px/1.4 sans-serif;
}
.cv-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: bold;
  font-size: 13px;
  border-bottom: 1px solid #444;
  padding-bottom: 8px;
  margin-bottom: 12px;
}
.cv-modal-close {
  background: transparent;
  border: none;
  color: #aaa;
  cursor: pointer;
  font-size: 14px;
}
.cv-form-group {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.cv-form-group select,
.cv-form-group input[type="number"] {
  background: #333;
  color: #fff;
  border: 1px solid #555;
  padding: 4px 6px;
  border-radius: 4px;
}
.cv-export-info {
  background: #181818;
  padding: 8px;
  border-radius: 4px;
  margin: 12px 0;
  border: 1px solid #333;
}
.cv-progress-container { margin-top: 10px; }
.cv-progress-bar {
  background: #444;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
}
.cv-progress-fill {
  background: #2e78d2;
  height: 100%;
  width: 0%;
  transition: width 0.2s ease;
}
.cv-progress-text {
  text-align: center;
  font-size: 10px;
  color: #aaa;
  margin-top: 4px;
}

.cv-hidden { display: none !important; }

.cesium-viewer.cv-active,
#cesiumContainer.cv-active { outline: 2px solid #8fd3ff; outline-offset: -2px; }

/* Logo Altaïr dans la barre de crédits Cesium */
.cesium-credit-container {
  display: flex;
  align-items: center;
  gap: 6px;
}
.cv-credit-logo {
  height: 22px;          /* à ajuster selon le ratio du SVG vertical */
  width: auto;
  opacity: 0.85;
  pointer-events: none;  /* ne bloque pas les clics caméra en bord de canvas */
  user-select: none;
}

