SPB Git

spb/lou-ka

Public

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

Logo officiel Lou-Ka selon les spécifications géométriques complètes (grille 100×100) : cadre squircle vertical 60×90 rx 19 en contour orange dégradé #FF7A1A→#F56000 (7,5 u, extrémités rondes), porte parallélogramme charnières à gauche ouverte ≈30° (fuite ≈9°, marine #101A3D→#0B1330, coins adoucis), coin de lumière s'élargissant vers le bas entre porte et cadre droit, tapis de lumière trapèze seuil≈30→avant≈49 u évasé vers l'avant-droite (#FF8533→#FF6A00, bord avant arrondi touchant le cadre), reflet spéculaire blanc 28 % + ombre portée douce marine 14 % (liquid glass) ; favicon barre d'URL et icône PWA en version FLAT (aplats purs, contour épaissi, carré marine arrondi) ; espace icône↔wordmark ≈40 % ; captures README refaites avec le logo final

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Aug 15, 2026) parent a9b9ef8 Browse files

13 changed files +73 −30

modified docs/screenshots/accueil-mobile.png +0 −0

Binary file not shown.

modified docs/screenshots/accueil.png +0 −0

Binary file not shown.

modified docs/screenshots/annonces.jpg +0 −0

Binary file not shown.

modified docs/screenshots/carte.jpg +0 −0

Binary file not shown.

modified docs/screenshots/fiche-logement.jpg +0 −0

Binary file not shown.

modified docs/screenshots/sources.png +0 −0

Binary file not shown.

modified docs/screenshots/stats.png +0 −0

Binary file not shown.

modified docs/screenshots/ville-quebec.jpg +0 −0

Binary file not shown.

modified docs/screenshots/villes.jpg +0 −0

Binary file not shown.

modified frontend/index.html +1 −1
@@ -18,7 +18,7 @@
18 <link rel="preconnect" href="https://fonts.googleapis.com" /> 18 <link rel="preconnect" href="https://fonts.googleapis.com" />
19 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> 19 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
20 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" /> 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" /> 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='14.6' y='5.9' width='34.8' height='52.2' rx='11' fill='none' stroke='%23FF6A00' stroke-width='5' stroke-linejoin='round'/%3E%3Cpath d='M19.8 12.9 L41.3 16.1 L39 45.6 L19.8 48.8 Z' fill='%23ffffff' stroke='%23ffffff' stroke-width='2' stroke-linejoin='round'/%3E%3Cpath d='M22 48.2 L39.5 45.8 L45.5 55.9 L20 55.9 Z' fill='%23FF6A00'/%3E%3C/svg%3E" />
22 </head> 22 </head>
23 <body> 23 <body>
24 <div id="root"></div> 24 <div id="root"></div>
modified frontend/public/manifest.webmanifest +1 −1
@@ -9,7 +9,7 @@
9 "lang": "fr", 9 "lang": "fr",
10 "icons": [ 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='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", 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='117' y='47' width='278' height='418' rx='88' fill='none' stroke='%23FF6A00' stroke-width='40' stroke-linejoin='round'/%3E%3Cpath d='M158 103 L330 129 L312 365 L158 390 Z' fill='%23ffffff' stroke='%23ffffff' stroke-width='16' stroke-linejoin='round'/%3E%3Cpath d='M176 386 L316 366 L364 447 L160 447 Z' fill='%23FF6A00'/%3E%3C/svg%3E",
13 "sizes": "512x512", 13 "sizes": "512x512",
14 "type": "image/svg+xml", 14 "type": "image/svg+xml",
15 "purpose": "any" 15 "purpose": "any"
modified frontend/src/components/Logo.tsx +69 −26
@@ -1,60 +1,103 @@
1 // ----------------------------------------------------------------------------- 1 // -----------------------------------------------------------------------------
2 // Lou-Ka — Agrégateur de logements à louer (province de Québec) 2 // Lou-Ka — Agrégateur de logements à louer (province de Québec)
3 // Auteur : Simon-Pierre Boucher — contact@spboucher.ai 3 // Auteur : Simon-Pierre Boucher — contact@spboucher.ai
4−// components/Logo.tsx : icône officielle Lou-Ka — la porte d'entrée. 4+// components/Logo.tsx : icône officielle Lou-Ka — la porte entrouverte qui
5−// Cadre orange #FF6A00 aux coins très arrondis ; porte entrouverte bleu 5+// laisse entrer la lumière. Spécifications géométriques (grille 100 × 100) :
6−// marine #0B1330 en perspective (ouverture vers la droite) ; tapis de 6+// A. cadre : rect vertical 60 × 90 centré, rx 19 (squircle), contour seul
7−// lumière orange projeté au sol. Effet « liquid glass » subtil. 7+// 7,5 u, dégradé orange #FF7A1A → #F56000, extrémités arrondies ;
8+// B. porte : parallélogramme charnières à GAUCHE, ouverte ≈ 30° vers le
9+// spectateur, coins droits rapprochés verticalement (fuite ≈ 9°), marine
10+// #101A3D → #0B1330, coins adoucis ; coin de lumière (espace négatif)
11+// entre la porte et le cadre droit, s'élargissant vers le bas ;
12+// C. tapis de lumière : trapèze au seuil (≈ 30 u) s'évasant vers l'avant
13+// (≈ 49 u), bord avant arrondi touchant le trait bas du cadre,
14+// dégradé #FF8533 → #FF6A00.
15+// Ordre des calques : porte → tapis → cadre → reflet. Finition « liquid
16+// glass » : reflet blanc 28 % sur la courbe haute + ombre portée douce
17+// marine 14 %. Version flat (sans dégradés) : favicon + icône PWA.
8 // Baseline : « La porte d'entrée vers votre prochain chez-vous. » 18 // Baseline : « La porte d'entrée vers votre prochain chez-vous. »
9 // ----------------------------------------------------------------------------- 19 // -----------------------------------------------------------------------------
10 20
11−/** Icône seule (fond transparent — pour fonds clairs). */ 21+/** Icône seule (fond transparent — pour fonds clairs ; dark = porte blanche). */
12 export function LogoIcon({ size = 30, dark = false }: { size?: number; dark?: boolean }) { 22 export function LogoIcon({ size = 30, dark = false }: { size?: number; dark?: boolean }) {
13 // dark = version pour fond bleu marine : la porte devient blanche 23 // dark = version pour fond bleu marine : la porte devient blanche
14− const door = dark ? "#ffffff" : "#0b1330"; 24+ const doorTop = dark ? "#ffffff" : "#101a3d";
15− const doorTop = dark ? "#ffffff" : "#16204a"; 25+ const doorBot = dark ? "#e8edf8" : "#0b1330";
16 const uid = dark ? "lk-dark" : "lk-light-bg"; 26 const uid = dark ? "lk-dark" : "lk-light-bg";
17 return ( 27 return (
18 <svg 28 <svg
19 className="logo-ico" 29 className="logo-ico"
20 width={size} 30 width={size}
21 height={size} 31 height={size}
22− viewBox="0 0 64 64" 32+ viewBox="0 0 100 100"
23 fill="none" 33 fill="none"
24 aria-hidden="true" 34 aria-hidden="true"
25 > 35 >
26 <defs> 36 <defs>
37+ {/* cadre : orange plus lumineux en haut, plus saturé en bas */}
38+ <linearGradient id={`${uid}-frame`} x1="0" y1="0" x2="0" y2="1">
39+ <stop offset="0" stopColor="#ff7a1a" />
40+ <stop offset="1" stopColor="#f56000" />
41+ </linearGradient>
42+ {/* porte : micro-dégradé de profondeur */}
27 <linearGradient id={`${uid}-door`} x1="0" y1="0" x2="0" y2="1"> 43 <linearGradient id={`${uid}-door`} x1="0" y1="0" x2="0" y2="1">
28 <stop offset="0" stopColor={doorTop} /> 44 <stop offset="0" stopColor={doorTop} />
29− <stop offset="1" stopColor={door} /> 45+ <stop offset="1" stopColor={doorBot} />
30 </linearGradient> 46 </linearGradient>
31− <linearGradient id={`${uid}-light`} x1="0" y1="0" x2="1" y2="0"> 47+ {/* tapis : lumière chaude qui se diffuse vers l'avant */}
32− <stop offset="0" stopColor="#ff6a00" /> 48+ <linearGradient id={`${uid}-light`} x1="0" y1="0" x2="0" y2="1">
33− <stop offset="1" stopColor="#ff6a00" stopOpacity="0.72" /> 49+ <stop offset="0" stopColor="#ff8533" />
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" /> 50 <stop offset="1" stopColor="#ff6a00" />
38 </linearGradient> 51 </linearGradient>
52+ {/* ombre portée très douce, teinte marine — jamais d'ombre dure */}
53+ <filter id={`${uid}-soft`} x="-25%" y="-25%" width="150%" height="150%">
54+ <feDropShadow dx="0" dy="2" stdDeviation="3" floodColor="#0b1330" floodOpacity="0.14" />
55+ </filter>
39 </defs> 56 </defs>
40− {/* cadre : rectangle vertical, coins très arrondis, contour orange épais */} 57+ <g filter={`url(#${uid}-soft)`}>
41− <rect x="15" y="5" width="34" height="54" rx="10" stroke={`url(#${uid}-frame)`} strokeWidth="4.5" /> 58+ {/* B — porte entrouverte : charnière gauche, fuite en perspective à droite ;
42− {/* porte entrouverte : parallélogramme en perspective, bord droit plus proche */} 59+ le coin de lumière (espace vide) s'élargit vers le bas */}
43− <polygon points="22,13.5 37,10.5 37,52 22,48.5" fill={`url(#${uid}-door)`} /> 60+ <path
44− {/* reflet « liquid glass » sur la porte */} 61+ d="M29 17 L66 22.5 L62 73.5 L29 79 Z"
45− <polygon points="24,13.2 28,12.4 28,49 24,48.2" fill="#ffffff" opacity="0.08" /> 62+ fill={`url(#${uid}-door)`}
46− {/* lumière projetée au sol — tapis d'accueil */} 63+ stroke={`url(#${uid}-door)`}
47− <polygon points="22,48.5 37,52 44.5,55.8 22,55.8" fill={`url(#${uid}-light)`} /> 64+ strokeWidth="4"
65+ strokeLinejoin="round"
66+ />
67+ {/* C — tapis de lumière : du seuil vers l'avant-droite, bord avant arrondi
68+ qui touche le trait inférieur du cadre */}
69+ <path
70+ d="M37 77.4 L63 73.2 L74.8 88.5 Q76.4 92.5 71.6 92.5 L34.5 92.5 Q30.2 92.5 32 88.6 Z"
71+ fill={`url(#${uid}-light)`}
72+ />
73+ {/* A — cadre : contour seul, coins très arrondis (squircle vertical) */}
74+ <rect
75+ x="20" y="5" width="60" height="90" rx="19"
76+ stroke={`url(#${uid}-frame)`}
77+ strokeWidth="7.5"
78+ strokeLinecap="round"
79+ strokeLinejoin="round"
80+ />
81+ {/* reflet spéculaire « liquid glass » sur la courbe supérieure */}
82+ <path
83+ d="M31 6.8 Q50 4.4 69 6.8"
84+ stroke="#ffffff"
85+ strokeOpacity="0.28"
86+ strokeWidth="2.6"
87+ strokeLinecap="round"
88+ />
89+ </g>
48 </svg> 90 </svg>
49 ); 91 );
50 } 92 }
51 93
52−/** Wordmark complet : icône + « Lou-Ka » (Lou- marine, Ka orange). */ 94+/** Logo horizontal complet : icône + wordmark « Lou-Ka »
95+ * (Lou- marine, Ka orange ; espace icône↔texte ≈ 40 % de la largeur d'icône). */
53 export default function Logo({ size = 30 }: { size?: number }) { 96 export default function Logo({ size = 30 }: { size?: number }) {
54 return ( 97 return (
55− <span style={{ display: "inline-flex", alignItems: "center" }}> 98+ <span style={{ display: "inline-flex", alignItems: "center", gap: size * 0.4 * 0.6 }}>
56 <LogoIcon size={size} /> 99 <LogoIcon size={size} />
57− <span style={{ color: "#0b1330", fontWeight: 700 }}> 100+ <span style={{ color: "#0b1330", fontWeight: 700, letterSpacing: "-0.005em" }}>
58 Lou-<span style={{ color: "#ff6a00" }}>Ka</span> 101 Lou-<span style={{ color: "#ff6a00" }}>Ka</span>
59 </span> 102 </span>
60 </span> 103 </span>
modified frontend/src/styles.css +2 −2
@@ -104,7 +104,7 @@ h1 .hl, h2 .hl { color: var(--orange); }
104 letter-spacing: -0.03em; display: flex; align-items: center; line-height: 1; 104 letter-spacing: -0.03em; display: flex; align-items: center; line-height: 1;
105 color: var(--navy); 105 color: var(--navy);
106 } 106 }
107−.brand .logo-ico { margin-right: 9px; flex: none; } 107+.brand .logo-ico { margin-right: 12px; flex: none; } /* ≈ 40 % de la largeur de l'icône */
108 .brand .ka { color: var(--orange); } 108 .brand .ka { color: var(--orange); }
109 .brand-tag { 109 .brand-tag {
110 font-size: 11px; font-weight: 500; color: var(--ink-3); 110 font-size: 11px; font-weight: 500; color: var(--ink-3);
@@ -677,7 +677,7 @@ h1 .hl, h2 .hl { color: var(--orange); }
677 /* ================= Footer ================= */ 677 /* ================= Footer ================= */
678 .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; } 678 .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; }
679 .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; } 679 .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; }
680−.footer .fbrand .logo-ico { margin-right: 10px; } 680+.footer .fbrand .logo-ico { margin-right: 13px; }
681 .footer .fbrand .ka { color: var(--orange); } 681 .footer .fbrand .ka { color: var(--orange); }
682 .footer .fbaseline { color: rgba(255, 255, 255, 0.65); font-size: 14px; margin-bottom: 16px; } 682 .footer .fbaseline { color: rgba(255, 255, 255, 0.65); font-size: 14px; margin-bottom: 16px; }
683 .footer .fbaseline .hl { color: var(--orange); font-weight: 600; } 683 .footer .fbaseline .hl { color: var(--orange); font-weight: 600; }
684 684
Menu

Theme