SPB Git forge

spb/lou-ka

Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

232commits 1branches 0releases
172.9 MBsize
maindefault branch
2 days agolast push
HTML 98.9% Python 0.6%

Accueil : refonte majeure du rendu — CTA hero, filtres et boutons peaufines

- Hero : halo d accent + trame de points decorative, rangee CTA (Explorer /
  Voir la carte) avec ombres decalees accent, stat-chips interactives
  (tabular-nums, survol), avantages en mini-cartes bordees encre
- Filterbar : cadre 2px + rayon 16, recherche 52px focus accent (ombre 3x3),
  selects survolables, bouton Plus de filtres avec icone, badge compteur et
  chevron anime, panneau avance en pointille avec easing
- Segments : etat actif encre + souligne accent interieur ; pastilles actives
  avec animation d apparition et survol danger (intention de retrait)
- Chips 42px avec icones alignees ; bascule Liste/Carte etat actif encre
- Mobile : poignee de sheet, bouton Voir les resultats sticky en bas de la
  feuille, FAB avec badge compteur
Simon-Pierre Boucher committed 1 mo ago (Aug 25, 2026) parent bc6aef3

2 changed files +161 −56

modified frontend/src/pages/Home.tsx +26 −2
@@ -254,6 +254,26 @@ export default function Home() {
254 254 Tous les logements à louer au Québec, regroupés au même endroit — mis à jour
255 255 automatiquement, avec toutes les photos et un lien direct vers l'annonce originale.
256 256 </p>
257 + <div className="hero-cta">
258 + <button
259 + className="btn btn-primary btn-lg"
260 + onClick={() => {
261 + setView("liste");
262 + resultsRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
263 + }}
264 + >
265 + <IcoSearch size={16} /> Explorer les logements
266 + </button>
267 + <button
268 + className="btn btn-lg"
269 + onClick={() => {
270 + setView("carte");
271 + resultsRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
272 + }}
273 + >
274 + <IcoMap size={16} /> Voir la carte
275 + </button>
276 + </div>
257 277 <div className="benefits" aria-label="Avantages">
258 278 <div className="benefit">
259 279 <span className="benefit-ico"><IcoHouse size={20} /></span>
@@ -299,6 +319,7 @@ export default function Home() {
299 319 <div className="sheet-backdrop" onClick={() => setSheetOpen(false)} aria-hidden="true" />
300 320 )}
301 321 <section className={`filterbar ${sheetOpen ? "open" : ""}`} aria-label="Filtres">
322 + <div className="sheet-handle" aria-hidden="true" />
302 323 <div className="sheet-head">
303 324 <span>Filtres</span>
304 325 <button className="sheet-close" onClick={() => setSheetOpen(false)} aria-label="Fermer les filtres">
@@ -366,7 +387,9 @@ export default function Home() {
366 387 onClick={() => setAdvOpen(!advOpen)}
367 388 aria-expanded={advOpen}
368 389 >
369 − Plus de filtres{advCount > 0 ? ` · ${advCount}` : ""} {advOpen ? "▴" : "▾"}
390 + <IcoSliders size={14} /> Plus de filtres
391 + {advCount > 0 && <span className="f-more-badge">{advCount}</span>}
392 + <span className={`f-chev${advOpen ? " up" : ""}`} aria-hidden="true" />
370 393 </button>
371 394 </div>
372 395
@@ -603,7 +626,8 @@ export default function Home() {
603 626 onClick={() => setSheetOpen(true)}
604 627 aria-label="Ouvrir les filtres"
605 628 >
606 − <IcoSliders size={15} /> Filtres{activeFilters > 0 ? ` · ${activeFilters}` : ""}
629 + <IcoSliders size={15} /> Filtres
630 + {activeFilters > 0 && <span className="fab-badge">{activeFilters}</span>}
607 631 </button>
608 632 </div>
609 633 );
modified frontend/src/styles.css +135 −54
@@ -88,22 +88,52 @@ html, body { overflow-x: clip; }
88 88 }
89 89
90 90 /* ================= Hero ================= */
91 −.hero { padding: 58px 0 22px; }
92 −@media (max-width: 640px) { .hero { padding: 34px 0 14px; } }
91 +.hero { position: relative; padding: 64px 0 26px; }
92 +@media (max-width: 640px) { .hero { padding: 36px 0 14px; } }
93 +/* halo d'accent + trame de points en fond — purement décoratif, sous le texte */
94 +.hero::before {
95 + content: ""; position: absolute; z-index: -1; top: -60px; right: -120px;
96 + width: 560px; height: 460px; pointer-events: none;
97 + background: radial-gradient(closest-side, rgba(255, 106, 0, 0.13), transparent 72%);
98 +}
99 +.hero::after {
100 + content: ""; position: absolute; z-index: -1; inset: -20px -40px 0 0; pointer-events: none;
101 + background-image: radial-gradient(rgba(20, 24, 20, 0.16) 1px, transparent 1.5px);
102 + background-size: 24px 24px;
103 + -webkit-mask-image: linear-gradient(112deg, transparent 58%, rgba(0, 0, 0, 0.85));
104 + mask-image: linear-gradient(112deg, transparent 58%, rgba(0, 0, 0, 0.85));
105 +}
93 106 .hero h1 {
94 107 font-size: clamp(36px, 5.4vw, 56px); font-weight: 700; line-height: 1.06;
95 108 letter-spacing: -0.03em; max-width: 900px; margin-top: 14px; color: var(--navy);
96 109 }
97 110 .hero h1 .outline { color: var(--navy); }
98 111 .hero p.lede { color: var(--ink-2); font-size: 17px; max-width: 640px; margin: 18px 0 0; }
99 −.stat-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
112 +
113 +/* — CTA du héro : accès direct aux résultats / à la carte — */
114 +.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
115 +.btn-lg { min-height: 52px; padding: 14px 26px; font-size: 15px; border-radius: 12px; }
116 +.btn-lg svg { flex: none; }
117 +.hero-cta .btn-primary { box-shadow: 5px 5px 0 var(--accent); }
118 +.hero-cta .btn-primary:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--accent); }
119 +.hero-cta .btn-primary:active { transform: none; box-shadow: 3px 3px 0 var(--accent); }
120 +@media (max-width: 640px) {
121 + .hero-cta { gap: 10px; }
122 + .hero-cta .btn { flex: 1 1 45%; }
123 +}
124 +
125 +.stat-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
100 126 .stat-chip {
101 127 background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-pill);
102 128 padding: 8px 16px; font-size: 12.5px; font-weight: 500;
103 129 color: var(--ink-2); display: flex; gap: 8px; align-items: center;
104 130 box-shadow: var(--shadow-flat);
131 + transition: transform 0.13s ease, box-shadow 0.13s ease;
132 +}
133 +@media (hover: hover) {
134 + .stat-chip:hover { transform: translate(-1px, -1px); box-shadow: var(--shadow-off-mid); }
105 135 }
106 −.stat-chip b { color: var(--navy); font-weight: 700; }
136 +.stat-chip b { color: var(--navy); font-weight: 700; font-variant-numeric: tabular-nums; }
107 137 .stat-chip .pulse {
108 138 width: 8px; height: 8px; border-radius: 50%; background: var(--orange);
109 139 box-shadow: 0 0 0 4px var(--orange-soft); animation: pulse 2.4s ease infinite;
@@ -115,13 +145,22 @@ html, body { overflow-x: clip; }
115 145 display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
116 146 gap: 14px; margin-top: 30px;
117 147 }
118 −.benefit { display: flex; align-items: center; gap: 12px; }
148 +.benefit {
149 + display: flex; align-items: center; gap: 12px;
150 + background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
151 + padding: 11px 14px; box-shadow: var(--shadow-flat);
152 + transition: transform 0.15s ease, box-shadow 0.15s ease;
153 +}
154 +@media (hover: hover) {
155 + .benefit:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-off-mid); }
156 +}
119 157 .benefit-ico {
120 158 width: 42px; height: 42px; border-radius: var(--r-pill); flex: none;
121 159 display: flex; align-items: center; justify-content: center;
122 160 background: var(--orange-soft); color: var(--orange);
161 + border: 1px solid rgba(255, 106, 0, 0.25);
123 162 }
124 −.benefit-ico.blue { background: var(--blue-soft); color: var(--blue); }
163 +.benefit-ico.blue { background: var(--blue-soft); color: var(--blue); border-color: rgba(28, 92, 65, 0.25); }
125 164 .benefit-label {
126 165 font-size: 11.5px; font-weight: 700; text-transform: uppercase;
127 166 letter-spacing: 0.08em; color: var(--navy);
@@ -132,40 +171,43 @@ html, body { overflow-x: clip; }
132 171
133 172 /* ================= Filter bar ================= */
134 173 .filterbar {
135 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
136 − box-shadow: var(--shadow-off-soft); padding: 14px; margin: 30px 0 6px;
174 + background: var(--surface); border: 2px solid var(--ink); border-radius: 16px;
175 + box-shadow: var(--shadow-off-soft); padding: 14px; margin: 34px 0 6px;
137 176 display: flex; flex-direction: column; gap: 0; min-width: 0;
138 177 }
139 178
140 179 /* — rangée principale — */
141 180 .f-primary { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; min-width: 0; }
142 181 .f-search {
143 − flex: 1 1 220px; min-width: 0; max-width: 440px; align-self: center;
144 − display: flex; align-items: center; gap: 8px;
145 − border: 1px solid transparent; border-radius: var(--r-pill); background: var(--grey);
146 − padding: 0 15px; min-height: 42px; color: var(--ink-2);
147 − transition: box-shadow 0.15s ease, border-color 0.15s ease, background 0.15s ease;
182 + flex: 1 1 240px; min-width: 0; max-width: 460px;
183 + display: flex; align-items: center; gap: 9px;
184 + border: 1.5px solid var(--ink); border-radius: var(--r-pill); background: var(--grey);
185 + padding: 0 16px; min-height: 52px; color: var(--ink-2);
186 + transition: box-shadow 0.15s ease, border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
148 187 }
149 188 .f-search:focus-within {
150 − background: var(--white); border-color: var(--blue);
151 − box-shadow: 0 0 0 3px rgba(28, 92, 65, 0.15);
189 + background: var(--white); border-color: var(--ink);
190 + box-shadow: 3px 3px 0 var(--accent); color: var(--accent-deep);
152 191 }
153 192 .f-search input {
154 193 border: none; background: none; outline: none; flex: 1; min-width: 0;
155 − font-size: 14px; color: var(--ink); font-family: inherit;
194 + font-size: 14.5px; color: var(--ink); font-family: inherit;
156 195 }
196 +.f-search input::placeholder { color: var(--ink-3); }
157 197 .f-clear {
158 198 border: none; background: var(--line); color: var(--ink-2); border-radius: 50%;
159 − width: 20px; height: 20px; font-size: 10px; cursor: pointer; flex: none;
160 − display: grid; place-items: center;
199 + width: 22px; height: 22px; font-size: 10px; cursor: pointer; flex: none;
200 + display: grid; place-items: center; transition: background 0.12s ease, color 0.12s ease;
161 201 }
202 +.f-clear:hover { background: var(--ink); color: var(--white); }
162 203 .f-ctl {
163 204 flex: 0 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center;
164 205 gap: 2px; border: 1.5px solid var(--ink); border-radius: 14px; background: var(--surface);
165 206 padding: 7px 14px 6px; min-height: 52px; cursor: pointer;
166 − transition: box-shadow 0.15s ease, border-color 0.15s ease;
207 + transition: box-shadow 0.15s ease, background 0.15s ease;
167 208 }
168 −.f-ctl:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(28, 92, 65, 0.15); }
209 +@media (hover: hover) { .f-ctl:hover { background: var(--grey); } }
210 +.f-ctl:focus-within { background: var(--white); box-shadow: 3px 3px 0 var(--accent); }
169 211 .f-ctl > span {
170 212 font-size: 9.5px; font-weight: 700;
171 213 text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3);
@@ -182,21 +224,35 @@ html, body { overflow-x: clip; }
182 224 .range-pair select { max-width: 86px; }
183 225 .range-sep { color: var(--ink-3); font-size: 11px; }
184 226 .f-more {
185 − flex: none; align-self: stretch; border: 1.5px solid var(--ink); border-radius: var(--r-pill);
227 + flex: none; align-self: stretch; display: inline-flex; align-items: center; gap: 8px;
228 + border: 1.5px solid var(--ink); border-radius: var(--r-pill);
186 229 background: var(--surface); color: var(--navy); padding: 0 20px; cursor: pointer;
187 − font-family: var(--font-display); font-weight: 600; font-size: 14px; min-height: 52px;
188 − transition: all 0.13s ease;
230 + font-family: var(--font-display); font-weight: 700; font-size: 14px; min-height: 52px;
231 + transition: transform 0.13s ease, box-shadow 0.13s ease, background 0.13s ease, color 0.13s ease;
232 +}
233 +.f-more:hover { transform: translate(-1px, -1px); box-shadow: var(--shadow-off-mid); }
234 +.f-more:active { transform: none; box-shadow: none; }
235 +.f-more.on { background: var(--ink); border-color: var(--ink); color: var(--white); box-shadow: 3px 3px 0 var(--accent); }
236 +.f-more.on:hover { transform: none; }
237 +.f-more-badge {
238 + display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px;
239 + border-radius: var(--r-pill); background: var(--accent); color: var(--on-accent);
240 + font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
189 241 }
190 −.f-more:hover { background: var(--blue-soft); border-color: var(--blue); color: var(--blue); }
191 −.f-more.on { background: var(--blue); border-color: var(--blue); color: var(--white); }
242 +.f-chev {
243 + width: 8px; height: 8px; flex: none;
244 + border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
245 + transform: rotate(45deg); margin-top: -4px; transition: transform 0.18s ease, margin 0.18s ease;
246 +}
247 +.f-chev.up { transform: rotate(-135deg); margin-top: 4px; }
192 248
193 249 /* — panneau avancé — */
194 250 .f-adv {
195 − display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px 22px;
196 − border-top: 1px solid var(--line); margin-top: 14px; padding-top: 14px; min-width: 0;
197 − animation: adv-in 0.18s ease;
251 + display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px 26px;
252 + border-top: 1.5px dashed var(--line); margin-top: 14px; padding-top: 16px; min-width: 0;
253 + animation: adv-in 0.22s cubic-bezier(0.2, 0.9, 0.3, 1);
198 254 }
199 −@keyframes adv-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
255 +@keyframes adv-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
200 256 .f-group { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
201 257 .f-group > label {
202 258 font-size: 10.5px; font-weight: 700;
@@ -212,33 +268,39 @@ html, body { overflow-x: clip; }
212 268 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23141814'/%3E%3C/svg%3E");
213 269 background-repeat: no-repeat; background-position: right 12px center;
214 270 }
215 −.f-native:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(28, 92, 65, 0.15); background: var(--white); }
271 +.f-native:focus { border-color: var(--ink); box-shadow: 3px 3px 0 var(--accent); background: var(--white); }
216 272
217 273 /* segments (pilules soudées) */
218 274 .seg { display: inline-flex; flex-wrap: wrap; row-gap: 6px; }
219 275 .seg button {
220 276 border: 1.5px solid var(--ink); background: var(--surface); color: var(--ink-2);
221 277 padding: 8px 14px; font-family: var(--font-display); font-weight: 600; font-size: 13px;
222 − cursor: pointer; margin-left: -1px; white-space: nowrap; min-height: 38px;
223 − transition: all 0.12s ease;
278 + cursor: pointer; margin-left: -1.5px; white-space: nowrap; min-height: 40px;
279 + transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
224 280 }
225 281 .seg button:first-child { border-radius: var(--r-pill) 0 0 var(--r-pill); margin-left: 0; padding-left: 16px; }
226 282 .seg button:last-child { border-radius: 0 var(--r-pill) var(--r-pill) 0; padding-right: 16px; }
227 −.seg button:hover { background: var(--blue-soft); color: var(--blue); }
228 −.seg button.on { background: var(--blue); border-color: var(--blue); color: var(--white); position: relative; z-index: 1; }
283 +.seg button:hover { background: var(--orange-soft); color: var(--orange-deep); }
284 +.seg button.on {
285 + background: var(--ink); border-color: var(--ink); color: var(--white);
286 + position: relative; z-index: 1; box-shadow: inset 0 -2.5px 0 var(--accent);
287 +}
229 288
230 −/* pastilles de filtres actifs */
231 −.pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 2px; }
232 −.pill {
289 +/* pastilles de filtres actifs — survol = intention de retrait (danger) */
290 +.pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 2px; }
291 +.pills .pill {
233 292 display: inline-flex; align-items: center; gap: 7px;
234 − border: 1px solid rgba(28, 92, 65, 0.3); background: var(--blue-soft); color: var(--blue);
293 + border: 1.5px solid var(--ink); background: var(--surface); color: var(--ink);
235 294 border-radius: var(--r-pill); padding: 6px 14px; font-size: 12.5px; font-weight: 600;
236 − cursor: pointer; transition: all 0.13s ease;
237 −}
238 −.pill:hover { background: var(--blue); color: var(--white); }
239 −.pill-x { font-size: 10px; opacity: 0.65; }
240 −.pill-clear { background: var(--surface); border-color: var(--danger); color: var(--danger); }
241 −.pill-clear:hover { background: var(--danger); color: #fff; }
295 + cursor: pointer; transition: all 0.13s ease; box-shadow: 2px 2px 0 var(--orange-soft);
296 + animation: pill-in 0.18s ease;
297 +}
298 +@keyframes pill-in { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: none; } }
299 +.pills .pill:hover { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); box-shadow: none; }
300 +.pills .pill:hover .pill-x { opacity: 1; }
301 +.pill-x { font-size: 10px; opacity: 0.6; }
302 +.pills .pill-clear { background: var(--surface); border-color: var(--danger); color: var(--danger); box-shadow: none; }
303 +.pills .pill-clear:hover { background: var(--danger); color: #fff; }
242 304 .chip-sep { width: 1px; align-self: stretch; background: var(--line); margin: 4px 4px; flex: none; }
243 305 .link-btn {
244 306 background: none; border: none; padding: 0; color: var(--blue); font: inherit;
@@ -266,15 +328,17 @@ html, body { overflow-x: clip; }
266 328 /* .btn / .btn-primary / .btn-ghost : fournis par tokens.css (ka-ui). */
267 329
268 330 /* ================= Chips ================= */
269 −.chips { display: flex; gap: 8px; margin: 16px 0 4px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
331 +.chips { display: flex; gap: 8px; margin: 18px 0 4px; overflow-x: auto; padding: 2px 0 8px; scrollbar-width: none; }
270 332 .chips::-webkit-scrollbar { display: none; }
271 333 .chip {
334 + display: inline-flex; align-items: center; gap: 7px;
272 335 border: 1.5px solid var(--ink); background: var(--surface); color: var(--ink);
273 − border-radius: var(--r-pill); padding: 8px 18px; font-size: 13px; font-weight: 700; cursor: pointer;
274 − font-family: var(--font-display); white-space: nowrap; min-height: 40px;
336 + border-radius: var(--r-pill); padding: 9px 18px; font-size: 13px; font-weight: 700; cursor: pointer;
337 + font-family: var(--font-display); white-space: nowrap; min-height: 42px;
275 338 transition: transform 0.13s, box-shadow 0.13s, background 0.13s, color 0.13s;
276 339 }
277 340 .chip:hover { transform: translate(-1px, -1px); box-shadow: var(--shadow-off-mid); }
341 +.chip:active { transform: none; box-shadow: none; }
278 342 .chip.on { background: var(--ink); border-color: var(--ink); color: var(--accent); box-shadow: 3px 3px 0 var(--accent); }
279 343
280 344 /* ================= Results ================= */
@@ -542,9 +606,15 @@ html, body { overflow-x: clip; }
542 606
543 607 /* ================= Mobile : feuille de filtres + FAB ================= */
544 608 .sheet-head { display: none; }
609 +.sheet-handle { display: none; }
545 610 .sheet-apply { display: none; }
546 611 .sheet-backdrop { display: none; }
547 612 .fab { display: none; }
613 +.fab-badge {
614 + display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px;
615 + border-radius: var(--r-pill); background: var(--white); color: var(--accent-deep);
616 + font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; margin-left: 2px;
617 +}
548 618
549 619 @media (max-width: 640px) {
550 620 /* En-tête compact */
@@ -554,6 +624,7 @@ html, body { overflow-x: clip; }
554 624 .ticker { font-size: 10.5px; padding: 6px 0; }
555 625
556 626 /* Héro resserré + stats en rangée défilante */
627 + .hero::before { width: 320px; height: 260px; top: -30px; right: -90px; }
557 628 .hero h1 { font-size: clamp(30px, 8.6vw, 42px); }
558 629 .hero p.lede { font-size: 15px; }
559 630 .stat-row { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 6px; margin-right: -16px; padding-right: 16px; }
@@ -573,23 +644,31 @@ html, body { overflow-x: clip; }
573 644 position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-modal, 900);
574 645 margin: 0; border-radius: 24px 24px 0 0; border: none;
575 646 max-height: 82dvh; overflow-y: auto; -webkit-overflow-scrolling: touch;
576 − padding: 16px 18px calc(18px + env(safe-area-inset-bottom));
647 + padding: 10px 18px calc(18px + env(safe-area-inset-bottom));
577 648 box-shadow: 0 -16px 48px rgba(20, 24, 20, 0.28);
578 − animation: sheet-up 0.22s ease;
649 + animation: sheet-up 0.24s cubic-bezier(0.2, 0.9, 0.3, 1);
579 650 }
580 651 @keyframes sheet-up { from { transform: translateY(30%); opacity: 0.4; } to { transform: none; opacity: 1; } }
652 + .filterbar.open .sheet-handle {
653 + display: block; flex: none; width: 44px; height: 5px; border-radius: var(--r-pill);
654 + background: var(--line); margin: 0 auto 2px;
655 + }
581 656 .filterbar.open .sheet-head {
582 657 display: flex; justify-content: space-between; align-items: center;
583 658 font-family: var(--font-display); font-weight: 700; font-size: 17px;
584 659 letter-spacing: -0.01em; color: var(--navy);
585 − position: sticky; top: -16px; background: var(--surface); padding: 6px 0 8px;
660 + position: sticky; top: -10px; background: var(--surface); padding: 6px 0 8px;
586 661 border-bottom: 1px solid var(--line); margin-bottom: 2px; z-index: 1;
587 662 }
588 663 .sheet-close {
589 664 border: 1.5px solid var(--ink); background: var(--surface); border-radius: 50%;
590 665 width: 36px; height: 36px; font-size: 15px; cursor: pointer; line-height: 1; color: var(--navy);
591 666 }
592 − .filterbar.open .sheet-apply { display: block; width: 100%; }
667 + .filterbar.open .sheet-apply {
668 + display: block; width: 100%; min-height: 50px;
669 + position: sticky; bottom: 0; z-index: 1;
670 + box-shadow: 0 -14px 18px -12px rgba(20, 24, 20, 0.35), 5px 5px 0 var(--accent);
671 + }
593 672 .sheet-backdrop {
594 673 display: block; position: fixed; inset: 0; z-index: var(--z-overlay, 800);
595 674 background: rgba(20, 24, 20, 0.45); backdrop-filter: blur(2px);
@@ -674,15 +753,17 @@ html, body { overflow-x: clip; }
674 753 box-shadow: var(--shadow-flat);
675 754 }
676 755 .view-toggle button {
677 − border: 0; background: transparent; padding: 7px 16px; cursor: pointer;
678 − font-size: 12.5px; font-weight: 600; color: var(--ink-2);
756 + border: 0; background: transparent; padding: 8px 16px; cursor: pointer;
757 + font-size: 12.5px; font-weight: 700; color: var(--ink-2);
758 + font-family: var(--font-display); transition: background 0.12s ease, color 0.12s ease;
679 759 }
760 +.view-toggle button:hover { background: var(--grey); color: var(--ink); }
680 761 /* zone tactile >= 44 px au doigt (coarse pointer = mobile/tablette) */
681 762 @media (pointer: coarse) {
682 763 .view-toggle button { min-height: 44px; padding: 10px 18px; }
683 764 }
684 765 .view-toggle button + button { border-left: 1px solid var(--line); }
685 −.view-toggle button.on { background: var(--blue); color: var(--white); }
766 +.view-toggle button.on { background: var(--ink); color: var(--white); box-shadow: inset 0 -2.5px 0 var(--accent); }
686 767
687 768 .map-split {
688 769 display: grid; grid-template-columns: minmax(300px, 400px) 1fr; gap: 18px;
689 770