Fiche logement : refonte editoriale v2 — icones contextuelles, sections sans boites
- Nouveau composant AmenityIco (~34 pictos maison, trait 1.8) : chaque inclusion/caracteristique est appariee par mots-cles (accents neutralises) a SON icone — lave-vaisselle, chauffage, balcon, stationnement, animaux, piscine, foyer… — fini le meme ✓ repete dix fois - Inclusions : grille en filets (tuile icone 32px accent-soft, libelle, ✓ discret a droite pour le confirme ; neutre pour les mentions libres) - Chips cles du hero : hairline + icone contextuelle (3½ → porte, dispo → calendrier, pi² → regle…) au lieu d aplats marine - Colonne editoriale (gauche) de-boxee : description, inclusions, details pratiques respirent sans carte — les modules de donnees (droite) restent en cartes ; titres avec tiret accent net (sans bordure/ombre heritees) - Details pratiques : rangees en filets, cles en micro-mono, fini les tuiles - Prix 38-54px, ancres en onglets textes, en-bref en filet accent, galerie au cadre allege (hairline, rayon 10) - Mobile : le CTA sticky prend le bas d ecran, la tabbar s efface sur la fiche (body:has(.cta-sticky)) — plus de chevauchement
3 changed files +192 −4
added
frontend/src/components/AmenityIco.tsx
+112 −0
@@ -0,0 +1,112 @@ | ||
| 1 | +// ----------------------------------------------------------------------------- | |
| 2 | +// Groupe KA — composant partagé (lou-ka / immo-ka) | |
| 3 | +// components/AmenityIco.tsx : icône contextuelle d'une commodité ou inclusion. | |
| 4 | +// Fini l'icône unique répétée dix fois : chaque libellé est associé par | |
| 5 | +// mots-clés (accents neutralisés) à l'un des ~30 pictos maison — trait 1.8, | |
| 6 | +// 24×24, currentColor. Repli : ✓ (confirmé) ou étoile (mention libre). | |
| 7 | +// ----------------------------------------------------------------------------- | |
| 8 | +import { ReactNode } from "react"; | |
| 9 | + | |
| 10 | +const ICONS: Record<string, ReactNode> = { | |
| 11 | + heat: (<><rect x="4" y="9" width="16" height="9" rx="2" /><path d="M8 9v9M12 9v9M16 9v9M7.6 3.5c0 1.6 1.2 1.6 1.2 3.2M11.4 3.5c0 1.6 1.2 1.6 1.2 3.2M15.2 3.5c0 1.6 1.2 1.6 1.2 3.2" /></>), | |
| 12 | + bolt: <path d="M13 2.5 4.5 13.5H11l-1.5 8 8.5-11H11.5l1.5-8z" />, | |
| 13 | + droplet: (<><path d="M12 3.5S6.2 9.8 6.2 13.6a5.8 5.8 0 0 0 11.6 0C17.8 9.8 12 3.5 12 3.5z" /><path d="M9.4 14a2.7 2.7 0 0 0 2.1 2.6" /></>), | |
| 14 | + wifi: <path d="M3.5 9.5a13 13 0 0 1 17 0M6.5 13a8.5 8.5 0 0 1 11 0M9.5 16.4a4.4 4.4 0 0 1 5 0M12 19.6h.01" />, | |
| 15 | + dishwasher: (<><rect x="4.5" y="3" width="15" height="18" rx="2" /><path d="M4.5 8.5h15M8 12.5V17M12 12.5V17M16 12.5V17M7.5 5.7h.01M10.5 5.7h.01" /></>), | |
| 16 | + washer: (<><rect x="4.5" y="3" width="15" height="18" rx="2" /><circle cx="12" cy="14" r="4.2" /><path d="M4.5 7.5h15M16.4 5.2h.01M9.2 14c1 .8 1.9.8 2.8 0s1.9-.8 2.8 0" /></>), | |
| 17 | + fridge: (<><rect x="6.5" y="2.5" width="11" height="19" rx="2" /><path d="M6.5 9.5h11M9.5 5.5v2M9.5 12.5V16" /></>), | |
| 18 | + snow: <path d="M12 2.5v19M3.8 7.25l16.4 9.5M20.2 7.25 3.8 16.75" />, | |
| 19 | + elevator: (<><rect x="4.5" y="3" width="15" height="18" rx="2" /><path d="M12 3v18M7 11l1.5-1.8L10 11M14 13l1.5 1.8L17 13" /></>), | |
| 20 | + balcony: <path d="M4 11.5h16M5 11.5V20M19 11.5V20M9.5 11.5V20M14.5 11.5V20M4 20h16M7 11.5V6.5a5 5 0 0 1 10 0v5" />, | |
| 21 | + pool: <path d="M9 4.5v9M13.5 4.5v9M9 7.5h4.5M3 16.5c1.5 1.3 3 1.3 4.5 0s3-1.3 4.5 0 3 1.3 4.5 0 3-1.3 4.5 0M3 20c1.5 1.3 3 1.3 4.5 0s3-1.3 4.5 0 3 1.3 4.5 0 3-1.3 4.5 0" />, | |
| 22 | + gym: <path d="M6.7 6.7v10.6M17.3 6.7v10.6M3.5 9.2v5.6M20.5 9.2v5.6M6.7 12h10.6" />, | |
| 23 | + laundry: <path d="M4 9.5h16l-1.8 10a1.8 1.8 0 0 1-1.8 1.5H7.6a1.8 1.8 0 0 1-1.8-1.5zM8 9.5 12 3l4 6.5M9.3 13.5v3.5M12 13.5v3.5M14.7 13.5v3.5" />, | |
| 24 | + box: <path d="M3.5 8 12 3.5 20.5 8v8L12 20.5 3.5 16zM3.5 8 12 12.5 20.5 8M12 12.5v8" />, | |
| 25 | + parking: (<><rect x="3.5" y="3.5" width="17" height="17" rx="3.5" /><path d="M9.5 16.5v-9H13a2.9 2.9 0 0 1 0 5.8H9.5" /></>), | |
| 26 | + garage: <path d="M3.5 20V9.5L12 4l8.5 5.5V20M7 20v-6.5h10V20M7 16.8h10" />, | |
| 27 | + sofa: <path d="M5.5 11V8.8A2.8 2.8 0 0 1 8.3 6h7.4a2.8 2.8 0 0 1 2.8 2.8V11M3.5 13.7a2.2 2.2 0 0 1 4.4 0v1h8.2v-1a2.2 2.2 0 0 1 4.4 0V17.5h-17zM5.5 17.5v1.8M18.5 17.5v1.8" />, | |
| 28 | + nosmoke: <path d="M4 4l16 16M14.5 13H4v3h6.5M17.5 13H20v3h-1" />, | |
| 29 | + paw: (<><circle cx="8.2" cy="7.8" r="1.7" /><circle cx="15.8" cy="7.8" r="1.7" /><circle cx="4.8" cy="12" r="1.6" /><circle cx="19.2" cy="12" r="1.6" /><path d="M12 11c2.8 0 5.2 2.3 5.2 4.8 0 1.8-1.4 3-3.2 3-.8 0-1.3-.3-2-.3s-1.2.3-2 .3c-1.8 0-3.2-1.2-3.2-3C6.8 13.3 9.2 11 12 11z" /></>), | |
| 30 | + fire: (<><path d="M4 4.5h16M5.5 4.5V19.5M18.5 4.5V19.5M4 19.5h16" /><path d="M12 8.5c-1.8 2-3 3.4-3 5.3a3 3 0 0 0 6 0c0-1.9-1.2-3.3-3-5.3z" /></>), | |
| 31 | + tree: <path d="M12 3 7.2 9.5h2.4L5.5 15.5h13L14.4 9.5h2.4zM12 15.5V21" />, | |
| 32 | + spa: <path d="M8 3.5c0 1.7-1.4 2-1.4 3.7S8 9.5 8 11M12.5 3.5c0 1.7-1.4 2-1.4 3.7s1.4 2.3 1.4 3.8M17 3.5c0 1.7-1.4 2-1.4 3.7S17 9.5 17 11M3.5 15.5c1.4 1.3 2.8 1.3 4.2 0s2.9-1.3 4.3 0 2.8 1.3 4.2 0 2.9-1.3 4.3 0M3.5 19.5c1.4 1.3 2.8 1.3 4.2 0s2.9-1.3 4.3 0 2.8 1.3 4.2 0 2.9-1.3 4.3 0" />, | |
| 33 | + shield: (<><path d="M12 3 5 6v5.5c0 4.4 3 7.6 7 9.5 4-1.9 7-5.1 7-9.5V6z" /><path d="m9 11.5 2.2 2.2L15.5 9" /></>), | |
| 34 | + eye: (<><path d="M2.5 12S6.3 5.8 12 5.8 21.5 12 21.5 12 17.7 18.2 12 18.2 2.5 12 2.5 12z" /><circle cx="12" cy="12" r="2.8" /></>), | |
| 35 | + waves: <path d="M3 9c1.5 1.3 3 1.3 4.5 0s3-1.3 4.5 0 3 1.3 4.5 0 3-1.3 4.5 0M3 14c1.5 1.3 3 1.3 4.5 0s3-1.3 4.5 0 3 1.3 4.5 0 3-1.3 4.5 0M3 19c1.5 1.3 3 1.3 4.5 0s3-1.3 4.5 0 3 1.3 4.5 0 3-1.3 4.5 0" />, | |
| 36 | + calendar: (<><rect x="4" y="5" width="16" height="16" rx="2" /><path d="M4 10h16M8.5 3v4M15.5 3v4M8 14h.01M12 14h.01M16 14h.01" /></>), | |
| 37 | + ruler: <path d="M3.5 16.2 16.2 3.5l4.3 4.3L7.8 20.5zM7.8 15.9l1.8 1.8M10.6 13.1l1.8 1.8M13.4 10.3l1.8 1.8M16.2 7.5 18 9.3" />, | |
| 38 | + bed: <path d="M3.5 18V6.5M3.5 13.5h17V18M3.5 10h6.5v3.5M20.5 13.5v-1a3 3 0 0 0-3-3H10" />, | |
| 39 | + bath: <path d="M4 12.5h16v1.7a4.8 4.8 0 0 1-4.8 4.8H8.8A4.8 4.8 0 0 1 4 14.2zM6 12.5V6a2.5 2.5 0 0 1 4.6-1.3M7 19l-1 1.8M17 19l1 1.8" />, | |
| 40 | + people: (<><circle cx="9" cy="8" r="3.2" /><path d="M3.5 20.5c0-3.1 2.4-5.2 5.5-5.2s5.5 2.1 5.5 5.2M15.5 5.4a3.2 3.2 0 0 1 0 5.2M20.5 20.5c0-2.7-1.8-4.6-4.3-5.1" /></>), | |
| 41 | + stairs: <path d="M3.5 20.5h4.2v-4.2h4.2v-4.2h4.2V7.9h4.4" />, | |
| 42 | + door: (<><rect x="6" y="3" width="12" height="18" rx="1.5" /><path d="M14.8 12h.01M4 21h16" /></>), | |
| 43 | + home: <path d="m3.5 11 8.5-7 8.5 7M6 9.5V20h12V9.5" />, | |
| 44 | + sun: (<><circle cx="12" cy="12" r="4" /><path d="M12 2.5v2.5M12 19v2.5M2.5 12H5M19 12h2.5M5.3 5.3l1.8 1.8M16.9 16.9l1.8 1.8M18.7 5.3l-1.8 1.8M7.1 16.9l-1.8 1.8" /></>), | |
| 45 | + check: <path d="m4.5 12.5 5.3 5.3L19.5 6.5" />, | |
| 46 | + spark: <path d="M12 3.5 13.9 10l6.6 2-6.6 2L12 20.5 10.1 14l-6.6-2 6.6-2z" />, | |
| 47 | +}; | |
| 48 | + | |
| 49 | +/** [motif (sur libellé minuscule sans accents), clé d'icône] — ordre = priorité */ | |
| 50 | +const RULES: [RegExp, string][] = [ | |
| 51 | + [/lave-?vaisselle/, "dishwasher"], | |
| 52 | + [/laveuse|secheuse|lessive/, "washer"], | |
| 53 | + [/buanderie/, "laundry"], | |
| 54 | + [/electromenager|frigo|refrigerateur|cuisiniere|four incl|poele/, "fridge"], | |
| 55 | + [/climatis|air clim|thermopompe|echangeur d.air|\ba\/?c\b/, "snow"], | |
| 56 | + [/chauff/, "heat"], | |
| 57 | + [/eau chaude/, "droplet"], | |
| 58 | + [/electric|eclair|hydro/, "bolt"], | |
| 59 | + [/internet|wi-?fi|cablodistribution|\bcable\b|fibre/, "wifi"], | |
| 60 | + [/ascenseur/, "elevator"], | |
| 61 | + [/balcon|terrasse|patio|loggia|veranda/, "balcony"], | |
| 62 | + [/piscine/, "pool"], | |
| 63 | + [/gym|salle d.entrainement|exercice/, "gym"], | |
| 64 | + [/rangement|locker|entreposage|walk-?in|penderie/, "box"], | |
| 65 | + [/garage/, "garage"], | |
| 66 | + [/stationnement|parking|abri d.auto/, "parking"], | |
| 67 | + [/meuble/, "sofa"], | |
| 68 | + [/non-?fumeur|sans fumee/, "nosmoke"], | |
| 69 | + [/animau|chat|chien|\bpet\b/, "paw"], | |
| 70 | + [/foyer|cheminee|poele a bois/, "fire"], | |
| 71 | + [/spa\b|jacuzzi|sauna|bain tourbillon/, "spa"], | |
| 72 | + [/securite|surveill|camera|alarme|interphone|concierge|portier/, "shield"], | |
| 73 | + [/\bvue\b|panoram/, "eye"], | |
| 74 | + [/bord de l.eau|acces au lac|\blac\b|riviere|plage|navigable/, "waves"], | |
| 75 | + [/cour|jardin|arbre|boise|verdure|gazon|amenagement paysager/, "tree"], | |
| 76 | + [/ensoleill|luminosite|lumineux|solarium/, "sun"], | |
| 77 | + [/dispo|libre |libre$/, "calendar"], | |
| 78 | + [/pi2|pieds carres|superficie|\bm2\b/, "ruler"], | |
| 79 | + [/chambre/, "bed"], | |
| 80 | + [/salle[s]? de bain|salle[s]? d.eau|douche|\bsdb\b/, "bath"], | |
| 81 | + [/occupant|personne|colocataire/, "people"], | |
| 82 | + [/etage|niveau|escalier|mezzanine/, "stairs"], | |
| 83 | + [/studio|loft|(^|\s)\d ?1\/2|½/, "door"], | |
| 84 | + [/maison|plain-?pied|unifamiliale/, "home"], | |
| 85 | + [/egout|septique|fosse/, "waves"], | |
| 86 | + [/aqueduc|approvisionnement en eau|puits/, "droplet"], | |
| 87 | + [/construction|neuve|fondation|toiture|revetement|renov/, "home"], | |
| 88 | + [/commerce|zonage|usage/, "box"], | |
| 89 | +]; | |
| 90 | + | |
| 91 | +/** minuscules + accents neutralisés, pour un appariement robuste */ | |
| 92 | +const norm = (s: string) => | |
| 93 | + s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); | |
| 94 | + | |
| 95 | +export function amenityKey(label: string, fallback = "check"): string { | |
| 96 | + const n = norm(label); | |
| 97 | + for (const [re, key] of RULES) if (re.test(n)) return key; | |
| 98 | + return fallback; | |
| 99 | +} | |
| 100 | + | |
| 101 | +export default function AmenityIco({ label, size = 16, fallback = "check" }: | |
| 102 | + { label: string; size?: number; fallback?: string }) { | |
| 103 | + return ( | |
| 104 | + <svg | |
| 105 | + width={size} height={size} viewBox="0 0 24 24" aria-hidden="true" | |
| 106 | + fill="none" stroke="currentColor" strokeWidth={1.8} | |
| 107 | + strokeLinecap="round" strokeLinejoin="round" | |
| 108 | + > | |
| 109 | + {ICONS[amenityKey(label, fallback)] ?? ICONS.check} | |
| 110 | + </svg> | |
| 111 | + ); | |
| 112 | +} | |
modified
frontend/src/pages/Listing.tsx
+16 −4
@@ -30,6 +30,7 @@ import ImmeubleBloc from "../components/ImmeubleBloc"; | ||
| 30 | 30 | import GestionnaireBloc from "../components/GestionnaireBloc"; |
| 31 | 31 | import HiverScore from "../components/HiverScore"; |
| 32 | 32 | import { IcoAlert, IcoDoc } from "../components/Icons"; |
| 33 | +import AmenityIco from "../components/AmenityIco"; | |
| 33 | 34 | import KaScoresBlock from "../components/KaScoresBlock"; |
| 34 | 35 | import { markSeen } from "../search/seen"; |
| 35 | 36 | |
@@ -378,7 +379,11 @@ export default function ListingPage() { | ||
| 378 | 379 | {[l.address !== l.title ? l.address : "", l.sector, l.city].filter(Boolean).join(" · ")} |
| 379 | 380 | </div> |
| 380 | 381 | <div className="chips-scroll" role="list" aria-label="Caractéristiques clés"> |
| 381 | − {chips.map((c) => <span className="chip-key" role="listitem" key={c}>{c}</span>)} | |
| 382 | + {chips.map((c) => ( | |
| 383 | + <span className="chip-key" role="listitem" key={c}> | |
| 384 | + <AmenityIco label={c} size={14} fallback="spark" /> {c} | |
| 385 | + </span> | |
| 386 | + ))} | |
| 382 | 387 | </div> |
| 383 | 388 | <nav className="ancres" aria-label="Sections de la fiche"> |
| 384 | 389 | <a href="#description">Description</a> |
@@ -424,12 +429,19 @@ export default function ListingPage() { | ||
| 424 | 429 | <section className="f-bloc f-incl" id="inclusions"> |
| 425 | 430 | <h2>Inclusions et commodités</h2> |
| 426 | 431 | {zeroFrais && <div className="deal-badge deal-good">💡 Chauffage, électricité et eau chaude inclus — 0{NBSP}$ de frais cachés</div>} |
| 427 | − <div className="amenity-row"> | |
| 432 | + <div className="amenity-grid"> | |
| 428 | 433 | {confirmes.map((b) => ( |
| 429 | − <span className="amenity confirmed" key={`c-${b}`}>✓ {b}</span> | |
| 434 | + <span className="amenity-it confirmed" key={`c-${b}`}> | |
| 435 | + <span className="am-ico"><AmenityIco label={b} /></span> | |
| 436 | + <span className="am-txt">{b}</span> | |
| 437 | + <span className="am-conf" title="Confirmé par les données structurées de la source">✓</span> | |
| 438 | + </span> | |
| 430 | 439 | ))} |
| 431 | 440 | {autres.map((a) => ( |
| 432 | − <span className="amenity unconfirmed" key={a} title="Mentionné par la source, sans confirmation structurée">{a}</span> | |
| 441 | + <span className="amenity-it unconfirmed" key={a} title="Mentionné par la source, sans confirmation structurée"> | |
| 442 | + <span className="am-ico"><AmenityIco label={a} fallback="spark" /></span> | |
| 443 | + <span className="am-txt">{a}</span> | |
| 444 | + </span> | |
| 433 | 445 | ))} |
| 434 | 446 | </div> |
| 435 | 447 | {confirmes.length === 0 && autres.length === 0 && ( |
modified
frontend/src/styles.css
+64 −0
@@ -2711,3 +2711,67 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */ | ||
| 2711 | 2711 | } |
| 2712 | 2712 | /* le badge Groupe KA lâche prise un peu plus tôt (débordement de ~6px à 1100) */ |
| 2713 | 2713 | @media (max-width: 1140px) { .header .gk-badge { display: none; } } |
| 2714 | + | |
| 2715 | +/* ---- Fiche logement : DA v2 — sections en filets, icônes contextuelles ---- */ | |
| 2716 | +.f-bloc > h2 { display: flex; align-items: center; gap: 10px; font-size: 21px; } | |
| 2717 | +.f-bloc > h2::before { content: ""; width: 20px; height: 3px; border-radius: 2px; background: var(--accent); flex: none; } | |
| 2718 | +.f-hero .price { font-size: clamp(38px, 8.5vw, 54px); letter-spacing: -0.04em; } | |
| 2719 | +.f-hero h1 { color: var(--ink); } | |
| 2720 | +.f-hero .loc { font-size: 14px; } | |
| 2721 | +/* chips clés : hairline + icône contextuelle (plus d'aplat marine) */ | |
| 2722 | +.chip-key { | |
| 2723 | + background: transparent; color: var(--ink); border: 1px solid var(--hairline-strong); | |
| 2724 | + gap: 7px; font-weight: 600; padding: 7px 13px; | |
| 2725 | +} | |
| 2726 | +.chip-key svg { color: var(--accent-deep); flex: none; } | |
| 2727 | +/* ancres en onglets textes */ | |
| 2728 | +.ancres { gap: 18px; border-bottom: 1px solid var(--hairline); } | |
| 2729 | +.ancres a { padding: 10px 2px; border-radius: 0; font-family: var(--font-display); font-weight: 700; font-size: 13px; color: var(--ink-3); } | |
| 2730 | +.ancres a:hover { background: none; color: var(--accent-deep); box-shadow: inset 0 -2.5px 0 var(--accent); } | |
| 2731 | +/* inclusions : grille d'items en filets — chaque commodité a SON icône */ | |
| 2732 | +.amenity-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 0 28px; margin-bottom: 8px; } | |
| 2733 | +.amenity-it { | |
| 2734 | + display: flex; align-items: center; gap: 11px; padding: 7px 0; | |
| 2735 | + border-bottom: 1px solid var(--hairline); font-size: 13.5px; color: var(--ink); min-height: 46px; | |
| 2736 | +} | |
| 2737 | +.am-ico { | |
| 2738 | + display: inline-grid; place-items: center; width: 32px; height: 32px; | |
| 2739 | + border-radius: 10px; background: var(--accent-soft); color: var(--accent-deep); flex: none; | |
| 2740 | +} | |
| 2741 | +.am-txt { min-width: 0; } | |
| 2742 | +.am-conf { margin-left: auto; color: var(--green); font-weight: 700; font-size: 12px; } | |
| 2743 | +.amenity-it.unconfirmed { color: var(--ink-2); } | |
| 2744 | +.amenity-it.unconfirmed .am-ico { background: var(--surface-2); color: var(--ink-3); } | |
| 2745 | +/* détails pratiques : rangées en filets (plus de boîtes grises) */ | |
| 2746 | +.kv { gap: 0 30px; margin: 14px 0 0; } | |
| 2747 | +.kv .cell { | |
| 2748 | + background: transparent; border-radius: 0; padding: 9px 0; | |
| 2749 | + border-bottom: 1px solid var(--hairline); | |
| 2750 | + display: flex; align-items: baseline; justify-content: space-between; gap: 14px; | |
| 2751 | +} | |
| 2752 | +.kv .cell .k { font-family: var(--font-mono); } | |
| 2753 | +.kv .cell .v { margin-top: 0; text-align: right; } | |
| 2754 | +/* galerie : cadre allégé, rayon photo 10 */ | |
| 2755 | +.carousel { border: 1px solid var(--hairline-strong); box-shadow: none; border-radius: var(--r-2); } | |
| 2756 | +.thumbs button { border-radius: 8px; } | |
| 2757 | +/* « en bref » : filet accent au lieu d'une boîte pleine */ | |
| 2758 | +.enbref { background: transparent; border: 0; border-left: 3px solid var(--accent); border-radius: 0; padding: 2px 0 2px 14px; } | |
| 2759 | +/* CTA sticky : sur la fiche, il prend le bas d'écran — la tabbar s'efface */ | |
| 2760 | +body:has(.cta-sticky) .tabbar { display: none; } | |
| 2761 | +.cta-sticky { border-top: 1px solid var(--hairline-strong); background: rgba(250, 249, 245, 0.92); } | |
| 2762 | +@media (max-width: 760px) { | |
| 2763 | + body:has(.cta-sticky) { padding-bottom: 0; } | |
| 2764 | +} | |
| 2765 | + | |
| 2766 | +/* colonne éditoriale (gauche) : les sections respirent sans boîte — | |
| 2767 | + les modules de données de la colonne droite restent en cartes */ | |
| 2768 | +.fiche > .f-col:first-child > .f-bloc:not(.f-galerie):not(.f-hero) { | |
| 2769 | + background: transparent; border: 0; border-radius: 0; padding: 0; box-shadow: none; | |
| 2770 | +} | |
| 2771 | +@media (max-width: 640px) { | |
| 2772 | + .fiche > .f-col:first-child > .f-bloc:not(.f-galerie):not(.f-hero) { padding: 0; } | |
| 2773 | +} | |
| 2774 | +/* cellules kv : neutraliser la tuile (bord encre + ombre) de la couche fiche */ | |
| 2775 | +.kv .cell { border: 0; border-bottom: 1px solid var(--hairline); box-shadow: none; } | |
| 2776 | +/* tiret accent des titres : sans bordure ni ombre héritées de la couche fiche */ | |
| 2777 | +.f-bloc > h2::before, .f-bloc h2::before, .quartier h2::before { border: 0; box-shadow: none; } | |
| 2714 | 2778 | |