État du nœud — captures README régénérées en prod + Logo.tsx ; gitignore data/uploads/
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
11 changed files +106 −0
modified
.gitignore
+1 −0
@@ -12,3 +12,4 @@ data/quartier.db | ||
| 12 | 12 | |
| 13 | 13 | # app iOS native — dépôt séparé (git.spboucher.ai/lou-ka-ios) |
| 14 | 14 | /ios/ |
| 15 | +data/uploads/ | |
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.
added
frontend/src/Logo.tsx
+105 −0
@@ -0,0 +1,105 @@ | ||
| 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 entrouverte qui | |
| 5 | +// laisse entrer la lumière. Spécifications géométriques (grille 100 × 100) : | |
| 6 | +// A. cadre : rect vertical 60 × 90 centré, rx 19 (squircle), contour seul | |
| 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. | |
| 18 | +// Baseline : « La porte d'entrée vers votre prochain chez-vous. » | |
| 19 | +// ----------------------------------------------------------------------------- | |
| 20 | + | |
| 21 | +/** Icône seule (fond transparent — pour fonds clairs ; dark = porte blanche). */ | |
| 22 | +export function LogoIcon({ size = 30, dark = false }: { size?: number; dark?: boolean }) { | |
| 23 | + // dark = version pour fond bleu marine : la porte devient blanche | |
| 24 | + const doorTop = dark ? "#ffffff" : "#101a3d"; | |
| 25 | + const doorBot = dark ? "#e8edf8" : "#0b1330"; | |
| 26 | + const uid = dark ? "lk-dark" : "lk-light-bg"; | |
| 27 | + return ( | |
| 28 | + <svg | |
| 29 | + className="logo-ico" | |
| 30 | + width={size} | |
| 31 | + height={size} | |
| 32 | + viewBox="0 0 100 100" | |
| 33 | + fill="none" | |
| 34 | + aria-hidden="true" | |
| 35 | + > | |
| 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 */} | |
| 43 | + <linearGradient id={`${uid}-door`} x1="0" y1="0" x2="0" y2="1"> | |
| 44 | + <stop offset="0" stopColor={doorTop} /> | |
| 45 | + <stop offset="1" stopColor={doorBot} /> | |
| 46 | + </linearGradient> | |
| 47 | + {/* tapis : lumière chaude qui se diffuse vers l'avant */} | |
| 48 | + <linearGradient id={`${uid}-light`} x1="0" y1="0" x2="0" y2="1"> | |
| 49 | + <stop offset="0" stopColor="#ff8533" /> | |
| 50 | + <stop offset="1" stopColor="#ff6a00" /> | |
| 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> | |
| 56 | + </defs> | |
| 57 | + <g filter={`url(#${uid}-soft)`}> | |
| 58 | + {/* B — porte entrouverte : charnière gauche, fuite en perspective à droite ; | |
| 59 | + le coin de lumière (espace vide) s'élargit vers le bas */} | |
| 60 | + <path | |
| 61 | + d="M29 17 L66 22.5 L62 73.5 L29 79 Z" | |
| 62 | + fill={`url(#${uid}-door)`} | |
| 63 | + stroke={`url(#${uid}-door)`} | |
| 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> | |
| 90 | + </svg> | |
| 91 | + ); | |
| 92 | +} | |
| 93 | + | |
| 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). */ | |
| 96 | +export default function Logo({ size = 30 }: { size?: number }) { | |
| 97 | + return ( | |
| 98 | + <span style={{ display: "inline-flex", alignItems: "center", gap: size * 0.4 * 0.6 }}> | |
| 99 | + <LogoIcon size={size} /> | |
| 100 | + <span style={{ color: "#0b1330", fontWeight: 700, letterSpacing: "-0.005em" }}> | |
| 101 | + Lou-<span style={{ color: "#ff6a00" }}>Ka</span> | |
| 102 | + </span> | |
| 103 | + </span> | |
| 104 | + ); | |
| 105 | +} | |
| 106 | ||