/* ============================================================
   NOCTURNE - page d'accueil v26 (Unified)
   ------------------------------------------------------------
   Contenu de la page d'accueil uniquement : hero, rail de
   categories, barre de filtres, cartes de pros, vue carte,
   modale de devis, footer.

   Les tokens, la base html/body, les primitives .btn/.tag/.input
   et le header + tiroir mobile vivent dans css/nocturne-base.css,
   partages avec la fiche pro v28. Charger les deux, dans cet
   ordre :
     <link rel="stylesheet" href="css/nocturne-base.css">
     <link rel="stylesheet" href="css/home-nocturne.css">

   index.html ne doit contenir AUCUNE valeur en dur - uniquement
   des var(--...). Les autres pages (hors fiche pro) gardent
   css/navbar.css et css/style.css (design ink/brass).

   Les regles marquees "REGLE §6" viennent de la section
   "Regles responsive a ne pas casser" de INTEGRATION.md. Elles
   ont demande beaucoup d'iterations : ne pas les "ameliorer".
   ============================================================ */

/* ============================================================
   HERO
   ============================================================ */
.pd-hero {
  position: relative; overflow: hidden;
  /* REGLE §6 : padding de section en clamp(14px, 4vw, 28px). */
  padding: 76px clamp(14px, 4vw, 28px) 56px;
  border-bottom: 1px solid var(--color-divider);
  background:
    radial-gradient(900px 420px at 18% 0%, var(--color-accent-900) 0%, transparent 70%),
    radial-gradient(700px 500px at 92% 20%, var(--color-section) 0%, transparent 72%),
    var(--color-bg);
}
.pd-herobg { position: absolute; inset: 0; background: var(--color-section); }
.pd-herobg img { width: 100%; height: 100%; object-fit: cover; }
/* REGLE §6 : UN SEUL calque couvrant toute la section, dont le
   degrade va jusqu'a transparent. Un calque borne dont la
   derniere etape est encore opaque cree une couture verticale. */
.pd-heroveil {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(96deg,
    var(--color-bg) 0 30%,
    color-mix(in srgb, var(--color-bg) 66%, transparent) 52%,
    transparent 78%);
}
/* REGLE §6 : pistes en minmax(min(Npx, 100%), 1fr). Un
   minmax(520px, ...) sec coupe le contenu a 393px de large. */
.pd-body {
  position: relative; max-width: 1560px; margin: 0 auto 0 0;
  display: grid;
  grid-template-columns: minmax(min(520px, 100%), 860px) minmax(min(290px, 100%), 340px);
  gap: 44px; align-items: start; justify-content: space-between;
}
.pd-panel {
  min-width: 0; border-radius: 18px;
  background: color-mix(in srgb, var(--color-surface) 94%, transparent);
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.pd-panelhead {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--color-divider);
  background: color-mix(in srgb, var(--color-bg) 42%, transparent);
}
.pd-kicker {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-neutral-400);
}
.pd-dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: var(--color-accent); animation: pd-ping 2.4s ease-out infinite;
}
.pd-panelbody { padding: 30px 24px 22px; }
.pd-h1 {
  margin: 0; font-size: clamp(34px, 5vw, 58px); line-height: 1.02;
  letter-spacing: -.03em; max-width: 16ch; text-wrap: pretty;
}
.pd-h1 em { font-style: italic; color: var(--color-accent-300); }

/* REGLE §6 : sur telephone, ZIP en largeur fixe (~100px), champ
   de requete flexible, bouton Search sur sa propre ligne pleine
   largeur. Voir la media query 620px plus bas. */
.pd-searchrow { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; position: relative; }
.pd-searchfield {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  padding: 0 13px; border-radius: 10px; background: var(--color-bg);
  box-shadow: inset 0 0 0 1px var(--color-neutral-800);
}
.pd-searchzip { flex: 0 0 auto; width: 118px; }
.pd-searchq { flex: 1 1 180px; gap: 10px; }
.pd-searchfield input {
  flex: 1; min-width: 0; border: 0; background: transparent; box-shadow: none;
  padding: 14px 0; font-size: 15px; color: var(--color-text); font-family: var(--font-body);
}
.pd-searchfield input::placeholder { color: var(--color-neutral-600); }
.pd-searchbtn { flex: 0 0 auto; padding: 14px 20px; font-size: 15px; }
/* Ligne "5 quotes" sous la recherche : un metier, un bouton. */
.pd-quoterow {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--color-divider);
}
.pd-quotelead { flex: 1 1 220px; font-size: 13.5px; line-height: 1.4; color: var(--color-neutral-400); }
.pd-quotelead strong { color: var(--color-text); font-weight: 500; }
.pd-quotecat { flex: 0 1 200px; min-height: 44px; }
.pd-quotecat[data-err="true"] {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent);
}
/* Bouton "Get 5 quotes" : seul bouton PLEIN du hero. Search reste en
   contour, donc l'oeil tombe d'abord ici. Texte en --color-surface :
   clair sur l'accent sombre (jour), sombre sur l'accent clair (nuit). */
.pd-quotebtn {
  flex: 0 0 auto; padding: 12px 20px; font-weight: 600;
  color: var(--color-surface);
  background: var(--color-accent); border-color: var(--color-accent);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--color-accent) 35%, transparent);
  transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
}
.pd-quotebtn:hover {
  background: color-mix(in srgb, var(--color-accent) 86%, var(--color-text));
  box-shadow: 0 8px 20px color-mix(in srgb, var(--color-accent) 45%, transparent);
  transform: translateY(-1px);
}
.pd-quotebtn:active {
  background: color-mix(in srgb, var(--color-accent) 78%, var(--color-text));
  box-shadow: 0 3px 10px color-mix(in srgb, var(--color-accent) 35%, transparent);
  transform: none;
}

/* Autocompletion */
.pd-ac {
  display: none; position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 30;
  border-radius: var(--radius-lg); background: var(--color-surface);
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.pd-ac.pd-open { display: block; }
.pd-acitem {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px; cursor: pointer;
  font-size: 14px; color: var(--color-text);
}
.pd-acitem + .pd-acitem { border-top: 1px solid var(--color-divider); }
.pd-acitem:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.pd-acmeta { margin-left: auto; font-size: 12px; color: var(--color-neutral-600); }

/* ===== CARTE D'ACTIVITE ===== */
.pd-side {
  min-width: 0; border-radius: 16px;
  background: color-mix(in srgb, var(--color-surface) 94%, transparent);
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.pd-sidehead {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 13px 18px; border-bottom: 1px solid var(--color-divider);
}
.pd-feed { display: flex; flex-direction: column; }
.pd-feedcell { display: block; padding: 13px 18px; animation: pd-rise .5s ease; }
/* REGLE §6 : separateurs en border-top sur les lignes 2+, PAS un
   border-bottom partout - sinon un filet pend dans le vide quand
   une seule ligne est visible. */
.pd-feedcell + .pd-feedcell { border-top: 1px solid var(--color-divider); }
/* REGLE §6 : le texte des evenements passe a la ligne. Jamais
   white-space: nowrap + ellipse, sinon il est tronque des que la
   cellule est etroite. */
.pd-feedtext {
  display: block; font-size: 13px; line-height: 1.35;
  color: var(--color-neutral-200); text-wrap: pretty;
}
.pd-feedname { color: var(--color-accent-300); }
.pd-feedmeta { display: block; font-size: 11px; color: var(--color-neutral-500); margin-top: 3px; }

/* ============================================================
   RAIL DE CATEGORIES
   ============================================================ */
.pd-railsection { padding: 26px 0 6px; border-bottom: 1px solid var(--color-divider); }
.pd-railhead {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  max-width: 1240px; margin: 0 auto 16px; padding: 0 28px;
}
.pd-railtitle {
  margin: 0; font-size: 15px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-neutral-500);
}
.pd-railhint { font-size: 13px; color: var(--color-neutral-600); }
.pd-railmask {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 90px, #000 calc(100% - 90px), transparent);
  mask-image: linear-gradient(to right, transparent, #000 90px, #000 calc(100% - 90px), transparent);
}
.pd-marquee {
  display: flex; gap: 12px; width: max-content; padding: 4px 28px 20px;
  animation: pd-marquee 46s linear infinite;
}
.pd-railmask:hover .pd-marquee { animation-play-state: paused; }
/* REGLE §6 : tuiles 168x104 au-dessus de 760px, 122x74 en
   dessous (nom 12px, sous-titre 10px). */
.pd-cat {
  position: relative; flex: 0 0 auto; width: 168px; height: 104px; padding: 0;
  text-align: left; cursor: pointer; overflow: hidden; border-radius: 12px;
  border: 1px solid var(--color-neutral-800);
  background: linear-gradient(150deg, var(--color-accent-900), var(--color-neutral-900));
  box-shadow: var(--shadow-sm);
  transition: transform .2s;
}
.pd-cat:hover { transform: translateY(-2px); }
.pd-cat.pd-on {
  border-color: var(--color-accent);
  background: linear-gradient(150deg, var(--color-accent-800), var(--color-neutral-900));
  box-shadow: 0 0 0 1px var(--color-accent-600), var(--shadow-md);
}
/* Image de categorie (colonne categories.image_url). Elle remplit la tuile ;
   le voile ::after garde le nom et le sous-titre lisibles par-dessus.
   POINT IMPORTANT : le voile est construit sur --color-neutral-900, jamais sur
   une couleur sombre en dur. La rampe neutre s'inverse entre les deux themes -
   le nom de tuile utilise --color-neutral-100, qui vaut #1b1b26 (fonce) en
   clair et #f2f2f5 (clair) en sombre. Un voile sombre fige donnerait du texte
   fonce sur fond fonce en theme clair. En prenant le meme token que le fond de
   la tuile, le voile s'inverse avec le texte.
   Le §7 interdit par ailleurs mix-blend-mode: lighten ("il efface les photos") :
   c'est un simple degrade superpose, pas un mode de fusion. */
.pd-cat img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pd-cat.pd-hasimg::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top,
    var(--color-neutral-900) 8%,
    color-mix(in srgb, var(--color-neutral-900) 72%, transparent) 46%,
    color-mix(in srgb, var(--color-neutral-900) 18%, transparent) 100%);
}
.pd-catlabel { position: absolute; inset: auto 10px 10px 12px; z-index: 1; display: flex; flex-direction: column; gap: 2px; }
.pd-catname { font-family: var(--font-heading); font-size: 14px; color: var(--color-neutral-100); }
.pd-catsub { font-size: 11px; color: var(--color-neutral-600); }
.pd-cat.pd-on .pd-catsub, .pd-cat.pd-on .pd-catmark { color: var(--color-accent-300); }
.pd-catmark { position: absolute; top: 10px; right: 12px; z-index: 1; font-size: 12px; color: var(--color-neutral-600); }

/* ============================================================
   RESULTATS
   ============================================================ */
.pd-results {
  max-width: 1560px; margin: 0 auto;
  padding: 34px clamp(14px, 4vw, 28px) 10px;
}
/* Barre compacte (v41) : Filters + puces + compte, puis tri + List/Map,
   serres les uns contre les autres. La barre prend la largeur de son
   contenu (fit-content), pas toute la page : en pleine largeur elle laissait
   un grand vide au milieu (demande du 2026-10-02). Elle se replie sur deux
   lignes quand l'ecran est trop etroit. */
.pd-filters {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: flex-start;
  width: fit-content; max-width: 100%;
  padding: 7px 10px; border-radius: 14px; background: var(--color-surface); box-shadow: var(--shadow-sm);
}
.pd-filtergroup { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
/* Filet vertical entre le compte et le tri. */
.pd-filterright { flex-wrap: nowrap; padding-left: 10px; border-left: 1px solid var(--color-divider); }
@media (max-width: 620px) {
  .pd-filterright { padding-left: 0; border-left: 0; }
}
.pd-filtersbtn {
  display: flex; align-items: center; gap: 8px; min-height: 38px; padding: 6px 14px; cursor: pointer;
  border-radius: 10px; border: 1px solid var(--color-neutral-800); background: var(--color-bg);
  color: var(--color-text); font-family: var(--font-heading); font-size: 13px;
}
.pd-filtersbtn.pd-active {
  border-color: var(--color-accent-600);
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}
.pd-filtercount {
  display: grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--color-accent); color: var(--color-neutral-900); font-size: 11.5px;
}
.pd-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pd-chips:empty { display: none; }
.pd-chip {
  display: flex; align-items: center; gap: 6px; min-height: 30px; padding: 4px 10px; cursor: pointer;
  border-radius: 999px; border: 1px solid var(--color-accent-600);
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent-200); font-size: 12px; font-family: var(--font-heading);
}
.pd-sortselect { padding: 7px 10px; font-size: 13px; min-height: 38px; }
.pd-seg { display: flex; gap: 2px; padding: 3px; border-radius: 10px; background: var(--color-bg); }
.pd-segbtn {
  cursor: pointer; padding: 6px 14px; font-size: 13px; border: 0; border-radius: 8px;
  font-family: var(--font-heading); background: transparent; color: var(--color-neutral-500);
}
.pd-segbtn.pd-on { background: var(--color-accent); color: var(--color-neutral-900); }
.pd-matchcount { font-size: 13px; color: var(--color-neutral-500); }
.pd-matchcount strong { color: var(--color-text); }

/* ===== TIROIR DE FILTRES (v41) =====
   Glisse depuis la droite, 400px (pleine largeur sur telephone). Meme
   etage que le panneau du bouton flottant : 70 / 71. */
.pd-drawerback {
  position: fixed; inset: 0; z-index: 70;
  background: color-mix(in srgb, var(--color-bg) 70%, transparent); backdrop-filter: blur(5px);
}
.pd-filterdrawer {
  position: fixed; z-index: 71; top: 0; right: 0; bottom: 0; width: min(400px, 100%);
  display: flex; flex-direction: column; background: var(--color-bg);
  box-shadow: -1px 0 0 var(--color-neutral-800), var(--shadow-lg);
  animation: pd-slidein .28s cubic-bezier(.33,1,.68,1) both;
}
@keyframes pd-slidein { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.pd-fdhead {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px clamp(16px, 3vw, 22px); border-bottom: 1px solid var(--color-divider);
}
.pd-fdtitlewrap { display: flex; flex-direction: column; gap: 2px; }
.pd-fdtitle { font-family: var(--font-heading); font-size: 18px; letter-spacing: -.015em; }
.pd-fdsub { font-size: 12px; color: var(--color-neutral-500); }
.pd-fdbody {
  flex: 1; overflow: auto; overscroll-behavior: contain;
  padding: 6px clamp(16px, 3vw, 22px) 20px; display: flex; flex-direction: column;
}
.pd-fdsection {
  display: flex; flex-direction: column; gap: 10px; padding: 18px 0;
  border-bottom: 1px solid var(--color-divider);
}
.pd-fdsection.pd-fdtoggles { gap: 0; padding: 8px 0; }
.pd-fdsection.pd-fdsort { border-bottom: 0; padding-bottom: 8px; }
.pd-fdlabel { font-family: var(--font-heading); font-size: 14px; }
.pd-ratingopts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.pd-optbtn {
  display: flex; align-items: center; justify-content: center; min-height: 40px; cursor: pointer;
  border-radius: 10px; border: 1px solid var(--color-neutral-800); background: var(--color-surface);
  color: var(--color-text); font-family: var(--font-heading); font-size: 13px;
}
.pd-optbtn.pd-on {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 16%, transparent); color: var(--color-accent-200);
}
.pd-switchrow {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  min-height: 56px; padding: 10px 0; cursor: pointer;
}
.pd-switchtext { display: flex; flex-direction: column; gap: 2px; }
.pd-switchtitle { font-family: var(--font-heading); font-size: 14px; }
.pd-switchsub { font-size: 12.5px; color: var(--color-neutral-500); }
/* Vraie case a cocher habillee en interrupteur 44x26 : clavier, lecteur
   d'ecran et evenement change restent ceux du navigateur. */
.pd-switch {
  appearance: none; -webkit-appearance: none; position: relative; flex: none; margin: 0; cursor: pointer;
  width: 44px; height: 26px; border-radius: 999px; background: var(--color-neutral-800);
  transition: background .2s ease;
}
.pd-switch::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 999px;
  background: var(--color-neutral-100); box-shadow: var(--shadow-sm);
  transition: left .2s cubic-bezier(.33,1,.68,1);
}
.pd-switch:checked { background: var(--color-accent); }
.pd-switch:checked::after { left: 21px; }
.pd-switch:focus-visible { outline: 2px solid var(--color-accent-400); outline-offset: 2px; }
.pd-sortopts { display: flex; flex-direction: column; gap: 6px; }
.pd-sortopt {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 42px; padding: 8px 12px; cursor: pointer; text-align: left;
  border-radius: 10px; border: 1px solid var(--color-neutral-800); background: var(--color-surface);
  color: var(--color-text); font-size: 13.5px;
}
.pd-sortopt.pd-on {
  border-color: var(--color-accent-600);
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}
/* Coche ronde du tri choisi (meme couleurs que la pastille de Filters). */
.pd-sortcheck {
  display: none; place-items: center; flex: none; width: 20px; height: 20px; border-radius: 999px;
  background: var(--color-accent); color: var(--color-neutral-900);
}
.pd-sortopt.pd-on .pd-sortcheck { display: grid; }
.pd-fdfoot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px clamp(16px, 3vw, 22px) calc(14px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--color-divider); background: var(--color-bg);
}
.pd-fdclear { color: var(--color-neutral-400); text-decoration: underline; text-underline-offset: 3px; }
/* Plein, comme dans la maquette et comme le bouton flottant (.btn-primary
   du site est en contour). */
.pd-fdshow {
  flex: 1; justify-content: center; min-height: 46px;
  background: var(--color-accent); border-color: var(--color-accent); color: var(--color-neutral-900);
}
.pd-fdshow:hover { background: var(--color-accent-400); border-color: var(--color-accent-400); color: var(--color-neutral-900); }

.pd-resulthead {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px;
  margin: 34px 0 18px; flex-wrap: wrap;
}
.pd-resultkicker { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-accent-400); }
.pd-resulttitle { margin: 8px 0 0; font-size: 32px; letter-spacing: -.02em; }
.pd-resultplace { font-size: 13px; color: var(--color-neutral-600); white-space: nowrap; }
/* Lieu + bouton "Get quotes from 5 pros", a droite du titre des resultats. */
.pd-resultcta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
@media (max-width: 720px) {
  .pd-resultcta { width: 100%; justify-content: space-between; }
}

/* ===== CARTE DE PRO ===== */
.pd-card {
  position: relative; display: flex; flex-direction: column;
  border-radius: 14px; background: var(--color-surface);
  box-shadow: var(--shadow-sm); overflow: hidden;
  transition: transform .2s;
}
.pd-card:hover { transform: translateY(-3px); }
.pd-card.pd-sel { box-shadow: 0 0 0 1px var(--color-accent-600), var(--shadow-md); }

/* ------------------------------------------------------------
   REGLE §6 - EN-TETE DE CARTE DE PRO : le mecanisme central de
   v26. flex-wrap, AUCUNE media query, trois enfants :
     .pd-thumb  vignette 66px      flex: none
     .pd-idcol  colonne nom        flex: 1 1 190px
     .pd-fav    bouton favori      flex: none; margin-left: auto
   - carte large (telephone/tablette, une colonne) : tout tient
     sur une ligne, le nom se place a cote de la photo ;
   - carte etroite (desktop, trois colonnes) : la colonne nom et
     le coeur passent sous la photo, le nom prend toute la
     largeur.
   Ne pas "ameliorer" : ces valeurs ont demande beaucoup
   d'iterations.
   ------------------------------------------------------------ */
.pd-cardhead {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px;
  padding: 14px 14px 0;
}
.pd-thumb {
  position: relative; flex: none; width: 66px; height: 66px;
  border-radius: 13px; overflow: hidden;
  background: linear-gradient(140deg, var(--color-accent-900), var(--color-neutral-900));
  /* §7 : les contours d'interface utilisent accent-600, pas 700. */
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--color-accent) 42%, transparent),
    0 0 0 1px var(--color-neutral-800),
    0 0 0 4px color-mix(in srgb, var(--color-accent) 12%, transparent),
    var(--shadow-md);
}
.pd-card.pd-sel .pd-thumb {
  background: linear-gradient(140deg, var(--color-accent-800), var(--color-neutral-900));
}
.pd-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pd-thumbletter {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-heading); font-size: 24px; color: var(--color-accent-200);
}
.pd-idcol { flex: 1 1 190px; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
/* Ligne pastille de statut + adresse.
   Elle vit A L'INTERIEUR de .pd-idcol : les trois enfants directs de
   .pd-cardhead (vignette flex:none / colonne nom flex:1 1 190px / coeur
   flex:none margin-left:auto) restent exactement les memes, donc le mecanisme
   de repli §6 de l'en-tete n'est pas touche.
   Les liens site/reseaux ont quitte cette rangee pour le pied de carte
   (.pd-footlinks) ; la place restante revient a l'adresse. */
.pd-statusrow { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
/* Adresse sur UNE ligne : flex-basis 0 + min-width 0 font qu'elle ne
   provoque jamais le repli de la rangee, et l'ellipse coupe le texte trop long
   (le texte complet est dans le title). L'en-tete garde ainsi une hauteur
   fixe, condition de l'egalite des hauteurs de cartes. */
.pd-addr {
  flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--color-neutral-500);
}
.pd-addr svg { flex: none; }
.pd-addrtext { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Bouton d'icone (site, reseaux), rendu dans .pd-footlinks au pied de la
   carte : memes valeurs de contour que le coeur, pour que les deux se lisent
   comme la meme famille de controles. */
.pd-link {
  display: grid; place-items: center; flex: none; width: 24px; height: 24px;
  border-radius: 999px; border: 1px solid var(--color-neutral-800);
  background: var(--color-bg); color: var(--color-accent-300);
}
.pd-link:hover { background: var(--color-accent-900); color: var(--color-accent-200); }

.pd-status {
  display: flex; align-items: center; gap: 6px; align-self: flex-start;
  padding: 4px 9px; border-radius: 999px; background: var(--color-bg);
  font-size: 11px; color: var(--color-neutral-400);
}
.pd-status .pd-statusdot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; }
.pd-status.pd-openpill { color: var(--color-accent-300); }
/* REGLE §6 : la note est EMPILEE sous le nom, pas sur la meme
   ligne. En justify-content: space-between le badge de note
   (75px) ne laissait au nom que 114px sur une carte de 271px,
   soit deux lignes pour tous les noms. */
.pd-namecol { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.pd-name { margin: 0; font-size: 17px; letter-spacing: -.01em; text-wrap: balance; }
/* Le nom est un vrai lien (robots) mais se lit comme un titre. */
.pd-name a { color: inherit; text-decoration: none; }
.pd-name a:hover { color: var(--color-accent-300); }
.pd-rating { display: flex; align-items: center; gap: 5px; font-size: 13px; color: var(--color-neutral-300); }
.pd-rating strong { color: var(--color-text); }
.pd-ratingcount { color: var(--color-neutral-600); }
/* REGLE §6 : le coeur reste dans le flux, jamais en
   position: absolute. En absolu il faut reserver son espace en
   padding, et ce padding ampute la ligne du nom une fois
   qu'elle est passee a la ligne. */
.pd-fav {
  flex: none; align-self: flex-start; margin-left: auto;
  display: grid; place-items: center; width: 32px; height: 32px; cursor: pointer;
  border-radius: 999px; border: 1px solid var(--color-neutral-800);
  background: var(--color-bg); color: var(--color-neutral-400);
}
.pd-fav.pd-on { color: var(--color-accent); }

.pd-cardbody { display: flex; flex-direction: column; gap: 8px; padding: 10px 14px 12px; }
.pd-tags { display: flex; flex-wrap: wrap; gap: 6px; }
/* Puce "Claimed" : la fiche a un vrai proprietaire. Meme fond que la puce de
   categorie, mais un anneau interne accent-600 l'en separe. §7 : le texte
   descend a accent-200 et le contour utilise 600, pas 700, pour rester
   visible sur le fond clair. */
.pd-claimed {
  display: flex; align-items: center; gap: 5px;
  color: var(--color-accent-200);
  background: var(--color-accent-800);
  box-shadow: inset 0 0 0 1px var(--color-accent-600);
}
.pd-tags .tag-outline { display: flex; align-items: center; gap: 5px; }
/* Creneaux sur UNE ligne, sans cadre (variante choisie le 2026-09-22) :
   libelle court "Next:" / "Instant book:" puis les puces. Hauteur = celle
   d'une puce (~25px), contre 54 en deux lignes avec cadre.
   Budget a 1280px : pire cas "Instant book:" (~80px) + deux puces
   "Tomorrow 10:00 AM" (~2 x 115px) + gaps = ~320px pour 362px utiles.
   .pd-slotrow est en nowrap + overflow hidden : la ligne ne se replie
   JAMAIS, donc la hauteur du bloc (et des cartes) reste fixe ; sur une
   carte tres etroite la seconde puce est rognee plutot que renvoyee a la
   ligne. Une fiche porte au plus 2 puces (pros-data.js, nextSlots). */
.pd-slots { display: flex; align-items: center; gap: 6px; padding: 0; background: none; border-radius: 0; }
.pd-slotlabel { flex: none; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-neutral-600); }
.pd-slotrow { display: flex; flex-wrap: nowrap; gap: 5px; margin-top: 0; flex: 1 1 0; min-width: 0; overflow: hidden; }
.pd-slot {
  cursor: pointer; padding: 3px 8px; border-radius: 6px; white-space: nowrap;
  border: 1px solid var(--color-accent-600); background: transparent;
  color: var(--color-accent-300); font-size: 11px; font-family: var(--font-heading);
}
.pd-slot:hover { background: var(--color-accent-900); }
/* Bloc fantome rendu quand la fiche n'a pas de creneaux : meme structure que
   le vrai bloc, donc meme hauteur, mais invisible et non focusable. */
.pd-slots--empty { visibility: hidden; }
/* Texte "About" du business (listings.description). Coupe a 2 lignes : les
   vraies descriptions font 450 a 550 caracteres sur plusieurs paragraphes, la
   ou le slot de la maquette tenait une ligne courte - sans limite une carte
   devient trois fois plus haute que ses voisines et la grille 3 colonnes perd
   son rythme. La coupe est visuelle : le texte entier reste dans le DOM et
   dans l'attribut title.
   A ne pas confondre avec la REGLE §6 qui interdit nowrap + ellipse : elle
   vise le texte des lignes du feed, qui doit pouvoir passer a la ligne. Ici le
   texte passe bien a la ligne - sur deux lignes - avant d'etre coupe. */
.pd-about {
  font-size: 13px; color: var(--color-neutral-400); text-wrap: pretty;
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  /* Deux lignes reservees meme si le texte tient sur une ou est absent :
     le bloc est toujours rendu, pour une hauteur de carte identique. */
  min-height: calc(2 * 1.55em);
}
/* Le pied suit directement le corps : les cartes vivent dans des colonnes
   flex (.pd-listcol, .pd-maplist) en flex: none, donc la carte n'a jamais de
   surplus de hauteur a placer. Ne pas ajouter de margin-top: auto ici. */
.pd-cardfoot {
  display: flex; align-items: center; justify-content: flex-end; gap: 6px;
  padding: 11px 14px; border-top: 1px solid var(--color-divider); flex-wrap: wrap;
}
/* Budget du pied a 1280px de large : 362px utiles. Les trois boutons en
   13px / padding 8px font 247px + 18px de gaps ; il reste 97px pour les
   liens. A 22px + 3px de gouttiere, 4 icones faisaient exactement 97px et la
   ligne se repliait (arrondi sous-pixel). A 20px + 2px elles font 86px, soit
   11px de marge. flex-wrap reste en filet pour les ecrans plus etroits : les
   boutons passent alors sous les liens. */
.pd-cardfoot .btn { font-size: 13px; padding: 6px 8px; }
.pd-footlinks { display: flex; align-items: center; gap: 2px; margin-right: auto; }
.pd-footlinks .pd-link { width: 20px; height: 20px; }
/* Les trois boutons du pied de carte portent le meme style : Call et Message
   sont passes en .btn-primary comme Request Quote (texte et contour en
   --color-accent, survol accent 12%). Aucune surcharge de couleur ici - tout
   vient de .btn-primary, donc les trois ne peuvent pas diverger.
   L'icone de Call est en currentColor pour suivre exactement la couleur du
   libelle du bouton. */
/* Propre a Call : lui seul porte une icone a cote de son libelle. */
.pd-callbtn { display: flex; align-items: center; gap: 6px; }

/* ===== SQUELETTES / VIDE ===== */
.pd-skel { border-radius: 14px; background: var(--color-surface); box-shadow: var(--shadow-sm); overflow: hidden; }
.pd-skelbanner {
  height: 92px;
  background: linear-gradient(90deg, var(--color-neutral-900) 0%, var(--color-neutral-800) 50%, var(--color-neutral-900) 100%);
  background-size: 340px 100%; animation: pd-shimmer 1.2s linear infinite;
}
.pd-skelbody { padding: 26px 16px 20px; display: flex; flex-direction: column; gap: 10px; }
.pd-skelline { height: 11px; border-radius: 4px; background: var(--color-neutral-900); }
.pd-skelline.pd-lg { height: 14px; background: var(--color-neutral-800); }
.pd-skelblock { height: 34px; margin-top: 6px; border-radius: 8px; background: var(--color-neutral-900); }
.pd-empty {
  display: grid; place-items: center; text-align: center; gap: 10px; padding: 70px 24px;
  border-radius: 16px; border: 1px dashed var(--color-neutral-800);
  background: color-mix(in srgb, var(--color-surface) 55%, transparent);
}
.pd-empty p { max-width: 44ch; color: var(--color-neutral-500); }

/* ===== VUE CARTE =====
   Meme grille que la vue Liste (.pd-withside) : les fiches dans la colonne
   de gauche qui defile (#mapList est aussi une .pd-listcol). A droite, la
   meme colonne collante (.pd-sidecol) : Get 5 quotes en haut, puis la carte
   a la place du journal. La colonne prend la hauteur de la colonne de pros
   et la carte remplit ce qui reste sous la carte de devis. */
/* stretch : la colonne descend jusqu'au bas des fiches (filtres + titre +
   720px de liste), plafonnee a la hauteur de l'ecran pour rester collante. */
.pd-withside.pd-mapview .pd-sidecol {
  align-self: stretch; max-height: calc(100vh - 110px); overflow: hidden; padding-right: 0;
}
.pd-mapwrap { flex: 1 1 auto; min-height: 280px; min-width: 0; display: flex; flex-direction: column; }
.pd-mapwrap .pd-mapcanvas { flex: 1 1 auto; height: auto; }
/* La colonne reutilise les cartes completes de la vue Liste (.pd-card,
   rendues par cardHtml). Pas de soulevement au survol, il ferait sauter le
   defilement. */
.pd-maplist .pd-card { flex: none; cursor: pointer; }
.pd-maplist .pd-card:hover, .pd-listcol .pd-card:hover { transform: none; }
/* Colonnes Map et Liste : pas de grille a aligner, chaque carte prend la
   hauteur de son contenu. Les blocs reserves vides (creneaux fantomes,
   description vide) disparaissent. Le JS rend .pd-about strictement vide
   quand il n'y a pas de texte, donc :empty le cible. */
.pd-maplist .pd-slots--empty, .pd-listcol .pd-slots--empty { display: none; }
.pd-maplist .pd-about, .pd-listcol .pd-about { min-height: 0; }
.pd-maplist .pd-about:empty, .pd-listcol .pd-about:empty { display: none; }
.pd-mapcanvas {
  position: relative; height: 620px; border-radius: 16px; overflow: hidden;
  box-shadow: var(--shadow-sm); background: var(--color-neutral-900);
}
/* Cible #map seul, pas "> div" : la barre du pro selectionne est elle aussi
   un enfant direct, et une hauteur de 100% ecrasait son ancrage en bas. */
.pd-mapcanvas #map { width: 100%; height: 100%; }
.pd-mapbar {
  position: absolute; inset: auto 16px 16px 16px; z-index: 5;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 16px; border-radius: 12px;
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(10px); box-shadow: var(--shadow-md);
}
.pd-mapbarname { display: block; font-family: var(--font-heading); font-size: 16px; }
.pd-mapbarmeta { display: block; font-size: 12px; color: var(--color-neutral-500); }

/* ===== VUE LISTE : COLONNE DE PROS + COLONNE JOURNAL (maquette v41) =====
   Deux colonnes 1fr | 46%. A gauche les cartes completes (cardHtml) dans une
   colonne qui defile seule ; a droite une colonne collante sous le header
   (top 90px) : Get 5 quotes puis le journal. Sous 1240px tout s'empile et
   la page reprend le defilement (voir media query plus bas). */
.pd-withside {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 46%);
  gap: 22px; align-items: start;
}
.pd-listmain { min-width: 0; }
/* Les enfants d'une colonne flex qui defile doivent etre en flex: none
   (piege v41 §6), sinon les cartes s'ecrasent pour tenir dans la hauteur. */
.pd-listcol {
  display: flex; flex-direction: column; gap: 14px;
  max-height: min(720px, calc(100vh - 120px)); overflow: auto;
  overscroll-behavior: contain; padding-right: 6px;
}
.pd-listcol > * { flex: none; }
.pd-sidecol {
  position: sticky; top: 90px;
  display: flex; flex-direction: column; gap: 16px;
  max-height: calc(100vh - 110px); overflow: auto; padding-right: 4px;
}
.pd-sidequote {
  flex: none; display: flex; flex-direction: column; gap: 9px; padding: 18px 20px;
  border-radius: 16px; box-shadow: var(--shadow-md);
  background: linear-gradient(160deg, var(--color-accent-900), var(--color-surface) 80%);
}
.pd-sidekicker {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--color-accent-300);
}
.pd-sidequotetitle { margin: 0; font-size: clamp(16px, 1.4vw, 20px); letter-spacing: -.015em; text-wrap: pretty; }
.pd-sidequotetext { margin: 0; font-size: 13px; line-height: 1.5; color: var(--color-neutral-400); }
.pd-sidequote .btn { justify-content: center; margin-top: 2px; }

.pd-journalwrap { display: flex; flex-direction: column; gap: 16px; }
.pd-journalhead {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 4px 2px 0;
}
.pd-journaltitle { margin: 0; font-size: clamp(16px, 1.3vw, 19px); letter-spacing: -.015em; }
.pd-journalall { font-size: 12.5px; font-family: var(--font-heading); }
.pd-journalbody { display: flex; flex-direction: column; gap: 16px; }
/* Article vedette : grande photo + titre + extrait. */
.pd-postfeat {
  display: flex; flex-direction: column; border-radius: 16px; overflow: hidden;
  background: var(--color-surface); box-shadow: var(--shadow-md); color: var(--color-text);
  transition: transform .25s cubic-bezier(.33,1,.68,1), box-shadow .25s ease;
}
.pd-postfeat:hover { color: var(--color-text); transform: translateY(-3px); box-shadow: 0 0 0 1px var(--color-accent-600), var(--shadow-lg); }
.pd-postfeatimg {
  position: relative; display: block; height: 210px;
  background: linear-gradient(140deg, var(--color-accent-900), var(--color-neutral-900));
}
.pd-postfeatimg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pd-posttag {
  position: absolute; top: 12px; left: 12px; padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--color-bg) 85%, transparent);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--color-accent-200);
}
.pd-postfeatbody { display: flex; flex-direction: column; gap: 7px; padding: 16px 18px 18px; }
.pd-postfeattitle { font-family: var(--font-heading); font-size: clamp(16px, 1.4vw, 20px); line-height: 1.25; letter-spacing: -.015em; text-wrap: pretty; }
.pd-postexcerpt { font-size: clamp(12.5px, 1vw, 14px); line-height: 1.55; color: var(--color-neutral-400); text-wrap: pretty; }
.pd-postmeta { font-size: 12px; color: var(--color-neutral-500); }
/* Liste des autres articles : vignette 92px | texte. */
.pd-postlist {
  display: flex; flex-direction: column; padding: 4px 20px 10px;
  border-radius: 16px; background: var(--color-surface); box-shadow: var(--shadow-sm);
}
.pd-postrow {
  display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 14px; align-items: center;
  padding: 14px 0; color: var(--color-text);
}
.pd-postrow + .pd-postrow { border-top: 1px solid var(--color-divider); }
.pd-postrow:hover { color: var(--color-accent-300); }
.pd-postthumb {
  display: block; width: 92px; height: 68px; border-radius: 10px; overflow: hidden;
  background: linear-gradient(140deg, var(--color-accent-900), var(--color-neutral-900));
  box-shadow: inset 0 0 0 1px var(--color-neutral-800);
}
.pd-postthumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pd-posttext { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pd-postrowtag { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--color-accent-300); }
.pd-postrowtitle { font-family: var(--font-heading); font-size: clamp(13px, 1vw, 14.5px); line-height: 1.3; text-wrap: pretty; }
/* Aucun article publie : un encart discret, meme bordure que .pd-empty. */
.pd-journalempty {
  margin: 0; padding: 22px 20px; border-radius: 16px; text-align: center;
  border: 1px dashed var(--color-neutral-800);
  background: color-mix(in srgb, var(--color-surface) 55%, transparent);
  font-size: 13.5px; line-height: 1.5; color: var(--color-neutral-500);
}

/* ===== BANDEAU SAUVEGARDES ===== */
.pd-saved {
  margin-top: 34px; padding: 18px 20px; border-radius: 14px;
  background: color-mix(in srgb, var(--color-surface) 60%, transparent);
  box-shadow: var(--shadow-sm);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px;
}
.pd-savedline { font-size: 14px; color: var(--color-neutral-400); }

/* ===== HOW IT WORKS ===== */
.pd-how {
  margin-top: 56px; padding: 60px clamp(14px, 4vw, 28px);
  border-top: 1px solid var(--color-divider); border-bottom: 1px solid var(--color-divider);
  background: radial-gradient(800px 400px at 80% 0%, var(--color-section) 0%, transparent 70%), var(--color-bg);
}
.pd-howin { max-width: 1240px; margin: 0 auto; }
.pd-howtitle { margin: 10px 0 0; font-size: 34px; letter-spacing: -.02em; max-width: 22ch; }
.pd-steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: 20px; margin-top: 34px;
}
.pd-step { padding: 22px; border-radius: 14px; background: var(--color-surface); box-shadow: var(--shadow-sm); }
.pd-stepn { font-family: var(--font-heading); font-size: 13px; color: var(--color-accent-400); letter-spacing: .1em; }
.pd-step h3 { margin: 12px 0 6px; font-size: 19px; }
.pd-step p { margin: 0; font-size: 14px; color: var(--color-neutral-400); text-wrap: pretty; }

/* ===== BOUTON FLOTTANT + PANNEAU MAP / JOURNAL (maquette v41) =====
   Affiche sous 1240px seulement (voir media query plus bas) : au-dela, la
   carte et le journal sont deja a cote de la liste. Pose au-dessus du bouton
   haut de page (44px a 18px du bas, scroll-to-top.css). z-index 54 : sous
   le tiroir du hamburger (55) et le bandeau cookies (90) ; le panneau est
   a 70/71. */
.pd-fabwrap {
  display: none; position: fixed; right: 18px; bottom: calc(18px + 44px + 12px); z-index: 54;
  flex-direction: column; align-items: flex-end; gap: 10px;
}
.pd-fab {
  display: grid; place-items: center; width: 54px; height: 54px; padding: 0;
  cursor: pointer; border: 0; border-radius: 999px;
  background: var(--color-accent); color: var(--color-neutral-900);
  box-shadow: 0 0 0 1px var(--color-accent-700), 0 0 24px color-mix(in srgb, var(--color-accent) 45%, transparent), var(--shadow-lg);
  transition: transform .25s cubic-bezier(.33,1,.68,1);
}
.pd-fab:hover { transform: scale(1.06); }
.pd-fab svg { transition: transform .25s cubic-bezier(.33,1,.68,1); }
.pd-fab[aria-expanded="true"] svg { transform: rotate(45deg); }
.pd-fabmenu {
  display: flex; flex-direction: column; gap: 8px; padding: 8px; border-radius: 14px;
  background: var(--color-surface); box-shadow: 0 0 0 1px var(--color-neutral-800), var(--shadow-lg);
}
.pd-fabitem {
  display: flex; align-items: center; gap: 10px; min-width: 170px; padding: 10px 12px;
  cursor: pointer; border: 0; border-radius: 10px; background: transparent;
  color: var(--color-text); font-family: var(--font-heading); font-size: 13.5px; text-align: left;
}
.pd-fabitem:hover, .pd-fabitem:focus-visible { background: color-mix(in srgb, var(--color-accent) 14%, transparent); }
.pd-fabicon {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 9px;
  background: color-mix(in srgb, var(--color-accent) 18%, transparent); color: var(--color-accent-200);
}
.pd-fabtext { display: flex; flex-direction: column; gap: 1px; }
.pd-fabsub { font-size: 11px; color: var(--color-neutral-500); font-family: var(--font-body); }

.pd-sheetback {
  position: fixed; inset: 0; z-index: 70;
  background: color-mix(in srgb, var(--color-bg) 72%, transparent); backdrop-filter: blur(6px);
}
.pd-sheet {
  position: fixed; z-index: 71; left: 50%; bottom: 0; transform: translateX(-50%);
  width: min(960px, 100%); max-height: 92vh;
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: 20px 20px 0 0; background: var(--color-bg);
  box-shadow: 0 0 0 1px var(--color-neutral-800), var(--shadow-lg);
}
.pd-sheethead {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px clamp(14px, 3vw, 22px); border-bottom: 1px solid var(--color-divider);
}
.pd-sheetclose {
  display: grid; place-items: center; width: 38px; height: 38px; padding: 0; cursor: pointer;
  border-radius: 999px; border: 1px solid var(--color-neutral-800);
  background: var(--color-surface); color: var(--color-text);
}
.pd-sheetbody {
  overflow: auto; overscroll-behavior: contain; padding: clamp(14px, 3vw, 22px);
  display: flex; flex-direction: column; gap: 14px;
}
.pd-sheet .pd-mapcanvas { height: min(640px, calc(100vh - 170px)); }
/* Barre du pro selectionne : Call et View in list n'existent que dans le
   panneau ; dans la vue Map, seul Request Quote reste. */
.pd-mapbarbtns { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; flex: none; }
.pd-mapbarbtns .btn { white-space: nowrap; }
.pd-sheetonly { display: none; }
.pd-sheet .pd-sheetonly { display: inline-flex; }
.pd-sheet .pd-mapbar > span:first-child { min-width: 0; }
html.pd-sheetopen { overflow: hidden; }

/* ===== FOOTER =====
   Le bloc .pd-footer vit dans css/footer.css (auto-charge par
   js/footer.js), partage avec toutes les pages publiques. */

/* ===== RETOUR EN HAUT =====
   L habillage vit dans css/scroll-to-top.css, desormais aux tokens et
   chargee par index.html. Le bloc qui etait duplique ici a ete retire :
   cette feuille n a plus rien a dire sur ce bouton. */

/* ============================================================
   MEDIA QUERIES - reprises telles quelles de la maquette.
   ============================================================ */

/* Vue Liste : une seule colonne. Plus de defilement interne ni de colonne
   collante - la page defile, et Get 5 quotes + journal passent sous les pros. */
@media (max-width: 1240px) {
  .pd-withside { grid-template-columns: minmax(0, 1fr); }
  .pd-listcol { max-height: none; overflow: visible; padding-right: 0; }
  .pd-fabwrap { display: flex; }
  /* Les deux colonnes s'effacent (display: contents) : leurs enfants se
     rangent dans un seul flux, ordonne par order.
     Vue Liste : filtres, titre, pros, puis Get 5 quotes + journal.
     Vue Map : filtres, titre, Get 5 quotes, carte (regle v41 : carte SOUS
     le titre et AU-DESSUS des fiches), puis les pros.
     stretch : la carte n'a pas de largeur propre, en "start" elle tombait
     a 0px. La barre de filtres garde sa largeur fit-content. */
  .pd-withside { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  .pd-listmain, .pd-sidecol { display: contents; }
  .pd-filters { order: -3; }
  .pd-resulthead { order: -2; }
  .pd-sidequote { margin-top: 22px; }
  .pd-journalwrap { margin-top: 16px; }
  .pd-withside.pd-mapview .pd-sidequote { order: -1; margin: 0 0 14px; }
  .pd-mapwrap { order: -1; min-height: 0; margin-bottom: 14px; }
  .pd-mapwrap .pd-mapcanvas { flex: none; height: 340px; }
}
@media (max-width: 760px) {
  .pd-mapwrap .pd-mapcanvas { height: 260px; }
}

/* Panneau du bouton flottant : ancre en HAUT de l'ecran sur telephone
   (regle v41), carte plus basse, barre du pro sur deux lignes. */
@media (max-width: 760px) {
  .pd-sheet { top: 0; bottom: auto; max-height: 88vh; border-radius: 0 0 20px 20px; }
  .pd-sheet .pd-mapcanvas { height: min(440px, 58vh); }
  .pd-sheet .pd-mapbar { flex-wrap: wrap; inset: auto 10px 10px 10px; padding: 12px; }
  .pd-sheet .pd-mapbarbtns { flex: 1 1 100%; }
  .pd-sheet .pd-mapbarbtns .btn { flex: 1 1 0; justify-content: center; padding-left: 6px; padding-right: 6px; }
}

/* Suit le bouton haut de page, qui passe a 40px a 12px du bord. */
@media (max-width: 600px) {
  .pd-fabwrap { right: 12px; bottom: calc(12px + 40px + 12px); }
}

@media (prefers-reduced-motion: reduce) {
  .pd-fab, .pd-fab svg { transition: none; }
  .pd-filterdrawer { animation: none; }
  .pd-switch, .pd-switch::after { transition: none; }
}

/* Le hero passe en une colonne. */
@media (max-width: 900px) {
  .pd-body { grid-template-columns: 1fr; }
}

/* REGLE §6 : on masque les lignes du feed avec une regle
   d'adjacence, JAMAIS en plafonnant une hauteur - sinon la
   derniere ligne est coupee en deux. :last-of-type ne marche pas
   ici : il cible la ligne masquee. */
@media (max-width: 780px) {
  .pd-feedcell + .pd-feedcell { display: none; }
}

@media (max-width: 620px) {
  .pd-h1 { font-size: 29px; max-width: none; }
  .pd-quotecat, .pd-quotebtn { flex: 1 1 100%; }
  /* REGLE §6 : ZIP fige a 100px, requete flexible, Search seul
     sur sa ligne en pleine largeur. */
  .pd-searchzip { flex: 0 0 auto; width: 100px; }
  .pd-searchq { flex: 1 1 0; min-width: 0; }
  .pd-searchbtn { flex: 1 0 100%; padding: 13px; }
}

/* REGLE §6 : tuiles du rail a 122x74 (nom 12px, sous-titre 10px)
   et padding du hero. Les regles de nav du meme palier vivent
   dans nocturne-base.css, partagees avec la fiche pro. */
@media (max-width: 760px) {
  .pd-hero { padding-top: 26px; padding-bottom: 24px; }
  .pd-cat { width: 122px; height: 74px; }
  .pd-cat .pd-catname { font-size: 12px; }
  .pd-cat .pd-catsub { font-size: 10px; }
}
