/* ============================================================================
   The tile map (block « carte »).
   Companion of graph/static/graph/js/carte.js and graph/blocks/carte.html.
   Rules: spec-experience.md §6.15 (one map dialect), §6.2 (yellow = « ici »),
   §6.7 (colour means something), spec-design.md §2.

   Loaded by graph/templates/graph/blocks/carte_assets.html, AFTER leaflet.css:
   several rules below undo Leaflet's own defaults, which arrive in another
   dialect (rounded corners, shadows, #0078A8 blue).
   ========================================================================== */

/* ── The container ────────────────────────────────────────────────────────── */

.carte {
  /* The search button floats over the map and is placed against this box. */
  position: relative;
  /* A STACKING CONTEXT OF ITS OWN, AT LEVEL 0 (the user, 2026-10-02: « the map should go under
     the menu when scrolling up »). Leaflet layers its panes and controls from z-index 200 to
     1000, and the floating button above is at 1001. Without a context to hold them they are
     compared with the page's own layers, and the map's controls, marks and button were drawn
     OVER the sticky header (100) and the rail (40) as the page scrolled. The cartouche's map
     never showed it: `.mode-terminal .section-inner` is already a context at level 1. The
     map of a section (the fonds plate since the same day) had none. The full screen below
     sets its own level (200) on this same element, so it still rises above the header. */
  z-index: 0;
  margin: 0;
  border: 1px solid var(--ca-filet);
  background: var(--ca-surface);
}

/* Two heights, and no third (graph/blocks/carte.py HAUTEURS). « repere »: the
   map of a plate, under the cartouche — it situates, it is not explored.
   « vue »: the map that REPLACES the list, and must hold as many points as the
   list held rows.
   On compact §6.15 asks for the height of the list's first ten rows: a list row
   is 36 px, hence 360 px, and the map never takes more than 70 % of the window
   so the page stays scrollable around it. Decision 12 (B11) keeps that number and amends the
   sentence: the list's cards have grown since (277-323 px each on compact, ten rows would be
   about 3 000 px), so « ten rows » no longer means anything; 360 px is 43 % of an 844 px
   screen and the map never scrolls the page. */
.carte-cadre {
  height: min(360px, 70vh);
  width: 100%;
  background: var(--ca-surface-2);
}

@media (min-width: 1024px) {
  .carte--vue .carte-cadre { height: 520px; }
  .carte--repere .carte-cadre { height: 300px; }
}

/* ── The basemap: muted ──────────────────────────────────────────────────────
   protomaps-leaflet's « grayscale » flavor is already colourless, but it still
   reads louder than the ink of the points. The filter applies to the TILE pane
   only: the points live in overlayPane and markerPane and must keep their
   green, red and yellow (§6.7). Dimming the background rather than the points
   is what makes « no label louder than the points » (§6.15). */
.carte-cadre .leaflet-tile-pane {
  filter: grayscale(1) contrast(0.82) opacity(0.62);
}

/* Leaflet paints a blue-white background and rounds every corner: radius 0 and
   our surfaces, or it is a second site (spec-design §2). */
.carte-cadre.leaflet-container {
  background: var(--ca-surface-2);
  font-family: inherit;
  outline-offset: 2px;
}
.carte-cadre .leaflet-bar,
.carte-cadre .leaflet-bar a,
.carte-cadre .leaflet-popup-content-wrapper,
.carte-cadre .leaflet-tooltip {
  border-radius: 0;
  box-shadow: none;
}

/* ── The controls ─────────────────────────────────────────────────────────── */

.carte-cadre .leaflet-bar {
  border: 1px solid var(--ca-filet);
}
.carte-cadre .leaflet-bar a,
.carte-cadre .leaflet-bar a:hover {
  background: var(--ca-surface);
  color: var(--ca-charbon);
  border-bottom: 1px solid var(--ca-filet);
  /* §6.14 / spec-design §2: a 44 px touch target on the phone. */
  width: 44px;
  height: 44px;
  line-height: 44px;
  font-family: "IBM Plex Mono", monospace;
}
.carte-cadre .leaflet-bar a:hover {
  background: var(--ca-jaune-surlignage);
}

/* The four arrows (carte.js « THE FOUR ARROWS »): a cross in a 3 × 3 grid, each button on its
   side, the centre and the corners empty and open to the map under them (the group itself
   takes no click, its buttons do). The surface, the rule and the hover are the zoom bar's.
   30 px with a mouse, which can also drag: at the zoom bar's 44 px the cross was 132 px
   square, a sixth of a 300 px repère. 44 px on the touch tier (§6.14), where the cross is
   the only way to move a repère and the map is at least 360 px tall. */
.carte-cadre .carte-deplacer {
  --fleche: 30px;
  display: grid;
  grid-template-columns: repeat(3, var(--fleche));
  grid-template-rows: repeat(3, var(--fleche));
  pointer-events: none;
}
.carte-cadre .carte-fleche {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--ca-filet);
  border-radius: 0;
  background: var(--ca-surface);
  cursor: pointer;
}
.carte-cadre .carte-fleche:hover {
  background: var(--ca-jaune-surlignage);
}
.carte-cadre .carte-fleche--haut { grid-area: 1 / 2; }
.carte-cadre .carte-fleche--gauche { grid-area: 2 / 1; }
.carte-cadre .carte-fleche--droite { grid-area: 2 / 3; }
.carte-cadre .carte-fleche--bas { grid-area: 3 / 2; }
/* The triangle: two transparent sides and one inked, the oldest drawing in CSS. Drawn, not
   typed: ↑ ↓ ← → are not signs of the atlas (§6.4), and a font draws them four ways. */
.carte-cadre .carte-fleche::before {
  content: "";
  border: 5px solid transparent;
}
.carte-cadre .carte-fleche--haut::before { border-top-width: 0; border-bottom: 7px solid var(--ca-charbon); }
.carte-cadre .carte-fleche--bas::before { border-bottom-width: 0; border-top: 7px solid var(--ca-charbon); }
.carte-cadre .carte-fleche--gauche::before { border-left-width: 0; border-right: 7px solid var(--ca-charbon); }
.carte-cadre .carte-fleche--droite::before { border-right-width: 0; border-left: 7px solid var(--ca-charbon); }
@media (max-width: 767.98px), (max-width: 1023.98px) and (pointer: coarse) {
  .carte-cadre .carte-deplacer { --fleche: 44px; }
}

/* The attribution: required by the ODbL, so it stays, but at the typographic
   floor and in grey — it is not content. On compact its links (67 x 14 and 91 x 14 px
   measured) get a 44 px target: vertical padding of an inline link enlarges the area
   that answers a tap and moves nothing. */
.carte-cadre .leaflet-control-attribution {
  background: rgba(255, 255, 255, 0.78);
  color: var(--ca-gris-fort);
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--fs-xs);
}
.carte-cadre .leaflet-control-attribution a {
  color: var(--ca-lien);
}
@media (max-width: 767.98px), (max-width: 1023.98px) and (pointer: coarse) {
  .carte-cadre .leaflet-control-attribution a { padding: 15px 6px; }
}

/* ── A point's tooltip ────────────────────────────────────────────────────── */

.carte-cadre .leaflet-tooltip.carte-bulle {
  background: var(--ca-surface);
  border: 1px solid var(--ca-filet);
  color: var(--ca-charbon);
  font-size: var(--fs-s);
  padding: var(--sp-2);
  /* One line for the name, then the mono details on lines of their own: the bubble was
     109 x 123 px at every width and seven lines tall (« Boulangerie / n° 35 / vente · /
     196 k€ »…) against this very max-width, because Leaflet sizes a tooltip to its
     narrowest wrap. */
  white-space: normal;
  width: max-content;
  min-width: 12rem;
  max-width: 18rem;
}
.carte-cadre .leaflet-tooltip.carte-bulle::before { display: none; } /* no arrow: a rule, not a speech balloon */
.carte-bulle-nom { font-family: "IBM Plex Sans", sans-serif; }

/* The written label (the « libellés » box): the name alone, mono at the floor, a rule, no
   arrow, no shadow; it reads over the basemap and never hides the mark it names. */
.carte-cadre .leaflet-tooltip.carte-libelle {
  background: rgb(var(--ca-blanc-rgb) / 0.88);
  border: 1px solid var(--ca-filet);
  color: var(--ca-charbon);
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--fs-xs);
  line-height: 1.2;
  padding: 1px var(--sp-1);
  white-space: nowrap;
  pointer-events: none;
}
.carte-cadre .leaflet-tooltip.carte-libelle::before { display: none; }

/* The control of the foot: a checkbox with its word, in the legend's face. On compact the
   label around the 13 px box is the target: 44 px tall (the box measured 13 x 13 in a 19 px
   label). */
.carte-controle {
  flex: 0 0 auto;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-xs);
  color: var(--ca-gris-fort);
  cursor: pointer;
}
@media (max-width: 767.98px), (max-width: 1023.98px) and (pointer: coarse) {
  .carte-controle,
  .carte-tout-voir { min-height: 44px; }
}
.carte-bulle-detail,
.carte-bulle-position {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--fs-xs);
  color: var(--ca-gris-fort);
}

/* ── The selection: the yellow « ici » ─────────────────────────────────────────
   A yellow disc with an ink rim and the point inside it, in the état's colour when there is
   one (§6.7). Built as a DOM marker (carte.js drawSelected) so that it stays above the other
   points; the yellow is a fill under charbon, never text on light (spec-design decision 3). */
/* 16 px, the SELECTION of carte.js (22 until 2026-10-01, E0 #31: « a bit smaller »; 18 until
   2026-10-05, when the points shrank to 6 px). */
.carte-selection {
  display: block;
  width: 16px;
  height: 16px;
  box-sizing: border-box;
  border: 1px solid var(--ca-charbon);
  border-radius: 50%;
  background: var(--ca-jaune);
  position: relative;
}
.carte-selection::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--ca-charbon);
}
.carte-selection[data-etat="actif"]::after { background: var(--ca-vert-vif); }
.carte-selection[data-etat="ferme"]::after { background: var(--ca-rouge-vif); }

/* « Chercher dans ce cadre » (decision 12, Q32): the one primary action of the map, over it
   at the top and centred, above Leaflet's panes (800-1000). Shown by carte.js only once the
   reader has moved the map. */
.carte-chercher {
  position: absolute;
  top: var(--sp-3);
  left: 50%;
  transform: translateX(-50%);
  z-index: 1001;
  min-height: 44px;
  white-space: nowrap;
}
.carte-chercher[hidden] { display: none; }

/* ── The foot: legend, counting sentence, labels control ─────────────────────────
   Two lines on compact (decision 12, Q34): the legend takes the first (at most two lines of
   its own, its entries being the marks actually drawn), the counting sentence and the labels
   control the last; the source line is the SECTION's, not the map's. */

.carte-pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  border-top: 1px solid var(--ca-filet);
}

.carte-compte {
  /* Shares the second line with the labels control and wraps in its own box rather than
     pushing the control to a third line (the sentence is 30 characters at 15 million rows).
     A base of 8rem, not 0: with a base of 0 the sentence was whatever the row had left, and in
     the cartouche's foot at 437 px (the atlas row at 86 rem, 2026-10-02) the control and the
     two actions fitted on its line and left it 30 px, « 77 établissements » broken under the
     checkbox. 8rem holds a short count on one line; when the row cannot give them, the
     actions wrap, as they did in the 362 px foot. */
  flex: 1 1 8rem;
  min-width: 0;
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ca-gris-fort);
}

/* « tout voir › », the plate's way back to every place: a link in the sentence's own face. */
.carte-tout-voir {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--ca-lien);
  cursor: pointer;
}
.carte-tout-voir:hover { text-decoration: underline; }

.carte-libelles-note:empty { display: none; }
.carte-insecable { white-space: nowrap; }

.carte-legende {
  display: flex;
  flex: 1 0 100%;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-xs);
  color: var(--ca-gris-fort);
}

.carte-legende-entree {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

/* The swatch repeats EXACTLY what the JS draws: a solid disc for a position
   held to be exact, a hollow ring for an approximate one. Those two shapes are
   the only thing the reader has to learn from this map. */
.carte-legende-entree::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ca-charbon);
}
.carte-legende-entree[data-forme="anneau"]::before {
  background: transparent;
  border: 1.25px solid var(--ca-charbon);
}
.carte-legende-entree[data-cle="actif"]::before { background: var(--ca-vert-vif); }
.carte-legende-entree[data-cle="ferme"]::before { background: var(--ca-rouge-vif); }
/* The yellow disc of the selection, as the map draws it: a yellow fill with an ink rim. */
.carte-legende-entree[data-cle="selection"]::before {
  background: var(--ca-jaune);
  border: 1px solid var(--ca-charbon);
}
.carte-legende[hidden],
.carte-legende-entree[hidden] { display: none; }

.carte-sans-position {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ca-gris-fort);
}
/* Inside the counting sentence the count of rows with no position follows it, dotted. */
.carte-compte .carte-sans-position:not([hidden])::before { content: "· "; }

.carte-vide {
  margin: 0;
  padding: var(--sp-4);
  font-family: "IBM Plex Sans", sans-serif;
  font-size: var(--fs-m);
  color: var(--ca-gris-fort);
}

.carte-pied .bloc-source { margin: 0; }

/* ── « Plein écran » ──────────────────────────────────────────────────────────
   The block's last control (carte.html), and the state carte.js sets on the figure. The link
   to the list (`.carte-liste`, before it) wears the same box.

   THE BUTTON. `.carte .ca-action.carte-plein-ecran`, three classes: the cartouche is a dark
   `.hero`, where `.hero .ca-action` (tokens.css) turns an action yellow on black — but the
   map's foot is a white surface, and yellow on white is not read. The button keeps the
   light-surface action here, hover included, wherever the map sits. */
.carte .ca-action.carte-plein-ecran,
.carte .ca-action.carte-liste {
  flex: 0 0 auto;
  border-color: var(--ca-lien);
  color: var(--ca-charbon);
  text-decoration: none;
}
.carte .ca-action.carte-plein-ecran:hover,
.carte .ca-action.carte-liste:hover {
  border-color: var(--ca-jaune);
  color: var(--ca-noir);
}
@media (max-width: 767.98px), (max-width: 1023.98px) and (pointer: coarse) {
  .carte .ca-action.carte-plein-ecran,
  .carte .ca-action.carte-liste { display: inline-flex; align-items: center; min-height: 44px; }
}

/* The two travel together, at the right of the foot: alone, « Plein écran » wrapped onto a
   line of its own under « Tous les établissements › » in the 360 px foot of the cartouche. */
.carte-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-left: auto;
}

/* THE STATE. The figure is fixed over the page with the margin the graph's full screen has
   (site.css `.graphe--plein-ecran`); the map takes what the foot leaves. `height: auto` takes
   three classes to beat the two heights above, whatever the order of the rules. */
.carte.carte--plein-ecran {
  position: fixed;
  inset: var(--sp-4);
  z-index: 200;
  display: flex;
  flex-direction: column;
}
.carte.carte--plein-ecran .carte-cadre {
  flex: 1 1 0;
  min-height: 0;
  height: auto;
}

/* THE REPÈRE IS STILL outside the full screen (user, 2026-10-02; carte.js holds the other
   half and the reasons). Leaflet's stylesheet sets `touch-action: none` on a container that
   drags and pinches, which keeps a phone's swipe from scrolling the page; here the swipe goes
   back to the browser. `manipulation`, not `auto`: a double tap must not zoom the page.
   `!important` against the three-class selector of leaflet.css, whatever the load order. */
.carte--repere:not(.carte--plein-ecran) .carte-cadre,
.carte--repere:not(.carte--plein-ecran) .carte-cadre * {
  touch-action: manipulation !important;
}

/* A fixed box is still painted inside the stacking context of its ancestors: the cartouche's
   `.section-inner` sits at z-index 1 (site.css), under the sticky header (100) and the rail
   (40), which were drawn across the open map. The ancestor that holds an open map is lifted
   above them for as long as it is open. */
.section-inner:has(.carte--plein-ecran) { z-index: 200; }

/* The page does not scroll behind an open map. */
.carte-plein-ecran-ouverte { overflow: hidden; }

/* viewport.css bounds every <canvas> to its box (`max-width: 100%`) so that a vis-network
   canvas cannot push a page sideways. Leaflet's panes are 0 × 0 boxes positioned at the map's
   origin, and the overlay canvas the points are drawn on (L.canvas renderer) sits in one of
   them: bounded to its pane it measures 0 px wide, and every point, ring and selection is
   painted on a canvas nobody can see. Measured on /design/ on 2026-09-23 (3 460 painted
   pixels, a bounding box of 0 × 936 px). The selection was never affected: it is a DOM
   marker. */
.leaflet-overlay-pane canvas {
  max-width: none;
}

