/* zones.css : la famille « zones d'intervention » dans le système Arche.
   Hub /zones-d-intervention/ et les 60 pages communes (tpl/commune.php).

   Le héros (texte à gauche, baie cintrée à droite) est posé par core.css ;
   ici, ses réglages propres : surtitre au-dessus du titre, bloc de texte
   centré sur la hauteur de la baie, baie de 580 px à 1440 comme l'accueil,
   la lumière de persienne qui glisse (une vraie .ombre-persienne, que
   motion.js anime, à la place du ::before immobile de rest.css).

   Corrections de l'audit pour cette famille :
   - plus aucun grand numéro (« 03 ») : les tournées sont numérotées dans
     la petite arche de pierre, et le balisage n'a plus d'index géant ;
   - les longs noms (« Le Rayol-Canadel-sur-Mer ») passent à la ligne dans
     leur colonne : distance et délai gardent une colonne fixe, à droite ;
   - les noms de port de la bande ont tous le même corps et la même
     réserve de deux lignes : aucune carte ne paraît plus grande qu'une autre.

   Toutes les feuilles de pages/ sont chargées sur tout le site : chaque
   règle est donc préfixée par une classe zn-. Aucun état d'attente
   (opacité nulle, clip-path fermé) n'est écrit ici : le JS part de l'état
   final (docs/motion-api.md). */

@layer components {
  /* ======================================================================
     Héros : hub et pages communes
     ====================================================================== */
  .zn-hero::before { content: none; }
  .zn-hero > .wrap { position: relative; z-index: 1; }
  .rameau--zn { width: min(40vw, 540px); height: min(40vw, 540px); top: -8%; left: -9%; transform: rotate(-8deg); }
  .zn-hero__surtitre { margin-bottom: 0; }
  .zn-hero__titre { font-size: var(--fs-h1); }
  .zn-hero__titre--long { font-size: clamp(2.1rem, 1rem + 2.7vw, 3.7rem); }
  .zn-hero__texte .lead { max-width: 30em; }
  .zn-hero__volet { margin: 0; }
  .zn-hero__reperes .stat strong { font-size: clamp(2rem, 1.45rem + 1.25vw, 2.9rem); }
  .zn-hero__reperes .stat > span .u-num { font-style: normal; }
  .zn-hero__cote-legende { display: flex; align-items: center; gap: .7rem; margin-top: var(--esp-s); font: italic 1.15rem / 1.35 var(--serif); color: var(--argile); max-width: none; }
  .zn-hero__anneau { flex: none; width: 10px; height: 10px; border: 1.5px solid var(--argile); border-radius: 50%; }
  .zn-hero__carte { max-width: 32rem; }
  /* La petite côte : des noms d'au moins 14 px réels (le SVG fait environ
     500 px pour 1200 unités) et un halo d'enduit épais, peint sous la
     lettre, pour que le trait de côte ne barre plus l'étiquette. */
  .zn-hero__carte .coastline__point text { font-size: 36px; stroke: var(--chaux); stroke-width: 10px; paint-order: stroke; }
  /* La moulure de pierre de l'accueil (.hero__baie::before) : un contour fin,
     décalé autour de l'arche. Visible sans JS ; motion.js peut seulement la
     faire apparaître (--moulure de 0 à 1), jamais la laisser cachée. */
  .zn-hero__panneau::before { content: ""; position: absolute; inset: -16px -16px 0; border: 1px solid var(--pierre); border-bottom: 0; border-radius: var(--cintre); pointer-events: none; opacity: var(--moulure, 1); }

  @media (min-width: 900px) {
    /* Cinq rangées : un ressort, le surtitre, le titre, le texte (qui reçoit
       le second ressort), puis la bande des repères. Le bloc de texte se
       tient ainsi au milieu de la baie, comme sur l'accueil. */
    .zn-hero__grille { grid-template-columns: minmax(0, 1fr) minmax(0, min(44%, 580px)); grid-template-rows: minmax(0, 1fr) auto auto minmax(0, 1fr) auto; }
    .zn-hero__grille > .zn-hero__surtitre { grid-column: 1; grid-row: 2; margin-bottom: 1.3rem; }
    .zn-hero__grille > h1 { grid-column: 1; grid-row: 3; align-self: auto; padding-top: 0; }
    .zn-hero__grille > .zn-hero__texte { grid-column: 1; grid-row: 4; align-self: start; margin-top: var(--esp-l); }
    .zn-hero__grille > .zn-hero__panneau { grid-column: 2; grid-row: 1 / span 4; height: clamp(520px, 76svh, 720px); }
    .zn-hero__grille > .zn-hero__reperes { grid-column: 1 / -1; grid-row: 5; margin-top: calc(var(--esp-xl) + 1rem); padding-top: var(--esp-l); border-top: var(--filet); }
    /* Page commune : la petite côte à gauche, les quatre repères en deux
       rangées sous la baie, sur la même ligne de pierre. */
    .zn-hero--commune .zn-hero__grille > .zn-hero__cote { grid-column: 1; grid-row: 5; align-self: start; margin-top: calc(var(--esp-xl) + 1rem); padding-top: var(--esp-l); border-top: var(--filet); }
    .zn-hero--commune .zn-hero__grille > .zn-hero__reperes { grid-column: 2; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.2rem 1.5rem; }
    /* Sous les repères, le bas du héros et le haut des prestations
       s'additionnaient en 250 px de fond vide (revue) : la ligne de pierre
       des repères sépare déjà les deux blocs, l'enchaînement se resserre
       comme sur l'accueil. */
    .zn-hero--commune { padding-bottom: var(--esp-l); }
    .zn-hero--commune + .zn-prestas.section { padding-top: var(--section-y-s); }
  }
  @media (max-width: 899px) {
    /* Sur téléphone : surtitre, titre, baie, chapo et bouton dans le premier
       écran ; les repères et la légende de la côte suivent. */
    .zn-hero { padding-top: 1.2rem; }
    .rameau--zn { width: 90vw; height: 90vw; top: -4%; left: -34%; }
    .zn-hero__surtitre { margin-bottom: .7rem; }
    .zn-hero__titre { font-size: clamp(2.15rem, 1.2rem + 4.4vw, 2.9rem); }
    .zn-hero__titre--long { font-size: clamp(1.95rem, 1.1rem + 4vw, 2.6rem); }
    /* Baie large et basse : l'anse de panier, le plein cintre en ferait un dôme. */
    .zn-hero__grille > .zn-hero__panneau { height: clamp(210px, 30svh, 330px); margin-top: 1.25rem; }
    .zn-hero__volet { border-radius: var(--anse); }
    .zn-hero__texte .lead { font-size: 1rem; line-height: 1.6; }
    .zn-hero__texte > * + * { margin-block-start: 1.1rem; }
    .zn-hero__reperes { order: 4; margin-top: var(--esp-xl); padding-top: var(--esp-l); border-top: var(--filet); }
    /* La petite côte et sa légende disparaissent ensemble : seule, la
       légende restait orpheline au-dessus d'un vide. La distance reste dans
       les repères (« 56 km, depuis notre base »). */
    .zn-hero__cote { display: none; }
    .zn-hero__panneau::before { inset: -10px -10px 0; border-radius: var(--anse); }
  }
  @media (min-width: 600px) and (max-width: 899px) {
    /* Tablette : la baie garde de la hauteur, sinon elle devient un bandeau ;
       les quatre repères tiennent sur une seule rangée. */
    .zn-hero__grille > .zn-hero__panneau { height: clamp(300px, 46vw, 420px); }
    .zn-hero__reperes { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.5rem 1.25rem; }
  }

  /* ======================================================================
     Hub · le littoral : la côte réelle et les trois tournées en sommaire
     ====================================================================== */
  .zn-littoral { position: relative; padding-block: var(--section-y); background: var(--enduit); overflow: hidden; }
  /* Halo d'enduit épais, peint sous la lettre : le trait ne barre plus un nom. */
  .zn-littoral .coastline--cote .coastline__point text { stroke: var(--enduit); stroke-width: 6px; paint-order: stroke; }
  .zn-littoral__invite { display: none; }
  .zn-littoral__grille { display: grid; gap: var(--esp-xl) var(--gouttiere); }
  .zn-littoral__tete > .lead { margin-top: var(--esp-m); }
  .zn-littoral__rythmes { border-top: var(--filet); }
  .zn-littoral__rythme { max-width: none; }
  .zn-littoral__rythme a { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: .25rem 1.2rem; align-items: center; min-height: var(--cible); padding-block: 1.15rem; border-bottom: var(--filet); }
  /* Le numéro de tournée dans la petite arche de pierre, jamais en grand. */
  .zn-littoral__num { grid-row: 1 / span 2; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 48px; padding-top: 8px; border: 1px solid var(--pierre); border-radius: 999px 999px 4px 4px; font-size: .9rem; color: var(--argile); background: var(--chaux-clair); }
  .zn-littoral__nom { font: 400 var(--fs-h4) / 1.2 var(--serif); transition: color var(--dur-survol) var(--doux), transform var(--dur-survol) var(--doux); }
  .zn-littoral__rythme a:is(:hover, :focus-visible) .zn-littoral__nom { color: var(--argile); transform: translateX(5px); }
  .zn-littoral__delai { grid-column: 2; font-size: var(--fs-petit); color: var(--encre-doux); }
  .zn-littoral__trace { position: relative; max-width: 1240px; width: 100%; margin-inline: auto; }
  @media (min-width: 900px) {
    .zn-littoral__grille { grid-template-columns: minmax(0, 5fr) minmax(0, 1fr) minmax(0, 5fr); }
    .zn-littoral__tete { grid-column: 1; grid-row: 1; align-self: end; }
    .zn-littoral__rythmes { grid-column: 3; grid-row: 1; align-self: end; }
    .zn-littoral__trace { grid-column: 1 / -1; grid-row: 2; margin-top: var(--esp-l); }
  }
  @media (min-width: 600px) and (max-width: 899px) {
    /* Tablette : la côte entière tient dans la largeur, de Cassis à
       Saint-Tropez, sans défilement ; noms d'environ 15 px réels. */
    .zn-littoral__trace > .coastline { width: 100%; }
    .zn-littoral .coastline--cote .coastline__point text,
    .zn-littoral .coastline--cote .coastline__point.is-cle text { font-size: 26px; stroke-width: 8px; }
    .zn-littoral .coastline__point circle { r: 6; }
  }
  @media (max-width: 599px) {
    /* Téléphone : la côte se parcourt au doigt, à 160vw (Toulon et Hyères
       tiennent dans le premier écran, 230vw n'en montrait que trois noms).
       Une invite visible et un fondu au bord droit disent qu'elle continue. */
    .zn-littoral__invite { display: block; margin: 0 0 -1rem; font: italic 1.08rem / 1.35 var(--serif); color: var(--argile); max-width: none; }
    .zn-littoral__trace { margin-inline: calc(-1 * var(--marge)); width: auto; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; scroll-padding-inline: var(--gout);
      -webkit-mask-image: linear-gradient(90deg, #000 0, #000 90%, transparent); mask-image: linear-gradient(90deg, #000 0, #000 90%, transparent); }
    .zn-littoral__trace::-webkit-scrollbar { display: none; }
    .zn-littoral__trace > .coastline { width: 160vw; padding-inline: var(--gout); }
    .zn-littoral .coastline--cote .coastline__point text,
    .zn-littoral .coastline--cote .coastline__point.is-cle text { font-size: 30px; stroke-width: 9px; }
    .zn-littoral .coastline__point circle { r: 7; }
  }

  /* ======================================================================
     Hub · les tournées : la baie collante change de paysage (data-vues)
     ====================================================================== */
  .zn-tournees { position: relative; padding-block: var(--section-y); background: var(--chaux); }
  .zn-tournees__grille { display: grid; align-items: start; }
  .zn-tournees__arche { box-shadow: var(--ombre-baie); }
  .zn-tournees__arche img { position: absolute; inset: 0; opacity: 0; transform: scale(1.05); transition: opacity 1.6s var(--doux), transform 2.4s var(--doux); }
  .zn-tournees__arche img.is-actif { opacity: 1; transform: none; }
  /* Un paysage dans la baie en portrait (la terrasse en terre cuite) garde
     son sujet grâce au cadrage posé sur l'image (--cadrage). */
  :is(.zn-tournees__arche, .zn-groupe__baie) img { object-position: var(--cadrage, 50% 50%); }
  .zn-tournees__repere { margin: 18px auto 0; max-width: none; text-align: center; font: italic 1.3rem / 1.3 var(--serif); color: var(--argile); }
  .zn-groupe { scroll-margin-top: calc(var(--h-entete) + 1rem); }
  .zn-groupe + .zn-groupe { margin-top: var(--section-y-s); padding-top: var(--section-y-s); border-top: var(--filet); }
  .zn-groupe h2 { font-size: var(--fs-h2-s); }
  .zn-groupe__rythme { margin-top: var(--esp-m); font: italic 1.25rem / 1.35 var(--serif); color: var(--argile); max-width: none; }
  .zn-groupe__texte { margin-top: .6rem; color: var(--encre-doux); }
  .zn-groupe__registre { margin-top: var(--esp-l); }
  .zn-groupe__baie { display: none; }
  @media (min-width: 900px) {
    .zn-tournees__grille { grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); column-gap: clamp(3rem, 6vw, 7rem); }
    .zn-tournees__baie { position: sticky; top: calc(var(--h-entete) + 3svh); height: min(calc(100svh - var(--h-entete) - 8svh), 780px); }
    .zn-tournees__arche { height: calc(100% - 52px); }
  }
  @media (max-width: 899px) {
    .zn-tournees__baie { display: none; }
    /* Les trois baies sur toute la colonne, alignées sur la gouttière comme
       le texte : décalées à 88 %, elles passaient pour un défaut d'alignement. */
    .zn-groupe__baie { display: block; height: clamp(200px, 56vw, 320px); margin-bottom: var(--esp-l); box-shadow: var(--ombre-baie); }
  }

  /* ---- Registres de communes (tournées du hub, voisines d'une commune) :
     le nom passe à la ligne dans sa colonne, jamais à côté de ses chiffres ;
     distance et délai tiennent dans une colonne fixe, alignée à droite. ---- */
  .registre__ligne:is(.zn-groupe__ligne, .zn-voisines__ligne) { grid-template-columns: minmax(0, 1fr) 6.6rem; column-gap: 1rem; padding-block: 1rem; }
  :is(.zn-groupe__ligne, .zn-voisines__ligne) .registre__titre { font-size: 1.3rem; line-height: 1.18; }
  :is(.zn-groupe__ligne, .zn-voisines__ligne) .registre__chiffres { grid-column: 2; display: grid; justify-items: end; gap: .15rem; text-align: right; white-space: nowrap; }
  .zn-groupe__commune, .zn-voisines__commune { min-width: 0; }
  .zn-groupe__ligne--base .registre__meta { color: var(--argile); }
  /* Le survol glisse le NOM (un span dans le lien), plus le paragraphe :
     un ancêtre transformé devient le bloc conteneur du ::after étiré du
     lien (rest.css), qui se réduisait alors à la ligne du nom (26 px) ; un
     clic sur les kilomètres ou le délai ne menait plus nulle part. Le span
     est DANS le lien : le ::after garde la ligne entière pour bloc. */
  .registre__ligne:is(.zn-groupe__ligne, .zn-voisines__ligne, .zn-prestas__ligne) .registre__titre { transition: color var(--dur-survol) var(--doux); }
  .registre__ligne:is(.zn-groupe__ligne, .zn-voisines__ligne, .zn-prestas__ligne):is(:hover, :focus-within) .registre__titre { transform: none; }
  :is(.zn-groupe__ligne, .zn-voisines__ligne, .zn-prestas__ligne) .registre__nom { display: inline-block; transition: transform var(--dur-survol) var(--doux); }
  .registre__ligne:is(.zn-groupe__ligne, .zn-voisines__ligne, .zn-prestas__ligne):is(:hover, :focus-within) .registre__nom { transform: translateX(6px); }
  /* Dès la tablette, deux colonnes : une seule colonne de 60 lignes faisait
     5 000 px de liste. */
  @media (min-width: 600px) {
    .zn-groupe__registre, .zn-voisines__registre { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(1.5rem, 2.6vw, 2.75rem); }
    .zn-groupe__ligne .registre__titre { font-size: 1.22rem; }
  }
  /* Téléphone : un registre compact en deux colonnes, le nom au-dessus, le
     code postal, puis « 9 km · 24 à 48 h » sur une ligne. La ligne entière
     reste la cible du lien (bien au-delà de 44 px). */
  @media (max-width: 599px) {
    .zn-groupe__registre { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1rem; }
    .registre__ligne.zn-groupe__ligne { grid-template-columns: minmax(0, 1fr); row-gap: .1rem; align-content: start; padding-block: .7rem; }
    .zn-groupe__ligne .registre__titre { font-size: 1.1rem; overflow-wrap: anywhere; }
    .zn-groupe__ligne .registre__meta { margin-top: 0; font-size: .86rem; }
    .zn-groupe__ligne .registre__chiffres { grid-column: 1; display: flex; flex-wrap: wrap; gap: 0 .4rem; justify-items: start; text-align: left; white-space: nowrap; font-size: .86rem; }
    .zn-groupe__ligne .registre__chiffres > span + span::before { content: "·"; margin-right: .4rem; }
  }

  /* ======================================================================
     Hub · les 30 ports : une bande de niches (épinglée et horizontale sur
     bureau ; au doigt, avec aimantation, sur mobile et sans JavaScript)
     ====================================================================== */
  .zn-ports { display: grid; gap: var(--esp-xl); align-content: center; padding-block: var(--section-y-s); background: var(--lin); overflow: clip; }
  .zn-ports__tete { display: grid; gap: var(--esp-l) var(--gouttiere); }
  .zn-ports__tete h2 { max-width: 14em; }
  .zn-ports__texte > * + * { margin-block-start: var(--esp-m); }
  .zn-ports__note { font-size: var(--fs-petit); color: var(--encre-doux); max-width: 34em; }
  /* scroll-padding : l'aimantation alignait la première niche sur le bord de
     l'écran et « mangeait » la marge de la piste ; elle s'aligne sur le titre. */
  /* La barre de défilement n'est masquée que lorsque motion.js épingle la
     bande et la fait défiler à la molette (html.js-bureau). Sans JavaScript
     ou en mouvement réduit, sur bureau, elle restait coupée au sixième port
     sans aucun moyen visible d'atteindre les autres (revue) : une barre
     fine, couleur de pierre, le dit. */
  .zn-ports__bande { overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: thin; scrollbar-color: var(--pierre) transparent; scroll-padding-inline: var(--marge); }
  html.js-bureau .zn-ports__bande { scrollbar-width: none; }
  /* Une barre de défilement en surimpression (macOS) reste cachée tant
     qu'on ne défile pas : un fondu au bord droit, comme sur la côte du
     téléphone, dit aussi que la bande continue. */
  html:not(.js-bureau) .zn-ports__bande { -webkit-mask-image: linear-gradient(90deg, #000 0, #000 88%, transparent); mask-image: linear-gradient(90deg, #000 0, #000 88%, transparent); }
  html.js-bureau .zn-ports__bande::-webkit-scrollbar { display: none; }
  .zn-ports__piste { display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, auto); gap: 16px; width: max-content; padding: .5rem var(--marge) 1.5rem; }
  .zn-ports__item { width: 15rem; max-width: none; scroll-snap-align: start; }
  .zn-ports__escale { display: flex; flex-direction: column; justify-content: flex-end; gap: .35rem; height: 100%; min-height: 10rem; padding: 1.6rem 1.4rem 1.3rem; border-radius: 120px 120px var(--rayon) var(--rayon); background: var(--chaux-clair); box-shadow: inset 0 0 0 1px rgba(205, 184, 149, .6); color: var(--encre); transition: translate var(--dur-survol) var(--doux), box-shadow var(--dur-survol) var(--doux); }
  .zn-ports__escale:is(:hover, :focus-visible) { translate: 0 -5px; box-shadow: inset 0 0 0 1px var(--argile), var(--ombre-douce); }
  /* Même corps pour tous, cartes de même hauteur (la rangée de grille),
     nom posé en bas : un nom court ne paraît pas plus grand qu'un long. */
  .zn-ports__nom { display: block; font: 400 1.3rem / 1.2 var(--serif); text-wrap: balance; }
  .zn-ports__commune { font-size: var(--fs-petit); color: var(--encre-doux); }
  @media (min-width: 900px) {
    .zn-ports__tete { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: end; }
    html.js-bureau .zn-ports { min-height: 100svh; padding-block: calc(var(--h-entete) + 1.5rem) 1.5rem; }
  }

  /* ======================================================================
     Page commune : prestations, quartiers, climat, quai, FAQ, voisines
     ====================================================================== */
  .zn-prestas__grille, .zn-quartiers__grille, .zn-quai__grille, .zn-faq__grille, .zn-voisines__grille { display: grid; gap: var(--esp-xl) var(--gouttiere); align-items: start; }
  :is(.zn-prestas__tete, .zn-faq__tete, .zn-voisines__tete) > :is(.zn-prestas__lien, .zn-faq__lien, .zn-voisines__lien) { margin-top: var(--esp-l); }
  @media (min-width: 900px) {
    .zn-prestas__grille, .zn-quartiers__grille, .zn-faq__grille, .zn-voisines__grille { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(2.5rem, 6vw, 7rem); }
    .zn-prestas__tete, .zn-quartiers__tete, .zn-faq__tete, .zn-voisines__tete { position: sticky; top: calc(var(--h-entete) + 2.5rem); }
    .zn-faq__corps { max-width: none; }
  }

  /* Les prestations : quatre lignes au prix d'appel, puis les pilules de lin. */
  .registre__ligne.zn-prestas__ligne { grid-template-columns: auto minmax(0, 1fr); }
  .zn-prestas__prix { grid-column: 2; display: grid; gap: .1rem; max-width: none; color: var(--encre); }
  .zn-prestas__prefixe { font: italic 1.02rem / 1.2 var(--serif); color: var(--argile); }
  .zn-prestas__montant { font: 400 1.3rem / 1.2 var(--sans); white-space: nowrap; }
  .zn-prestas__note { font-size: var(--fs-mini); line-height: 1.35; color: var(--encre-doux); }
  /* Dès 600 px, le prix d'appel prend sa colonne à droite (il tombait sous
     le nom à la tablette, avec 170 px vides à droite). */
  @media (min-width: 600px) {
    .registre__ligne.zn-prestas__ligne { grid-template-columns: auto minmax(0, 1fr) 9.5rem; }
    .zn-prestas__prix { grid-column: 3; justify-items: end; text-align: right; }
  }
  .zn-prestas__chapo { margin-top: var(--esp-m); color: var(--encre-doux); max-width: 26em; }
  .zn-voisines__note { margin-top: var(--esp-m); font: italic 1.08rem / 1.4 var(--serif); color: var(--encre-doux); max-width: none; }
  .zn-prestas__liste { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--esp-xl); }
  .zn-prestas__liste li { max-width: none; }
  .zn-prestas__item { display: inline-flex; align-items: center; min-height: var(--cible); padding: .55rem 1.15rem; border-radius: var(--pill); background: var(--lin); font-size: .94rem; line-height: 1.3; transition: color var(--dur-survol) var(--doux), box-shadow var(--dur-survol) var(--doux); }
  .zn-prestas__item:is(:hover, :focus-visible) { color: var(--argile); box-shadow: inset 0 0 0 1px var(--argile); }
  /* Téléphone : onze pastilles presque une par ligne faisaient 550 px
     d'empilement (revue). Deux colonnes égales, le nom sur deux lignes au
     besoin, une cible qui reste à 44 px au moins. */
  @media (max-width: 599px) {
    .zn-prestas__liste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .zn-prestas__item { display: flex; width: 100%; height: 100%; min-height: 44px; padding: .5rem .9rem; border-radius: 22px; font-size: .88rem; line-height: 1.25; }
    /* Une dernière pastille seule sur sa rangée prend sa largeur naturelle,
       sur une ligne, au lieu d'une demi-colonne coupée en deux. */
    .zn-prestas__liste li:last-child:nth-child(odd) { grid-column: 1 / -1; justify-self: start; }
  }

  /* Les quartiers, sur l'enduit, avec le rameau en filigrane. */
  .zn-quartiers { overflow: hidden; }
  .zn-quartiers > .wrap { position: relative; z-index: 1; }
  .rameau--zn-quartiers { width: min(34vw, 440px); height: min(34vw, 440px); right: -4%; bottom: -12%; transform: scaleX(-1) rotate(6deg); }
  .zn-quartiers__liste { border-top: var(--filet); }
  .zn-quartiers__item { display: grid; gap: .4rem var(--gouttiere); padding-block: 1.25rem; border-bottom: var(--filet); }
  .zn-quartiers__item dt { font: 400 var(--fs-h4) / 1.2 var(--serif); }
  .zn-quartiers__item dd { margin: 0; color: var(--encre-doux); max-width: var(--mesure); }
  @media (min-width: 900px) { .zn-quartiers__item { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); align-items: baseline; } }

  /* Le climat : une baie et un encadré d'enduit côte à côte, sans recouvrement. */
  .zn-climat__grille { display: grid; gap: var(--esp-l) clamp(2.5rem, 6vw, 7rem); align-items: center; }
  .zn-climat__baie { height: clamp(360px, 70svh, 660px); margin: 0; box-shadow: var(--ombre-baie); }
  .zn-climat__baie picture, .zn-quai__baie picture { inset: -6% 0; }
  .zn-climat__baie img, .zn-quai__baie img { object-position: var(--cadrage, 50% 50%); }
  .zn-climat__panneau h2 { font-size: var(--fs-h2-s); }
  .zn-climat__panneau > .surtitre { margin-bottom: -.4rem; }
  @media (min-width: 900px) { .zn-climat__grille { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); } }
  @media (max-width: 899px) { .zn-climat__baie { height: clamp(300px, 92vw, 440px); } }

  /* À quai : les ports de la commune le long d'un fil, et un port dans une
     baie en anse de panier. */
  .zn-quai__grille { align-items: center; }
  .zn-quai__tete > .lead, .zn-quai__note { margin-top: var(--esp-m); }
  .zn-quai__note { font-size: var(--fs-petit); color: var(--encre-doux); max-width: 34em; }
  .zn-quai__liste { position: relative; margin-top: var(--esp-l); padding-left: 2.2rem; }
  .zn-quai__fil { position: absolute; top: .6rem; bottom: .6rem; left: 5px; width: 1px; background: linear-gradient(180deg, var(--pierre), rgba(205, 184, 149, 0)); transform-origin: top; }
  .zn-quai__escales { display: grid; gap: var(--esp-xs); }
  .zn-quai__escale { max-width: none; }
  .zn-quai__port { position: relative; display: grid; gap: .2rem; min-height: var(--cible); padding-block: .45rem; }
  .zn-quai__point { position: absolute; left: calc(-2.2rem + .5px); top: 1.05em; width: 10px; height: 10px; border: 1.3px solid var(--argile); border-radius: 50%; background: var(--chaux-clair); transition: background-color var(--dur-survol) var(--doux); }
  .zn-quai__port:is(:hover, :focus-visible) .zn-quai__point { background: var(--argile); }
  .zn-quai__nom { font: 400 var(--fs-h4) / 1.2 var(--serif); transition: color var(--dur-survol) var(--doux); }
  .zn-quai__port:is(:hover, :focus-visible) .zn-quai__nom { color: var(--argile); }
  .zn-quai__meta { font-size: var(--fs-petit); color: var(--encre-doux); max-width: 40ch; }
  .zn-quai__lien { margin-top: var(--esp-l); }
  .zn-quai__baie { height: clamp(420px, 74svh, 680px); margin: 0; box-shadow: var(--ombre-baie); }
  @media (min-width: 900px) { .zn-quai__grille { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(2.5rem, 6vw, 7rem); } }
  @media (max-width: 899px) { .zn-quai__baie { order: -1; height: clamp(260px, 78vw, 380px); } }

  /* Blocs de structure : leur rythme vient de .section et de leurs enfants. */
  .zn-hero--hub, .zn-hero--commune, .zn-tournees__liste, .zn-prestas, .zn-prestas__corps, .zn-prestas__registre, .zn-quartiers, .zn-climat, .zn-quai, .zn-faq, .zn-voisines { min-width: 0; }
  .zn-ports__lien { margin-top: var(--esp-m); }
}
