En-tête tablette réparé, titre + OG/twitter, icônes et og.png servis à la racine
- Header : plus aucun chevauchement 768–1439 px (marque/nav en flex:none, nav compacte et recherche masquée 768–1023, recherche dès 1024, badge Groupe KA dès 1280, « Créer un compte » dès 1360) ; débordement horizontal de +139 px à 768 px ramené à 0 (validé 360/768/1024/1280/1440). - Titre SSR de l accueil suffixé « · Un service Groupe KA ». - ka-assets/ -> frontend/public/ (og.png, favicon.svg, apple-touch-icon.png) ; liens icônes + og:image absolu 1200x630 + twitter:card/image dans index.html et le head SSR (seo.py, sans doublons de balises). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6 changed files +59 −8
modified
fabrika/seo.py
+12 −4
@@ -26,7 +26,8 @@ from .schema import CATEGORIES, REGIONS | ||
| 26 | 26 | |
| 27 | 27 | BASE = os.environ.get("FABRIKA_BASE_URL", "https://www.fabri-ka.com").rstrip("/") |
| 28 | 28 | SITE = "Fabri-Ka" |
| 29 | −DEFAULT_TITLE = "Fabri-Ka — Tous les produits québécois. Un seul endroit." | |
| 29 | +DEFAULT_TITLE = ("Fabri-Ka — Tous les produits québécois. Un seul endroit." | |
| 30 | + " · Un service Groupe KA") | |
| 30 | 31 | FRONT_DIST = Path(__file__).resolve().parent.parent / "frontend" / "dist" |
| 31 | 32 | PER_PAGE = 24 |
| 32 | 33 | SITEMAP_CHUNK = 40_000 |
@@ -151,12 +152,19 @@ def render(*, title: str, description: str, canonical: str | None = None, | ||
| 151 | 152 | "og:title": title, "og:description": description} |
| 152 | 153 | if canonical: |
| 153 | 154 | og_all["og:url"] = BASE + canonical |
| 154 | − og_all.update(og or {}) | |
| 155 | + custom = og or {} | |
| 156 | + if not custom.get("og:image"): | |
| 157 | + og_all["og:image"] = f"{BASE}/og.png" | |
| 158 | + og_all["og:image:width"] = "1200" | |
| 159 | + og_all["og:image:height"] = "630" | |
| 160 | + og_all.update(custom) | |
| 161 | + # les balises og/twitter statiques du gabarit sont remplacées par celles-ci | |
| 162 | + tpl = re.sub(r'\s*<meta (?:property="og:|name="twitter:)[^>]*/?>', "", tpl) | |
| 155 | 163 | for k, v in og_all.items(): |
| 156 | 164 | if v: |
| 157 | 165 | extra.append(f'<meta property="{esc(k)}" content="{esc(v)}" />') |
| 158 | − card = "summary_large_image" if og_all.get("og:image") else "summary" | |
| 159 | − extra.append(f'<meta name="twitter:card" content="{card}" />') | |
| 166 | + extra.append('<meta name="twitter:card" content="summary_large_image" />') | |
| 167 | + extra.append(f'<meta name="twitter:image" content="{esc(og_all["og:image"])}" />') | |
| 160 | 168 | for obj in jsonld or []: |
| 161 | 169 | payload = json.dumps(obj, ensure_ascii=False).replace("</", "<\\/") |
| 162 | 170 | extra.append(f'<script type="application/ld+json">{payload}</script>') |
modified
frontend/index.html
+7 −1
@@ -2,7 +2,8 @@ | ||
| 2 | 2 | <html lang="fr"> |
| 3 | 3 | <head> |
| 4 | 4 | <meta charset="UTF-8" /> |
| 5 | − <link rel="icon" type="image/svg+xml" href="/icon.svg" /> | |
| 5 | + <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> | |
| 6 | + <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> | |
| 6 | 7 | <meta |
| 7 | 8 | name="viewport" |
| 8 | 9 | content="width=device-width, initial-scale=1.0, viewport-fit=cover" |
@@ -19,6 +20,11 @@ | ||
| 19 | 20 | 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 | 21 | rel="stylesheet" |
| 21 | 22 | /> |
| 23 | + <meta property="og:image" content="https://www.fabri-ka.com/og.png" /> | |
| 24 | + <meta property="og:image:width" content="1200" /> | |
| 25 | + <meta property="og:image:height" content="630" /> | |
| 26 | + <meta name="twitter:card" content="summary_large_image" /> | |
| 27 | + <meta name="twitter:image" content="https://www.fabri-ka.com/og.png" /> | |
| 22 | 28 | <title>Fabri-Ka — Un service Groupe KA</title> |
| 23 | 29 | </head> |
| 24 | 30 | <body> |
added
frontend/public/apple-touch-icon.png
+0 −0
Binary file not shown.
added
frontend/public/favicon.svg
+5 −0
@@ -0,0 +1,5 @@ | ||
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"> | |
| 2 | +<rect width="64" height="64" rx="14" fill="#141814"/> | |
| 3 | +<rect x="4.5" y="4.5" width="55" height="55" rx="11" fill="none" stroke="#c4532e" stroke-opacity="0.35" stroke-width="2"/> | |
| 4 | +<text x="32" y="43" text-anchor="middle" font-family="'Space Grotesk','Arial Black',sans-serif" font-size="30" font-weight="700" letter-spacing="-1" fill="#c4532e" transform="rotate(-4 32 32)">Ka</text> | |
| 5 | +</svg> | |
| \ No newline at end of file | ||
added
frontend/public/og.png
+0 −0
Binary file not shown.
modified
frontend/src/styles.css
+35 −3
@@ -240,6 +240,7 @@ button:focus-visible, | ||
| 240 | 240 | display: none; |
| 241 | 241 | margin-left: auto; |
| 242 | 242 | width: min(320px, 32vw); |
| 243 | + min-width: 160px; | |
| 243 | 244 | } |
| 244 | 245 | |
| 245 | 246 | @media (min-width: 768px) { |
@@ -249,8 +250,31 @@ button:focus-visible, | ||
| 249 | 250 | |
| 250 | 251 | .site-nav { |
| 251 | 252 | display: flex; |
| 253 | + flex: none; | |
| 252 | 254 | } |
| 255 | +} | |
| 256 | + | |
| 257 | +/* Tablette (768-1023 px) : nav compacte, recherche d en-tete masquee | |
| 258 | + (la recherche reste disponible sur l accueil et la page /produits) */ | |
| 259 | +@media (min-width: 768px) and (max-width: 1023px) { | |
| 260 | + .site-header-inner { | |
| 261 | + gap: 1rem; | |
| 262 | + } | |
| 263 | + | |
| 264 | + .site-nav { | |
| 265 | + gap: 0.15rem; | |
| 266 | + } | |
| 267 | + | |
| 268 | + .site-nav a { | |
| 269 | + display: inline-flex; | |
| 270 | + align-items: center; | |
| 271 | + min-height: 44px; | |
| 272 | + font-size: 0.9rem; | |
| 273 | + padding: 0.3rem 0.5rem; | |
| 274 | + } | |
| 275 | +} | |
| 253 | 276 | |
| 277 | +@media (min-width: 1024px) { | |
| 254 | 278 | .site-header-search { |
| 255 | 279 | display: block; |
| 256 | 280 | } |
@@ -3525,7 +3549,7 @@ a.card:active { | ||
| 3525 | 3549 | flex: none; |
| 3526 | 3550 | } |
| 3527 | 3551 | |
| 3528 | −@media (min-width: 768px) { | |
| 3552 | +@media (min-width: 1024px) { | |
| 3529 | 3553 | .site-header-account { |
| 3530 | 3554 | margin-left: 0; |
| 3531 | 3555 | } |
@@ -4342,11 +4366,19 @@ a.card:active { border-color: var(--ink); } | ||
| 4342 | 4366 | } |
| 4343 | 4367 | } |
| 4344 | 4368 | |
| 4369 | +/* Tablette / petit desktop : pas de place dans l en-tete — le badge est | |
| 4370 | + repris par le pied de page (KaFooter) */ | |
| 4371 | +@media (min-width: 768px) and (max-width: 1279px) { | |
| 4372 | + .site-header .gk-badge { | |
| 4373 | + display: none; | |
| 4374 | + } | |
| 4375 | +} | |
| 4376 | + | |
| 4345 | 4377 | .header-brand { |
| 4346 | 4378 | display: flex; |
| 4347 | 4379 | align-items: center; |
| 4348 | 4380 | gap: 0.7rem; |
| 4349 | − min-width: 0; | |
| 4381 | + flex: none; | |
| 4350 | 4382 | } |
| 4351 | 4383 | |
| 4352 | 4384 | .signup-link { |
@@ -4360,7 +4392,7 @@ a.card:active { border-color: var(--ink); } | ||
| 4360 | 4392 | white-space: nowrap; |
| 4361 | 4393 | } |
| 4362 | 4394 | |
| 4363 | −@media (min-width: 768px) { | |
| 4395 | +@media (min-width: 1360px) { | |
| 4364 | 4396 | .signup-link { |
| 4365 | 4397 | display: inline-flex; |
| 4366 | 4398 | } |
| 4367 | 4399 | |