/* Mise en page de l'application : la carte plein écran et les éléments de verre qui flottent dessus.
   Les composants (cm-*) vivent dans components.css, les jetons dans tokens.css. */
[hidden] { display: none !important; }

.home { position: relative; width: 100%; height: 100vh; height: 100dvh; overflow: hidden; overflow: clip; background: var(--night); }
.home__map { position: absolute; inset: 0; z-index: var(--z-map); }
/* le canevas est focalisable (tabindex="0" : flèches et +/−) et occupe tout l'écran : pas d'anneau au clic ni à la touche de la souris, mais au clavier un anneau « fog » tracé à l'intérieur
   (décalé de −4 px, hors du cadre l'anneau global serait rogné par le conteneur) ; l'ombre sombre du :focus-visible global, invisible sous un canevas, est retirée */
.home__map .maplibregl-canvas { outline: none; }
.home__map .maplibregl-canvas:focus-visible { outline: 2px solid var(--fog); outline-offset: -4px; box-shadow: none; }
.home__nav { position: absolute; z-index: var(--z-nav); top: 0; left: 0; right: 0; padding: var(--space-4) var(--space-5); pointer-events: none; }
.home__nav > * { pointer-events: auto; }
.home__nav .cm-nav { pointer-events: none; }
.home__nav .cm-nav > *, .home__nav .cm-nav__actions > * { pointer-events: auto; }
/* pile en bas à gauche : la pastille « Revoir la présentation » (quand elle est visible), la carte d'accueil (qui peut être fermée ou de hauteur variable), puis l'attribution des données : le dernier élément ne peut passer sous aucun autre */
.home__pile { position: absolute; z-index: var(--z-ui); left: var(--space-5); bottom: var(--space-4); display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); max-width: calc(100% - 2 * var(--space-5)); pointer-events: none; }
.home__pile > * { pointer-events: auto; }
.home__pile .home__intro { align-self: stretch; }
.home__pile .presentation-pastille { margin-bottom: var(--space-2); }
.home__controls { position: absolute; z-index: var(--z-ui); right: var(--space-5); bottom: var(--space-5); }
.home__bottom { display: contents; }
.home__pile .home__attribution { margin: 0; font: 400 11px/11px var(--font-sans); color: var(--fog-2); text-shadow: 0 1px 3px rgba(0, 0, 0, .8); pointer-events: none; }

/* barre du haut */
.cm-nav { flex-wrap: wrap; }
.cm-nav .cm-search { position: relative; flex: 1; min-width: 220px; max-width: 520px; }

/* modale */
.modal { position: fixed; inset: 0; z-index: var(--z-modal); display: flex; align-items: center; justify-content: center; padding: var(--space-4); }
.modal__scrim { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; cursor: default; }
.modal .cm-dialog { z-index: 1; max-height: calc(100dvh - 2 * var(--space-4)); overflow: auto; }
html.is-modal-open { overflow: hidden; }
.modal .cm-dialog { overscroll-behavior: contain; }
.cm-dialog:focus { outline: none; }
@keyframes modal-in { from { opacity: 0; } }
@keyframes dialog-in { from { opacity: 0; transform: translateY(var(--space-2)) scale(.98); } }
.modal:not([hidden]) .modal__scrim { animation: modal-in var(--dur-base) var(--ease); }
.modal:not([hidden]) .cm-dialog { animation: dialog-in var(--dur-base) var(--ease); }
@media (prefers-reduced-motion: reduce) { .modal:not([hidden]) .modal__scrim, .modal:not([hidden]) .cm-dialog { animation: none; } }

/* présentation vidéo de l'accueil : modale native (<dialog>), « affiche d'abord » (gabarits Presentation et PresentationPastille, contrôleur « presentation »).
   Le <dialog> est le voile (cm-scrim) et couvre tout l'écran ; le film y est centré. Largeur du film : 90 % de l'écran, 50 % à partir de 1280 px ; la hauteur
   de l'écran la borne (écran bas en paysage : le film garde sa place, avec son bouton et sa mention dessous). L'état vient de data-etat :
   affiche | lecture | termine | erreur. */
.presentation { --presentation-w: min(90vw, max(17rem, calc((100vh - 11rem) * 16 / 9))); position: fixed; inset: 0; z-index: var(--z-modal); flex-direction: column; justify-content: safe center; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; border: 0; overflow-x: hidden; overflow-y: auto; color: var(--fog); }
@supports (height: 100dvh) { .presentation { --presentation-w: min(90vw, max(17rem, calc((100dvh - 11rem) * 16 / 9))); } }
@media (min-width: 1280px) {
  .presentation { --presentation-w: min(50vw, max(17rem, calc((100vh - 11rem) * 16 / 9))); }
  @supports (height: 100dvh) { .presentation { --presentation-w: min(50vw, max(17rem, calc((100dvh - 11rem) * 16 / 9))); } }
}
.presentation:not([open]) { display: none; }
.presentation::backdrop { background: transparent; }
.presentation[open] { animation: modal-in var(--dur-base) var(--ease); }
.presentation[open] .presentation__carte { animation: dialog-in var(--dur-base) var(--ease); }
.presentation__carte { position: relative; flex: none; container-type: inline-size; width: var(--presentation-w); aspect-ratio: 16 / 9; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-xl); background: var(--night); box-shadow: var(--shadow-float); }
.presentation__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: var(--night); }
/* la carte rogne (overflow) l'anneau de focus du film : c'est elle qui le porte */
.presentation__carte:has(.presentation__video:focus-visible) { outline: 2px solid var(--fog); outline-offset: 3px; box-shadow: var(--shadow-float), 0 0 0 3px var(--night); }
.presentation__video:focus-visible { outline: none; box-shadow: none; }
.presentation__couverture { position: absolute; inset: 0; }
/* tout ce qui se lit sur l'affiche repose sur du verre fort : jamais de texte directement sur l'image */
.presentation__titre { position: absolute; left: var(--space-4); bottom: var(--space-4); width: 300px; max-width: calc(100% - 2 * var(--space-4)); padding: 14px 16px; border-radius: var(--radius-md); }
.presentation__titre h2 { margin: 10px 0 0; font: 400 22px/24px var(--font-serif); letter-spacing: -.01em; color: var(--fog); }
.presentation__titre h2 span { display: block; }
.presentation__titre em { font-style: italic; color: var(--ember); }
.presentation__lecture { --anneau: 10px; position: absolute; inset: 0; width: 88px; height: 88px; margin: auto; padding: 0; border-radius: 50%; box-shadow: 0 0 0 var(--anneau) var(--line), var(--shadow-lift); }
/* le voile clair de l'anneau écrase le double anneau du système sur l'affiche claire : le halo sombre du focus reste en tête */
.presentation__lecture:focus-visible { box-shadow: var(--shadow-focus), 0 0 0 var(--anneau) var(--line), var(--shadow-lift); }
.presentation__lecture .cm-ic { transform: translateX(2px); }
.presentation__passer { flex: none; margin-top: 20px; }
.presentation__mention { flex: none; margin: 16px 0 0; text-align: center; color: var(--fog); }
.presentation__fermer { position: absolute; top: var(--space-5); right: var(--space-5); width: 48px; padding: 0; }
.presentation__erreur { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; margin: 0; padding: var(--space-5); text-align: center; border: 0; border-radius: 0; }
.presentation[data-etat="erreur"] .presentation__erreur { display: flex; }
.presentation[data-etat="erreur"] .presentation__video { visibility: hidden; }
.presentation:not([data-etat="affiche"]) .presentation__couverture { display: none; }
/* film terminé : « Explorer la carte » devient l'action principale (la seule en `fog`) */
.presentation__passer-apres { display: none; }
.presentation[data-etat="termine"] .presentation__passer { background: var(--fog); color: var(--night); box-shadow: var(--shadow-lift); }
.presentation[data-etat="termine"] .presentation__passer-avant { display: none; }
.presentation[data-etat="termine"] .presentation__passer-apres { display: inline; }
/* affiche étroite (film de moins de 560 px : téléphone, ou écran bas en paysage) : le contenu se resserre selon la taille du film, pas celle de l'écran */
@container (max-width: 560px) {
  .presentation__titre { left: 12px; bottom: 12px; width: auto; padding: 8px 12px; border-radius: var(--radius-sm); }
  .presentation__titre h2 { margin-top: 4px; font-size: 17px; line-height: 19px; }
  .presentation__mot { display: none; }
  .presentation__lecture { --anneau: 8px; inset: 26px auto auto calc(50% - 36px); width: 72px; height: 72px; margin: 0; }
  .presentation__lecture .cm-ic { width: 30px; height: 30px; transform: translateX(1.5px); }
}
@container (max-width: 340px) {
  .presentation__lecture { --anneau: 6px; inset: 14px 14px auto auto; width: 56px; height: 56px; }
  .presentation__lecture .cm-ic { width: 24px; height: 24px; }
}
@media (max-width: 640px) {
  .presentation { padding-bottom: 48px; }
  .presentation__passer { width: var(--presentation-w); margin-top: 16px; }
  .presentation__mention { margin-top: 12px; }
  .presentation__fermer { top: var(--space-3); right: var(--space-3); }
}
@media (prefers-reduced-motion: reduce) { .presentation[open], .presentation[open] .presentation__carte { animation: none; } }

/* pastille « Revoir la présentation » : verre fort, vignette du film avec une lecture, durée ; posée dans la pile en bas à gauche */
.presentation-pastille { display: inline-flex; align-items: center; gap: var(--space-3); padding: 10px 22px 10px 10px; border-radius: var(--radius-pill); color: var(--fog); text-align: left; cursor: pointer; }
.presentation-pastille:hover { background-image: linear-gradient(var(--glass-hover), var(--glass-hover)); }
.presentation-pastille__vignette { position: relative; display: block; flex: none; width: 44px; height: 44px; overflow: hidden; border-radius: var(--radius-sm); }
.presentation-pastille__vignette img { display: block; width: 100%; height: 100%; object-fit: cover; }
.presentation-pastille__lecture { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin: auto; border-radius: 50%; }
.presentation-pastille__lecture .cm-ic { transform: translateX(.5px); }
.presentation-pastille__texte { display: flex; flex-direction: column; gap: 2px; }
.presentation-pastille__titre { font: 500 14px/18px var(--font-sans); }

/* contenu du cadre « auth » : connexion et inscription, dans la modale ou en pleine page (accès direct) */
.auth-page { display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; min-height: 100vh; min-height: 100dvh; padding: var(--space-4); }
.auth__brand { gap: 10px; flex-wrap: nowrap; color: var(--fog); text-decoration: none; }
/* sur les pages directes la marque est un lien (« retour à la carte ») : une cible de 44 px, dont les marges négatives gardent la mise en page de la carte (le logo fait 30 px) */
a.auth__brand { min-height: var(--control-sm); margin-block: calc((30px - var(--control-sm)) / 2); }
/* la règle des écrans étroits masque le mot-symbole de la barre du haut ; dans la carte, la marque reste complète */
.auth__brand .cm-wordmark { display: inline; }
.auth__tabs { margin-top: 22px; }
.cm-seg a { display: inline-flex; flex: 1; align-items: center; justify-content: center; height: var(--control-sm); padding: 0 18px; border-radius: var(--radius-pill); font: 500 14px/14px var(--font-sans); color: var(--fog-2); text-decoration: none; white-space: nowrap; }
.cm-seg a:hover { color: var(--fog); }
.cm-seg a[aria-current="page"] { background: var(--fog); color: var(--night); }
.auth__help { margin: 8px 0 0; font: 400 15px/22px var(--font-sans); color: var(--fog-2); }
.auth__form { margin: 0; }
.auth__error { display: flex; align-items: flex-start; gap: 10px; margin: 16px 0 0; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--rose-soft); color: var(--rose); font: 500 14px/20px var(--font-sans); }
.auth__error .cm-ic { margin-top: 1px; }
.auth__field-error { margin: 6px 0 0; font: 500 13px/18px var(--font-sans); color: var(--rose); }
.cm-field__box:has(input[aria-invalid="true"]) { border-color: var(--rose); }
/* la boîte du champ porte déjà l'anneau de focus : on retire l'ombre sombre que le focus global ajoute autour de la saisie */
.cm-field__box input:focus-visible { box-shadow: none; }
.auth__reveal { display: inline-flex; flex: none; align-items: center; justify-content: center; width: var(--control-sm); height: var(--control-sm); margin-right: -10px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--fog-2); cursor: pointer; }
.auth__reveal:hover { background: var(--glass-hover); color: var(--fog); }
.auth__reveal span { display: inline-flex; }
.auth__actions { margin-top: 18px; }
.auth__terms { margin: 14px 0 0; text-align: center; }

/* écrans étroits : la recherche passe sur une deuxième ligne, la carte d'accueil se resserre */
@media (max-width: 960px) {
  .home__nav { padding: var(--space-3) var(--space-4); }
  .cm-nav .cm-search { order: 3; flex-basis: 100%; max-width: none; }
  .cm-kbd { display: none; }
}
@media (max-width: 640px) {
  .cm-wordmark { display: none; }
  .cm-brand { padding: 0 10px; }
  .cm-toggle__count, .cm-nav__login { display: none; }
  /* bascule et « Créer un compte » tiennent sur une ligne à 390 px (358 px utiles) ; plus étroit, le bouton passe dessous */
  .cm-nav__actions { flex-wrap: wrap; justify-content: flex-end; }
  .cm-nav__actions .cm-toggle { gap: 6px; padding: 0 8px 0 12px; }
  .cm-nav__actions .cm-btn--lg { padding: 0 14px; }
  /* la carte d'accueil (de hauteur variable) et les contrôles (en rangée) s'empilent : les contrôles restent en bas à droite, que la carte soit ouverte ou fermée */
  .home__bottom { position: absolute; z-index: var(--z-ui); left: var(--space-4); right: var(--space-4); bottom: calc(var(--space-4) + var(--space-2)); display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-3); pointer-events: none; }
  .home__bottom > * { position: static; pointer-events: auto; }
  .home__bottom .home__pile { align-self: stretch; gap: var(--space-3); pointer-events: none; }
  .home__bottom .home__controls { flex-direction: row; }
  .home__bottom .home__controls button { border-top: 0; border-left: 1px solid var(--line); }
  .home__bottom .home__controls button:first-child { border-left: 0; }
  .home[data-fiche="replie"] .home__bottom { bottom: calc(var(--control-sm) + var(--space-4) + var(--space-2)); }
  /* attribution des données (IGN, DGFiP) : jamais cachée sur téléphone, une ligne compacte, dernière de la pile (sous la carte d'accueil) */
  .home__pile .home__attribution { width: fit-content; margin-inline: auto; padding: 0 var(--space-2); border-radius: var(--radius-pill); background: var(--glass); font-size: 10px; line-height: 14px; text-align: center; }
  .home[data-fiche="ouvert"] .home__bottom { bottom: calc(60dvh + var(--space-2)); }
}
/* sous 390 px la bascule et « Créer un compte » ne tiennent plus sur une ligne (353 px pour 343 à 375 px) : au lieu de passer chacun sur sa ligne sous la marque (quatre lignes
   avec la recherche, 272 px, qui ne laissent plus de place à la carte, ni au volet de la fiche), ils s'empilent à droite de la marque (trois lignes, 204 px) */
@media (max-width: 389.98px) {
  .cm-nav .cm-brand { align-self: flex-start; }
  .cm-nav__actions { flex: 1 1 0; min-width: 0; }
}
/* connecté, « Se déconnecter » (169 px) est plus large que « Créer un compte » : bascule et bouton font 374 px, qui ne tiennent sur une ligne qu'à partir de 406 px ; de 390 à 419 px
   (iPhone, Pixel) la barre faisait donc quatre lignes (272 px) : même arrangement que sous 390 px */
@media (min-width: 390px) and (max-width: 419.98px) {
  .cm-nav:has(.cm-nav__actions form) .cm-brand { align-self: flex-start; }
  .cm-nav__actions:has(form) { flex: 1 1 0; min-width: 0; }
}

/* recherche : la boîte (pastille de verre + panneau de suggestions frère) ; contrôleur search */
.cm-searchbox { position: relative; flex: 1; min-width: 220px; max-width: 520px; }
.cm-searchbox .cm-search { width: 100%; }
/* Au-dessus de 960 px la recherche partage la ligne de la marque et des actions. Le champ ne descend jamais sous la place de son texte d'aide (« Adresse, commune ou parcelle » : 211 px
   en police système de 15 px, 15rem = 240 px laissent la marge d'une police plus large) et la boîte jamais sous celle de son contenu (icône, champ et, quand il y est, le raccourci : sur
   un écran tactile il est masqué). Quand cela ne tient plus sur la ligne, la barre passe sur deux lignes, la recherche sur la seconde. Avec les 220 px de la boîte seule le champ tombait
   à 79 px (anonyme, 1 080 px) ou 82 px (connecté, 970 px) : texte d'aide coupé. */
@media (min-width: 960.02px) {
  .cm-searchbox { min-width: min-content; }
  .cm-searchbox input[type="search"] { min-width: 15rem; }
}
.cm-search input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.cm-suggest { position: absolute; z-index: var(--z-ui); top: calc(100% + var(--space-2)); left: 0; right: 0; max-height: min(26rem, calc(100dvh - 9rem)); overflow-y: auto; margin: 0; padding: var(--space-2); border-radius: var(--radius-lg); animation: cm-suggest-in var(--dur-fast) var(--ease); }
.cm-suggest ul { margin: 0; padding: 0; list-style: none; }
.cm-suggest li { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); color: var(--fog); cursor: pointer; }
.cm-suggest li[aria-selected="true"] { background: var(--glass-hover); outline: 1.5px solid var(--line-strong); outline-offset: -1.5px; }
.cm-suggest__text { flex: 1; min-width: 0; }
.cm-suggest__title { display: block; overflow: hidden; font: 500 15px/20px var(--font-sans); text-overflow: ellipsis; white-space: nowrap; }
.cm-suggest li small { display: block; overflow: hidden; font: 400 13px/18px var(--font-sans); color: var(--fog-2); text-overflow: ellipsis; white-space: nowrap; }
.cm-suggest li .cm-chip { flex: none; }
.cm-suggest__empty { margin: 0; padding: var(--space-3) var(--space-4); font: 400 14px/20px var(--font-sans); color: var(--fog-2); }
.cm-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@keyframes cm-suggest-in { from { opacity: 0; transform: translateY(calc(-1 * var(--space-1))); } }
@media (max-width: 960px) {
  .cm-searchbox { order: 3; flex-basis: 100%; max-width: none; }
}
@media (hover: none), (pointer: coarse) { .cm-kbd { display: none; } }
@media (prefers-reduced-motion: reduce) { .cm-suggest { animation: none; } }

/* Fiche : panneau de la parcelle sélectionnée (contrôleur fiche ; composants Panel, AnnonceCard, VenteRow).
   Écran large : panneau de 408 px à droite, sous la barre du haut ; écran étroit : volet qui remonte du bas (60 % de la hauteur). */
.fiche { position: absolute; z-index: calc(var(--z-ui) + 1); top: var(--fiche-haut, calc(var(--space-4) + var(--control-lg) + var(--space-4))); right: var(--space-4); bottom: var(--space-4); width: var(--panel-w); max-width: calc(100% - 2 * var(--space-4)); display: flex; flex-direction: column; overflow: hidden; border-radius: var(--radius-xl); opacity: 0; visibility: hidden; pointer-events: none; transform: translateX(var(--space-6)); transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease), visibility 0s linear var(--dur-base); }
.fiche:not([data-etat="ferme"]) { opacity: 1; visibility: visible; pointer-events: auto; transform: none; transition-delay: 0s; }
.fiche > turbo-frame { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.fiche__contenu { flex: 1; min-height: 0; transition: opacity var(--dur-fast) var(--ease); }
.fiche > turbo-frame[busy] .fiche__contenu, .fiche turbo-frame#ventes[busy] { opacity: .55; }
/* avant la première fiche : une plaque d'attente */
.fiche > turbo-frame:empty { min-height: 220px; }
.fiche > turbo-frame:empty::before { content: ""; display: block; height: 120px; margin: var(--space-6) var(--space-5); border-radius: var(--radius-md); background: linear-gradient(90deg, var(--glass-hover), var(--line), var(--glass-hover)) 0 0 / 200% 100%; animation: fiche-attente 1.4s var(--ease) infinite; }
@keyframes fiche-attente { to { background-position: -200% 0; } }
.fiche__poignee { display: none; }
.fiche .cm-ic { fill: none; }
.fiche .cm-panel__head > div:first-child { min-width: 0; }
.fiche .cm-panel__title { overflow-wrap: anywhere; }
.fiche .cm-panel__title:focus { outline: 0; box-shadow: none; }
.fiche .cm-panel__body { overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }

/* sections */
.fiche__texte { max-width: 65ch; margin: 10px 0 0; font: 400 14.5px/22px var(--font-sans); color: var(--fog); }
.fiche__note { margin: 10px 0 0; }
.fiche__legende { margin: -6px 0 6px; }
/* message d'erreur du cadre « ventes » (.cm-alert) : 12 px d'écart avec ce qui suit ; la marge haute négative de la légende ne s'y soustrait pas (elle collait au message) */
.fiche .cm-alert { margin-bottom: var(--space-3); }
.fiche .cm-alert + .fiche__legende { margin-top: 0; }
.fiche__sous-titre { margin: 20px 0 0; font: 600 14px/18px var(--font-sans); color: var(--fog); }
.fiche__actions { margin-top: var(--space-4); }
.fiche__liste { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 0; padding: 0; list-style: none; }
.fiche__liste li { display: flex; align-items: flex-start; gap: 10px; font: 400 14.5px/22px var(--font-sans); color: var(--fog); }
.fiche__liste .cm-chip { flex: none; margin-top: 2px; }
.fiche__liste li > :last-child { min-width: 0; overflow-wrap: anywhere; }
/* puces d'état (constructibilité, zone, risques, plans de prévention) : un libellé long passe à la ligne au lieu de déborder du panneau ;
   la hauteur de 26 px du design system est un minimum, atteint exactement par une ligne (interligne 1,3 × 13 px) */
.fiche .cm-row > .cm-chip { align-items: flex-start; max-width: 100%; height: auto; min-height: 26px; padding-block: calc((26px - 1.3em) / 2); line-height: 1.3; white-space: normal; overflow-wrap: anywhere; }
.fiche .cm-row > .cm-chip .cm-ic { margin-top: calc((1.3em - 14px) / 2); }
.fiche__lien { display: inline-flex; align-items: center; gap: 6px; min-height: 24px; font: 500 14px/18px var(--font-sans); color: var(--fog); text-decoration: underline; text-underline-offset: 3px; }
/* 24 px de haut au moins (WCAG 2.5.8, ces liens sont seuls dans leur paragraphe), 44 px au doigt comme les liens de source du chat */
@media (pointer: coarse) { .fiche__lien { min-height: var(--control-sm); } }
.fiche__lien:hover { text-decoration-thickness: 2px; }

/* annonces */
.fiche__titre-annonces { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.fiche__titre-annonces + .fiche__note { margin: -4px 0 12px; }
.fiche__annonces { display: flex; flex-direction: column; gap: var(--space-3); }
.cm-annonce .cm-logo { --s: 44px; }
.cm-annonce .cm-logo:not(.cm-logo--img) { background: var(--night); }
.cm-annonce__detail { margin: 10px 0 0; }
.cm-annonce__description { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; margin: 10px 0 0; font: 400 14px/20px var(--font-sans); color: var(--fog-2); white-space: pre-line; }
.cm-annonce__actions--seule { grid-template-columns: minmax(0, 1fr); }
.cm-annonce__tel { grid-column: 1 / -1; order: -1; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.cm-annonce__tel-numero { font: 600 17px/22px var(--font-sans); font-variant-numeric: tabular-nums; letter-spacing: -.01em; -webkit-user-select: text; user-select: text; }
.cm-annonce__actions:has(.cm-annonce__tel:not([hidden])) .cm-btn--fog { grid-column: 1 / -1; }

/* ventes : la ligne d'option est un interrupteur sur toute sa largeur */
.fiche__option { width: 100%; min-height: var(--control-sm); padding: 0; border: 0; border-radius: var(--radius-sm); background: transparent; text-align: left; }
.cm-check-row[aria-checked="true"] .cm-switch { background: var(--ember); border-color: var(--ember); }
.cm-check-row[aria-checked="true"] .cm-switch::after { transform: translateX(18px); }
.fiche__ventes { margin-top: 4px; }
.cm-sale__price { font-size: 17px; line-height: 17px; }
.cm-sale .cm-chip { height: 22px; margin-left: 6px; font-size: 12px; line-height: 12px; }

/* pied : sources en panne, puis sources citées */
.fiche__erreurs { padding: 12px 14px; border-radius: var(--radius-sm); background: var(--ambre-soft); }
.fiche__erreurs-titre { display: flex; align-items: center; gap: var(--space-2); margin: 0; font: 600 14px/20px var(--font-sans); color: var(--ambre); }
.fiche__erreurs ul { margin: 8px 0 0; padding-left: 18px; font: 400 13.5px/20px var(--font-sans); color: var(--fog); }
.fiche__erreurs .cm-caption { margin: 8px 0 0; }
.fiche__sources-titre { margin: 0; font-weight: 600; }
.fiche__pied ul { display: flex; flex-direction: column; gap: var(--space-1); margin: 6px 0 0; padding: 0; list-style: none; }

/* écran large : les contrôles de carte se décalent à gauche du panneau */
.home__controls { transition: right var(--dur-base) var(--ease), bottom var(--dur-base) var(--ease); }
@media (min-width: 960px) {
  .home[data-fiche] .home__controls { right: calc(var(--panel-w) + var(--space-4) + var(--space-5)); }
}

/* écran étroit : volet qui remonte du bas ; la poignée le replie sur elle-même */
@media (max-width: 959.98px) {
  .fiche { top: auto; right: 0; bottom: 0; left: 0; width: auto; max-width: none; height: 60vh; height: 60dvh; border-radius: var(--radius-xl) var(--radius-xl) 0 0; border-bottom: 0; transform: translateY(100%); }
  .fiche:not([data-etat="ferme"]) { transform: none; }
  .fiche[data-etat="replie"] { transform: translateY(calc(100% - var(--control-sm))); }
  /* le volet ouvert (60 % de la hauteur) recouvre le bas de la carte : la pile (réduite à la mention d'attribution, la carte d'accueil et la pastille étant masquées) se pose juste au-dessus de lui ; sur téléphone, c'est `.home__bottom` qui monte */
  .home[data-fiche="ouvert"] .home__pile { bottom: calc(60vh + var(--space-2)); bottom: calc(60dvh + var(--space-2)); }
  /* replié, le volet ne laisse que sa poignée (--control-sm) : la pile reste au-dessus d'elle, de 641 à 959 px comme sur téléphone */
  .home[data-fiche="replie"] .home__pile { bottom: calc(var(--control-sm) + var(--space-2)); }
  .fiche__poignee { display: flex; flex: none; align-items: center; justify-content: center; width: 100%; height: var(--control-sm); padding: 0; border: 0; background: transparent; cursor: pointer; }
  .fiche__poignee::before { content: ""; width: 40px; height: 4px; border-radius: var(--radius-pill); background: var(--line-strong); }
  .fiche .cm-panel__head { padding-top: 4px; }
  .fiche .cm-panel__body { padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px)); }
  .home[data-fiche="ouvert"] .home__controls { bottom: calc(60dvh + var(--space-4)); }
  .home[data-fiche="replie"] .home__controls { bottom: calc(var(--control-sm) + var(--space-4)); }
  .home[data-fiche] .home__intro, .home[data-fiche] .presentation-pastille { display: none; }
}
/* écran bas : la pile (pastille + carte d'accueil) irait sous la barre du haut ; la pastille se réduit à sa vignette et se range à côté de la carte (ordinateur)
   ou sur la rangée des contrôles (téléphone) */
@media (min-width: 641px) and (max-height: 600px) {
  .home__pile { display: grid; grid-template-columns: minmax(0, 420px) auto; align-items: end; column-gap: var(--space-3); row-gap: var(--space-2); }
  .home__pile .home__intro { grid-column: 1; grid-row: 1; }
  .home__pile .presentation-pastille { grid-column: 2; grid-row: 1; margin-bottom: 0; }
  .home__pile .home__attribution { grid-column: 1 / -1; grid-row: 2; }
  .presentation-pastille__texte { display: none; }
  .presentation-pastille { padding-right: 10px; }
}
/* écran bas (paysage, petits téléphones) : la carte d'accueil se resserre pour ne pas passer sous la barre du haut (sa croix doit rester cliquable) */
@media (max-height: 640px), (max-width: 640px) and (max-height: 720px) {
  .home__intro { padding: 16px 20px 18px; }
  .home__intro .cm-intro__title { margin-top: 10px; font-size: 30px; line-height: 32px; }
  .home__intro .cm-intro__text { display: none; }
}
/* La pile se range sur une rangée dès qu'elle ne tient plus sous la barre du haut : jusqu'à 740 px de haut sur tout téléphone ; jusqu'à 820 px de haut sur les téléphones de 450 px et moins,
   où la barre fait trois lignes (212 px) et la carte d'accueil, sur trois lignes de titre, 393 px : empilées (pastille de 66 px, carte, attribution, contrôles) elles demandent
   807 px de haut, et la pastille passait sous la barre de 741 à 806 px */
@media (max-width: 640px) and (max-height: 740px), (max-width: 450px) and (max-height: 820px) {
  .home__bottom { flex-direction: row; flex-wrap: wrap; align-items: flex-end; }
  .home__bottom .home__pile { display: contents; }
  .home__pile .home__intro { order: -1; flex: 0 0 100%; }
  .home__pile .home__attribution { order: 1; flex: 0 0 100%; }
  .home__bottom .home__controls { margin-left: auto; }
  .presentation-pastille__texte { display: none; }
  .presentation-pastille { padding: 4px; }
}
/* fiche ouverte, la pile des contrôles (158 px de haut, posée à 16 px au-dessus du volet) ne tient pas entre la barre du haut et le volet (60 % de la hauteur) :
   - téléphone (≤ 640 px) : la barre fait trois lignes, le volet ne laisse pas la place ;
   - de 641 à 879 px : la barre fait encore trois lignes (212 px : la marque, puis les actions, puis la recherche), il faut 1005 px de haut ; la tablette (768 × 1024) les garde ;
   - de 880 à 959 px : la barre fait deux lignes (144 px), il faut 800 px de haut ; le téléphone en paysage (844 × 390) en est loin.
   Masquées, elles se retrouvent dès que la fiche est repliée ou fermée ; le pincement, la molette et les touches + et − zooment toujours. */
@media (max-width: 640px), (min-width: 641px) and (max-width: 879.98px) and (max-height: 1000px), (min-width: 880px) and (max-width: 959.98px) and (max-height: 810px) {
  .home[data-fiche="ouvert"] .home__controls { display: none; }
}
/* écran bas de 641 à 834 px de large, 580 px de haut au plus : un téléphone en paysage (iPhone SE 667 × 375, 8 Plus 736 × 414, X 812 × 375, Galaxy 740 × 360 ; l'iPhone 12 à 15, 844 × 390, tient déjà).
   La marque, la bascule et les deux boutons demandent 835 px et ne tiennent pas sur une ligne : la barre faisait trois lignes (204 px), le volet de la fiche (60 % de la hauteur) passait dessous,
   avec sa poignée « Replier la fiche », la mention d'attribution et, repliée, les contrôles de zoom. Comme sous 641 px « Connexion » s'efface (« Créer un compte » ouvre la même modale, avec
   ses onglets), le mot-symbole aussi sous 722 px (connecté, « Se déconnecter » élargit la ligne à 722 px) : deux lignes, la marque et les actions puis la recherche. Au-dessus de 580 px de
   haut (tablette en portrait) la barre garde ses trois lignes : le volet, 60 % de plus de 580 px, laisse alors 19 px ou plus sous elle. */
@media (min-width: 641px) and (max-width: 834.98px) and (max-height: 580px) {
  .cm-nav__login { display: none; }
}
@media (min-width: 641px) and (max-width: 721.98px) and (max-height: 580px) {
  .cm-nav .cm-wordmark { display: none; }
  .cm-nav .cm-brand { padding: 0 10px; }
}
/* paysage : sous la barre du haut (144 px) le volet ouvert (60 % de 390 px) ne laisse que 12 px, où la mention d'attribution (11 px) ne tient pas : la barre rend le remplissage
   transparent de son bas, ce qui laisse 20 px entre elle et le volet */
@media (max-height: 500px) {
  .home__nav { padding-bottom: var(--space-1); }
}
/* téléphone en paysage de 641 à 959 px de large, 450 px de haut au plus : sous la barre de deux lignes (136 px) le volet ouvert ne laisse que 14 px à 375 px de haut et 8 px à 360 px, où la mention
   d'attribution (11 px et sa marge de 8 px) ne tient pas ; la marge du haut et l'écart des deux lignes se resserrent de 12 px en tout (124 px) : 26 px à 375 px de haut, 20 px à 360 px */
@media (min-width: 641px) and (max-width: 959.98px) and (max-height: 450px) {
  .home__nav { padding-top: var(--space-2); }
  .home__nav .cm-nav { row-gap: var(--space-2); }
}
/* paysage très bas, sous 360 px de haut (un téléphone dont le navigateur garde sa barre d'adresse : la fenêtre est plus basse que l'écran) : sous la barre (124 px) il ne reste plus de place pour
   tout ce qui y est empilé. Le volet ouvert passe à 55 % de la hauteur (à 60 % il laisse moins de 19 px à la mention d'attribution et à sa marge) ; replié, la pile des contrôles de zoom (158 px
   au-dessus de la poignée) passerait sous la barre : masquée comme volet ouvert (le pincement, la molette et les touches + et − zooment toujours, et fiche fermée elle est là) ; la carte
   d'accueil se resserre de 14 px. Tient jusqu'à 318 px de haut. */
@media (min-width: 641px) and (max-width: 959.98px) and (max-height: 359.98px) {
  .fiche { height: 55vh; height: 55dvh; }
  .home[data-fiche="ouvert"] .home__pile { bottom: calc(55vh + var(--space-2)); bottom: calc(55dvh + var(--space-2)); }
  .home[data-fiche="replie"] .home__controls { display: none; }
  .home__intro { padding-block: 12px; }
  .home__intro .cm-intro__title { margin-top: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .fiche, .fiche__contenu, .home__controls { transition: none; }
  .fiche > turbo-frame:empty::before { animation: none; }
}

/* Chat : conversation avec l'assistant IA d'une annonce (contrôleur chat ; composants Chat, ChatBulle, ChatNote ; classes cm-bubble, cm-typing, cm-src…).
   Le chat remplace la fiche dans le même panneau : mêmes 408 px à droite sur écran large, plein écran sous 960 px. */
.chat { flex: 1; min-height: 0; }
.chat__tete { flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: 6px; padding: 12px 12px 12px 10px; }
.chat__qui { flex: 1; min-width: 0; margin-left: 6px; }
.chat__qui .cm-who { min-width: 0; }
.chat__nom { min-width: 0; overflow: hidden; font: 600 16px/20px var(--font-sans); text-overflow: ellipsis; white-space: nowrap; color: var(--fog); }
.cm-ai { flex: none; }
.cm-ai abbr { text-decoration: none; }
.chat__legende { margin-top: 3px; }
/* numéro dévoilé : une ligne sous l'en-tête, sélectionnable, à côté du lien tel: */
.chat__tel { flex: 1 1 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) 0 0 var(--space-3); border-top: 1px solid var(--line); }
.chat__tel-numero { font: 600 17px/22px var(--font-sans); font-variant-numeric: tabular-nums; letter-spacing: -.01em; -webkit-user-select: text; user-select: text; }

/* position: relative : les textes réservés aux lecteurs d'écran (absolus) restent dans la zone qui défile ; sans cela le volet entier, qui masque son débordement, pouvait glisser vers le haut et cacher l'en-tête */
.chat__corps { position: relative; padding: var(--space-4) 22px var(--space-2); overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
/* la zone est atteignable au clavier (tabindex="0") : l'anneau global (2 px, décalé de 2 px) serait coupé par le volet, qui masque son débordement ; il est tracé à l'intérieur */
.chat__corps:focus-visible { outline-offset: -2px; box-shadow: none; }
/* focalisable (tabindex="0") : sur Android, un toucher sur une bulle grisait toute la zone de conversation ; pas de voile de toucher */
.chat__corps { -webkit-tap-highlight-color: transparent; }
/* les zones d'écriture, de brouillon et d'alerte restent dans la page même vides (régions vives) : sans interligne tant qu'elles sont vides */
.chat__fil { display: flex; flex-direction: column; }
.chat__fil > * + * { margin-top: 14px; }
.chat__fil > :empty { margin-top: 0; }
.chat__journal, .chat__brouillon { min-width: 0; }
.chat .cm-bubble { overflow-wrap: anywhere; white-space: pre-line; }
.chat__sources { gap: 6px; margin-top: 2px; }
.chat__sources[hidden] { display: none; }
/* puces de source : jusqu'à 8, de 60 caractères au plus (« Web · mairie-eguilles.fr ») ; une puce longue passe à la ligne dans le volet au lieu de le déborder */
.chat__sources .cm-src { min-width: 0; max-width: 100%; height: auto; min-height: 24px; padding-block: 5px; line-height: 14px; white-space: normal; overflow-wrap: anywhere; text-align: left; }
/* un lien de source se vise au doigt : cible de 44 px sur écran tactile (les puces sans lien gardent leur hauteur) */
@media (pointer: coarse) { .chat__sources .cm-src--lien { min-height: var(--control-sm); } }
.chat__alerte, .chat__ecriture { display: flex; flex-direction: column; }
.chat__alerte > * + *, .chat__ecriture > * + * { margin-top: var(--space-2); }
/* ce que l'assistant cherche, tant que le texte n'a pas commencé : une ligne par étape, sans fond (une activité, pas un message) ;
   coche = faite, points d'écriture = en cours (la dernière reçue) ; le repère de chaque ligne fait 18 px pour que les textes s'alignent */
.chat__attente { min-width: 0; max-width: 100%; }
/* le texte était déjà commencé (une phrase avant de chercher) : les étapes prolongent sa bulle, sans seconde étiquette « Assistant IA » */
.chat__brouillon:not(:empty) + .chat__ecriture .chat__attente .cm-bubble__who { display: none; }
.chat__etapes { display: flex; flex-direction: column; gap: 6px; max-width: 100%; margin: 0; padding: 0; list-style: none; }
.chat__etape { display: flex; align-items: flex-start; gap: var(--space-2); min-width: 0; font: 400 13.5px/19px var(--font-sans); color: var(--fog-2); overflow-wrap: anywhere; }
.chat__etape .cm-ic { margin: 2.5px 2px 0; color: var(--mousse); }
.chat__etape .cm-typing { flex: none; align-items: center; height: 19px; padding: 0; gap: 3px; border-radius: 0; background: none; }
.chat__etape .cm-typing i { width: 4px; height: 4px; }
.chat__etape--en-cours { color: var(--fog); }
.chat__etape--en-cours .cm-ic, .chat__etape:not(.chat__etape--en-cours) .cm-typing { display: none; }
.chat__etape--resume { padding-left: calc(18px + var(--space-2)); }
.chat__etape--nouvelle { animation: chat-etape var(--dur-fast) var(--ease); }
@keyframes chat-etape { from { opacity: 0; transform: translateY(4px); } }
/* attente longue (« Je vérifie encore… ») : une phrase discrète sous les étapes */
.chat__patience { margin: 0; font: 400 13px/18px var(--font-sans); color: var(--fog-2); }
.chat__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.chat__note--succes .cm-ic { color: var(--mousse); }
.chat__note--avertissement .cm-ic { color: var(--ambre); }
.chat__note--information .cm-ic { color: var(--fog-2); }
.chat .cm-sysnote__t { overflow-wrap: anywhere; }
/* cibles de 44 px au moins (le design system dessine ces boutons à 36 px) */
.chat__mini { display: inline-flex; align-items: center; gap: 6px; min-height: var(--control-sm); padding: 0 14px; border: 1.5px solid var(--line-strong); border-radius: var(--radius-pill); background: transparent; color: var(--fog); font: 500 13px/13px var(--font-sans); cursor: pointer; }
.chat__mini:hover { background: var(--glass-hover); }
.chat .cm-quick button { min-height: var(--control-sm); height: auto; padding-block: 0; }
.chat .cm-quick button:hover { background: var(--glass-hover); }

/* pied : réponses rapides, saisie, mention et effacement */
.chat__pied { flex: none; padding: var(--space-3) var(--space-4) 14px; border-top: 1px solid var(--line); }
.chat__rapides { margin-bottom: 10px; }
.chat .cm-composer__field { align-self: stretch; }
.chat .cm-composer__field:focus-within { border-color: var(--fog); outline: 2px solid var(--fog); outline-offset: 2px; box-shadow: var(--shadow-focus); }
.chat .cm-composer__field textarea { max-height: 129px; overflow-y: auto; scrollbar-width: thin; }
.chat .cm-composer__field textarea:disabled { cursor: not-allowed; }
.chat .cm-composer__field:has(textarea:disabled) { opacity: .55; }
.chat__envoi { display: inline-flex; align-items: center; justify-content: center; flex: none; width: var(--control-md); height: var(--control-md); padding: 0; border: 0; border-radius: 50%; background: var(--fog); color: var(--night); cursor: pointer; transition: filter var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease); }
.chat__envoi:hover { filter: brightness(1.08); }
.chat__envoi:active { transform: scale(.96); }
.chat__envoi:disabled { opacity: .45; cursor: not-allowed; filter: none; transform: none; }
.chat__effacer { display: inline-flex; align-items: center; min-height: var(--control-sm); margin: 0 0 calc(-1 * var(--space-2)); padding: 0; border: 0; background: transparent; color: var(--fog-2); font: 400 12px/17px var(--font-sans); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.chat__effacer:hover { color: var(--fog); }
/* ce que l'effacement ne rappelle pas : sous le bouton, et caché avec lui tant qu'il n'y a pas de conversation à effacer */
.chat__effacer-aide { margin: 0; font: 400 12px/17px var(--font-sans); color: var(--fog-2); }
.chat__effacer[hidden] + .chat__effacer-aide { display: none; }
/* retour du chat : la fiche revient en haut et « Discuter » reprend le focus ; ramené dans la vue (scrollIntoView, au plus près), le lien garde de l'air pour son anneau de focus */
.cm-annonce__actions a[href*="/chat"] { scroll-margin-block: var(--space-4); }

/* écran étroit : le chat remplit l'écran (au-dessus de la barre du haut) au lieu du volet de 60 % de la fiche */
@media (max-width: 959.98px) {
  .fiche:has(.chat) { top: 0; z-index: calc(var(--z-nav) + 1); height: 100vh; height: 100dvh; border: 0; border-radius: 0; transform: none; }
  .fiche:has(.chat) .fiche__poignee { display: none; }
  .fiche:has(.chat) .chat__tete { padding: calc(var(--space-3) + env(safe-area-inset-top, 0px)) var(--space-2) var(--space-3) 6px; gap: 4px; }
  .fiche:has(.chat) .chat__qui { margin-left: 4px; }
  .fiche:has(.chat) .chat__corps { padding: var(--space-4) var(--space-4) var(--space-2); }
  .fiche:has(.chat) .chat__pied { padding: 10px var(--space-3) calc(14px + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  .chat__envoi { transition: none; }
  .chat__etape--nouvelle { animation: none; }
}

/* code (zone du PLU, servitude) : la casse du code compte (1AUa), le chip n'est pas mis en capitales */
.cm-chip--code { text-transform: none; letter-spacing: .02em; }
.cm-seg button { height: var(--control-sm); }
