Thème famille KA « éditorial sharp » (aligné sur Food-Ka / Lou-Ka)
- Typo : Space Grotesk (display) + Inter (texte) + JetBrains Mono (prix, micro-étiquettes) — remplace Fraunces/Outfit - Signature famille : bordures encre, ombres décalées (boutons, cartes, recherche), chip « ·Ka » rotée dans le logo, grain de fond, kickers mono - Palette Fabri-Ka conservée (papier crème, terracotta, pin) + miel #F2CF63 en surlignage ; footer pin profond ; nav pilule à état actif pin/miel - Couche d'override en fin de styles.css (jetons partagés --line, --shadow-off, --highlight — mêmes rôles que Food-Ka/Lou-Ka) - Captures d'écran README refaites avec le nouveau thème Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
13 changed files +260 −13
modified
README.md
+1 −1
@@ -97,7 +97,7 @@ flowchart LR | ||
| 97 | 97 | | **API** | Recherche FTS5, facettes, filtres catégorie/région/origine/prix, stats, rapport PDF, sync | `fabrika/web.py` | |
| 98 | 98 | | **SEO / SSR** | HTML complet dès la 1ʳᵉ requête sur toutes les routes, pages programmatiques, JSON-LD, sitemaps, 301/404/410 | `fabrika/seo.py` | |
| 99 | 99 | | **Comptes** | « Se connecter avec KA ID » (SSO du Groupe KA), favoris « Mon univers Ka » poussés au hub central | `fabrika/auth.py`, `fabrika/hubfav.py`, `fabrika/hubprofile.py` | |
| 100 | −| **Frontend** | « Chaleur artisanale, précision éditoriale » — Fraunces + Outfit, crème/terracotta/pin, PWA-lite, fr-CA | `frontend/` | | |
| 100 | +| **Frontend** | Identité famille KA « éditorial sharp » (cf. Food-Ka/Lou-Ka) — Space Grotesk + Inter + JetBrains Mono, bordures encre, ombres décalées, palette crème/terracotta/pin/miel, PWA-lite, fr-CA | `frontend/` | | |
| 101 | 101 | |
| 102 | 102 | ## SEO & rendu serveur — 292 000+ pages indexables |
| 103 | 103 | |
modified
docs/screenshots/accueil.png
+0 −0
Binary file not shown.
modified
docs/screenshots/boutique.png
+0 −0
Binary file not shown.
modified
docs/screenshots/boutiques.png
+0 −0
Binary file not shown.
modified
docs/screenshots/catalogue.png
+0 −0
Binary file not shown.
modified
docs/screenshots/categorie.png
+0 −0
Binary file not shown.
modified
docs/screenshots/mobile-produit.png
+0 −0
Binary file not shown.
modified
docs/screenshots/mobile.png
+0 −0
Binary file not shown.
modified
docs/screenshots/produit.png
+0 −0
Binary file not shown.
modified
docs/screenshots/stats.png
+0 −0
Binary file not shown.
modified
frontend/index.html
+1 −1
@@ -16,7 +16,7 @@ | ||
| 16 | 16 | <link rel="preconnect" href="https://fonts.googleapis.com" /> |
| 17 | 17 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> |
| 18 | 18 | <link |
| 19 | − href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,700;9..144,900&family=Outfit:wght@400;500;600;700&display=swap" | |
| 19 | + 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;600&display=swap" | |
| 20 | 20 | rel="stylesheet" |
| 21 | 21 | /> |
| 22 | 22 | <title>Fabri-Ka — Tous les produits québécois. Un seul endroit.</title> |
modified
frontend/src/App.tsx
+2 −2
@@ -145,7 +145,7 @@ function Header() { | ||
| 145 | 145 | <header className="site-header"> |
| 146 | 146 | <div className="site-header-inner"> |
| 147 | 147 | <Link to="/" className="logo" aria-label="Fabri-Ka — Accueil"> |
| 148 | − Fabri<span className="logo-dot">·</span>Ka | |
| 148 | + Fabri<span className="logo-ka">·Ka</span> | |
| 149 | 149 | </Link> |
| 150 | 150 | <nav className="site-nav" aria-label="Navigation principale"> |
| 151 | 151 | <NavLink to="/produits">Produits</NavLink> |
@@ -180,7 +180,7 @@ function Footer() { | ||
| 180 | 180 | <div className="site-footer-inner"> |
| 181 | 181 | <div className="footer-brand"> |
| 182 | 182 | <span className="logo logo-footer"> |
| 183 | − Fabri<span className="logo-dot">·</span>Ka | |
| 183 | + Fabri<span className="logo-ka">·Ka</span> | |
| 184 | 184 | </span> |
| 185 | 185 | <p>Tous les produits québécois. Un seul endroit.</p> |
| 186 | 186 | </div> |
modified
frontend/src/styles.css
+256 −9
@@ -1,10 +1,13 @@ | ||
| 1 | 1 | /* ========================================================================== |
| 2 | − Fabri-Ka — chaleur artisanale, précision éditoriale | |
| 3 | − Mobile-first · palette crème/encre/terracotta/pin | |
| 2 | + Fabri-Ka — identité famille KA « éditorial sharp » (cf. Food-Ka / Lou-Ka) | |
| 3 | + · Typo display Space Grotesk / texte Inter / micro-étiquettes JetBrains Mono | |
| 4 | + · Signature : bordures encre + ombres décalées (néo-brutalisme raffiné) | |
| 5 | + · Palette Fabri-Ka conservée : papier crème, encre chaude, terracotta | |
| 6 | + #C4532E en accent, pin #234438 en profond, miel #F2CF63 en surlignage | |
| 4 | 7 | ========================================================================== */ |
| 5 | 8 | |
| 6 | 9 | :root { |
| 7 | − --bg: #FAF6F0; | |
| 10 | + --bg: #FAF6EE; | |
| 8 | 11 | --ink: #1E1B16; |
| 9 | 12 | --accent: #C4532E; |
| 10 | 13 | --accent-dark: #A94525; |
@@ -14,18 +17,27 @@ | ||
| 14 | 17 | --white: #FFFFFF; |
| 15 | 18 | --muted: #6E6455; |
| 16 | 19 | |
| 20 | + /* jetons famille KA (mêmes rôles que Food-Ka/Lou-Ka) */ | |
| 21 | + --line: rgba(30, 27, 22, 0.14); | |
| 22 | + --line-strong: rgba(30, 27, 22, 0.85); | |
| 23 | + --highlight: #F2CF63; | |
| 24 | + --highlight-soft: #F9F0D2; | |
| 25 | + | |
| 17 | 26 | --origin-a: #234438; |
| 18 | 27 | --origin-b: #C4532E; |
| 19 | 28 | --origin-c: #8A6D3B; |
| 20 | 29 | --origin-d: #5B5B8A; |
| 21 | 30 | --origin-e: #999999; |
| 22 | 31 | |
| 23 | − --font-display: 'Fraunces', Georgia, serif; | |
| 24 | − --font-body: 'Outfit', system-ui, -apple-system, sans-serif; | |
| 32 | + --font-display: 'Space Grotesk', system-ui, sans-serif; | |
| 33 | + --font-body: 'Inter', system-ui, -apple-system, sans-serif; | |
| 34 | + --font-mono: 'JetBrains Mono', ui-monospace, monospace; | |
| 25 | 35 | |
| 26 | − --radius: 8px; | |
| 27 | − --radius-lg: 12px; | |
| 36 | + --radius: 6px; | |
| 37 | + --radius-lg: 10px; | |
| 28 | 38 | --shadow-hover: 0 6px 18px rgba(30, 27, 22, 0.08); |
| 39 | + --shadow-off: 6px 6px 0 var(--ink); | |
| 40 | + --shadow-off-soft: 8px 8px 0 rgba(30, 27, 22, 0.08); | |
| 29 | 41 | --shadow-sheet: 0 -12px 40px rgba(30, 27, 22, 0.18); |
| 30 | 42 | --maxw: 1280px; |
| 31 | 43 | |
@@ -4112,12 +4124,12 @@ a.card:active { | ||
| 4112 | 4124 | line-height: 1.6; |
| 4113 | 4125 | } |
| 4114 | 4126 | .seo-page h1 { |
| 4115 | − font-family: 'Fraunces', serif; | |
| 4127 | + font-family: var(--font-display); | |
| 4116 | 4128 | font-size: 1.9rem; |
| 4117 | 4129 | margin: 0.4em 0; |
| 4118 | 4130 | } |
| 4119 | 4131 | .seo-page h2 { |
| 4120 | − font-family: 'Fraunces', serif; | |
| 4132 | + font-family: var(--font-display); | |
| 4121 | 4133 | font-size: 1.25rem; |
| 4122 | 4134 | margin: 1.6em 0 0.5em; |
| 4123 | 4135 | } |
@@ -4193,3 +4205,238 @@ a.card:active { | ||
| 4193 | 4205 | margin: 18px 0; |
| 4194 | 4206 | align-items: center; |
| 4195 | 4207 | } |
| 4208 | + | |
| 4209 | +/* ========================================================================== | |
| 4210 | + Couche « famille KA » — même thème et display que Food-Ka / Lou-Ka | |
| 4211 | + (éditorial sharp : bordures encre, ombres décalées, chip ·Ka, micro-mono). | |
| 4212 | + Placée en fin de fichier : elle prime sur les règles historiques. | |
| 4213 | + ========================================================================== */ | |
| 4214 | + | |
| 4215 | +/* grain subtil — texture signature de la famille */ | |
| 4216 | +body::before { | |
| 4217 | + content: ""; | |
| 4218 | + position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 0.35; | |
| 4219 | + 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"); | |
| 4220 | +} | |
| 4221 | +#root { position: relative; z-index: 1; } | |
| 4222 | + | |
| 4223 | +/* Space Grotesk plafonne à 700 (Fraunces montait à 900) */ | |
| 4224 | +h1, h2, h3, h4 { | |
| 4225 | + font-weight: 700; | |
| 4226 | + letter-spacing: -0.03em; | |
| 4227 | + line-height: 1.08; | |
| 4228 | +} | |
| 4229 | +::selection { background: var(--highlight); color: var(--ink); } | |
| 4230 | + | |
| 4231 | +/* ---- header : trait d'encre + chip ·Ka rotée --------------------------- */ | |
| 4232 | +.site-header { | |
| 4233 | + background: rgba(250, 246, 238, 0.88); | |
| 4234 | + border-bottom: 2px solid var(--ink); | |
| 4235 | +} | |
| 4236 | +.logo { | |
| 4237 | + font-weight: 700; | |
| 4238 | + letter-spacing: -0.04em; | |
| 4239 | + display: inline-flex; | |
| 4240 | + align-items: center; | |
| 4241 | +} | |
| 4242 | +.logo-ka { | |
| 4243 | + background: var(--pine); | |
| 4244 | + color: var(--highlight); | |
| 4245 | + padding: 2px 7px 4px; | |
| 4246 | + border-radius: 6px; | |
| 4247 | + margin-left: 3px; | |
| 4248 | + transform: rotate(-2deg); | |
| 4249 | + transition: transform 0.2s ease; | |
| 4250 | + display: inline-block; | |
| 4251 | +} | |
| 4252 | +.logo:hover .logo-ka, | |
| 4253 | +.logo:focus-visible .logo-ka { transform: rotate(0deg); } | |
| 4254 | + | |
| 4255 | +.site-nav a { | |
| 4256 | + border: 1.5px solid transparent; | |
| 4257 | + font-weight: 600; | |
| 4258 | + border-radius: 999px; | |
| 4259 | + transition: all 0.15s ease; | |
| 4260 | +} | |
| 4261 | +@media (hover: hover) { | |
| 4262 | + .site-nav a:hover { | |
| 4263 | + border-color: var(--ink); | |
| 4264 | + color: var(--ink); | |
| 4265 | + background: transparent; | |
| 4266 | + } | |
| 4267 | +} | |
| 4268 | +.site-nav a.active, | |
| 4269 | +.site-nav a[aria-current='page'] { | |
| 4270 | + background: var(--pine); | |
| 4271 | + color: var(--highlight); | |
| 4272 | +} | |
| 4273 | + | |
| 4274 | +/* ---- recherche : champs encrés ----------------------------------------- */ | |
| 4275 | +.searchbar-field, | |
| 4276 | +.catalog-searchbar-field { | |
| 4277 | + border: 1.5px solid var(--ink); | |
| 4278 | + border-radius: var(--radius); | |
| 4279 | + background: var(--white); | |
| 4280 | +} | |
| 4281 | +.searchbar button[type='submit'] { | |
| 4282 | + border: 1.5px solid var(--ink); | |
| 4283 | + border-radius: var(--radius); | |
| 4284 | + box-shadow: 3px 3px 0 var(--ink); | |
| 4285 | + transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.15s ease; | |
| 4286 | +} | |
| 4287 | +.searchbar button[type='submit']:active { | |
| 4288 | + transform: translate(2px, 2px); | |
| 4289 | + box-shadow: 1px 1px 0 var(--ink); | |
| 4290 | +} | |
| 4291 | +.searchbar-kbd { | |
| 4292 | + font-family: var(--font-mono); | |
| 4293 | + border: 1px solid var(--line); | |
| 4294 | + border-radius: 4px; | |
| 4295 | +} | |
| 4296 | + | |
| 4297 | +/* ---- kicker / entêtes de section : micro-mono -------------------------- */ | |
| 4298 | +.hero-eyebrow, | |
| 4299 | +.filter-label, | |
| 4300 | +.footer-col-title { | |
| 4301 | + font-family: var(--font-mono); | |
| 4302 | + font-size: 11.5px; | |
| 4303 | + font-weight: 500; | |
| 4304 | + text-transform: uppercase; | |
| 4305 | + letter-spacing: 0.14em; | |
| 4306 | + color: var(--accent); | |
| 4307 | +} | |
| 4308 | +.hero-eyebrow::before { background: var(--accent); } | |
| 4309 | +.section-header h2::before { | |
| 4310 | + border-radius: 0; | |
| 4311 | + background: var(--accent); | |
| 4312 | +} | |
| 4313 | + | |
| 4314 | +/* ---- cartes : bordure encre + ombre décalée au survol ------------------- */ | |
| 4315 | +.card { | |
| 4316 | + border: 1.5px solid var(--line); | |
| 4317 | + border-radius: var(--radius-lg); | |
| 4318 | + transition: border-color 0.15s ease, box-shadow 0.15s ease, | |
| 4319 | + transform 0.15s ease; | |
| 4320 | +} | |
| 4321 | +@media (hover: hover) { | |
| 4322 | + a.card:hover { | |
| 4323 | + border-color: var(--ink); | |
| 4324 | + box-shadow: var(--shadow-off-soft); | |
| 4325 | + transform: translate(-2px, -2px); | |
| 4326 | + } | |
| 4327 | +} | |
| 4328 | +a.card:active { border-color: var(--ink); } | |
| 4329 | + | |
| 4330 | +/* ---- chips catégories --------------------------------------------------- */ | |
| 4331 | +.chip { | |
| 4332 | + border: 1.5px solid var(--line); | |
| 4333 | + font-weight: 600; | |
| 4334 | +} | |
| 4335 | +@media (hover: hover) { | |
| 4336 | + .chip:hover { | |
| 4337 | + border-color: var(--ink); | |
| 4338 | + background: var(--white); | |
| 4339 | + box-shadow: 3px 3px 0 rgba(30, 27, 22, 0.12); | |
| 4340 | + transform: translate(-1px, -1px); | |
| 4341 | + } | |
| 4342 | +} | |
| 4343 | +.chip:active { border-color: var(--ink); background: var(--highlight-soft); } | |
| 4344 | +.chip-count { | |
| 4345 | + font-family: var(--font-mono); | |
| 4346 | + font-size: 11px; | |
| 4347 | + background: var(--sand); | |
| 4348 | + border-radius: 999px; | |
| 4349 | + padding: 2px 8px; | |
| 4350 | +} | |
| 4351 | + | |
| 4352 | +/* ---- prix & étiquettes : mono ------------------------------------------- */ | |
| 4353 | +.price-chip { | |
| 4354 | + font-family: var(--font-mono); | |
| 4355 | + font-weight: 600; | |
| 4356 | + letter-spacing: -0.02em; | |
| 4357 | +} | |
| 4358 | +.price-chip-muted { font-family: var(--font-mono); font-weight: 500; } | |
| 4359 | +.tag, | |
| 4360 | +.origin-badge, | |
| 4361 | +.unavailable-badge, | |
| 4362 | +.stats-newest-chip { | |
| 4363 | + font-family: var(--font-mono); | |
| 4364 | + text-transform: uppercase; | |
| 4365 | + letter-spacing: 0.06em; | |
| 4366 | + font-size: 10.5px; | |
| 4367 | +} | |
| 4368 | + | |
| 4369 | +/* ---- boutons : encre + ombre décalée ------------------------------------ */ | |
| 4370 | +.btn { | |
| 4371 | + border-radius: var(--radius); | |
| 4372 | + font-weight: 600; | |
| 4373 | +} | |
| 4374 | +.btn-primary { | |
| 4375 | + border: 1.5px solid var(--ink); | |
| 4376 | + box-shadow: 3px 3px 0 var(--ink); | |
| 4377 | + transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.15s ease; | |
| 4378 | +} | |
| 4379 | +@media (hover: hover) { | |
| 4380 | + .btn-primary:hover { | |
| 4381 | + background: var(--accent-dark); | |
| 4382 | + transform: translate(-1px, -1px); | |
| 4383 | + box-shadow: 4px 4px 0 var(--ink); | |
| 4384 | + } | |
| 4385 | +} | |
| 4386 | +.btn-primary:active { | |
| 4387 | + transform: translate(2px, 2px); | |
| 4388 | + box-shadow: 1px 1px 0 var(--ink); | |
| 4389 | +} | |
| 4390 | +.btn-secondary { | |
| 4391 | + border: 1.5px solid var(--ink); | |
| 4392 | + background: var(--white); | |
| 4393 | +} | |
| 4394 | +@media (hover: hover) { | |
| 4395 | + .btn-secondary:hover { | |
| 4396 | + box-shadow: 3px 3px 0 rgba(30, 27, 22, 0.15); | |
| 4397 | + transform: translate(-1px, -1px); | |
| 4398 | + } | |
| 4399 | +} | |
| 4400 | + | |
| 4401 | +/* ---- filtre flottant mobile --------------------------------------------- */ | |
| 4402 | +.filter-fab { | |
| 4403 | + border: 1.5px solid var(--ink); | |
| 4404 | + box-shadow: 3px 3px 0 var(--ink); | |
| 4405 | + font-weight: 600; | |
| 4406 | +} | |
| 4407 | +.filter-fab:active { | |
| 4408 | + transform: translate(2px, 2px); | |
| 4409 | + box-shadow: 1px 1px 0 var(--ink); | |
| 4410 | +} | |
| 4411 | + | |
| 4412 | +/* ---- barre d'onglets mobile ---------------------------------------------- */ | |
| 4413 | +.bottom-nav { | |
| 4414 | + background: rgba(250, 246, 238, 0.96); | |
| 4415 | + border-top: 2px solid var(--ink); | |
| 4416 | +} | |
| 4417 | + | |
| 4418 | +/* ---- footer : bloc pin profond ------------------------------------------- */ | |
| 4419 | +.site-footer { | |
| 4420 | + background: var(--pine); | |
| 4421 | + border-top: 2px solid var(--ink); | |
| 4422 | + color: rgba(250, 246, 238, 0.92); | |
| 4423 | +} | |
| 4424 | +.site-footer .logo, | |
| 4425 | +.site-footer a, | |
| 4426 | +.footer-brand p, | |
| 4427 | +.footer-legal { | |
| 4428 | + color: rgba(250, 246, 238, 0.92); | |
| 4429 | +} | |
| 4430 | +.site-footer .footer-col-title { color: var(--highlight); } | |
| 4431 | +.site-footer a:hover { color: var(--highlight); } | |
| 4432 | +.site-footer .logo-ka { | |
| 4433 | + background: var(--highlight); | |
| 4434 | + color: var(--pine); | |
| 4435 | +} | |
| 4436 | + | |
| 4437 | +/* ---- contenu SSR (seo.py) aligné sur le thème ---------------------------- */ | |
| 4438 | +.seo-page h1, .seo-page h2 { font-family: var(--font-display); } | |
| 4439 | +.seo-stats b { color: var(--accent); font-family: var(--font-mono); } | |
| 4440 | +.seo-card a { font-weight: 600; } | |
| 4441 | +.seo-card-price { font-family: var(--font-mono); color: var(--accent); } | |
| 4442 | +.seo-card-media img { border: 1.5px solid var(--line); } | |
| 4196 | 4443 | |