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%

Identité visuelle officielle Lou-Ka — palette marine #0B1330 / bleu vif #2258FF / orange #FF6A00 / gris #F2F2F2 ; logo « porte entrouverte » (Logo.tsx, favicon + icône PWA sur carré marine) ; wordmark Lou-Ka (Ka orange) ; baseline « La porte d'entrée vers votre prochain chez-vous. » ; héro « Trouvez votre prochain chez-vous. » + rangée des 4 avantages ; Inter partout (fin de Space Grotesk/JetBrains Mono) ; coins très arrondis + pill-shaped + ombres douces (styles.css réécrit, mêmes sélecteurs) ; barre de nav mobile 4 onglets (active orange) ; thème Ka Maps marine/orange + immeuble 3D orange ; PDF (pdfgen.py) et SSR SEO alignés

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 15, 2026) parent 2aed158

13 changed files +744 −554

modified frontend/index.html +3 −3
@@ -9,7 +9,7 @@
9 9 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
10 10 <title>Lou-Ka — Logements à louer au Québec</title>
11 11 <meta name="description" content="Lou-Ka agrège les appartements et logements à louer publiés par les gestionnaires immobiliers partout au Québec — Montréal, Québec, Lévis, Gatineau et plus — toujours à jour." />
12 − <meta name="theme-color" content="#f5f3ee" />
12 + <meta name="theme-color" content="#ffffff" />
13 13 <meta name="mobile-web-app-capable" content="yes" />
14 14 <meta name="apple-mobile-web-app-capable" content="yes" />
15 15 <meta name="apple-mobile-web-app-status-bar-style" content="default" />
@@ -17,8 +17,8 @@
17 17 <link rel="manifest" href="/manifest.webmanifest" />
18 18 <link rel="preconnect" href="https://fonts.googleapis.com" />
19 19 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
20 − <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet" />
21 − <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%23121712'/%3E%3Ctext x='32' y='45' font-family='Arial Black,sans-serif' font-size='32' font-weight='900' fill='%23d9f26b' text-anchor='middle'%3ELK%3C/text%3E%3C/svg%3E" />
20 + <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
21 + <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='14' fill='%230B1330'/%3E%3Crect x='19' y='9' width='26' height='46' rx='8' fill='none' stroke='%23FF6A00' stroke-width='4'/%3E%3Cpolygon points='24.5,16 36,13.5 36,49 24.5,46' fill='%23ffffff'/%3E%3Cpolygon points='24.5,46 36,49 42,52.5 24.5,52.5' fill='%23FF6A00'/%3E%3C/svg%3E" />
22 22 </head>
23 23 <body>
24 24 <div id="root"></div>
modified frontend/public/manifest.webmanifest +4 −4
@@ -1,15 +1,15 @@
1 1 {
2 2 "name": "Lou-Ka — Logements à louer au Québec",
3 3 "short_name": "Lou-Ka",
4 − "description": "Tous les logements à louer de Québec et Lévis, un seul endroit.",
4 + "description": "La porte d'entrée vers votre prochain chez-vous. Tous les logements à louer au Québec, regroupés au même endroit.",
5 5 "start_url": "/",
6 6 "display": "standalone",
7 − "background_color": "#f5f3ee",
8 − "theme_color": "#f5f3ee",
7 + "background_color": "#ffffff",
8 + "theme_color": "#0b1330",
9 9 "lang": "fr",
10 10 "icons": [
11 11 {
12 − "src": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Crect width='512' height='512' rx='96' fill='%23121712'/%3E%3Ctext x='256' y='356' font-family='Arial Black,sans-serif' font-size='256' font-weight='900' fill='%23d9f26b' text-anchor='middle'%3ELK%3C/text%3E%3C/svg%3E",
12 + "src": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Crect width='512' height='512' rx='112' fill='%230B1330'/%3E%3Crect x='152' y='72' width='208' height='368' rx='64' fill='none' stroke='%23FF6A00' stroke-width='32'/%3E%3Cpolygon points='196,128 288,108 288,392 196,368' fill='%23ffffff'/%3E%3Cpolygon points='196,368 288,392 336,420 196,420' fill='%23FF6A00'/%3E%3C/svg%3E",
13 13 "sizes": "512x512",
14 14 "type": "image/svg+xml",
15 15 "purpose": "any"
modified frontend/src/App.tsx +38 −9
@@ -12,8 +12,10 @@ import {
12 12 import { AccountProvider, useAccount } from "./account";
13 13 import CookieConsent from "./components/CookieConsent";
14 14 import {
15 − IcoChart, IcoCompass, IcoDoc, IcoFolder, IcoHouse, IcoLock, IcoMap,
15 + IcoChart, IcoCompass, IcoDoc, IcoFolder, IcoHeart, IcoHouse, IcoLock,
16 + IcoMap, IcoSearch, IcoUser,
16 17 } from "./components/Icons";
18 +import { LogoIcon } from "./components/Logo";
17 19 import Home from "./pages/Home";
18 20 import ListingPage from "./pages/Listing";
19 21 import BotPage from "./pages/Bot";
@@ -97,12 +99,11 @@ function AccountMenu() {
97 99 justifyContent: "center",
98 100 width: 18,
99 101 height: 16,
100 − borderRadius: 4,
101 − background: "#141814",
102 − color: "#d9f26b",
103 − font: "700 9px/1 'Space Grotesk', system-ui, sans-serif",
102 + borderRadius: 5,
103 + background: "#ff6a00",
104 + color: "#ffffff",
105 + font: "700 9px/1 'Inter', system-ui, sans-serif",
104 106 letterSpacing: "-0.02em",
105 − transform: "rotate(-2deg)",
106 107 }}
107 108 >
108 109 KA
@@ -199,8 +200,9 @@ function Header() {
199 200 <header className="header">
200 201 <div className="container header-inner">
201 202 <NavLink to="/" className="brand" aria-label="Lou-Ka — accueil">
202 − Lou<span className="ka">Ka</span>
203 − <span className="brand-tag">Québec · Lévis · Montréal — toujours à jour</span>
203 + <LogoIcon size={30} />
204 + Lou-<span className="ka">Ka</span>
205 + <span className="brand-tag">La porte d'entrée vers votre prochain chez-vous.</span>
204 206 </NavLink>
205 207 <nav className="nav" aria-label="Navigation principale">
206 208 <NavLink to="/" end className={({ isActive }) => (isActive ? "active" : "")}>
@@ -258,7 +260,11 @@ function Footer() {
258 260 <footer className="footer">
259 261 <div className="container">
260 262 <div className="fbrand">
261 − Lou<span className="ka">Ka</span>
263 + <LogoIcon size={32} dark />
264 + Lou-<span className="ka">Ka</span>
265 + </div>
266 + <div className="fbaseline">
267 + La porte d'entrée vers votre prochain <span className="hl">chez-vous.</span>
262 268 </div>
263 269 <div className="frow">
264 270 <div>
@@ -294,6 +300,28 @@ function Footer() {
294 300 );
295 301 }
296 302
303 +/** Barre de navigation inférieure (mobile) — icône active en orange. */
304 +function MobileTabBar() {
305 + const location = useLocation();
306 + const isCarte = new URLSearchParams(location.search).get("view") === "carte";
307 + const tabs = [
308 + { to: "/", label: "Rechercher", icon: <IcoSearch size={20} />, on: location.pathname === "/" && !isCarte },
309 + { to: "/?view=carte", label: "Carte", icon: <IcoMap size={20} />, on: location.pathname === "/" && isCarte },
310 + { to: "/favoris", label: "Favoris", icon: <IcoHeart size={20} />, on: location.pathname.startsWith("/favoris") },
311 + { to: "/profil", label: "Profil", icon: <IcoUser size={20} />, on: location.pathname.startsWith("/profil") },
312 + ];
313 + return (
314 + <nav className="tabbar" aria-label="Navigation mobile">
315 + {tabs.map((t) => (
316 + <NavLink key={t.label} to={t.to} className={() => (t.on ? "active" : "")}>
317 + {t.icon}
318 + {t.label}
319 + </NavLink>
320 + ))}
321 + </nav>
322 + );
323 +}
324 +
297 325 export default function App() {
298 326 return (
299 327 <AccountProvider>
@@ -330,6 +358,7 @@ export default function App() {
330 358 </Routes>
331 359 </main>
332 360 <Footer />
361 + <MobileTabBar />
333 362 <CookieConsent />
334 363 </AccountProvider>
335 364 );
modified frontend/src/components/Icons.tsx +12 −5
@@ -1,9 +1,9 @@
1 1 // -----------------------------------------------------------------------------
2 2 // Lou-Ka — Agrégateur de logements à louer (province de Québec)
3 3 // Auteur : Simon-Pierre Boucher — contact@spboucher.ai
4 −// components/Icons.tsx : icônes SVG maison « éditorial sharp »
5 −// Tracés au trait (stroke) 2 px, coins vifs (square/miter), currentColor —
6 −// remplacent les emojis génériques pour coller à l'identité de l'app.
4 +// components/Icons.tsx : icônes SVG maison — style linéaire (outline),
5 +// trait moyen 2 px, extrémités arrondies, currentColor — conformes à
6 +// l'identité visuelle Lou-Ka (minimaliste et chaleureuse).
7 7 // -----------------------------------------------------------------------------
8 8 import { SVGProps } from "react";
9 9
@@ -13,8 +13,8 @@ function Base({ size = 16, children, ...rest }: P) {
13 13 return (
14 14 <svg
15 15 width={size} height={size} viewBox="0 0 24 24" fill="none"
16 − stroke="currentColor" strokeWidth="2" strokeLinecap="square"
17 − strokeLinejoin="miter" aria-hidden="true" focusable="false" {...rest}
16 + stroke="currentColor" strokeWidth="2" strokeLinecap="round"
17 + strokeLinejoin="round" aria-hidden="true" focusable="false" {...rest}
18 18 >
19 19 {children}
20 20 </svg>
@@ -163,6 +163,13 @@ export const IcoHeart = (p: P & { filled?: boolean }) => {
163 163
164 164 // -- réseaux sociaux (tracés au trait, même langage que le reste) --------------
165 165
166 +export const IcoUser = (p: P) => (
167 + <Base {...p}>
168 + <circle cx="12" cy="8" r="3.5" />
169 + <path d="M5 20c1.2-3.4 3.8-5 7-5s5.8 1.6 7 5" />
170 + </Base>
171 +);
172 +
166 173 export const IcoInstagram = (p: P) => (
167 174 <Base {...p}>
168 175 <rect x="4" y="4" width="16" height="16" rx="4.5" />
modified frontend/src/components/ListingMap3D.tsx +2 −2
@@ -17,7 +17,7 @@ import { louKaMapTheme } from "../kamaps/theme";
17 17 import { MAPBOX_TOKEN } from "../kamaps/config";
18 18
19 19 /** Rouge signal de la fiche — même langage que les badges d'alerte. */
20 −export const BUILDING_RED = "#e03131";
20 +export const BUILDING_RED = "#ff6a00"; // orange officiel Lou-Ka
21 21
22 22 export default function ListingMap3D({ l }: { l: Listing }) {
23 23 const property = useMemo<MapProperty | null>(() => {
@@ -41,7 +41,7 @@ export default function ListingMap3D({ l }: { l: Listing }) {
41 41
42 42 return (
43 43 <div className="lmap3d" role="img"
44 − aria-label={`Carte 3D — ${l.address || l.title}, bâtiment de l'annonce en rouge`}>
44 + aria-label={`Carte 3D — ${l.address || l.title}, bâtiment de l'annonce en orange`}>
45 45 <KaSpotlightMap
46 46 theme={louKaMapTheme}
47 47 mapboxToken={MAPBOX_TOKEN}
added frontend/src/components/Logo.tsx +62 −0
@@ -0,0 +1,62 @@
1 +// -----------------------------------------------------------------------------
2 +// Lou-Ka — Agrégateur de logements à louer (province de Québec)
3 +// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
4 +// components/Logo.tsx : icône officielle Lou-Ka — la porte d'entrée.
5 +// Cadre orange #FF6A00 aux coins très arrondis ; porte entrouverte bleu
6 +// marine #0B1330 en perspective (ouverture vers la droite) ; tapis de
7 +// lumière orange projeté au sol. Effet « liquid glass » subtil.
8 +// Baseline : « La porte d'entrée vers votre prochain chez-vous. »
9 +// -----------------------------------------------------------------------------
10 +
11 +/** Icône seule (fond transparent — pour fonds clairs). */
12 +export function LogoIcon({ size = 30, dark = false }: { size?: number; dark?: boolean }) {
13 + // dark = version pour fond bleu marine : la porte devient blanche
14 + const door = dark ? "#ffffff" : "#0b1330";
15 + const doorTop = dark ? "#ffffff" : "#16204a";
16 + const uid = dark ? "lk-dark" : "lk-light-bg";
17 + return (
18 + <svg
19 + className="logo-ico"
20 + width={size}
21 + height={size}
22 + viewBox="0 0 64 64"
23 + fill="none"
24 + aria-hidden="true"
25 + >
26 + <defs>
27 + <linearGradient id={`${uid}-door`} x1="0" y1="0" x2="0" y2="1">
28 + <stop offset="0" stopColor={doorTop} />
29 + <stop offset="1" stopColor={door} />
30 + </linearGradient>
31 + <linearGradient id={`${uid}-light`} x1="0" y1="0" x2="1" y2="0">
32 + <stop offset="0" stopColor="#ff6a00" />
33 + <stop offset="1" stopColor="#ff6a00" stopOpacity="0.72" />
34 + </linearGradient>
35 + <linearGradient id={`${uid}-frame`} x1="0" y1="0" x2="0" y2="1">
36 + <stop offset="0" stopColor="#ff7d1f" />
37 + <stop offset="1" stopColor="#ff6a00" />
38 + </linearGradient>
39 + </defs>
40 + {/* cadre : rectangle vertical, coins très arrondis, contour orange épais */}
41 + <rect x="15" y="5" width="34" height="54" rx="10" stroke={`url(#${uid}-frame)`} strokeWidth="4.5" />
42 + {/* porte entrouverte : parallélogramme en perspective, bord droit plus proche */}
43 + <polygon points="22,13.5 37,10.5 37,52 22,48.5" fill={`url(#${uid}-door)`} />
44 + {/* reflet « liquid glass » sur la porte */}
45 + <polygon points="24,13.2 28,12.4 28,49 24,48.2" fill="#ffffff" opacity="0.08" />
46 + {/* lumière projetée au sol — tapis d'accueil */}
47 + <polygon points="22,48.5 37,52 44.5,55.8 22,55.8" fill={`url(#${uid}-light)`} />
48 + </svg>
49 + );
50 +}
51 +
52 +/** Wordmark complet : icône + « Lou-Ka » (Lou- marine, Ka orange). */
53 +export default function Logo({ size = 30 }: { size?: number }) {
54 + return (
55 + <span style={{ display: "inline-flex", alignItems: "center" }}>
56 + <LogoIcon size={size} />
57 + <span style={{ color: "#0b1330", fontWeight: 700 }}>
58 + Lou-<span style={{ color: "#ff6a00" }}>Ka</span>
59 + </span>
60 + </span>
61 + );
62 +}
modified frontend/src/kamaps/theme.ts +43 −43
@@ -2,75 +2,75 @@
2 2 // Author: Simon-Pierre Boucher
3 3 // Contact: contact@spboucher.ai
4 4 // Project: Groupe Ka / Ka Maps (Lou-Ka integration)
5 −// kamaps/theme.ts : thème Lou-Ka Maps — les jetons du design system
6 −// (encre/lime/vert « éditorial sharp ») appliqués au framework Ka Maps.
5 +// kamaps/theme.ts : thème Lou-Ka Maps — identité officielle Lou-Ka
6 +// (marine #0B1330 / bleu vif #2258FF / orange #FF6A00) appliquée à Ka Maps.
7 7 // -----------------------------------------------------------------------------
8 8 import type { KaMapTheme } from "@groupe-ka/ka-maps";
9 9
10 −const INK = "#141814";
11 −const PAPER = "#f5f3ee";
12 −const GREEN = "#1c5c41";
13 −const LIME = "#d9f26b";
10 +const NAVY = "#0b1330";
11 +const BLUE = "#2258ff";
12 +const ORANGE = "#ff6a00";
13 +const WHITE = "#ffffff";
14 14
15 15 export const louKaMapTheme: KaMapTheme = {
16 16 id: "lou-ka",
17 17 productName: "Lou-Ka Maps",
18 − accent: GREEN,
19 − onAccent: LIME,
18 + accent: BLUE,
19 + onAccent: WHITE,
20 20 fontFamily:
21 21 '"Inter", system-ui, -apple-system, "Segoe UI", sans-serif',
22 22 markers: {
23 − // Prix : pastille encre, texte BLANC — contraste maximal sur fond clair.
24 − // Le lime n'apparaît qu'à la sélection (le moment de marque).
23 + // Prix : pastille bleu marine, texte BLANC — contraste maximal sur fond clair.
24 + // L'orange n'apparaît qu'à la sélection (le moment de marque).
25 25 sale: {
26 − background: INK,
27 − text: "#ffffff",
26 + background: NAVY,
27 + text: WHITE,
28 28 halo: "rgba(255,255,255,0.45)",
29 − selectedBackground: LIME,
30 − selectedText: INK,
29 + selectedBackground: ORANGE,
30 + selectedText: WHITE,
31 31 },
32 32 rent: {
33 − background: INK,
34 − text: "#ffffff",
33 + background: NAVY,
34 + text: WHITE,
35 35 halo: "rgba(255,255,255,0.45)",
36 − selectedBackground: LIME,
37 − selectedText: INK,
36 + selectedBackground: ORANGE,
37 + selectedText: WHITE,
38 38 },
39 39 highlight: {
40 − background: GREEN,
41 − text: "#ffffff",
40 + background: BLUE,
41 + text: WHITE,
42 42 halo: "rgba(255,255,255,0.45)",
43 − selectedBackground: LIME,
44 − selectedText: INK,
43 + selectedBackground: ORANGE,
44 + selectedText: WHITE,
45 45 },
46 46 },
47 47 cluster: {
48 − background: INK,
49 − text: "#ffffff",
50 − border: LIME,
48 + background: NAVY,
49 + text: WHITE,
50 + border: ORANGE,
51 51 },
52 − // Cartographie Lou-Ka : fond neutre et raffiné — papier chaud discret,
53 − // eau bleu-gris désaturé, parcs verts subtils, bâtiments bien définis.
52 + // Cartographie Lou-Ka : fond neutre et raffiné — gris très pâle,
53 + // eau bleu désaturé, parcs verts subtils, bâtiments bien définis.
54 54 // Les prix restent l'élément dominant de la carte.
55 55 basemapOverrides: {
56 56 light: {
57 − background: "#f6f5f1",
58 − residential: "#efeee8",
59 − water: "#c3d6df",
60 − waterway: "#b8cdd8",
61 − park: "#dde8d1",
62 − wood: "#d2e0c4",
63 − building: "#e7e4db",
64 − buildingOutline: "#d2cec1",
57 + background: "#f7f8fa",
58 + residential: "#f0f1f4",
59 + water: "#c9d8ef",
60 + waterway: "#bfd0ea",
61 + park: "#dce8d8",
62 + wood: "#d0e0ca",
63 + building: "#e6e8ee",
64 + buildingOutline: "#d0d3dd",
65 65 road: "#ffffff",
66 − roadCasing: "#dcd8cc",
67 − motorway: "#f0e9d0",
68 − boundary: "#b0a998",
69 − label: "#474b45",
70 − labelHalo: "rgba(246,245,241,0.92)",
71 − cityLabel: "#1f231e",
72 − roadLabel: "#8b8d82",
73 − waterLabel: "#5c7c8c",
66 + roadCasing: "#dcdee6",
67 + motorway: "#f4ede2",
68 + boundary: "#a9adbd",
69 + label: "#3e4560",
70 + labelHalo: "rgba(247,248,250,0.92)",
71 + cityLabel: "#0b1330",
72 + roadLabel: "#8a90a5",
73 + waterLabel: "#5c74a8",
74 74 },
75 75 },
76 76 supportsDark: false,
modified frontend/src/pages/Home.tsx +25 −8
@@ -15,7 +15,8 @@ import {
15 15 import ListingCard from "../components/ListingCard";
16 16 import Pager from "../components/Pager";
17 17 import {
18 − IcoAlert, IcoBolt, IcoList, IcoMap, IcoPaw, IcoSearch, IcoSliders, IcoSofa,
18 + IcoAlert, IcoBolt, IcoHeart, IcoHouse, IcoList, IcoMap, IcoPaw, IcoPin,
19 + IcoSearch, IcoSliders, IcoSofa,
19 20 } from "../components/Icons";
20 21
21 22 // La carte (MapLibre, ~220 ko) n'est chargée que si l'utilisateur l'ouvre
@@ -196,16 +197,32 @@ export default function Home() {
196 197 return (
197 198 <div className="container">
198 199 <section className="hero">
199 − <span className="kicker">Agrégateur — Québec · Lévis · Montréal</span>
200 + <span className="kicker">La porte d'entrée vers votre prochain chez-vous.</span>
200 201 <h1>
201 − Tous les logements <span className="outline">à louer</span>,<br />
202 − <span className="hl">un seul</span> endroit.
202 + Trouvez votre prochain <span className="hl">chez-vous.</span>
203 203 </h1>
204 204 <p className="lede">
205 − Lou-Ka rassemble les appartements affichés par les gestionnaires immobiliers du
206 − Québec — Québec, Lévis et le Grand Montréal — mis à jour automatiquement, avec
207 − toutes les photos et un lien direct vers l'annonce originale.
205 + Tous les logements à louer au Québec, regroupés au même endroit — mis à jour
206 + automatiquement, avec toutes les photos et un lien direct vers l'annonce originale.
208 207 </p>
208 + <div className="benefits" aria-label="Avantages">
209 + <div className="benefit">
210 + <span className="benefit-ico"><IcoHouse size={20} /></span>
211 + <span className="benefit-label">Nouveaux logements</span>
212 + </div>
213 + <div className="benefit">
214 + <span className="benefit-ico"><IcoSearch size={20} /></span>
215 + <span className="benefit-label">Recherche facile</span>
216 + </div>
217 + <div className="benefit">
218 + <span className="benefit-ico"><IcoHeart size={20} /></span>
219 + <span className="benefit-label">Favoris et alertes</span>
220 + </div>
221 + <div className="benefit">
222 + <span className="benefit-ico blue"><IcoPin size={20} /></span>
223 + <span className="benefit-label">Partout au Québec</span>
224 + </div>
225 + </div>
209 226 <div className="stat-row">
210 227 <span className="stat-chip"><span className="pulse" /> Données synchronisées en continu</span>
211 228 {stats && (
@@ -245,7 +262,7 @@ export default function Home() {
245 262 <div className="f-search">
246 263 <IcoSearch size={15} strokeWidth={2.4} />
247 264 <input
248 − id="f-q" placeholder="Adresse, quartier, rue…" value={q}
265 + id="f-q" placeholder="Ville, quartier ou code postal" value={q}
249 266 onChange={(e) => setQ(e.target.value)}
250 267 aria-label="Recherche"
251 268 />
modified frontend/src/pages/Listing.tsx +1 −1
@@ -342,7 +342,7 @@ export default function ListingPage() {
342 342 <ListingMap3D l={l} />
343 343 </Suspense>
344 344 <p className="fine">
345 − Vue 3D du secteur — l'immeuble de l'annonce est surligné en rouge.
345 + Vue 3D du secteur — l'immeuble de l'annonce est surligné en orange.
346 346 Position selon l'adresse géocodée (Adresses Québec).
347 347 </p>
348 348 </section>
modified frontend/src/styles.css +537 −462
@@ -1,36 +1,61 @@
1 1 /* -----------------------------------------------------------------------------
2 2 Lou-Ka — Agrégateur de logements à louer (province de Québec)
3 3 Auteur : Simon-Pierre Boucher — contact@spboucher.ai
4 − styles.css : système de design « éditorial sharp » — thème clair
5 − · Typo display Space Grotesk / texte Inter / micro-étiquettes JetBrains Mono
6 − · Signature : bordures encre + ombres décalées (néo-brutalisme raffiné)
7 − · Accent électrique lime #d9f26b sur encre verte profonde
4 + styles.css : identité visuelle officielle Lou-Ka
5 + · Palette : marine #0B1330 · bleu vif #2258FF · orange #FF6A00
6 + gris pâle #F2F2F2 · blanc #FFFFFF
7 + · Typo : Inter (fallback SF Pro / system-ui)
8 + · Style : minimaliste chaleureux — coins très arrondis, pill-shaped,
9 + ombres douces diffuses, touches « liquid glass »
10 + · Baseline : « La porte d'entrée vers votre prochain chez-vous. »
8 11 · 100 % adaptatif mobile (PWA installable, safe-areas iOS)
9 12 ----------------------------------------------------------------------------- */
10 13 :root {
11 − --paper: #f5f3ee;
12 − --surface: #ffffff;
13 − --surface-2: #faf9f5;
14 − --ink: #141814;
15 − --ink-2: #4d5551;
16 − --ink-3: #8b928c;
17 − --line: rgba(20, 24, 20, 0.14);
18 − --line-strong: rgba(20, 24, 20, 0.85);
19 − --green: #1c5c41;
20 − --green-deep: #123f2e;
21 − --lime: #d9f26b;
22 − --lime-soft: #f0f9d2;
23 − --amber: #e8a33d;
24 − --amber-soft: #fdf3e2;
25 − --danger: #b3423a;
26 − --r-card: 10px;
27 − --r-ctl: 6px;
28 − --shadow-flat: 0 1px 2px rgba(20, 24, 20, 0.05);
29 − --shadow-off: 6px 6px 0 var(--ink);
30 − --shadow-off-soft: 8px 8px 0 rgba(20, 24, 20, 0.08);
31 − --font-display: "Space Grotesk", system-ui, sans-serif;
32 − --font-body: "Inter", system-ui, sans-serif;
33 − --font-mono: "JetBrains Mono", ui-monospace, monospace;
14 + /* palette officielle */
15 + --navy: #0b1330;
16 + --blue: #2258ff;
17 + --orange: #ff6a00;
18 + --grey: #f2f2f2;
19 + --white: #ffffff;
20 +
21 + /* dérivés (nuances des couleurs officielles) */
22 + --orange-deep: #e55f00;
23 + --orange-soft: #fff1e6;
24 + --blue-soft: #e9efff;
25 + --navy-soft: #eef0f6;
26 +
27 + /* jetons sémantiques */
28 + --paper: var(--white);
29 + --surface: var(--white);
30 + --surface-2: var(--grey);
31 + --ink: var(--navy);
32 + --ink-2: #3e4560;
33 + --ink-3: #8a90a5;
34 + --line: rgba(11, 19, 48, 0.1);
35 + --line-strong: rgba(11, 19, 48, 0.16);
36 + --danger: #d64545;
37 +
38 + /* alias hérités (compatibilité) */
39 + --green: var(--blue);
40 + --green-deep: var(--navy);
41 + --lime: var(--orange);
42 + --lime-soft: var(--orange-soft);
43 + --amber: var(--orange);
44 + --amber-soft: var(--orange-soft);
45 +
46 + /* géométrie : coins très arrondis, contrôles pill */
47 + --r-card: 18px;
48 + --r-ctl: 12px;
49 + --r-pill: 999px;
50 +
51 + /* ombres douces et diffuses, jamais dures */
52 + --shadow-flat: 0 1px 3px rgba(11, 19, 48, 0.06);
53 + --shadow-off: 0 16px 40px rgba(11, 19, 48, 0.14);
54 + --shadow-off-soft: 0 8px 24px rgba(11, 19, 48, 0.08);
55 +
56 + --font-display: "Inter", "SF Pro Display", system-ui, sans-serif;
57 + --font-body: "Inter", "SF Pro Text", system-ui, sans-serif;
58 + --font-mono: "Inter", "SF Pro Text", system-ui, sans-serif;
34 59 }
35 60
36 61 * { box-sizing: border-box; }
@@ -45,27 +70,23 @@ body {
45 70 -webkit-font-smoothing: antialiased;
46 71 padding-bottom: env(safe-area-inset-bottom);
47 72 }
48 −/* grain subtil — texture signature */
49 −body::before {
50 − content: "";
51 − position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 0.35;
52 − background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.02 0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
53 −}
54 73 #root { position: relative; z-index: 1; }
55 74
56 −h1, h2, h3, h4 { font-family: var(--font-display); letter-spacing: -0.03em; margin: 0; }
75 +h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.02em; margin: 0; }
57 76 a { color: inherit; text-decoration: none; }
58 77 button { font-family: inherit; }
59 78 img { display: block; }
60 −::selection { background: var(--lime); color: var(--ink); }
79 +::selection { background: var(--orange); color: var(--white); }
61 80
62 81 .mono { font-family: var(--font-mono); }
82 +/* mot-clé accentué des titres — toujours orange (« chez-vous. ») */
83 +h1 .hl, h2 .hl { color: var(--orange); }
63 84 .kicker {
64 − font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
65 − text-transform: uppercase; letter-spacing: 0.14em; color: var(--green);
85 + font-family: var(--font-body); font-size: 12px; font-weight: 600;
86 + text-transform: uppercase; letter-spacing: 0.12em; color: var(--blue);
66 87 display: inline-flex; align-items: center; gap: 8px;
67 88 }
68 −.kicker::before { content: ""; width: 22px; height: 2px; background: var(--green); }
89 +.kicker::before { content: ""; width: 22px; height: 3px; border-radius: 2px; background: var(--orange); }
69 90
70 91 .container { max-width: 1240px; margin: 0 auto; padding: 0 24px; }
71 92 @media (max-width: 640px) { .container { padding: 0 16px; } }
@@ -73,45 +94,41 @@ img { display: block; }
73 94 /* ================= Header ================= */
74 95 .header {
75 96 position: sticky; top: 0; z-index: 50;
76 − background: rgba(245, 243, 238, 0.88);
77 − backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
78 − border-bottom: 2px solid var(--ink);
97 + background: rgba(255, 255, 255, 0.86);
98 + backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
99 + border-bottom: 1px solid var(--line);
79 100 }
80 −.header-inner { display: flex; align-items: center; gap: 20px; height: 64px; }
101 +.header-inner { display: flex; align-items: center; gap: 20px; height: 66px; }
81 102 .brand {
82 − font-family: var(--font-display); font-weight: 700; font-size: 26px;
83 − letter-spacing: -0.04em; display: flex; align-items: center; line-height: 1;
84 −}
85 −.brand .ka {
86 − background: var(--ink); color: var(--lime); padding: 2px 7px 4px;
87 − border-radius: 6px; margin-left: 3px; transform: rotate(-2deg);
88 − transition: transform 0.2s ease;
103 + font-family: var(--font-display); font-weight: 700; font-size: 25px;
104 + letter-spacing: -0.03em; display: flex; align-items: center; line-height: 1;
105 + color: var(--navy);
89 106 }
90 −.brand:hover .ka { transform: rotate(0deg); }
107 +.brand .logo-ico { margin-right: 9px; flex: none; }
108 +.brand .ka { color: var(--orange); }
91 109 .brand-tag {
92 − font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3);
93 − letter-spacing: 0.08em; text-transform: uppercase; margin-left: 12px;
110 + font-size: 11px; font-weight: 500; color: var(--ink-3);
111 + letter-spacing: 0.02em; margin-left: 12px;
94 112 }
95 −@media (max-width: 760px) { .brand-tag { display: none; } }
113 +@media (max-width: 900px) { .brand-tag { display: none; } }
96 114 .nav { margin-left: auto; display: flex; gap: 4px; }
97 115 .nav a {
98 − padding: 9px 16px; border-radius: 999px; font-weight: 600; font-size: 14px;
99 − color: var(--ink-2); border: 1.5px solid transparent;
100 − transition: all 0.15s ease; min-height: 40px; display: inline-flex; align-items: center;
116 + padding: 9px 16px; border-radius: var(--r-pill); font-weight: 600; font-size: 14px;
117 + color: var(--navy); transition: all 0.15s ease; min-height: 40px;
118 + display: inline-flex; align-items: center;
101 119 }
102 −.nav a:hover { border-color: var(--ink); color: var(--ink); }
103 −.nav a.active { background: var(--ink); color: var(--lime); }
120 +.nav a:hover { color: var(--orange); background: var(--orange-soft); }
121 +.nav a.active { background: var(--navy); color: var(--white); }
104 122
105 123 /* ================= Ticker ================= */
106 124 .ticker {
107 − background: var(--ink); color: var(--lime); overflow: hidden;
108 − font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.1em;
125 + background: var(--navy); color: rgba(255, 255, 255, 0.85); overflow: hidden;
126 + font-size: 11.5px; font-weight: 500; letter-spacing: 0.08em;
109 127 text-transform: uppercase; padding: 7px 0; white-space: nowrap;
110 − border-bottom: 1px solid rgba(217, 242, 107, 0.25);
111 128 }
112 129 .ticker-track { display: inline-flex; gap: 0; animation: ticker 40s linear infinite; will-change: transform; }
113 130 .ticker span { padding: 0 26px; position: relative; }
114 −.ticker span::after { content: "◆"; position: absolute; right: -6px; opacity: 0.5; font-size: 8px; top: 3px; }
131 +.ticker span::after { content: "◆"; position: absolute; right: -6px; color: var(--orange); opacity: 0.8; font-size: 8px; top: 3px; }
115 132 @keyframes ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
116 133 @media (prefers-reduced-motion: reduce) {
117 134 .ticker-track { animation: none; }
@@ -122,34 +139,49 @@ img { display: block; }
122 139 .hero { padding: 58px 0 22px; }
123 140 @media (max-width: 640px) { .hero { padding: 34px 0 14px; } }
124 141 .hero h1 {
125 − font-size: clamp(38px, 6.4vw, 78px); font-weight: 700; line-height: 0.98;
126 − text-transform: uppercase; letter-spacing: -0.035em; max-width: 900px; margin-top: 14px;
127 −}
128 −.hero h1 .outline {
129 − color: transparent; -webkit-text-stroke: 2px var(--ink);
142 + font-size: clamp(36px, 5.4vw, 56px); font-weight: 700; line-height: 1.06;
143 + letter-spacing: -0.03em; max-width: 900px; margin-top: 14px; color: var(--navy);
130 144 }
131 −.hero h1 .hl {
132 − background: var(--lime); padding: 0 10px; border-radius: 8px; display: inline-block;
133 − transform: rotate(-1deg);
134 −}
135 −.hero p.lede { color: var(--ink-2); font-size: 16.5px; max-width: 640px; margin: 20px 0 0; }
145 +.hero h1 .outline { color: var(--navy); }
146 +.hero h1 .hl { color: var(--orange); }
147 +.hero p.lede { color: var(--ink-2); font-size: 17px; max-width: 640px; margin: 18px 0 0; }
136 148 .stat-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
137 149 .stat-chip {
138 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: 999px;
139 − padding: 8px 16px; font-family: var(--font-mono); font-size: 12px;
150 + background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-pill);
151 + padding: 8px 16px; font-size: 12.5px; font-weight: 500;
140 152 color: var(--ink-2); display: flex; gap: 8px; align-items: center;
141 − box-shadow: 3px 3px 0 rgba(20, 24, 20, 0.12);
153 + box-shadow: var(--shadow-flat);
142 154 }
143 −.stat-chip b { color: var(--ink); font-weight: 700; }
155 +.stat-chip b { color: var(--navy); font-weight: 700; }
144 156 .stat-chip .pulse {
145 − width: 8px; height: 8px; border-radius: 50%; background: var(--green);
146 − box-shadow: 0 0 0 4px var(--lime-soft); animation: pulse 2.4s ease infinite;
157 + width: 8px; height: 8px; border-radius: 50%; background: var(--orange);
158 + box-shadow: 0 0 0 4px var(--orange-soft); animation: pulse 2.4s ease infinite;
159 +}
160 +@keyframes pulse { 50% { box-shadow: 0 0 0 7px rgba(255, 106, 0, 0.18); } }
161 +
162 +/* ================= Rangée d'avantages ================= */
163 +.benefits {
164 + display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
165 + gap: 14px; margin-top: 30px;
166 +}
167 +.benefit { display: flex; align-items: center; gap: 12px; }
168 +.benefit-ico {
169 + width: 42px; height: 42px; border-radius: var(--r-pill); flex: none;
170 + display: flex; align-items: center; justify-content: center;
171 + background: var(--orange-soft); color: var(--orange);
172 +}
173 +.benefit-ico.blue { background: var(--blue-soft); color: var(--blue); }
174 +.benefit-label {
175 + font-size: 11.5px; font-weight: 700; text-transform: uppercase;
176 + letter-spacing: 0.08em; color: var(--navy);
177 +}
178 +@media (max-width: 640px) {
179 + .benefits { grid-template-columns: 1fr 1fr; gap: 12px; }
147 180 }
148 −@keyframes pulse { 50% { box-shadow: 0 0 0 7px rgba(217, 242, 107, 0.4); } }
149 181
150 182 /* ================= Filter bar ================= */
151 183 .filterbar {
152 − background: var(--surface); border: 2px solid var(--ink); border-radius: var(--r-card);
184 + background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
153 185 box-shadow: var(--shadow-off-soft); padding: 14px; margin: 30px 0 6px;
154 186 display: flex; flex-direction: column; gap: 0; min-width: 0;
155 187 }
@@ -158,11 +190,14 @@ img { display: block; }
158 190 .f-primary { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; min-width: 0; }
159 191 .f-search {
160 192 flex: 1 1 240px; min-width: 0; display: flex; align-items: center; gap: 9px;
161 − border: 1.5px solid var(--ink); border-radius: 9px; background: var(--surface-2);
162 − padding: 0 13px; min-height: 52px; color: var(--ink-2);
163 − transition: box-shadow 0.15s ease;
193 + border: 1px solid transparent; border-radius: var(--r-pill); background: var(--grey);
194 + padding: 0 18px; min-height: 52px; color: var(--ink-2);
195 + transition: box-shadow 0.15s ease, border-color 0.15s ease, background 0.15s ease;
196 +}
197 +.f-search:focus-within {
198 + background: var(--white); border-color: var(--blue);
199 + box-shadow: 0 0 0 3px rgba(34, 88, 255, 0.15);
164 200 }
165 −.f-search:focus-within { box-shadow: 3px 3px 0 var(--lime); background: var(--surface); }
166 201 .f-search input {
167 202 border: none; background: none; outline: none; flex: 1; min-width: 0;
168 203 font-size: 15px; color: var(--ink); font-family: inherit;
@@ -174,133 +209,139 @@ img { display: block; }
174 209 }
175 210 .f-ctl {
176 211 flex: 0 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center;
177 − gap: 2px; border: 1.5px solid var(--ink); border-radius: 9px; background: var(--surface);
178 − padding: 7px 12px 6px; min-height: 52px; cursor: pointer;
179 − transition: box-shadow 0.15s ease;
212 + gap: 2px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface);
213 + padding: 7px 14px 6px; min-height: 52px; cursor: pointer;
214 + transition: box-shadow 0.15s ease, border-color 0.15s ease;
180 215 }
181 −.f-ctl:focus-within { box-shadow: 3px 3px 0 var(--lime); }
216 +.f-ctl:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(34, 88, 255, 0.15); }
182 217 .f-ctl > span {
183 − font-family: var(--font-mono); font-size: 9px; font-weight: 700;
184 − text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3);
218 + font-size: 9.5px; font-weight: 700;
219 + text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3);
185 220 }
186 221 .f-ctl select {
187 222 border: none; background: transparent; outline: none; font-family: var(--font-display);
188 − font-weight: 700; font-size: 14.5px; color: var(--ink); cursor: pointer;
223 + font-weight: 700; font-size: 14.5px; color: var(--navy); cursor: pointer;
189 224 appearance: none; -webkit-appearance: none; padding-right: 16px; min-width: 0; max-width: 170px;
190 225 text-overflow: ellipsis;
191 − background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='5'%3E%3Cpath d='M0 0l4.5 5L9 0z' fill='%23141814'/%3E%3C/svg%3E");
226 + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='5'%3E%3Cpath d='M0 0l4.5 5L9 0z' fill='%230B1330'/%3E%3C/svg%3E");
192 227 background-repeat: no-repeat; background-position: right center;
193 228 }
194 229 .range-pair { display: flex; align-items: center; gap: 4px; }
195 230 .range-pair select { max-width: 86px; }
196 −.range-sep { color: var(--ink-3); font-family: var(--font-mono); font-size: 11px; }
231 +.range-sep { color: var(--ink-3); font-size: 11px; }
197 232 .f-more {
198 − flex: none; align-self: stretch; border: 1.5px solid var(--ink); border-radius: 9px;
199 − background: var(--surface); color: var(--ink); padding: 0 18px; cursor: pointer;
200 − font-family: var(--font-display); font-weight: 700; font-size: 14px; min-height: 52px;
233 + flex: none; align-self: stretch; border: 1px solid var(--line-strong); border-radius: var(--r-pill);
234 + background: var(--surface); color: var(--navy); padding: 0 20px; cursor: pointer;
235 + font-family: var(--font-display); font-weight: 600; font-size: 14px; min-height: 52px;
201 236 transition: all 0.13s ease;
202 237 }
203 −.f-more:hover { background: var(--lime-soft); }
204 −.f-more.on { background: var(--ink); color: var(--lime); box-shadow: 3px 3px 0 rgba(20,24,20,0.22); }
238 +.f-more:hover { background: var(--blue-soft); border-color: var(--blue); color: var(--blue); }
239 +.f-more.on { background: var(--blue); border-color: var(--blue); color: var(--white); }
205 240
206 241 /* — panneau avancé — */
207 242 .f-adv {
208 243 display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px 22px;
209 − border-top: 1.5px dashed var(--line); margin-top: 14px; padding-top: 14px; min-width: 0;
244 + border-top: 1px solid var(--line); margin-top: 14px; padding-top: 14px; min-width: 0;
210 245 animation: adv-in 0.18s ease;
211 246 }
212 247 @keyframes adv-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
213 248 .f-group { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
214 249 .f-group > label {
215 − font-family: var(--font-mono); font-size: 10px; font-weight: 700;
216 − text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3);
250 + font-size: 10.5px; font-weight: 700;
251 + text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3);
217 252 }
218 253 .f-group-end { justify-content: flex-end; }
219 254 .f-group .btn:disabled { opacity: 0.4; cursor: default; }
220 255 .f-native {
221 − border: 1.5px solid var(--line); background: var(--surface-2); border-radius: var(--r-ctl);
222 − padding: 10px 30px 10px 12px; font-size: 14px; color: var(--ink); outline: none;
256 + border: 1px solid var(--line); background: var(--grey); border-radius: var(--r-ctl);
257 + padding: 10px 30px 10px 14px; font-size: 14px; color: var(--ink); outline: none;
223 258 font-family: inherit; min-height: 42px; width: 100%; min-width: 0;
224 259 appearance: none; -webkit-appearance: none;
225 − 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");
260 + 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='%230B1330'/%3E%3C/svg%3E");
226 261 background-repeat: no-repeat; background-position: right 12px center;
227 262 }
228 −.f-native:focus { border-color: var(--ink); box-shadow: 3px 3px 0 var(--lime); }
263 +.f-native:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(34, 88, 255, 0.15); background: var(--white); }
229 264
230 265 /* segments (pilules soudées) */
231 266 .seg { display: inline-flex; flex-wrap: wrap; row-gap: 6px; }
232 267 .seg button {
233 − border: 1.5px solid var(--ink); background: var(--surface); color: var(--ink-2);
234 − padding: 8px 13px; font-family: var(--font-display); font-weight: 600; font-size: 13px;
235 − cursor: pointer; margin-left: -1.5px; white-space: nowrap; min-height: 38px;
268 + border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-2);
269 + padding: 8px 14px; font-family: var(--font-display); font-weight: 600; font-size: 13px;
270 + cursor: pointer; margin-left: -1px; white-space: nowrap; min-height: 38px;
236 271 transition: all 0.12s ease;
237 272 }
238 −.seg button:first-child { border-radius: 8px 0 0 8px; margin-left: 0; }
239 −.seg button:last-child { border-radius: 0 8px 8px 0; }
240 −.seg button:hover { background: var(--lime-soft); color: var(--ink); }
241 −.seg button.on { background: var(--ink); color: var(--lime); position: relative; z-index: 1; }
273 +.seg button:first-child { border-radius: var(--r-pill) 0 0 var(--r-pill); margin-left: 0; padding-left: 16px; }
274 +.seg button:last-child { border-radius: 0 var(--r-pill) var(--r-pill) 0; padding-right: 16px; }
275 +.seg button:hover { background: var(--blue-soft); color: var(--blue); }
276 +.seg button.on { background: var(--blue); border-color: var(--blue); color: var(--white); position: relative; z-index: 1; }
242 277
243 278 /* pastilles de filtres actifs */
244 279 .pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 2px; }
245 280 .pill {
246 281 display: inline-flex; align-items: center; gap: 7px;
247 − border: 1.5px solid var(--ink); background: var(--lime-soft); color: var(--ink);
248 − border-radius: 999px; padding: 6px 13px; font-size: 12.5px; font-weight: 600;
249 − font-family: var(--font-mono); cursor: pointer; transition: all 0.13s ease;
282 + border: 1px solid rgba(34, 88, 255, 0.3); background: var(--blue-soft); color: var(--blue);
283 + border-radius: var(--r-pill); padding: 6px 14px; font-size: 12.5px; font-weight: 600;
284 + cursor: pointer; transition: all 0.13s ease;
250 285 }
251 −.pill:hover { background: var(--lime); }
286 +.pill:hover { background: var(--blue); color: var(--white); }
252 287 .pill-x { font-size: 10px; opacity: 0.65; }
253 288 .pill-clear { background: var(--surface); border-color: var(--danger); color: var(--danger); }
254 289 .pill-clear:hover { background: var(--danger); color: #fff; }
255 −.chip-sep { width: 1.5px; align-self: stretch; background: var(--line); margin: 4px 4px; flex: none; }
290 +.chip-sep { width: 1px; align-self: stretch; background: var(--line); margin: 4px 4px; flex: none; }
256 291 .link-btn {
257 − background: none; border: none; padding: 0; color: var(--green); font: inherit;
292 + background: none; border: none; padding: 0; color: var(--blue); font: inherit;
258 293 text-decoration: underline; cursor: pointer;
259 294 }
260 295 .field { display: flex; flex-direction: column; gap: 5px; }
261 296 .field label {
262 − font-family: var(--font-mono); font-size: 10px; font-weight: 700;
263 − text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3); padding-left: 2px;
297 + font-size: 10.5px; font-weight: 700;
298 + text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); padding-left: 2px;
264 299 }
265 300 .field input, .field select {
266 − border: 1.5px solid var(--line); background: var(--surface-2); border-radius: var(--r-ctl);
267 − padding: 11px 12px; font-size: 15px; color: var(--ink); outline: none; font-family: inherit;
268 − transition: border-color 0.15s ease, box-shadow 0.15s ease; min-height: 44px;
301 + border: 1px solid var(--line); background: var(--grey); border-radius: var(--r-ctl);
302 + padding: 11px 14px; font-size: 15px; color: var(--ink); outline: none; font-family: inherit;
303 + transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease; min-height: 44px;
269 304 appearance: none; -webkit-appearance: none;
270 305 }
271 306 .field select {
272 − 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");
307 + 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='%230B1330'/%3E%3C/svg%3E");
273 308 background-repeat: no-repeat; background-position: right 12px center; padding-right: 30px;
274 309 }
275 −.field input:focus, .field select:focus { border-color: var(--ink); box-shadow: 3px 3px 0 var(--lime); }
310 +.field input:focus, .field select:focus {
311 + border-color: var(--blue); background: var(--white);
312 + box-shadow: 0 0 0 3px rgba(34, 88, 255, 0.15);
313 +}
276 314 .btn {
277 − border: 1.5px solid var(--ink); border-radius: var(--r-ctl); padding: 11px 20px;
278 − font-weight: 700; font-size: 14px; cursor: pointer; min-height: 44px;
315 + border: 1px solid transparent; border-radius: var(--r-pill); padding: 11px 22px;
316 + font-weight: 600; font-size: 14px; cursor: pointer; min-height: 44px;
279 317 transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.15s ease;
280 318 font-family: var(--font-display); letter-spacing: 0.01em;
281 319 }
282 −.btn:active { transform: translate(2px, 2px); box-shadow: none !important; }
283 −.btn-primary { background: var(--ink); color: var(--lime); box-shadow: 4px 4px 0 rgba(20,24,20,0.25); }
284 −.btn-primary:hover { background: var(--green-deep); }
285 −.btn-ghost { background: transparent; color: var(--ink); }
286 −.btn-ghost:hover { background: var(--lime); box-shadow: 4px 4px 0 rgba(20,24,20,0.2); }
320 +.btn:active { transform: translateY(1px); }
321 +.btn-primary {
322 + background: var(--orange); color: var(--white);
323 + box-shadow: 0 6px 18px rgba(255, 106, 0, 0.32);
324 +}
325 +.btn-primary:hover { background: var(--orange-deep); }
326 +.btn-ghost { background: transparent; color: var(--navy); border-color: var(--line-strong); }
327 +.btn-ghost:hover { background: var(--navy-soft); border-color: var(--navy); }
287 328
288 329 /* ================= Chips ================= */
289 330 .chips { display: flex; gap: 8px; margin: 16px 0 4px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
290 331 .chips::-webkit-scrollbar { display: none; }
291 332 .chip {
292 − border: 1.5px solid var(--ink); background: var(--surface); color: var(--ink);
293 − border-radius: 999px; padding: 8px 18px; font-size: 13.5px; font-weight: 600; cursor: pointer;
333 + border: 1px solid var(--line-strong); background: var(--surface); color: var(--navy);
334 + border-radius: var(--r-pill); padding: 8px 18px; font-size: 13.5px; font-weight: 600; cursor: pointer;
294 335 font-family: var(--font-display); white-space: nowrap; min-height: 40px;
295 336 transition: all 0.13s ease;
296 337 }
297 −.chip:hover { background: var(--lime-soft); transform: translateY(-1px); }
298 −.chip.on { background: var(--ink); color: var(--lime); box-shadow: 3px 3px 0 rgba(20,24,20,0.2); }
338 +.chip:hover { background: var(--blue-soft); border-color: var(--blue); color: var(--blue); transform: translateY(-1px); }
339 +.chip.on { background: var(--blue); border-color: var(--blue); color: var(--white); box-shadow: 0 6px 16px rgba(34, 88, 255, 0.28); }
299 340
300 341 /* ================= Results ================= */
301 342 .results-head { display: flex; align-items: baseline; gap: 14px; margin: 28px 0 18px; }
302 −.results-head h2 { font-size: 22px; text-transform: uppercase; letter-spacing: -0.02em; }
303 −.results-head span { font-family: var(--font-mono); color: var(--ink-3); font-size: 12px; letter-spacing: 0.06em; }
343 +.results-head h2 { font-size: 22px; letter-spacing: -0.02em; color: var(--navy); }
344 +.results-head span { color: var(--ink-3); font-size: 12.5px; font-weight: 500; }
304 345 .grid {
305 346 display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
306 347 gap: 22px; padding-bottom: 70px;
@@ -308,43 +349,44 @@ img { display: block; }
308 349 @media (max-width: 640px) { .grid { grid-template-columns: 1fr; gap: 16px; padding-bottom: 48px; } }
309 350
310 351 .card {
311 − background: var(--surface); border: 1.5px solid var(--line-strong); border-radius: var(--r-card);
352 + background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
312 353 overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--shadow-flat);
313 354 transition: transform 0.16s ease, box-shadow 0.16s ease;
314 355 }
315 −.card:hover { transform: translate(-3px, -3px); box-shadow: var(--shadow-off); }
316 −.card:focus-visible { outline: 3px solid var(--lime); outline-offset: 2px; }
317 −.card-img { position: relative; aspect-ratio: 16/10.5; background: repeating-linear-gradient(45deg, #eceae3 0 12px, #f3f1ea 12px 24px); overflow: hidden; }
356 +.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-off); }
357 +.card:focus-visible { outline: 3px solid rgba(34, 88, 255, 0.4); outline-offset: 2px; }
358 +.card-img { position: relative; aspect-ratio: 16/10.5; background: var(--grey); overflow: hidden; }
318 359 .card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
319 360 .card:hover .card-img img { transform: scale(1.05); }
320 361 .card-img .noimg { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--ink-3); font-size: 34px; }
321 362 .badge {
322 − position: absolute; top: 12px; left: 12px; border-radius: 6px; padding: 4px 10px;
323 − font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em;
324 − background: rgba(255, 255, 255, 0.95); color: var(--ink); border: 1px solid var(--ink);
363 + position: absolute; top: 12px; left: 12px; border-radius: var(--r-pill); padding: 4px 12px;
364 + font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
365 + background: rgba(255, 255, 255, 0.94); color: var(--navy);
366 + backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
325 367 }
326 −.badge.type { background: var(--ink); color: var(--lime); border-color: var(--ink); }
327 −.badge.right { left: auto; right: 12px; background: rgba(255,255,255,0.92); border-color: transparent; }
368 +.badge.type { background: var(--orange); color: var(--white); }
369 +.badge.right { left: auto; right: 12px; background: rgba(255, 255, 255, 0.92); }
328 370 .card-body { padding: 16px 18px 16px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
329 −.card-price { font-family: var(--font-display); font-weight: 700; font-size: 21px; letter-spacing: -0.02em; }
330 −.card-price small { font-family: var(--font-mono); font-weight: 500; color: var(--ink-3); font-size: 11px; letter-spacing: 0.05em; }
371 +.card-price { font-family: var(--font-display); font-weight: 700; font-size: 21px; letter-spacing: -0.02em; color: var(--navy); }
372 +.card-price small { font-weight: 500; color: var(--ink-3); font-size: 11.5px; }
331 373 .card-title { font-weight: 600; font-size: 14.5px; color: var(--ink); }
332 −.card-meta { color: var(--ink-3); font-size: 12.5px; display: flex; gap: 7px; flex-wrap: wrap; align-items: center; font-family: var(--font-mono); }
333 −.card-meta .sep { width: 4px; height: 4px; background: var(--lime); border: 1px solid var(--ink); border-radius: 1px; transform: rotate(45deg); }
334 −.card-foot { margin-top: auto; padding-top: 11px; border-top: 1.5px dashed var(--line); display: flex; justify-content: space-between; align-items: center; gap: 8px; }
374 +.card-meta { color: var(--ink-3); font-size: 12.5px; display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }
375 +.card-meta .sep { width: 4px; height: 4px; background: var(--orange); border-radius: 50%; }
376 +.card-foot { margin-top: auto; padding-top: 11px; border-top: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; gap: 8px; }
335 377 .source-tag {
336 − font-family: var(--font-mono); font-size: 10px; font-weight: 700; text-transform: uppercase;
337 − letter-spacing: 0.08em; color: var(--green-deep); background: var(--lime-soft);
338 − border: 1px solid var(--green); border-radius: 4px; padding: 3px 8px;
378 + font-size: 10px; font-weight: 700; text-transform: uppercase;
379 + letter-spacing: 0.06em; color: var(--blue); background: var(--blue-soft);
380 + border-radius: var(--r-pill); padding: 3px 10px;
339 381 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60%;
340 382 }
341 383 .avail { font-size: 11.5px; color: var(--ink-2); font-weight: 500; text-align: right; }
342 384
343 385 /* ================= Skeletons ================= */
344 386 @keyframes shimmer { 0% { background-position: -400px 0; } 100% { background-position: 400px 0; } }
345 −.skel { border-radius: var(--r-card); border: 1.5px solid var(--line); overflow: hidden; background: var(--surface); }
387 +.skel { border-radius: var(--r-card); border: 1px solid var(--line); overflow: hidden; background: var(--surface); }
346 388 .skel .sk-img, .skel .sk-line {
347 − background: linear-gradient(90deg, #eeece5 25%, #f7f5ef 50%, #eeece5 75%);
389 + background: linear-gradient(90deg, #ececef 25%, #f7f7f9 50%, #ececef 75%);
348 390 background-size: 800px 100%; animation: shimmer 1.4s infinite linear;
349 391 }
350 392 .skel .sk-img { aspect-ratio: 16/10.5; }
@@ -354,16 +396,16 @@ img { display: block; }
354 396 /* ================= Empty / error ================= */
355 397 .notice { text-align: center; padding: 72px 24px; color: var(--ink-2); }
356 398 .notice .big { font-size: 44px; margin-bottom: 10px; }
357 −.notice h2 { text-transform: uppercase; }
399 +.notice h2 { color: var(--navy); }
358 400
359 401 /* ================= Detail page ================= */
360 402 .detail { padding: 30px 0 90px; }
361 403 .crumbs {
362 − font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase;
404 + font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
363 405 color: var(--ink-3); margin-bottom: 20px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
364 406 }
365 407 .crumbs a { border-bottom: 1.5px solid transparent; }
366 −.crumbs a:hover { color: var(--green); border-color: var(--green); }
408 +.crumbs a:hover { color: var(--blue); border-color: var(--blue); }
367 409 .detail-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 30px; align-items: start; }
368 410 @media (max-width: 900px) { .detail-grid { grid-template-columns: 1fr; } }
369 411 /* les enfants de grille ont min-width:auto par défaut : un contenu large
@@ -372,111 +414,112 @@ img { display: block; }
372 414
373 415 .gallery { display: flex; flex-direction: column; gap: 10px; }
374 416 .gallery-main {
375 − border-radius: var(--r-card); overflow: hidden; border: 1.5px solid var(--ink);
376 − aspect-ratio: 16/10; background: #eceae3; cursor: zoom-in; box-shadow: var(--shadow-off-soft);
417 + border-radius: var(--r-card); overflow: hidden; border: 1px solid var(--line);
418 + aspect-ratio: 16/10; background: var(--grey); cursor: zoom-in; box-shadow: var(--shadow-off-soft);
377 419 }
378 420 .gallery-main img { width: 100%; height: 100%; object-fit: cover; }
379 421 .thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; }
380 422 .thumbs button {
381 − border: 2px solid var(--line); border-radius: 8px; overflow: hidden; padding: 0; cursor: pointer;
382 − aspect-ratio: 4/3; background: #eceae3; transition: border-color 0.12s ease, transform 0.12s ease;
423 + border: 2px solid var(--line); border-radius: 12px; overflow: hidden; padding: 0; cursor: pointer;
424 + aspect-ratio: 4/3; background: var(--grey); transition: border-color 0.12s ease, transform 0.12s ease;
383 425 }
384 426 .thumbs button:hover { transform: translateY(-2px); }
385 −.thumbs button.on { border-color: var(--ink); box-shadow: 3px 3px 0 var(--lime); }
427 +.thumbs button.on { border-color: var(--orange); }
386 428 .thumbs img { width: 100%; height: 100%; object-fit: cover; }
387 429
388 430 .panel {
389 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
431 + background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
390 432 box-shadow: var(--shadow-off-soft); padding: 26px; position: sticky; top: 120px;
391 433 }
392 434 @media (max-width: 900px) { .panel { position: static; } }
393 −.panel .price { font-family: var(--font-display); font-size: 34px; font-weight: 700; letter-spacing: -0.03em; }
394 −.panel .price small { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); font-weight: 500; letter-spacing: 0.05em; }
435 +.panel .price { font-family: var(--font-display); font-size: 34px; font-weight: 700; letter-spacing: -0.03em; color: var(--navy); }
436 +.panel .price small { font-size: 12.5px; color: var(--ink-3); font-weight: 500; }
395 437 .panel h1 { font-size: 22px; margin: 8px 0 2px; }
396 438 .panel .loc { color: var(--ink-2); font-size: 14px; }
397 439 .kv { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 20px 0; }
398 440 @media (max-width: 380px) { .kv { grid-template-columns: 1fr; } }
399 −.kv .cell { background: var(--surface-2); border: 1.5px solid var(--line); border-radius: var(--r-ctl); padding: 10px 13px; }
400 −.kv .cell .k { font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); font-weight: 700; }
401 −.kv .cell .v { font-weight: 700; font-size: 14.5px; margin-top: 2px; font-family: var(--font-display); }
402 −.klabel { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); font-weight: 700; margin-bottom: 8px; }
441 +.kv .cell { background: var(--grey); border-radius: var(--r-ctl); padding: 10px 14px; }
442 +.kv .cell .k { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); font-weight: 700; }
443 +.kv .cell .v { font-weight: 700; font-size: 14.5px; margin-top: 2px; font-family: var(--font-display); color: var(--navy); }
444 +.klabel { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); font-weight: 700; margin-bottom: 8px; }
403 445 .amenity-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 20px; }
404 446 .amenity {
405 − background: var(--lime-soft); color: var(--green-deep); font-size: 12px; font-weight: 600;
406 − border: 1px solid var(--green); border-radius: 999px; padding: 5px 12px;
447 + background: var(--blue-soft); color: var(--blue); font-size: 12px; font-weight: 600;
448 + border: 1px solid rgba(34, 88, 255, 0.25); border-radius: var(--r-pill); padding: 5px 13px;
407 449 }
408 450 .cta {
409 − display: block; text-align: center; background: var(--ink); color: var(--lime);
410 − font-weight: 700; font-family: var(--font-display); border-radius: var(--r-ctl);
411 − padding: 15px; border: 1.5px solid var(--ink); min-height: 48px;
412 − box-shadow: 4px 4px 0 rgba(20,24,20,0.25); transition: all 0.14s ease;
451 + display: block; text-align: center; background: var(--orange); color: var(--white);
452 + font-weight: 600; font-family: var(--font-display); border-radius: var(--r-pill);
453 + padding: 15px; min-height: 48px;
454 + box-shadow: 0 8px 22px rgba(255, 106, 0, 0.34); transition: all 0.14s ease;
413 455 }
414 −.cta:hover { background: var(--lime); color: var(--ink); }
415 −.cta:active { transform: translate(2px, 2px); box-shadow: none; }
416 −.panel .fine { font-size: 11.5px; color: var(--ink-3); margin-top: 14px; text-align: center; font-family: var(--font-mono); letter-spacing: 0.02em; }
456 +.cta:hover { background: var(--orange-deep); }
457 +.cta:active { transform: translateY(1px); }
458 +.panel .fine { font-size: 11.5px; color: var(--ink-3); margin-top: 14px; text-align: center; }
417 459
418 460 /* ================= Lightbox ================= */
419 461 .lightbox {
420 − position: fixed; inset: 0; background: rgba(16, 18, 16, 0.94); z-index: 100;
462 + position: fixed; inset: 0; background: rgba(11, 19, 48, 0.94); z-index: 100;
421 463 display: flex; align-items: center; justify-content: center; cursor: zoom-out;
422 464 padding: max(16px, env(safe-area-inset-top)) 16px;
423 465 }
424 −.lightbox img { max-width: 94vw; max-height: 90vh; border-radius: 6px; border: 2px solid var(--lime); }
466 +.lightbox img { max-width: 94vw; max-height: 90vh; border-radius: 12px; }
425 467
426 468 /* ================= Sources page ================= */
427 469 .sources { padding: 44px 0 90px; }
428 −.sources h1 { font-size: clamp(28px, 4vw, 40px); text-transform: uppercase; margin: 10px 0 6px; }
470 +.sources h1 { font-size: clamp(28px, 4vw, 40px); margin: 10px 0 6px; color: var(--navy); }
429 471 .sources .sub { color: var(--ink-2); margin-bottom: 30px; max-width: 700px; }
430 −.src-wrap { overflow-x: auto; border: 1.5px solid var(--ink); border-radius: var(--r-card); box-shadow: var(--shadow-off-soft); background: var(--surface); }
472 +.src-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-off-soft); background: var(--surface); }
431 473 .src-table { width: 100%; border-collapse: separate; border-spacing: 0; min-width: 720px; }
432 474 .src-table th {
433 − text-align: left; font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
434 − letter-spacing: 0.12em; color: var(--ink-3); padding: 14px 18px;
435 − border-bottom: 1.5px solid var(--ink); background: var(--surface-2);
475 + text-align: left; font-size: 10.5px; text-transform: uppercase;
476 + letter-spacing: 0.1em; color: var(--ink-3); padding: 14px 18px;
477 + border-bottom: 1px solid var(--line-strong); background: var(--grey);
436 478 }
437 479 .src-table td { padding: 13px 18px; border-bottom: 1px solid var(--line); font-size: 14px; vertical-align: top; }
438 480 .src-table tr:last-child td { border-bottom: none; }
439 −.src-table tr:hover td { background: var(--surface-2); }
440 −.src-table a { color: var(--green-deep); font-weight: 600; border-bottom: 1.5px solid var(--lime); }
441 −.pill { display: inline-block; border-radius: 4px; padding: 3px 10px; font-family: var(--font-mono); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
442 −.pill.ok { background: var(--lime); color: var(--ink); border: 1px solid var(--ink); }
443 −.pill.todo { background: var(--amber-soft); color: #8a5a12; border: 1px solid var(--amber); }
444 −.count-pill { font-weight: 700; font-family: var(--font-display); font-size: 16px; }
481 +.src-table tr:hover td { background: var(--navy-soft); }
482 +.src-table a { color: var(--blue); font-weight: 600; border-bottom: 1.5px solid rgba(34, 88, 255, 0.35); }
483 +.pill { display: inline-block; border-radius: var(--r-pill); padding: 3px 10px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
484 +.pill.ok { background: var(--blue-soft); color: var(--blue); }
485 +.pill.todo { background: var(--orange-soft); color: var(--orange-deep); }
486 +.count-pill { font-weight: 700; font-family: var(--font-display); font-size: 16px; color: var(--navy); }
445 487
446 488 /* ================= Page Statistiques ================= */
447 489 .stats-page { padding: 44px 0 90px; }
448 −.stats-title { font-size: clamp(30px, 4.6vw, 46px); text-transform: uppercase; margin: 10px 0 6px; }
490 +.stats-title { font-size: clamp(30px, 4.6vw, 46px); margin: 10px 0 6px; color: var(--navy); }
449 491 .stats-page .sub { color: var(--ink-2); max-width: 640px; margin-bottom: 30px; }
450 492
451 493 .tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 30px; }
452 494 .tile {
453 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
454 − padding: 18px 20px; box-shadow: 3px 3px 0 rgba(20, 24, 20, 0.1);
495 + background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
496 + padding: 18px 20px; box-shadow: var(--shadow-flat);
455 497 }
456 −.tile-v { font-family: var(--font-display); font-weight: 700; font-size: clamp(24px, 3vw, 34px); letter-spacing: -0.03em; line-height: 1.05; }
457 −.tile-k { font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); margin-top: 6px; }
458 −.hero-tile { background: var(--ink); color: var(--lime); border-color: var(--ink); }
459 −.hero-tile .tile-k { color: rgba(217, 242, 107, 0.7); }
498 +.tile-v { font-family: var(--font-display); font-weight: 700; font-size: clamp(24px, 3vw, 34px); letter-spacing: -0.03em; line-height: 1.05; color: var(--navy); }
499 +.tile-k { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); margin-top: 6px; }
500 +.hero-tile { background: var(--navy); color: var(--white); border-color: var(--navy); }
501 +.hero-tile .tile-v { color: var(--white); }
502 +.hero-tile .tile-k { color: rgba(255, 255, 255, 0.6); }
460 503
461 504 .viz-card {
462 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
505 + background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
463 506 box-shadow: var(--shadow-off-soft); padding: 26px 28px 20px; margin-bottom: 22px;
464 507 }
465 −.viz-card h2 { font-size: 19px; text-transform: uppercase; letter-spacing: -0.01em; }
466 −.viz-sub { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin: 4px 0 20px; }
508 +.viz-card h2 { font-size: 19px; letter-spacing: -0.01em; color: var(--navy); }
509 +.viz-sub { font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin: 4px 0 20px; }
467 510 .viz-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
468 511 @media (max-width: 900px) { .viz-grid { grid-template-columns: 1fr; } }
469 512
470 −/* Histogramme (mono-série, encre verte) */
513 +/* Histogramme (mono-série, bleu vif) */
471 514 .histo { display: flex; align-items: stretch; gap: 2px; height: 240px; }
472 515 .histo-col { flex: 1; display: flex; flex-direction: column; min-width: 0; cursor: default; }
473 −.histo-bar-zone { flex: 1; display: flex; align-items: flex-end; border-bottom: 1.5px solid var(--ink); }
516 +.histo-bar-zone { flex: 1; display: flex; align-items: flex-end; border-bottom: 1px solid var(--line-strong); }
474 517 .histo-bar {
475 − width: 100%; background: var(--green); border-radius: 4px 4px 0 0;
518 + width: 100%; background: var(--blue); border-radius: 6px 6px 0 0;
476 519 min-height: 2px; transition: background 0.12s ease;
477 520 }
478 −.histo-col:hover .histo-bar { background: var(--ink); box-shadow: inset 0 0 0 2px var(--lime); }
479 −.histo-x { font-family: var(--font-mono); font-size: 9.5px; color: var(--ink-3); text-align: left; height: 18px; padding-top: 5px; overflow: visible; white-space: nowrap; }
521 +.histo-col:hover .histo-bar { background: var(--orange); }
522 +.histo-x { font-size: 9.5px; color: var(--ink-3); text-align: left; height: 18px; padding-top: 5px; overflow: visible; white-space: nowrap; }
480 523
481 524 /* Barres horizontales (mono-série) */
482 525 .hbars { display: flex; flex-direction: column; gap: 7px; }
@@ -485,15 +528,15 @@ img { display: block; }
485 528 gap: 12px; align-items: center; min-height: 26px; cursor: default;
486 529 }
487 530 .hbar-label { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
488 −.hbar-label a { border-bottom: 1.5px solid var(--lime); }
489 −.hbar-label a:hover { color: var(--green-deep); }
490 −.hbar-track { background: var(--surface-2); border-radius: 0 4px 4px 0; height: 18px; overflow: hidden; }
531 +.hbar-label a { border-bottom: 1.5px solid rgba(34, 88, 255, 0.35); }
532 +.hbar-label a:hover { color: var(--blue); }
533 +.hbar-track { background: var(--grey); border-radius: var(--r-pill); height: 18px; overflow: hidden; }
491 534 .hbar-fill {
492 − display: block; height: 100%; background: var(--green); border-radius: 0 4px 4px 0;
535 + display: block; height: 100%; background: var(--blue); border-radius: var(--r-pill);
493 536 min-width: 2px; transition: background 0.12s ease;
494 537 }
495 −.hbar-row:hover .hbar-fill { background: var(--ink); box-shadow: inset 0 0 0 2px var(--lime); }
496 −.hbar-value { font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; white-space: nowrap; }
538 +.hbar-row:hover .hbar-fill { background: var(--orange); }
539 +.hbar-value { font-size: 11.5px; font-weight: 700; white-space: nowrap; color: var(--navy); }
497 540 .hbar-value em { font-style: normal; font-weight: 500; color: var(--ink-3); }
498 541 @media (max-width: 640px) {
499 542 .hbar-row { grid-template-columns: minmax(80px, 110px) 1fr auto; gap: 8px; }
@@ -505,23 +548,23 @@ img { display: block; }
505 548 /* Infobulle */
506 549 .viz-tip {
507 550 position: fixed; z-index: 120; pointer-events: none; max-width: 180px;
508 − background: var(--ink); color: var(--paper); border-radius: 8px;
509 − border: 1px solid var(--lime); padding: 9px 12px; font-size: 12px; line-height: 1.5;
510 − box-shadow: 0 8px 24px rgba(16, 18, 16, 0.35);
551 + background: var(--navy); color: var(--white); border-radius: 12px;
552 + padding: 9px 12px; font-size: 12px; line-height: 1.5;
553 + box-shadow: 0 8px 24px rgba(11, 19, 48, 0.35);
511 554 }
512 −.viz-tip-title { font-family: var(--font-display); font-weight: 700; color: var(--lime); margin-bottom: 2px; }
555 +.viz-tip-title { font-family: var(--font-display); font-weight: 700; color: var(--orange); margin-bottom: 2px; }
513 556
514 557 /* Vue tableau repliable (accessibilité / relief) */
515 −.viz-table { margin-top: 16px; border-top: 1.5px dashed var(--line); padding-top: 10px; }
558 +.viz-table { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 10px; }
516 559 .viz-table summary {
517 − cursor: pointer; font-family: var(--font-mono); font-size: 11px; font-weight: 700;
518 − text-transform: uppercase; letter-spacing: 0.08em; color: var(--green-deep);
560 + cursor: pointer; font-size: 11.5px; font-weight: 700;
561 + text-transform: uppercase; letter-spacing: 0.08em; color: var(--blue);
519 562 }
520 563 .viz-table table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; }
521 −.viz-table th { text-align: left; font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); padding: 6px 10px; border-bottom: 1.5px solid var(--ink); }
564 +.viz-table th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-3); padding: 6px 10px; border-bottom: 1px solid var(--line-strong); }
522 565 .viz-table td { padding: 6px 10px; border-bottom: 1px solid var(--line); }
523 566
524 −.stats-foot { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); letter-spacing: 0.04em; margin-top: 6px; }
567 +.stats-foot { font-size: 11.5px; color: var(--ink-3); letter-spacing: 0.02em; margin-top: 6px; }
525 568
526 569 /* ================= Mobile : feuille de filtres + FAB ================= */
527 570 .sheet-head { display: none; }
@@ -531,13 +574,13 @@ img { display: block; }
531 574
532 575 @media (max-width: 640px) {
533 576 /* En-tête compact */
534 − .header-inner { height: 56px; }
577 + .header-inner { height: 58px; }
535 578 .brand { font-size: 21px; }
536 579 .nav a { padding: 8px 13px; font-size: 13.5px; }
537 580 .ticker { font-size: 10.5px; padding: 6px 0; }
538 581
539 582 /* Héro resserré + stats en rangée défilante */
540 − .hero h1 { font-size: clamp(30px, 9.4vw, 44px); }
583 + .hero h1 { font-size: clamp(30px, 8.6vw, 42px); }
541 584 .hero p.lede { font-size: 15px; }
542 585 .stat-row { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 6px; margin-right: -16px; padding-right: 16px; }
543 586 .stat-row::-webkit-scrollbar { display: none; }
@@ -552,39 +595,39 @@ img { display: block; }
552 595 .filterbar.open {
553 596 display: flex; flex-direction: column; gap: 12px;
554 597 position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
555 − margin: 0; border-radius: 20px 20px 0 0; border-width: 2px 0 0 0;
598 + margin: 0; border-radius: 24px 24px 0 0; border: none;
556 599 max-height: 82dvh; overflow-y: auto; -webkit-overflow-scrolling: touch;
557 600 padding: 16px 18px calc(18px + env(safe-area-inset-bottom));
558 − box-shadow: 0 -16px 48px rgba(16, 18, 16, 0.35);
601 + box-shadow: 0 -16px 48px rgba(11, 19, 48, 0.28);
559 602 animation: sheet-up 0.22s ease;
560 603 }
561 604 @keyframes sheet-up { from { transform: translateY(30%); opacity: 0.4; } to { transform: none; opacity: 1; } }
562 605 .filterbar.open .sheet-head {
563 606 display: flex; justify-content: space-between; align-items: center;
564 607 font-family: var(--font-display); font-weight: 700; font-size: 17px;
565 − text-transform: uppercase; letter-spacing: -0.01em;
608 + letter-spacing: -0.01em; color: var(--navy);
566 609 position: sticky; top: -16px; background: var(--surface); padding: 6px 0 8px;
567 − border-bottom: 1.5px solid var(--line); margin-bottom: 2px; z-index: 1;
610 + border-bottom: 1px solid var(--line); margin-bottom: 2px; z-index: 1;
568 611 }
569 612 .sheet-close {
570 − border: 1.5px solid var(--ink); background: var(--surface); border-radius: 50%;
571 − width: 36px; height: 36px; font-size: 15px; cursor: pointer; line-height: 1;
613 + border: 1px solid var(--line-strong); background: var(--surface); border-radius: 50%;
614 + width: 36px; height: 36px; font-size: 15px; cursor: pointer; line-height: 1; color: var(--navy);
572 615 }
573 616 .filterbar.open .sheet-apply { display: block; width: 100%; }
574 617 .sheet-backdrop {
575 618 display: block; position: fixed; inset: 0; z-index: 90;
576 − background: rgba(16, 18, 16, 0.45); backdrop-filter: blur(2px);
619 + background: rgba(11, 19, 48, 0.45); backdrop-filter: blur(2px);
577 620 }
578 621
579 622 /* Bouton flottant */
580 623 .fab {
581 624 display: flex; align-items: center; gap: 6px;
582 625 position: fixed; left: 50%; transform: translateX(-50%);
583 − bottom: calc(18px + env(safe-area-inset-bottom)); z-index: 80;
584 − background: var(--ink); color: var(--lime); border: 1.5px solid var(--ink);
585 − border-radius: 999px; padding: 13px 24px; font-family: var(--font-display);
586 − font-weight: 700; font-size: 15px; cursor: pointer;
587 − box-shadow: 0 8px 24px rgba(16, 18, 16, 0.35), 4px 4px 0 rgba(20, 24, 20, 0.25);
626 + bottom: calc(74px + env(safe-area-inset-bottom)); z-index: 80;
627 + background: var(--orange); color: var(--white); border: none;
628 + border-radius: var(--r-pill); padding: 13px 24px; font-family: var(--font-display);
629 + font-weight: 600; font-size: 15px; cursor: pointer;
630 + box-shadow: 0 10px 28px rgba(255, 106, 0, 0.4);
588 631 }
589 632 .fab:active { transform: translateX(-50%) scale(0.97); }
590 633
@@ -600,32 +643,58 @@ img { display: block; }
600 643 .notice { padding: 48px 16px; }
601 644 }
602 645
646 +/* ================= Barre de navigation inférieure (mobile) ================= */
647 +.tabbar { display: none; }
648 +@media (max-width: 760px) {
649 + .tabbar {
650 + display: grid; grid-template-columns: repeat(4, 1fr);
651 + position: fixed; left: 0; right: 0; bottom: 0; z-index: 85;
652 + background: rgba(255, 255, 255, 0.92);
653 + backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
654 + border-top: 1px solid var(--line);
655 + padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
656 + }
657 + .tabbar a {
658 + display: flex; flex-direction: column; align-items: center; gap: 3px;
659 + padding: 5px 2px; min-height: 48px; justify-content: center;
660 + font-size: 10.5px; font-weight: 600; color: var(--ink-3);
661 + border-radius: var(--r-ctl); transition: color 0.12s ease;
662 + }
663 + .tabbar a.active { color: var(--orange); }
664 + .tabbar a svg { display: block; }
665 + body { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
666 + .footer { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
667 +}
668 +
603 669 /* Anti-zoom iOS : les champs doivent faire >= 16px */
604 670 @media (max-width: 900px) {
605 671 .field input, .field select { font-size: 16px; }
606 672 }
607 673
608 674 /* ================= Footer ================= */
609 −.footer { background: var(--ink); color: rgba(245, 243, 238, 0.75); margin-top: 20px; padding: 44px 0 max(40px, env(safe-area-inset-bottom)); font-size: 13px; }
610 −.footer .fbrand { font-family: var(--font-display); font-weight: 700; font-size: 34px; color: var(--paper); letter-spacing: -0.04em; margin-bottom: 12px; }
611 −.footer .fbrand .ka { color: var(--lime); }
612 −.footer b { color: var(--paper); }
675 +.footer { background: var(--navy); color: rgba(255, 255, 255, 0.72); margin-top: 20px; padding: 44px 0 max(40px, env(safe-area-inset-bottom)); font-size: 13px; }
676 +.footer .fbrand { font-family: var(--font-display); font-weight: 700; font-size: 32px; color: var(--white); letter-spacing: -0.03em; margin-bottom: 4px; display: flex; align-items: center; }
677 +.footer .fbrand .logo-ico { margin-right: 10px; }
678 +.footer .fbrand .ka { color: var(--orange); }
679 +.footer .fbaseline { color: rgba(255, 255, 255, 0.65); font-size: 14px; margin-bottom: 16px; }
680 +.footer .fbaseline .hl { color: var(--orange); font-weight: 600; }
681 +.footer b { color: var(--white); }
613 682 .footer .frow { display: flex; flex-direction: column; gap: 5px; max-width: 720px; }
614 −.footer .fmono { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(245,243,238,0.45); margin-top: 18px; }
683 +.footer .fmono { font-size: 11.5px; letter-spacing: 0.04em; color: rgba(255, 255, 255, 0.42); margin-top: 18px; }
615 684
616 685 /* --- Carte interactive (mission 4) --------------------------------------- */
617 686 .results-tools { display: flex; align-items: center; gap: 14px; }
618 687 .view-toggle {
619 − display: inline-flex; border: 1.5px solid var(--line-strong);
620 − border-radius: var(--r-ctl); overflow: hidden; background: var(--surface);
688 + display: inline-flex; border: 1px solid var(--line-strong);
689 + border-radius: var(--r-pill); overflow: hidden; background: var(--surface);
621 690 box-shadow: var(--shadow-flat);
622 691 }
623 692 .view-toggle button {
624 − border: 0; background: transparent; padding: 7px 14px; cursor: pointer;
625 − font-family: var(--font-mono); font-size: 12px; color: var(--ink-2);
693 + border: 0; background: transparent; padding: 7px 16px; cursor: pointer;
694 + font-size: 12.5px; font-weight: 600; color: var(--ink-2);
626 695 }
627 −.view-toggle button + button { border-left: 1.5px solid var(--line-strong); }
628 −.view-toggle button.on { background: var(--ink); color: var(--lime); }
696 +.view-toggle button + button { border-left: 1px solid var(--line); }
697 +.view-toggle button.on { background: var(--blue); color: var(--white); }
629 698
630 699 .map-split {
631 700 display: grid; grid-template-columns: minmax(300px, 400px) 1fr; gap: 18px;
@@ -637,13 +706,13 @@ img { display: block; }
637 706 }
638 707 .map-list .card { margin: 0; flex: 0 0 auto; }
639 708 .mapview {
640 − width: 100%; height: 100%; border: 1.5px solid var(--line-strong);
709 + width: 100%; height: 100%; border: 1px solid var(--line);
641 710 border-radius: var(--r-card); box-shadow: var(--shadow-off-soft);
642 − overflow: hidden; background: var(--surface-2);
711 + overflow: hidden; background: var(--grey);
643 712 }
644 713 .map-loading {
645 714 display: flex; align-items: center; justify-content: center;
646 − color: var(--ink-3); font-family: var(--font-mono); font-size: 13px;
715 + color: var(--ink-3); font-size: 13px;
647 716 }
648 717
649 718 /* mobile d'abord : carte plein écran, liste masquée (bascule via l'onglet) */
@@ -656,30 +725,30 @@ img { display: block; }
656 725 /* popup MapLibre au style Lou-Ka */
657 726 .maplibregl-popup-content {
658 727 padding: 0; border-radius: var(--r-card); overflow: hidden;
659 − border: 1.5px solid var(--line-strong); box-shadow: var(--shadow-off);
728 + border: 1px solid var(--line); box-shadow: var(--shadow-off);
660 729 font-family: var(--font-body);
661 730 }
662 731 .maplibregl-popup-close-button {
663 − font-size: 18px; padding: 2px 8px; color: var(--paper); z-index: 2;
664 − text-shadow: 0 0 4px rgba(20, 24, 20, 0.8);
732 + font-size: 18px; padding: 2px 8px; color: var(--white); z-index: 2;
733 + text-shadow: 0 0 4px rgba(11, 19, 48, 0.8);
665 734 }
666 735 .mv-pop img, .mv-noimg { width: 100%; height: 130px; object-fit: cover; }
667 736 .mv-noimg { display: flex; align-items: center; justify-content: center;
668 − font-size: 34px; background: var(--surface-2); }
737 + font-size: 34px; background: var(--grey); }
669 738 .mv-pop-body { padding: 10px 12px 12px; }
670 −.mv-pop-price { font-family: var(--font-display); font-weight: 700; font-size: 18px; }
739 +.mv-pop-price { font-family: var(--font-display); font-weight: 700; font-size: 18px; color: var(--navy); }
671 740 .mv-pop-price small { font-weight: 400; color: var(--ink-3); font-size: 12px; }
672 741 .mv-pop-title { font-size: 13px; color: var(--ink-2); margin-top: 2px;
673 742 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
674 −.mv-pop-meta { font-family: var(--font-mono); font-size: 11px; color: var(--ink-2); margin-top: 6px; }
675 −.mv-pop-src { font-family: var(--font-mono); font-size: 10px; color: var(--ink-3);
743 +.mv-pop-meta { font-size: 11.5px; color: var(--ink-2); margin-top: 6px; }
744 +.mv-pop-src { font-size: 10px; color: var(--ink-3);
676 745 text-transform: uppercase; letter-spacing: 0.06em; margin-top: 2px; }
677 746 .mv-pop-cta {
678 − display: block; margin-top: 10px; padding: 8px 10px; text-align: center;
679 − background: var(--ink); color: var(--lime); border-radius: var(--r-ctl);
747 + display: block; margin-top: 10px; padding: 9px 10px; text-align: center;
748 + background: var(--orange); color: var(--white); border-radius: var(--r-pill);
680 749 font-weight: 600; font-size: 13px;
681 750 }
682 −.mv-pop-cta:hover { background: var(--green-deep); }
751 +.mv-pop-cta:hover { background: var(--orange-deep); }
683 752
684 753 /* --- Commodités de proximité (fiche) -------------------------------------- */
685 754 .poi-list {
@@ -688,27 +757,27 @@ img { display: block; }
688 757 }
689 758 .poi-list li {
690 759 display: flex; align-items: center; gap: 9px;
691 − padding: 5px 2px; border-bottom: 1px dashed var(--line);
760 + padding: 5px 2px; border-bottom: 1px solid var(--line);
692 761 font-size: 13px;
693 762 }
694 763 .poi-list li:last-child { border-bottom: 0; }
695 764 .poi-ico { width: 20px; text-align: center; flex: 0 0 auto; }
696 765 .poi-name { flex: 1; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
697 −.poi-dist { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink); font-weight: 600; flex: 0 0 auto; }
766 +.poi-dist { font-size: 11.5px; color: var(--navy); font-weight: 600; flex: 0 0 auto; }
698 767
699 768 /* --- Menu déroulant mobile ------------------------------------------------- */
700 769 .menu-btn {
701 770 display: none; position: relative; z-index: 60;
702 771 width: 44px; height: 44px; margin-left: auto;
703 − border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
772 + border: 1px solid var(--line-strong); border-radius: var(--r-ctl);
704 773 background: var(--surface); cursor: pointer; padding: 0;
705 774 flex-direction: column; align-items: center; justify-content: center; gap: 5px;
706 − box-shadow: 3px 3px 0 rgba(20, 24, 20, 0.15);
775 + box-shadow: var(--shadow-flat);
707 776 transition: box-shadow 0.15s ease, transform 0.15s ease;
708 777 }
709 −.menu-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 rgba(20,24,20,0.15); }
778 +.menu-btn:active { transform: scale(0.96); }
710 779 .menu-btn span {
711 − display: block; width: 18px; height: 2px; background: var(--ink);
780 + display: block; width: 18px; height: 2px; background: var(--navy);
712 781 border-radius: 2px; transition: transform 0.25s ease, opacity 0.2s ease;
713 782 }
714 783 .menu-btn.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
@@ -717,8 +786,8 @@ img { display: block; }
717 786
718 787 .mobile-menu {
719 788 display: none; position: absolute; left: 0; right: 0; top: 100%;
720 − background: var(--paper); border-bottom: 2px solid var(--ink);
721 − box-shadow: 0 18px 30px rgba(20, 24, 20, 0.18);
789 + background: var(--white); border-bottom: 1px solid var(--line);
790 + box-shadow: 0 18px 30px rgba(11, 19, 48, 0.14);
722 791 padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
723 792 max-height: 0; overflow: hidden; opacity: 0;
724 793 transition: max-height 0.3s ease, opacity 0.22s ease;
@@ -728,23 +797,24 @@ img { display: block; }
728 797 display: flex; align-items: center; gap: 12px;
729 798 padding: 15px 10px; min-height: 52px;
730 799 font-family: var(--font-display); font-weight: 700; font-size: 19px;
731 − letter-spacing: -0.02em; border-bottom: 1.5px dashed var(--line);
800 + letter-spacing: -0.02em; border-bottom: 1px solid var(--line);
801 + color: var(--navy);
732 802 opacity: 0; transform: translateY(-8px);
733 803 transition: opacity 0.25s ease, transform 0.25s ease;
734 804 }
735 805 .mobile-menu.open .mm-link { opacity: 1; transform: translateY(0); }
736 −.mm-link.active { color: var(--green); }
737 −.mm-link.active .mm-arrow { opacity: 1; }
806 +.mm-link.active { color: var(--orange); }
807 +.mm-link.active .mm-arrow { opacity: 1; color: var(--orange); }
738 808 .mm-ico { width: 26px; text-align: center; font-size: 17px; }
739 −.mm-arrow { margin-left: auto; opacity: 0.25; transition: opacity 0.15s ease; }
740 −.mm-link:active { background: var(--lime-soft); border-radius: var(--r-ctl); }
809 +.mm-arrow { margin-left: auto; opacity: 0.25; color: var(--orange); transition: opacity 0.15s ease; }
810 +.mm-link:active { background: var(--orange-soft); border-radius: var(--r-ctl); }
741 811 .mm-foot {
742 − padding: 12px 10px 4px; font-family: var(--font-mono);
743 − font-size: 10.5px; color: var(--ink-3); letter-spacing: 0.04em;
812 + padding: 12px 10px 4px;
813 + font-size: 11px; color: var(--ink-3); letter-spacing: 0.02em;
744 814 }
745 815 .mm-backdrop {
746 816 position: fixed; inset: 0; z-index: 40;
747 − background: rgba(20, 24, 20, 0.35); backdrop-filter: blur(2px);
817 + background: rgba(11, 19, 48, 0.35); backdrop-filter: blur(2px);
748 818 }
749 819 @media (max-width: 760px) {
750 820 .menu-btn { display: flex; }
@@ -761,18 +831,18 @@ img { display: block; }
761 831 @keyframes cookie-in { from { transform: translateY(24px); opacity: 0; } }
762 832 .cookie-inner {
763 833 max-width: 720px; margin: 0 auto; background: var(--surface);
764 − border: 2px solid var(--ink); border-radius: var(--r-card);
834 + border: 1px solid var(--line); border-radius: var(--r-card);
765 835 box-shadow: var(--shadow-off); padding: 16px 18px;
766 836 }
767 837 .cookie-text { font-size: 13.5px; color: var(--ink-2); line-height: 1.5; }
768 −.cookie-text b { color: var(--ink); }
838 +.cookie-text b { color: var(--navy); }
769 839 .cookie-text a { text-decoration: underline; text-underline-offset: 2px; }
770 840 .cookie-options { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
771 841 .cookie-opt {
772 842 display: flex; align-items: flex-start; gap: 10px; font-size: 13px;
773 843 color: var(--ink-2); cursor: pointer;
774 844 }
775 −.cookie-opt input { margin-top: 2px; accent-color: var(--green); width: 16px; height: 16px; }
845 +.cookie-opt input { margin-top: 2px; accent-color: var(--orange); width: 16px; height: 16px; }
776 846 .cookie-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; justify-content: flex-end; }
777 847 @media (max-width: 640px) {
778 848 .cookie-actions { justify-content: stretch; }
@@ -781,7 +851,7 @@ img { display: block; }
781 851
782 852 /* --- Page confidentialité + lien pied de page ------------------------------- */
783 853 .legal { padding: 48px 0 70px; max-width: 760px; }
784 −.legal h1 { font-size: clamp(30px, 5vw, 46px); margin: 12px 0 8px; letter-spacing: -0.03em; }
854 +.legal h1 { font-size: clamp(30px, 5vw, 46px); margin: 12px 0 8px; letter-spacing: -0.03em; color: var(--navy); }
785 855 .legal section { margin-top: 26px; }
786 856 .legal h3 { font-size: 18px; margin-bottom: 8px; }
787 857 .legal p, .legal li { color: var(--ink-2); font-size: 14.5px; }
@@ -793,38 +863,38 @@ img { display: block; }
793 863
794 864 /* --- Section « Le quartier » (fiche) --------------------------------------- */
795 865 .quartier { margin-top: 34px; }
796 −.quartier h2 { font-size: 24px; letter-spacing: -0.02em; }
866 +.quartier h2 { font-size: 24px; letter-spacing: -0.02em; color: var(--navy); }
797 867 .q-sub { color: var(--ink-3); font-size: 13px; margin: 4px 0 16px; }
798 868 .q-grid {
799 869 display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
800 870 }
801 871 @media (max-width: 640px) { .q-grid { grid-template-columns: repeat(2, 1fr); } }
802 872 .q-cell {
803 − background: var(--surface); border: 1.5px solid var(--line-strong);
873 + background: var(--surface); border: 1px solid var(--line);
804 874 border-radius: var(--r-card); padding: 12px 14px; box-shadow: var(--shadow-flat);
805 875 }
806 −.q-val { font-family: var(--font-display); font-weight: 700; font-size: 19px; letter-spacing: -0.02em; }
807 −.q-label { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3);
876 +.q-val { font-family: var(--font-display); font-weight: 700; font-size: 19px; letter-spacing: -0.02em; color: var(--navy); }
877 +.q-label { font-size: 10.5px; font-weight: 600; color: var(--ink-3);
808 878 text-transform: uppercase; letter-spacing: 0.06em; margin-top: 3px; }
809 879 .q-prox { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
810 880 .q-bar { display: flex; align-items: center; gap: 10px; font-size: 13px; }
811 881 .q-bar-label { flex: 0 0 150px; color: var(--ink-2); }
812 882 @media (max-width: 640px) { .q-bar-label { flex-basis: 120px; font-size: 12px; } }
813 883 .q-bar-track {
814 − flex: 1; height: 10px; background: var(--surface-2);
815 − border: 1px solid var(--line-strong); border-radius: 999px; overflow: hidden;
884 + flex: 1; height: 10px; background: var(--grey);
885 + border-radius: var(--r-pill); overflow: hidden;
816 886 }
817 −.q-bar-fill { display: block; height: 100%; background: var(--green); border-radius: 999px; }
818 −.q-bar-num { flex: 0 0 30px; text-align: right; font-family: var(--font-mono);
819 − font-size: 11.5px; font-weight: 700; }
887 +.q-bar-fill { display: block; height: 100%; background: var(--blue); border-radius: var(--r-pill); }
888 +.q-bar-num { flex: 0 0 30px; text-align: right;
889 + font-size: 11.5px; font-weight: 700; color: var(--navy); }
820 890 .q-badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
821 891 .q-badge {
822 892 display: inline-flex; align-items: center; gap: 6px;
823 − border: 1.5px solid var(--line-strong); border-radius: 999px;
824 − padding: 7px 13px; font-size: 12.5px; background: var(--surface);
893 + border: 1px solid var(--line-strong); border-radius: var(--r-pill);
894 + padding: 7px 14px; font-size: 12.5px; background: var(--surface);
825 895 }
826 −.q-badge.cool { background: var(--lime-soft); border-color: var(--green); color: var(--green-deep); }
827 −.q-badge.hot { background: var(--amber-soft); border-color: var(--amber); color: #8a5a12; }
896 +.q-badge.cool { background: var(--blue-soft); border-color: rgba(34, 88, 255, 0.3); color: var(--blue); }
897 +.q-badge.hot { background: var(--orange-soft); border-color: rgba(255, 106, 0, 0.35); color: var(--orange-deep); }
828 898 .quartier .fine { margin-top: 10px; }
829 899
830 900 /* --- Fiche v2 (mobile-first) ------------------------------------------------ */
@@ -839,12 +909,12 @@ img { display: block; }
839 909 .f-col { display: flex; flex-direction: column; gap: 26px; min-width: 0; }
840 910 }
841 911 .f-bloc { min-width: 0; }
842 −.f-bloc h2 { font-size: 21px; letter-spacing: -0.02em; margin-bottom: 10px; }
912 +.f-bloc h2 { font-size: 21px; letter-spacing: -0.02em; margin-bottom: 10px; color: var(--navy); }
843 913 .f-bloc:empty { display: none; }
844 914
845 915 /* galerie à balayage natif */
846 916 .carousel { position: relative; border-radius: var(--r-card); overflow: hidden;
847 − border: 1.5px solid var(--line-strong); background: var(--surface-2); }
917 + border: 1px solid var(--line); background: var(--grey); box-shadow: var(--shadow-off-soft); }
848 918 .carousel-track {
849 919 display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
850 920 -webkit-overflow-scrolling: touch; scrollbar-width: none; aspect-ratio: 16/11;
@@ -858,15 +928,17 @@ img { display: block; }
858 928 aspect-ratio: 16/11; font-size: 48px; }
859 929 .carousel-count {
860 930 position: absolute; right: 12px; bottom: 12px; z-index: 2;
861 − background: rgba(20, 24, 20, 0.82); color: var(--lime);
862 − font-family: var(--font-mono); font-size: 12px; font-weight: 700;
863 − padding: 4px 10px; border-radius: 999px;
931 + background: rgba(11, 19, 48, 0.78); color: var(--white);
932 + font-size: 12px; font-weight: 600;
933 + padding: 4px 11px; border-radius: var(--r-pill);
934 + backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
864 935 }
865 936 .carousel-nav {
866 937 position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
867 − width: 44px; height: 44px; border-radius: 50%; border: 1.5px solid var(--ink);
868 − background: rgba(255, 255, 255, 0.92); font-size: 22px; cursor: pointer;
938 + width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line);
939 + background: rgba(255, 255, 255, 0.92); color: var(--navy); font-size: 22px; cursor: pointer;
869 940 display: flex; align-items: center; justify-content: center; line-height: 1;
941 + box-shadow: var(--shadow-flat);
870 942 }
871 943 .carousel-nav.prev { left: 10px; } .carousel-nav.next { right: 10px; }
872 944 @media (max-width: 640px) { .carousel-nav { display: none; } } /* balayage natif */
@@ -875,12 +947,12 @@ img { display: block; }
875 947 .f-hero .price { font-size: clamp(34px, 8vw, 44px); }
876 948 .deal-badge {
877 949 display: inline-flex; align-items: center; gap: 6px; margin: 8px 0 4px;
878 − border-radius: 999px; padding: 7px 14px; font-size: 13px; font-weight: 600;
879 − border: 1.5px solid var(--line-strong);
950 + border-radius: var(--r-pill); padding: 7px 14px; font-size: 13px; font-weight: 600;
951 + border: 1px solid var(--line-strong);
880 952 }
881 −.deal-good { background: var(--lime-soft); border-color: var(--green); color: var(--green-deep); }
953 +.deal-good { background: var(--blue-soft); border-color: rgba(34, 88, 255, 0.3); color: var(--blue); }
882 954 .deal-ok { background: var(--surface); color: var(--ink-2); }
883 −.deal-high { background: var(--amber-soft); border-color: var(--amber); color: #8a5a12; }
955 +.deal-high { background: var(--orange-soft); border-color: rgba(255, 106, 0, 0.35); color: var(--orange-deep); }
884 956 .f-hero h1 { font-size: clamp(20px, 4.5vw, 26px); margin-top: 8px; }
885 957
886 958 /* chips clés à défilement horizontal */
@@ -890,30 +962,30 @@ img { display: block; }
890 962 }
891 963 .chips-scroll::-webkit-scrollbar { display: none; }
892 964 .chip-key {
893 − flex: 0 0 auto; background: var(--ink); color: var(--lime);
894 − border-radius: 999px; padding: 8px 14px; font-family: var(--font-mono);
895 − font-size: 12px; font-weight: 700; white-space: nowrap; min-height: 34px;
965 + flex: 0 0 auto; background: var(--navy); color: var(--white);
966 + border-radius: var(--r-pill); padding: 8px 15px;
967 + font-size: 12px; font-weight: 600; white-space: nowrap; min-height: 34px;
896 968 display: inline-flex; align-items: center;
897 969 }
898 970
899 971 /* ancres de navigation rapide */
900 972 .ancres {
901 973 display: flex; gap: 4px; overflow-x: auto; padding: 6px 0 2px;
902 − scrollbar-width: none; border-bottom: 1.5px dashed var(--line); margin-bottom: 8px;
974 + scrollbar-width: none; border-bottom: 1px solid var(--line); margin-bottom: 8px;
903 975 }
904 976 .ancres::-webkit-scrollbar { display: none; }
905 977 .ancres a {
906 − flex: 0 0 auto; padding: 9px 12px; font-size: 13.5px; font-weight: 600;
907 − color: var(--ink-2); border-radius: var(--r-ctl); min-height: 44px;
978 + flex: 0 0 auto; padding: 9px 14px; font-size: 13.5px; font-weight: 600;
979 + color: var(--ink-2); border-radius: var(--r-pill); min-height: 44px;
908 980 display: inline-flex; align-items: center;
909 981 }
910 −.ancres a:hover { background: var(--lime-soft); color: var(--ink); }
982 +.ancres a:hover { background: var(--orange-soft); color: var(--orange); }
911 983 html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
912 984
913 985 /* description restructurée */
914 986 .enbref {
915 − background: var(--lime-soft); border: 1.5px solid var(--green);
916 − border-radius: var(--r-card); padding: 12px 15px; color: var(--green-deep);
987 + background: var(--blue-soft); border: 1px solid rgba(34, 88, 255, 0.25);
988 + border-radius: var(--r-card); padding: 12px 16px; color: var(--navy);
917 989 font-size: 15px; margin: 0 0 14px;
918 990 }
919 991 .desc-section { margin-bottom: 12px; }
@@ -921,21 +993,21 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
921 993 .desc-section p { color: var(--ink-2); font-size: 14.5px; margin: 0; white-space: pre-line; }
922 994 .texte-original { margin-top: 12px; }
923 995 .texte-original summary {
924 − cursor: pointer; font-family: var(--font-mono); font-size: 12px;
996 + cursor: pointer; font-size: 12.5px;
925 997 color: var(--ink-3); min-height: 44px; display: flex; align-items: center;
926 998 }
927 999 .texte-original p { color: var(--ink-3); font-size: 13px; white-space: pre-line; }
928 1000
929 1001 /* inclusions : confirmées vs mentionnées */
930 −.amenity.confirmed { background: var(--lime-soft); border-color: var(--green); color: var(--green-deep); font-weight: 600; }
931 −.amenity.unconfirmed { background: transparent; border-style: dashed; color: var(--ink-3); }
1002 +.amenity.confirmed { background: var(--blue-soft); border-color: rgba(34, 88, 255, 0.25); color: var(--blue); font-weight: 600; }
1003 +.amenity.unconfirmed { background: transparent; border-style: dashed; border-color: var(--line-strong); color: var(--ink-3); }
932 1004
933 1005 /* détails pratiques : historique de prix */
934 1006 .prix-histo {
935 1007 margin-top: 12px; padding: 10px 14px; border-radius: var(--r-card);
936 − border: 1.5px solid var(--line-strong); font-size: 13.5px; background: var(--surface);
1008 + border: 1px solid var(--line-strong); font-size: 13.5px; background: var(--surface);
937 1009 }
938 −.prix-histo.down { background: var(--lime-soft); border-color: var(--green); color: var(--green-deep); }
1010 +.prix-histo.down { background: var(--blue-soft); border-color: rgba(34, 88, 255, 0.3); color: var(--blue); }
939 1011
940 1012 /* quartier compacté sur mobile */
941 1013 @media (max-width: 640px) {
@@ -947,7 +1019,7 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
947 1019 .q-badge-sub { display: block; font-size: 10.5px; color: var(--ink-3); font-weight: 400; margin-left: 4px; }
948 1020
949 1021 /* POI groupés repliables */
950 −.poi-groupe { border: 1.5px solid var(--line); border-radius: var(--r-card);
1022 +.poi-groupe { border: 1px solid var(--line); border-radius: var(--r-card);
951 1023 margin-bottom: 8px; background: var(--surface); overflow: hidden; }
952 1024 .poi-groupe summary {
953 1025 display: flex; justify-content: space-between; align-items: center; gap: 10px;
@@ -957,20 +1029,20 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
957 1029 .poi-groupe summary::-webkit-details-marker { display: none; }
958 1030 .poi-groupe summary::after { content: "▾"; color: var(--ink-3); transition: transform 0.15s ease; }
959 1031 .poi-groupe[open] summary::after { transform: rotate(180deg); }
960 −.poi-resume { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); font-weight: 400; }
1032 +.poi-resume { font-size: 11.5px; color: var(--ink-3); font-weight: 400; }
961 1033 .poi-groupe .poi-list { padding: 0 14px 10px; }
962 1034
963 1035 /* CTA sticky mobile */
964 1036 .cta-sticky {
965 − position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
1037 + position: fixed; left: 0; right: 0; bottom: 0; z-index: 88;
966 1038 display: flex; align-items: center; gap: 12px;
967 − background: rgba(245, 243, 238, 0.94); backdrop-filter: blur(12px);
968 − border-top: 2px solid var(--ink);
1039 + background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(12px);
1040 + border-top: 1px solid var(--line);
969 1041 padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
970 1042 }
971 1043 .cta-sticky .cta { flex: 1; margin: 0; text-align: center; }
972 −.cta-sticky-prix { font-family: var(--font-display); font-weight: 700; font-size: 19px; white-space: nowrap; }
973 −.cta-sticky-prix small { font-family: var(--font-mono); font-weight: 500; font-size: 10px; color: var(--ink-3); }
1044 +.cta-sticky-prix { font-family: var(--font-display); font-weight: 700; font-size: 19px; white-space: nowrap; color: var(--navy); }
1045 +.cta-sticky-prix small { font-weight: 500; font-size: 10px; color: var(--ink-3); }
974 1046 @media (min-width: 900px) { .cta-sticky { display: none; } }
975 1047 @media (max-width: 899px) {
976 1048 .cta-desktop { display: none; }
@@ -985,7 +1057,7 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
985 1057 }
986 1058 .pass-card {
987 1059 width: 100%; max-width: 520px; background: var(--surface);
988 − border: 2px solid var(--ink); border-radius: var(--r-card);
1060 + border: 1px solid var(--line); border-radius: var(--r-card);
989 1061 box-shadow: var(--shadow-off); padding: 30px 28px; text-align: center;
990 1062 }
991 1063 .pass-brands {
@@ -994,36 +1066,33 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
994 1066 }
995 1067 .pass-brand {
996 1068 font-family: var(--font-display); font-weight: 700; font-size: 24px;
997 − letter-spacing: -0.04em; display: inline-flex; align-items: center;
998 −}
999 −.pass-brand .ka {
1000 − background: var(--ink); color: var(--lime); padding: 2px 7px 4px;
1001 − border-radius: 6px; margin-left: 3px; transform: rotate(-2deg);
1069 + letter-spacing: -0.03em; display: inline-flex; align-items: center; color: var(--navy);
1002 1070 }
1071 +.pass-brand .ka { color: var(--orange); }
1003 1072 .pass-trajet { display: inline-flex; align-items: center; gap: 5px; }
1004 1073 .pass-dot {
1005 − width: 6px; height: 6px; border-radius: 50%; background: var(--green);
1074 + width: 6px; height: 6px; border-radius: 50%; background: var(--orange);
1006 1075 opacity: 0.25; animation: pass-dot 1.2s ease infinite;
1007 1076 }
1008 1077 .pass-dot:nth-child(2) { animation-delay: 0.2s; }
1009 1078 .pass-dot:nth-child(3) { animation-delay: 0.4s; }
1010 1079 @keyframes pass-dot { 40% { opacity: 1; transform: translateX(2px); } }
1011 −.pass-fleche { color: var(--green); font-size: 18px; }
1080 +.pass-fleche { color: var(--orange); font-size: 18px; }
1012 1081 .pass-gestionnaire {
1013 1082 font-family: var(--font-display); font-weight: 700; font-size: 19px;
1014 1083 display: inline-flex; align-items: center; gap: 8px;
1015 − background: var(--lime-soft); border: 1.5px solid var(--green);
1016 − border-radius: 999px; padding: 6px 16px; color: var(--green-deep);
1084 + background: var(--blue-soft); border: 1px solid rgba(34, 88, 255, 0.25);
1085 + border-radius: var(--r-pill); padding: 6px 16px; color: var(--blue);
1017 1086 }
1018 1087 .pass-card h1 { font-size: 20px; letter-spacing: -0.02em; }
1019 1088 .pass-texte { color: var(--ink-2); font-size: 14.5px; margin: 10px 0 20px; }
1020 1089 .pass-progress {
1021 − height: 10px; border: 1.5px solid var(--ink); border-radius: 999px;
1022 − overflow: hidden; background: var(--surface-2); margin-bottom: 20px;
1090 + height: 10px; border-radius: var(--r-pill);
1091 + overflow: hidden; background: var(--grey); margin-bottom: 20px;
1023 1092 }
1024 1093 .pass-progress-fill {
1025 − display: block; height: 100%; width: 0; background: var(--lime);
1026 − border-right: 2px solid var(--ink);
1094 + display: block; height: 100%; width: 0; background: var(--orange);
1095 + border-radius: var(--r-pill);
1027 1096 }
1028 1097 .pass-progress-fill.go { animation: pass-fill 2.2s linear forwards; }
1029 1098 @keyframes pass-fill { to { width: 100%; } }
@@ -1038,36 +1107,37 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1038 1107
1039 1108 /* --- Onglets de la page Stats -------------------------------------------- */
1040 1109 .onglets {
1041 − display: flex; gap: 6px; overflow-x: auto; margin: 26px 0 22px;
1110 + display: flex; gap: 8px; overflow-x: auto; margin: 26px 0 22px;
1042 1111 padding-bottom: 4px; scrollbar-width: none;
1043 − border-bottom: 2px solid var(--ink);
1112 + border-bottom: 1px solid var(--line);
1044 1113 }
1045 1114 .onglets::-webkit-scrollbar { display: none; }
1046 1115 .onglet {
1047 1116 flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
1048 − border: 1.5px solid var(--ink); border-bottom: 0;
1049 − border-radius: var(--r-ctl) var(--r-ctl) 0 0;
1117 + border: 1px solid var(--line-strong);
1118 + border-radius: var(--r-pill);
1050 1119 background: var(--surface); color: var(--ink-2); cursor: pointer;
1051 − padding: 10px 16px; font-weight: 600; font-size: 13.5px; min-height: 44px;
1052 − transition: background 0.12s ease, color 0.12s ease;
1120 + padding: 10px 18px; font-weight: 600; font-size: 13.5px; min-height: 44px;
1121 + margin-bottom: 8px;
1122 + transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
1053 1123 }
1054 −.onglet:hover { background: var(--lime-soft); color: var(--ink); }
1055 −.onglet.on { background: var(--ink); color: var(--lime); }
1124 +.onglet:hover { background: var(--blue-soft); color: var(--blue); border-color: var(--blue); }
1125 +.onglet.on { background: var(--blue); border-color: var(--blue); color: var(--white); }
1056 1126
1057 1127 /* baisses de prix */
1058 1128 .baisses { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
1059 1129 .baisses li {
1060 1130 display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
1061 − padding: 9px 4px; border-bottom: 1px dashed var(--line); font-size: 13.5px;
1131 + padding: 9px 4px; border-bottom: 1px solid var(--line); font-size: 13.5px;
1062 1132 }
1063 1133 .baisses li a { font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
1064 −.baisse-ville { color: var(--ink-3); font-family: var(--font-mono); font-size: 11px; }
1134 +.baisse-ville { color: var(--ink-3); font-size: 11.5px; }
1065 1135 .baisse-prix { margin-left: auto; }
1066 1136 .baisse-prix s { color: var(--ink-3); }
1067 1137 .baisse-pct {
1068 − font-style: normal; font-family: var(--font-mono); font-weight: 700;
1069 − background: var(--lime-soft); border: 1px solid var(--green);
1070 − color: var(--green-deep); border-radius: 999px; padding: 2px 8px;
1138 + font-style: normal; font-weight: 700;
1139 + background: var(--blue-soft);
1140 + color: var(--blue); border-radius: var(--r-pill); padding: 2px 9px;
1071 1141 font-size: 11px; margin-left: 8px;
1072 1142 }
1073 1143 .alertes { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--ink-2); }
@@ -1076,29 +1146,27 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1076 1146 .pager {
1077 1147 display: flex; align-items: center; justify-content: space-between;
1078 1148 gap: 16px; flex-wrap: wrap; margin: 26px 0 10px; padding-top: 18px;
1079 − border-top: 2px solid var(--ink);
1149 + border-top: 1px solid var(--line);
1080 1150 }
1081 1151 .pager-info {
1082 − font-family: var(--font-mono); font-size: 12px; color: var(--ink-2);
1083 − letter-spacing: 0.04em;
1152 + font-size: 12.5px; color: var(--ink-2); letter-spacing: 0.02em;
1084 1153 }
1085 1154 .pager-info em { font-style: normal; color: var(--ink-3); }
1086 1155 .pager-nav { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
1087 1156 .pager-btn {
1088 1157 min-width: 38px; height: 38px; padding: 0 10px;
1089 1158 display: inline-flex; align-items: center; justify-content: center;
1090 − background: var(--surface); border: 1.5px solid var(--ink);
1091 − border-radius: var(--r-ctl); cursor: pointer;
1092 − font-family: var(--font-mono); font-size: 13px; font-weight: 600;
1093 − color: var(--ink); transition: all 0.12s ease;
1159 + background: var(--surface); border: 1px solid var(--line-strong);
1160 + border-radius: var(--r-pill); cursor: pointer;
1161 + font-size: 13px; font-weight: 600;
1162 + color: var(--navy); transition: all 0.12s ease;
1094 1163 }
1095 1164 .pager-btn:hover:not(:disabled):not(.on) {
1096 − background: var(--lime-soft); transform: translate(-1px, -1px);
1097 − box-shadow: 3px 3px 0 var(--ink);
1165 + background: var(--blue-soft); border-color: var(--blue); color: var(--blue);
1098 1166 }
1099 −.pager-btn.on { background: var(--ink); color: var(--lime); cursor: default; }
1100 −.pager-btn:disabled { opacity: 0.35; cursor: not-allowed; border-color: var(--line-strong); }
1101 −.pager-ellipsis { color: var(--ink-3); font-family: var(--font-mono); padding: 0 2px; }
1167 +.pager-btn.on { background: var(--navy); border-color: var(--navy); color: var(--white); cursor: default; }
1168 +.pager-btn:disabled { opacity: 0.35; cursor: not-allowed; }
1169 +.pager-ellipsis { color: var(--ink-3); padding: 0 2px; }
1102 1170 .map-list .pager { margin: 10px 0 4px; }
1103 1171 @media (max-width: 640px) {
1104 1172 .pager { justify-content: center; }
@@ -1121,117 +1189,119 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1121 1189 .mv-noimg { display: flex; align-items: center; justify-content: center; color: var(--ink-3); }
1122 1190
1123 1191 /* footer — liens (Groupe KA, courriels, mentions légales) */
1124 −.footer .frow a { color: var(--paper); text-decoration: underline; text-decoration-color: rgba(217,242,107,0.5); text-underline-offset: 3px; }
1125 −.footer .frow a:hover { color: var(--lime); }
1126 −.footer .fmono a:hover { color: var(--lime); }
1192 +.footer .frow a { color: var(--white); text-decoration: underline; text-decoration-color: rgba(255, 106, 0, 0.5); text-underline-offset: 3px; }
1193 +.footer .frow a:hover { color: var(--orange); }
1194 +.footer .fmono a:hover { color: var(--orange); }
1127 1195
1128 1196 /* ================= Compte (connexion Google) ================= */
1129 1197 .login-btn {
1130 1198 display: inline-flex; align-items: center; gap: 8px;
1131 − padding: 8px 15px; margin-left: 10px; min-height: 38px;
1132 − background: var(--surface); border: 1.5px solid var(--ink);
1133 − border-radius: 999px; font-weight: 600; font-size: 13.5px; color: var(--ink);
1199 + padding: 8px 16px; margin-left: 10px; min-height: 38px;
1200 + background: var(--navy); border: none;
1201 + border-radius: var(--r-pill); font-weight: 600; font-size: 13.5px; color: var(--white);
1134 1202 transition: all 0.12s ease; white-space: nowrap;
1203 + box-shadow: 0 4px 14px rgba(11, 19, 48, 0.22);
1135 1204 }
1136 −.login-btn:hover { transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--ink); background: var(--lime-soft); }
1205 +.login-btn:hover { background: var(--blue); }
1137 1206 .account { position: relative; margin-left: 10px; }
1138 1207 .account-btn {
1139 − width: 38px; height: 38px; padding: 0; border: 2px solid var(--ink);
1140 − border-radius: 999px; overflow: hidden; cursor: pointer;
1141 − background: var(--lime); display: flex; align-items: center; justify-content: center;
1208 + width: 38px; height: 38px; padding: 0; border: 2px solid var(--orange);
1209 + border-radius: var(--r-pill); overflow: hidden; cursor: pointer;
1210 + background: var(--orange-soft); display: flex; align-items: center; justify-content: center;
1142 1211 }
1143 1212 .account-btn img { width: 100%; height: 100%; object-fit: cover; }
1144 −.account-initial { font-family: var(--font-display); font-weight: 700; font-size: 16px; color: var(--ink); }
1213 +.account-initial { font-family: var(--font-display); font-weight: 700; font-size: 16px; color: var(--orange); }
1145 1214 .account-backdrop { position: fixed; inset: 0; z-index: 90; }
1146 1215 .account-menu {
1147 1216 position: absolute; right: 0; top: calc(100% + 10px); z-index: 91;
1148 − min-width: 220px; background: var(--surface); border: 2px solid var(--ink);
1217 + min-width: 220px; background: var(--surface); border: 1px solid var(--line);
1149 1218 border-radius: var(--r-card); box-shadow: var(--shadow-off); overflow: hidden;
1150 1219 }
1151 −.account-id { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border-bottom: 1.5px solid var(--line); }
1220 +.account-id { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
1152 1221 .account-id b { font-size: 14px; }
1153 −.account-id span { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); word-break: break-all; }
1222 +.account-id span { font-size: 11.5px; color: var(--ink-3); word-break: break-all; }
1154 1223 .account-menu button {
1155 1224 width: 100%; text-align: left; padding: 11px 14px; border: 0; cursor: pointer;
1156 1225 background: transparent; font-weight: 600; font-size: 13.5px; color: var(--danger);
1157 1226 }
1158 −.account-menu button:hover { background: var(--lime-soft); color: var(--ink); }
1227 +.account-menu button:hover { background: var(--orange-soft); color: var(--navy); }
1159 1228 @media (max-width: 640px) { .login-btn { padding: 8px 12px; font-size: 12.5px; } }
1160 1229
1161 1230 /* ================= Profil — carte de membre Groupe KA ================= */
1162 1231 .profil { padding-top: 40px; padding-bottom: 60px; }
1163 −.profil h1 { font-size: clamp(30px, 5vw, 44px); margin: 10px 0 26px; }
1164 −.profil h1 .hl { background: var(--lime); padding: 0 8px; }
1232 +.profil h1 { font-size: clamp(30px, 5vw, 44px); margin: 10px 0 26px; color: var(--navy); }
1233 +.profil h1 .hl { color: var(--orange); }
1165 1234 .profil .lede { max-width: 520px; color: var(--ink-2); margin-bottom: 22px; }
1166 1235
1167 1236 .pc {
1168 1237 position: relative; max-width: 520px; overflow: hidden;
1169 − background: var(--ink); color: var(--paper);
1170 − border: 2px solid var(--ink); border-radius: 16px;
1171 − padding: 24px 26px 0; box-shadow: 10px 10px 0 rgba(20, 24, 20, 0.18);
1238 + background: linear-gradient(135deg, #101a40 0%, var(--navy) 55%, #080e24 100%);
1239 + color: var(--white);
1240 + border-radius: 20px;
1241 + padding: 24px 26px 0; box-shadow: var(--shadow-off);
1172 1242 }
1173 1243 .pc-watermark {
1174 1244 position: absolute; right: -18px; top: -34px; pointer-events: none;
1175 1245 font-family: var(--font-display); font-weight: 700; font-size: 170px;
1176 − letter-spacing: -0.06em; color: rgba(217, 242, 107, 0.07);
1246 + letter-spacing: -0.06em; color: rgba(255, 106, 0, 0.07);
1177 1247 transform: rotate(-8deg); line-height: 1;
1178 1248 }
1179 1249 .pc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
1180 −.pc-brand { font-family: var(--font-display); font-weight: 700; font-size: 24px; letter-spacing: -0.04em; }
1181 −.pc-ka { background: var(--lime); color: var(--ink); padding: 1px 6px 3px; border-radius: 5px; margin-left: 3px; display: inline-block; transform: rotate(-2deg); }
1182 −.pc-label { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.16em; color: rgba(245, 243, 238, 0.55); }
1250 +.pc-brand { font-family: var(--font-display); font-weight: 700; font-size: 24px; letter-spacing: -0.03em; }
1251 +.pc-ka { color: var(--orange); margin-left: 1px; display: inline-block; }
1252 +.pc-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.16em; color: rgba(255, 255, 255, 0.5); }
1183 1253 .pc-id-block { margin: 26px 0 22px; display: flex; flex-direction: column; gap: 4px; }
1184 −.pc-id-label { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.2em; color: rgba(217, 242, 107, 0.65); }
1254 +.pc-id-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.2em; color: rgba(255, 106, 0, 0.75); }
1185 1255 .pc-id {
1186 − font-family: var(--font-mono); font-weight: 700; color: var(--lime);
1256 + font-weight: 700; color: var(--orange);
1187 1257 font-size: clamp(22px, 6vw, 34px); letter-spacing: 0.14em;
1188 − text-shadow: 0 0 24px rgba(217, 242, 107, 0.35);
1258 + text-shadow: 0 0 24px rgba(255, 106, 0, 0.35);
1189 1259 }
1190 1260 .pc-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; padding-bottom: 18px; }
1191 1261 .pc-holder { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
1192 1262 .pc-holder-name { font-weight: 600; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1193 −.pc-holder-since { font-family: var(--font-mono); font-size: 10.5px; color: rgba(245, 243, 238, 0.5); letter-spacing: 0.06em; }
1263 +.pc-holder-since { font-size: 10.5px; color: rgba(255, 255, 255, 0.5); letter-spacing: 0.06em; }
1194 1264 .pc-role-badge {
1195 1265 display: inline-block; width: fit-content; margin: 3px 0 2px;
1196 − background: var(--lime); color: var(--ink);
1197 − font-family: var(--font-mono); font-size: 9px; font-weight: 700;
1266 + background: var(--orange); color: var(--white);
1267 + font-size: 9px; font-weight: 700;
1198 1268 text-transform: uppercase; letter-spacing: 0.12em;
1199 − padding: 2px 7px 3px; border-radius: 5px; transform: rotate(-1deg);
1269 + padding: 2px 8px 3px; border-radius: var(--r-pill);
1200 1270 }
1201 −.pc-avatar { width: 52px; height: 52px; border-radius: 999px; border: 2px solid var(--lime); flex: none; }
1202 −.pc-strip { display: flex; gap: 5px; margin: 0 -26px; padding: 9px 18px; background: rgba(217, 242, 107, 0.1); border-top: 1px solid rgba(217, 242, 107, 0.25); overflow: hidden; }
1203 −.pc-strip i { display: block; width: 3px; border-radius: 1px; background: var(--lime); opacity: 0.7; }
1271 +.pc-avatar { width: 52px; height: 52px; border-radius: var(--r-pill); border: 2px solid var(--orange); flex: none; }
1272 +.pc-strip { display: flex; gap: 5px; margin: 0 -26px; padding: 9px 18px; background: rgba(255, 106, 0, 0.1); border-top: 1px solid rgba(255, 106, 0, 0.25); overflow: hidden; }
1273 +.pc-strip i { display: block; width: 3px; border-radius: 1px; background: var(--orange); opacity: 0.7; }
1204 1274 .pc-strip i:nth-child(3n) { height: 14px; opacity: 0.35; }
1205 1275 .pc-strip i:nth-child(3n+1) { height: 9px; }
1206 1276 .pc-strip i:nth-child(3n+2) { height: 17px; opacity: 0.9; }
1207 1277 .pc-copy { margin-top: 16px; }
1208 −.pc-copy.ok { background: var(--lime); border-color: var(--ink); color: var(--ink); }
1278 +.pc-copy.ok { background: var(--blue); color: var(--white); }
1209 1279
1210 1280 .profil-grid {
1211 1281 display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
1212 1282 gap: 12px; margin-top: 30px; max-width: 760px;
1213 1283 }
1214 1284 .pg-item {
1215 − background: var(--surface); border: 1.5px solid var(--ink);
1285 + background: var(--surface); border: 1px solid var(--line);
1216 1286 border-radius: var(--r-card); padding: 14px 16px;
1217 1287 display: flex; flex-direction: column; gap: 4px; box-shadow: var(--shadow-flat);
1218 1288 }
1219 −.pg-label { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-3); }
1289 +.pg-label { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3); }
1220 1290 .pg-value { font-weight: 600; font-size: 14.5px; word-break: break-word; }
1221 −.pg-value.mono { font-family: var(--font-mono); color: var(--green-deep); }
1291 +.pg-value.mono { color: var(--blue); }
1222 1292
1223 1293 .profil-note { max-width: 640px; color: var(--ink-2); font-size: 13.5px; margin-top: 22px; }
1224 1294 .profil-note a { text-decoration: underline; text-underline-offset: 3px; }
1225 1295 .profil-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 26px; }
1226 1296 .profil-actions .btn { display: inline-flex; align-items: center; gap: 7px; }
1227 1297
1228 −.account-kaid { font-family: var(--font-mono); font-size: 10.5px; color: var(--green); letter-spacing: 0.08em; }
1298 +.account-kaid { font-size: 10.5px; color: var(--blue); letter-spacing: 0.08em; }
1229 1299 .account-link {
1230 1300 display: block; width: 100%; text-align: left; padding: 11px 14px;
1231 − font-weight: 600; font-size: 13.5px; color: var(--ink);
1232 − border-bottom: 1.5px solid var(--line);
1301 + font-weight: 600; font-size: 13.5px; color: var(--navy);
1302 + border-bottom: 1px solid var(--line);
1233 1303 }
1234 −.account-link:hover { background: var(--lime-soft); }
1304 +.account-link:hover { background: var(--orange-soft); }
1235 1305
1236 1306 /* profil public — section + lien partageable */
1237 1307 .profil-public { margin-top: 30px; max-width: 640px; }
@@ -1239,51 +1309,56 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1239 1309 .profil-public p { color: var(--ink-2); font-size: 13.5px; margin: 0 0 12px; }
1240 1310 .public-link {
1241 1311 display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
1242 − margin-top: 14px; padding: 12px 14px; background: var(--lime-soft);
1243 − border: 1.5px solid var(--green); border-radius: var(--r-card);
1312 + margin-top: 14px; padding: 12px 14px; background: var(--blue-soft);
1313 + border: 1px solid rgba(34, 88, 255, 0.25); border-radius: var(--r-card);
1244 1314 }
1245 −.public-link a { font-size: 13px; color: var(--green-deep); text-decoration: underline; text-underline-offset: 3px; word-break: break-all; }
1315 +.public-link a { font-size: 13px; color: var(--blue); text-decoration: underline; text-underline-offset: 3px; word-break: break-all; }
1246 1316
1247 1317 /* ================= Bienvenue — choix du rôle ================= */
1248 1318 .bienvenue { padding-top: 44px; padding-bottom: 70px; }
1249 −.bienvenue h1 { font-size: clamp(30px, 5vw, 46px); margin: 10px 0 14px; }
1250 −.bienvenue h1 .hl { background: var(--lime); padding: 0 8px; }
1319 +.bienvenue h1 { font-size: clamp(30px, 5vw, 46px); margin: 10px 0 14px; color: var(--navy); }
1320 +.bienvenue h1 .hl { color: var(--orange); }
1251 1321 .bienvenue .lede { max-width: 480px; color: var(--ink-2); margin-bottom: 30px; }
1252 1322 .role-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 18px; max-width: 780px; }
1253 1323 .role-card {
1254 1324 display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
1255 1325 text-align: left; padding: 24px 24px 20px; cursor: pointer;
1256 − background: var(--surface); border: 2px solid var(--ink);
1326 + background: var(--surface); border: 1px solid var(--line);
1257 1327 border-radius: var(--r-card); box-shadow: var(--shadow-flat);
1258 1328 font-family: var(--font-body); transition: all 0.15s ease;
1259 1329 }
1260 −.role-card:hover:not(:disabled) { transform: translate(-3px, -3px); box-shadow: var(--shadow-off); background: var(--lime-soft); }
1330 +.role-card:hover:not(:disabled) { transform: translateY(-4px); box-shadow: var(--shadow-off); border-color: rgba(255, 106, 0, 0.4); }
1261 1331 .role-card:disabled { opacity: 0.6; cursor: wait; }
1262 −.role-ico { display: flex; width: 54px; height: 54px; align-items: center; justify-content: center; background: var(--ink); color: var(--lime); border-radius: 12px; }
1263 −.role-title { font-family: var(--font-display); font-weight: 700; font-size: 19px; letter-spacing: -0.02em; }
1332 +.role-ico { display: flex; width: 54px; height: 54px; align-items: center; justify-content: center; background: var(--orange-soft); color: var(--orange); border-radius: 16px; }
1333 +.role-title { font-family: var(--font-display); font-weight: 700; font-size: 19px; letter-spacing: -0.02em; color: var(--navy); }
1264 1334 .role-desc { color: var(--ink-2); font-size: 13.5px; }
1265 1335 .role-perks { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
1266 −.role-perks li { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-2); }
1267 −.role-perks li::before { content: "◆"; color: var(--green); font-size: 8px; }
1268 −.role-cta { margin-top: 10px; font-family: var(--font-mono); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--green-deep); }
1336 +.role-perks li { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-2); }
1337 +.role-perks li::before {
1338 + content: "✓"; flex: none; width: 16px; height: 16px; border-radius: 50%;
1339 + background: var(--orange); color: var(--white); font-size: 10px; font-weight: 700;
1340 + display: inline-flex; align-items: center; justify-content: center;
1341 +}
1342 +.role-cta { margin-top: 10px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--orange); }
1269 1343
1270 1344 /* ================= Favoris — cœur sur les cartes ================= */
1271 1345 .fav-btn {
1272 1346 position: absolute; right: 10px; bottom: 10px; z-index: 2;
1273 1347 width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
1274 − background: rgba(255, 255, 255, 0.94); border: 1.5px solid var(--ink);
1275 − border-radius: 999px; cursor: pointer; color: var(--ink);
1276 − transition: transform 0.12s ease, background 0.12s ease;
1348 + background: rgba(255, 255, 255, 0.94); border: none;
1349 + border-radius: var(--r-pill); cursor: pointer; color: var(--navy);
1350 + box-shadow: var(--shadow-flat);
1351 + transition: transform 0.12s ease, background 0.12s ease, color 0.12s ease;
1277 1352 }
1278 1353 .fav-btn:hover { transform: scale(1.12); }
1279 −.fav-btn.on { background: var(--lime); color: var(--danger); }
1280 −.fav-btn.on svg { filter: drop-shadow(0 0 3px rgba(179, 66, 58, 0.35)); }
1354 +.fav-btn.on { background: var(--white); color: var(--orange); }
1355 +.fav-btn.on svg { filter: drop-shadow(0 0 3px rgba(255, 106, 0, 0.35)); }
1281 1356
1282 1357 /* ================= Espace gestionnaire ================= */
1283 1358 .claim-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; max-width: 640px; }
1284 1359 .claim-row select {
1285 − flex: 1; min-width: 260px; padding: 11px 12px; font-size: 14px;
1286 − border: 1.5px solid var(--ink); border-radius: var(--r-ctl);
1360 + flex: 1; min-width: 260px; padding: 11px 14px; font-size: 14px;
1361 + border: 1px solid var(--line-strong); border-radius: var(--r-ctl);
1287 1362 background: var(--surface); font-family: var(--font-body);
1288 1363 }
1289 1364 .claim-error { color: var(--danger); font-size: 13.5px; font-weight: 600; margin-top: 10px; }
@@ -1292,54 +1367,54 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1292 1367 .org-form { max-width: 640px; display: flex; flex-direction: column; gap: 14px; }
1293 1368 .org-form h3 { font-size: 18px; }
1294 1369 .org-form label { display: flex; flex-direction: column; gap: 5px; flex: 1; }
1295 −.org-form label span { font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3); }
1370 +.org-form label span { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); }
1296 1371 .org-form input, .org-form textarea {
1297 − padding: 10px 12px; font-size: 14px; font-family: var(--font-body);
1298 − border: 1.5px solid var(--ink); border-radius: var(--r-ctl); background: var(--surface);
1372 + padding: 10px 14px; font-size: 14px; font-family: var(--font-body);
1373 + border: 1px solid var(--line-strong); border-radius: var(--r-ctl); background: var(--surface);
1299 1374 }
1300 1375 .org-form textarea { resize: vertical; }
1301 −.org-form input:focus, .org-form textarea:focus { outline: 2px solid var(--lime); outline-offset: 1px; }
1376 +.org-form input:focus, .org-form textarea:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(34, 88, 255, 0.15); }
1302 1377 .org-form-row { display: flex; gap: 12px; flex-wrap: wrap; }
1303 1378 .org-form .btn { align-self: flex-start; }
1304 1379
1305 1380 /* ================= Page publique /g/{source} ================= */
1306 1381 .orgpub-head { display: flex; gap: 20px; align-items: flex-start; margin-top: 8px; }
1307 −.orgpub-logo { width: 84px; height: 84px; object-fit: contain; background: var(--surface); border: 2px solid var(--ink); border-radius: 14px; padding: 8px; flex: none; }
1308 −.orgpub-id h1 { font-size: clamp(26px, 4.4vw, 40px); margin: 6px 0 8px; }
1382 +.orgpub-logo { width: 84px; height: 84px; object-fit: contain; background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: 8px; flex: none; box-shadow: var(--shadow-flat); }
1383 +.orgpub-id h1 { font-size: clamp(26px, 4.4vw, 40px); margin: 6px 0 8px; color: var(--navy); }
1309 1384 .orgpub-tagline { font-size: 16px; color: var(--ink-2); margin: 0 0 12px; max-width: 640px; }
1310 1385 .orgpub-meta { display: flex; gap: 8px; flex-wrap: wrap; }
1311 −.orgpub-meta a.stat-chip:hover { background: var(--lime-soft); }
1312 −.orgpub-verified { background: var(--lime); border-color: var(--ink); font-weight: 600; }
1386 +.orgpub-meta a.stat-chip:hover { background: var(--blue-soft); }
1387 +.orgpub-verified { background: var(--blue-soft); border-color: rgba(34, 88, 255, 0.3); color: var(--blue); font-weight: 600; }
1313 1388 .orgpub-desc { max-width: 720px; color: var(--ink-2); margin: 18px 0 6px; white-space: pre-line; }
1314 1389 .orgpub .results-head h2 { display: inline-flex; align-items: center; gap: 8px; }
1315 1390 @media (max-width: 560px) { .orgpub-head { flex-direction: column; } }
1316 1391
1317 1392 /* ================= Éditeur de profil (photo, bio, réseaux) ================= */
1318 −.profil-edit { margin-top: 34px; padding-top: 24px; border-top: 2px solid var(--ink); }
1393 +.profil-edit { margin-top: 34px; padding-top: 24px; border-top: 1px solid var(--line-strong); }
1319 1394 /* profil géré au hub Groupe KA — lecture seule */
1320 1395 .hub-profile .hub-bio { color: var(--ink-2); font-size: 14px; margin: 0; max-width: 560px; }
1321 1396 .hub-profile .pub-meta { display: flex; gap: 8px; flex-wrap: wrap; }
1322 1397 .hub-profile .stat-chip { display: inline-flex; align-items: center; gap: 6px; }
1323 −.hub-profile a.stat-chip:hover { background: var(--lime-soft); }
1398 +.hub-profile a.stat-chip:hover { background: var(--blue-soft); }
1324 1399 .hub-profile .btn-primary { display: inline-flex; align-items: center; gap: 7px; }
1325 1400 .pe-avatar-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
1326 1401 .pe-avatar {
1327 − width: 84px; height: 84px; border-radius: 999px; object-fit: cover;
1328 − border: 2.5px solid var(--ink); box-shadow: 4px 4px 0 rgba(20,24,20,0.15);
1402 + width: 84px; height: 84px; border-radius: var(--r-pill); object-fit: cover;
1403 + border: 2.5px solid var(--orange); box-shadow: var(--shadow-flat);
1329 1404 display: flex; align-items: center; justify-content: center;
1330 1405 }
1331 −.pe-avatar-empty { background: var(--lime); font-family: var(--font-display); font-weight: 700; font-size: 34px; }
1406 +.pe-avatar-empty { background: var(--orange-soft); color: var(--orange); font-family: var(--font-display); font-weight: 700; font-size: 34px; }
1332 1407 .pe-avatar-actions { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
1333 1408 .pe-avatar-actions .btn { display: inline-flex; align-items: center; gap: 7px; }
1334 −.pe-hint { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3); }
1409 +.pe-hint { font-size: 11px; color: var(--ink-3); }
1335 1410 .pe-socials-title { font-size: 15px; margin-top: 6px; }
1336 1411 .pe-socials { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
1337 1412 .pe-social { display: flex !important; flex-direction: row !important; align-items: center; gap: 0 !important; }
1338 1413 .pe-social-ico {
1339 1414 display: flex; align-items: center; justify-content: center;
1340 1415 width: 40px; align-self: stretch; flex: none;
1341 − background: var(--ink); color: var(--lime);
1342 − border: 1.5px solid var(--ink); border-radius: var(--r-ctl) 0 0 var(--r-ctl);
1416 + background: var(--navy); color: var(--white);
1417 + border-radius: var(--r-ctl) 0 0 var(--r-ctl);
1343 1418 }
1344 1419 .pe-social input { flex: 1; border-radius: 0 var(--r-ctl) var(--r-ctl) 0; border-left: 0; }
1345 1420
@@ -1351,60 +1426,60 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1351 1426 .pub-social {
1352 1427 display: flex; align-items: center; justify-content: center;
1353 1428 width: 44px; height: 44px; background: var(--surface);
1354 − border: 2px solid var(--ink); border-radius: 12px; color: var(--ink);
1429 + border: 1px solid var(--line-strong); border-radius: 14px; color: var(--navy);
1355 1430 transition: all 0.12s ease;
1356 1431 }
1357 −.pub-social:hover { background: var(--ink); color: var(--lime); transform: translate(-2px, -2px); box-shadow: 4px 4px 0 rgba(20,24,20,0.25); }
1432 +.pub-social:hover { background: var(--navy); border-color: var(--navy); color: var(--white); transform: translateY(-2px); box-shadow: var(--shadow-off-soft); }
1358 1433
1359 1434 /* -----------------------------------------------------------------------------
1360 1435 Lou-Ka Maps (framework Ka Maps par Groupe Ka)
1361 1436 Jetons du design system appliqués au chrome de la carte + sync liste↔carte.
1362 1437 ----------------------------------------------------------------------------- */
1363 1438 .mapview .ka-map {
1364 − --ka-accent: var(--ink);
1365 − --ka-on-accent: var(--lime);
1439 + --ka-accent: var(--blue);
1440 + --ka-on-accent: var(--white);
1366 1441 --ka-surface: var(--surface);
1367 − --ka-ink: var(--ink);
1442 + --ka-ink: var(--navy);
1368 1443 --ka-line: var(--line-strong);
1369 1444 --ka-radius: var(--r-ctl);
1370 − --ka-shadow: 4px 4px 0 rgba(20, 24, 20, 0.18);
1445 + --ka-shadow: 0 8px 24px rgba(11, 19, 48, 0.14);
1371 1446 --ka-font: var(--font-body);
1372 1447 }
1373 1448 .mapview { position: relative; overflow: hidden; }
1374 1449 .mapview .ka-map { position: absolute; inset: 0; }
1375 1450
1376 −/* mini-carte 3D de la fiche (Emplacement) — bâtiment de l'annonce en rouge */
1451 +/* mini-carte 3D de la fiche (Emplacement) — bâtiment de l'annonce en orange */
1377 1452 .lmap3d {
1378 − position: relative; height: 340px; border: 1.5px solid var(--line-strong);
1453 + position: relative; height: 340px; border: 1px solid var(--line);
1379 1454 border-radius: var(--r-card); box-shadow: var(--shadow-off-soft);
1380 − overflow: hidden; background: var(--surface-2);
1455 + overflow: hidden; background: var(--grey);
1381 1456 }
1382 1457 .lmap3d .ka-map {
1383 − --ka-accent: var(--ink);
1384 − --ka-on-accent: var(--lime);
1458 + --ka-accent: var(--blue);
1459 + --ka-on-accent: var(--white);
1385 1460 --ka-surface: var(--surface);
1386 − --ka-ink: var(--ink);
1461 + --ka-ink: var(--navy);
1387 1462 --ka-line: var(--line-strong);
1388 1463 --ka-radius: var(--r-ctl);
1389 − --ka-shadow: 4px 4px 0 rgba(20, 24, 20, 0.18);
1464 + --ka-shadow: 0 8px 24px rgba(11, 19, 48, 0.14);
1390 1465 --ka-font: var(--font-body);
1391 1466 position: absolute; inset: 0;
1392 1467 }
1393 1468 .lmap3d-skel {
1394 − background: linear-gradient(90deg, #eeece5 25%, #f7f5ef 50%, #eeece5 75%);
1469 + background: linear-gradient(90deg, #ececef 25%, #f7f7f9 50%, #ececef 75%);
1395 1470 background-size: 800px 100%; animation: shimmer 1.4s infinite linear;
1396 1471 }
1397 1472 .lmap3d-legende {
1398 1473 position: absolute; left: 10px; bottom: 10px; z-index: 5;
1399 1474 display: inline-flex; align-items: center; gap: 6px;
1400 − padding: 4px 9px; border: 1.5px solid var(--line-strong);
1401 − border-radius: var(--r-ctl); background: var(--surface);
1402 − font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-2);
1475 + padding: 4px 10px; border: 1px solid var(--line);
1476 + border-radius: var(--r-pill); background: var(--surface);
1477 + font-size: 10.5px; font-weight: 500; color: var(--ink-2);
1403 1478 pointer-events: none;
1404 1479 }
1405 1480 .lmap3d-legende i {
1406 1481 width: 10px; height: 10px; border-radius: 3px;
1407 − background: #e03131; border: 1px solid rgba(20, 24, 20, 0.35);
1482 + background: var(--orange); border: 1px solid rgba(11, 19, 48, 0.25);
1408 1483 }
1409 1484 @media (max-width: 780px) { .lmap3d { height: 280px; } }
1410 1485 .ka-preview .mv-pop img, .ka-preview .mv-noimg { height: 120px; }
@@ -1413,4 +1488,4 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1413 1488
1414 1489 /* carte de liste synchronisée avec la carte (survol / sélection) */
1415 1490 .map-card { border-radius: var(--r-card); }
1416 −.map-card-sel { outline: 2px solid var(--ink); outline-offset: 2px; }
1491 +.map-card-sel { outline: 2px solid var(--blue); outline-offset: 2px; }
modified frontend/tsconfig.tsbuildinfo +1 −1
@@ -1 +1 @@
1 −{"root":["./src/app.tsx","./src/account.tsx","./src/api.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/cookieconsent.tsx","./src/components/icons.tsx","./src/components/listingcard.tsx","./src/components/listingmap3d.tsx","./src/components/mapview.tsx","./src/components/pager.tsx","./src/components/quartierblock.tsx","./src/kamaps/adapter.ts","./src/kamaps/config.ts","./src/kamaps/theme.ts","./src/pages/bienvenue.tsx","./src/pages/bot.tsx","./src/pages/favoris.tsx","./src/pages/gestion.tsx","./src/pages/gestionpublic.tsx","./src/pages/home.tsx","./src/pages/listing.tsx","./src/pages/passerelle.tsx","./src/pages/privacy.tsx","./src/pages/profile.tsx","./src/pages/publicprofile.tsx","./src/pages/sources.tsx","./src/pages/stats.tsx","./src/pages/terms.tsx","./src/pages/ville.tsx"],"version":"5.9.3"}
\ No newline at end of file
1 +{"root":["./src/app.tsx","./src/account.tsx","./src/api.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/cookieconsent.tsx","./src/components/icons.tsx","./src/components/listingcard.tsx","./src/components/listingmap3d.tsx","./src/components/logo.tsx","./src/components/mapview.tsx","./src/components/pager.tsx","./src/components/quartierblock.tsx","./src/kamaps/adapter.ts","./src/kamaps/config.ts","./src/kamaps/theme.ts","./src/pages/bienvenue.tsx","./src/pages/bot.tsx","./src/pages/favoris.tsx","./src/pages/gestion.tsx","./src/pages/gestionpublic.tsx","./src/pages/home.tsx","./src/pages/listing.tsx","./src/pages/passerelle.tsx","./src/pages/privacy.tsx","./src/pages/profile.tsx","./src/pages/publicprofile.tsx","./src/pages/sources.tsx","./src/pages/stats.tsx","./src/pages/terms.tsx","./src/pages/ville.tsx"],"version":"5.9.3"}
\ No newline at end of file
modified louka/pdfgen.py +15 −15
@@ -1,14 +1,14 @@
1 1 # -----------------------------------------------------------------------------
2 2 # Lou-Ka — Agrégateur de logements à louer (province de Québec)
3 3 # Auteur : Simon-Pierre Boucher — contact@spboucher.ai
4 −# pdfgen.py : génération PDF au style « éditorial sharp » de Lou-Ka
4 +# pdfgen.py : génération PDF à l'identité visuelle officielle Lou-Ka
5 5 # - fiche_pdf(uid) : fiche de propriété (photos, prix + badge marché, chips,
6 6 # description structurée, inclusions, quartier, à proximité, QR code)
7 7 # - rapport_pdf() : rapport global du marché (totaux, régions, histogramme
8 8 # des loyers, types, villes, gestionnaires)
9 −# Palette identique au site : crème #f5f3ee, encre #141814, lime #d9f26b,
10 −# vert #1c5c41. Polices de base (Helvetica/Courier) stylées par la mise en
11 −# page — aucune dépendance de police externe.
9 +# Palette identique au site : blanc #ffffff, marine #0b1330, orange #ff6a00,
10 +# bleu vif #2258ff, gris pâle #f2f2f2. Polices de base (Helvetica) stylées
11 +# par la mise en page — aucune dépendance de police externe.
12 12 # -----------------------------------------------------------------------------
13 13 from __future__ import annotations
14 14
@@ -26,18 +26,18 @@ from reportlab.pdfgen import canvas as rl_canvas
26 26
27 27 from . import db
28 28
29 −# --- palette Lou-Ka ---------------------------------------------------------
30 −PAPER = HexColor("#f5f3ee")
29 +# --- palette Lou-Ka (identité officielle) ------------------------------------
30 +PAPER = HexColor("#ffffff")
31 31 SURFACE = HexColor("#ffffff")
32 −INK = HexColor("#141814")
33 −INK2 = HexColor("#4d5551")
34 −INK3 = HexColor("#8b928c")
35 −GREEN = HexColor("#1c5c41")
36 −GREEN_DEEP = HexColor("#123f2e")
37 −LIME = HexColor("#d9f26b")
38 −LIME_SOFT = HexColor("#f0f9d2")
39 −AMBER = HexColor("#e8a33d")
40 −AMBER_SOFT = HexColor("#fdf3e2")
32 +INK = HexColor("#0b1330") # bleu marine profond
33 +INK2 = HexColor("#3e4560")
34 +INK3 = HexColor("#8a90a5")
35 +GREEN = HexColor("#2258ff") # accent secondaire : bleu vif
36 +GREEN_DEEP = HexColor("#0b1330")
37 +LIME = HexColor("#ff6a00") # accent d'action : orange vif
38 +LIME_SOFT = HexColor("#fff1e6")
39 +AMBER = HexColor("#ff6a00")
40 +AMBER_SOFT = HexColor("#fff1e6")
41 41
42 42 PAGE_W, PAGE_H = letter
43 43 M = 40 # marge
modified louka/seo.py +1 −1
@@ -120,7 +120,7 @@ def _render(*, title: str, description: str, path: str, jsonld: list[dict] | Non
120 120 page = page.replace("</head>", " " + "\n ".join(extras) + "\n</head>", 1)
121 121 if body:
122 122 seo_div = ('<div style="max-width:960px;margin:0 auto;padding:24px;'
123 − 'font-family:system-ui,sans-serif;color:#141814">' + body + "</div>")
123 + 'font-family:system-ui,sans-serif;color:#0B1330">' + body + "</div>")
124 124 page = page.replace('<div id="root">', '<div id="root">' + seo_div, 1)
125 125 return HTMLResponse(page, status_code=status,
126 126 headers={"Cache-Control": "no-cache"})
127 127