Barre de navigation mobile commune Groupe KA (KA Tabbar v1)
La tab bar maison migre vers la pilule flottante du standard ka-ui/nav : Accueil · Produits · Boutiques · Recherche, thème sombre vert masthead, actif ambre, safe-area iOS. L overlay de recherche plein écran est conservé. Sur les fiches produit/boutique, le CTA sticky prend le bas (pilule effacée). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4 changed files +345 −101
modified
frontend/src/components/BottomNav.tsx
+17 −27
@@ -1,6 +1,7 @@ | ||
| 1 | 1 | import { FormEvent, useEffect, useRef, useState } from 'react' |
| 2 | −import { NavLink, useLocation, useNavigate } from 'react-router-dom' | |
| 3 | −import { IconClose, IconGrid, IconHome, IconSearch, IconStore } from './Icons' | |
| 2 | +import { useLocation, useNavigate } from 'react-router-dom' | |
| 3 | +import { IconClose, IconSearch } from './Icons' | |
| 4 | +import KaTabbar from '../ka/KaTabbar' | |
| 4 | 5 | |
| 5 | 6 | /** |
| 6 | 7 | * Mobile bottom tab bar (<768px) — Accueil, Produits, Boutiques, Recherche. |
@@ -81,31 +82,20 @@ export default function BottomNav() { | ||
| 81 | 82 | </div> |
| 82 | 83 | )} |
| 83 | 84 | |
| 84 | − <nav className="bottom-nav" aria-label="Navigation mobile"> | |
| 85 | − <NavLink to="/" end className="bottom-nav-item"> | |
| 86 | − <IconHome size={22} /> | |
| 87 | − <span>Accueil</span> | |
| 88 | − </NavLink> | |
| 89 | − <NavLink to="/produits" className="bottom-nav-item"> | |
| 90 | − <IconGrid size={22} /> | |
| 91 | − <span>Produits</span> | |
| 92 | − </NavLink> | |
| 93 | − <NavLink to="/boutiques" className="bottom-nav-item"> | |
| 94 | − <IconStore size={22} /> | |
| 95 | − <span>Boutiques</span> | |
| 96 | − </NavLink> | |
| 97 | − <button | |
| 98 | − type="button" | |
| 99 | − className={ | |
| 100 | − searchOpen ? 'bottom-nav-item active' : 'bottom-nav-item' | |
| 101 | − } | |
| 102 | − onClick={() => setSearchOpen(true)} | |
| 103 | − aria-label="Ouvrir la recherche" | |
| 104 | − > | |
| 105 | − <IconSearch size={22} /> | |
| 106 | − <span>Recherche</span> | |
| 107 | − </button> | |
| 108 | − </nav> | |
| 85 | + <KaTabbar | |
| 86 | + theme="dark" | |
| 87 | + tabs={[ | |
| 88 | + { label: 'Accueil', icon: 'home', to: '/', active: location.pathname === '/' }, | |
| 89 | + { | |
| 90 | + label: 'Produits', | |
| 91 | + icon: 'grid', | |
| 92 | + to: '/produits', | |
| 93 | + active: ['/produits', '/categorie', '/region'].some((r) => location.pathname.startsWith(r)), | |
| 94 | + }, | |
| 95 | + { label: 'Boutiques', icon: 'store', to: '/boutiques', active: location.pathname.startsWith('/boutiques') }, | |
| 96 | + { label: 'Recherche', icon: 'search', onPress: () => setSearchOpen(true), active: searchOpen }, | |
| 97 | + ]} | |
| 98 | + /> | |
| 109 | 99 | </> |
| 110 | 100 | ) |
| 111 | 101 | } |
added
frontend/src/ka/KaTabbar.tsx
+197 −0
@@ -0,0 +1,197 @@ | ||
| 1 | +// KA Tabbar v1 — canonique ka-ui.git/nav/KaTabbar.tsx | |
| 2 | +// Barre de navigation mobile commune Groupe KA (voir TABBAR-STANDARD.md). | |
| 3 | +// Copier dans src/ka/ avec ka-tabbar.css. Apps react-router uniquement ; | |
| 4 | +// pour Next.js (vrai-prix), adapter Link/usePathname — voir le standard. | |
| 5 | +import type { CSSProperties, ReactElement } from "react"; | |
| 6 | +import { Link } from "react-router-dom"; | |
| 7 | +import "./ka-tabbar.css"; | |
| 8 | + | |
| 9 | +export type KaTabIcon = | |
| 10 | + | "compass" | "search" | "heart" | "user" | "map" | "pin" | "tag" | |
| 11 | + | "home" | "grid" | "store" | "basket" | "target" | "trendup" | |
| 12 | + | "receipt" | "book" | "chart" | "calendar"; | |
| 13 | + | |
| 14 | +const ICONS: Record<KaTabIcon, ReactElement> = { | |
| 15 | + compass: ( | |
| 16 | + <> | |
| 17 | + <circle cx="12" cy="12" r="9" /> | |
| 18 | + <path d="m15.5 8.5-2.2 5-4.8 2 2.2-5 4.8-2z" /> | |
| 19 | + </> | |
| 20 | + ), | |
| 21 | + search: ( | |
| 22 | + <> | |
| 23 | + <circle cx="11" cy="11" r="7" /> | |
| 24 | + <path d="m20.5 20.5-4.2-4.2" /> | |
| 25 | + </> | |
| 26 | + ), | |
| 27 | + heart: ( | |
| 28 | + <path d="M12 20.5S4.5 15.8 2.6 11.4A5.3 5.3 0 0 1 12 6.6a5.3 5.3 0 0 1 9.4 4.8C19.5 15.8 12 20.5 12 20.5z" /> | |
| 29 | + ), | |
| 30 | + user: ( | |
| 31 | + <> | |
| 32 | + <circle cx="12" cy="8.2" r="3.7" /> | |
| 33 | + <path d="M4.5 20.2a7.5 7.5 0 0 1 15 0" /> | |
| 34 | + </> | |
| 35 | + ), | |
| 36 | + map: ( | |
| 37 | + <> | |
| 38 | + <path d="M9 4 3.5 6v14L9 18l6 2 5.5-2V4L15 6 9 4z" /> | |
| 39 | + <path d="M9 4v14M15 6v14" /> | |
| 40 | + </> | |
| 41 | + ), | |
| 42 | + pin: ( | |
| 43 | + <> | |
| 44 | + <path d="M12 21s-7-5.6-7-11a7 7 0 0 1 14 0c0 5.4-7 11-7 11z" /> | |
| 45 | + <circle cx="12" cy="10" r="2.6" /> | |
| 46 | + </> | |
| 47 | + ), | |
| 48 | + tag: ( | |
| 49 | + <> | |
| 50 | + <path d="M20.6 13.4 12 22 2 12V2h10l8.6 8.6a2 2 0 0 1 0 2.8z" /> | |
| 51 | + <circle cx="7" cy="7" r="1.6" /> | |
| 52 | + </> | |
| 53 | + ), | |
| 54 | + home: ( | |
| 55 | + <> | |
| 56 | + <path d="m3.5 10.5 8.5-7 8.5 7" /> | |
| 57 | + <path d="M5.5 9v11h13V9" /> | |
| 58 | + </> | |
| 59 | + ), | |
| 60 | + grid: ( | |
| 61 | + <> | |
| 62 | + <rect x="4" y="4" width="7" height="7" rx="1.5" /> | |
| 63 | + <rect x="13" y="4" width="7" height="7" rx="1.5" /> | |
| 64 | + <rect x="4" y="13" width="7" height="7" rx="1.5" /> | |
| 65 | + <rect x="13" y="13" width="7" height="7" rx="1.5" /> | |
| 66 | + </> | |
| 67 | + ), | |
| 68 | + store: ( | |
| 69 | + <> | |
| 70 | + <path d="M4.5 9.5 6 4.5h12l1.5 5" /> | |
| 71 | + <path d="M5 9.5h14V20H5V9.5z" /> | |
| 72 | + <path d="M10 20v-5h4v5" /> | |
| 73 | + </> | |
| 74 | + ), | |
| 75 | + basket: ( | |
| 76 | + <> | |
| 77 | + <path d="M4 9h16l-1.6 10a2 2 0 0 1-2 1.7H7.6a2 2 0 0 1-2-1.7L4 9z" /> | |
| 78 | + <path d="M8.5 9 12 3l3.5 6" /> | |
| 79 | + </> | |
| 80 | + ), | |
| 81 | + target: ( | |
| 82 | + <> | |
| 83 | + <circle cx="12" cy="12" r="8.5" /> | |
| 84 | + <circle cx="12" cy="12" r="4.5" /> | |
| 85 | + <circle cx="12" cy="12" r="0.8" /> | |
| 86 | + </> | |
| 87 | + ), | |
| 88 | + trendup: ( | |
| 89 | + <> | |
| 90 | + <path d="m3.5 16.5 5.5-5.5 3.5 3.5 7.5-7.5" /> | |
| 91 | + <path d="M14.5 7H20v5.5" /> | |
| 92 | + </> | |
| 93 | + ), | |
| 94 | + receipt: ( | |
| 95 | + <> | |
| 96 | + <path d="M6 3.5h12V21l-2-1.4-2 1.4-2-1.4-2 1.4-2-1.4L6 21V3.5z" /> | |
| 97 | + <path d="M9 8h6M9 11.5h6M9 15h4" /> | |
| 98 | + </> | |
| 99 | + ), | |
| 100 | + book: ( | |
| 101 | + <> | |
| 102 | + <path d="M12 6.5C10.5 5 8.5 4.5 5.5 4.5H3.5V19h2c3 0 5 .5 6.5 2 1.5-1.5 3.5-2 6.5-2h2V4.5h-2c-3 0-5 .5-6.5 2z" /> | |
| 103 | + <path d="M12 6.5V21" /> | |
| 104 | + </> | |
| 105 | + ), | |
| 106 | + chart: ( | |
| 107 | + <> | |
| 108 | + <path d="M4 20h16" /> | |
| 109 | + <path d="M7.5 20v-6M12 20V9M16.5 20v-4" /> | |
| 110 | + </> | |
| 111 | + ), | |
| 112 | + calendar: ( | |
| 113 | + <> | |
| 114 | + <rect x="3.5" y="5" width="17" height="15.5" rx="2" /> | |
| 115 | + <path d="M8 3v4M16 3v4M3.5 10h17" /> | |
| 116 | + </> | |
| 117 | + ), | |
| 118 | +}; | |
| 119 | + | |
| 120 | +export function KaTabIco({ name, size = 21 }: { name: KaTabIcon; size?: number }) { | |
| 121 | + return ( | |
| 122 | + <svg | |
| 123 | + width={size} | |
| 124 | + height={size} | |
| 125 | + viewBox="0 0 24 24" | |
| 126 | + fill="none" | |
| 127 | + stroke="currentColor" | |
| 128 | + strokeWidth={1.7} | |
| 129 | + strokeLinecap="round" | |
| 130 | + strokeLinejoin="round" | |
| 131 | + aria-hidden="true" | |
| 132 | + > | |
| 133 | + {ICONS[name]} | |
| 134 | + </svg> | |
| 135 | + ); | |
| 136 | +} | |
| 137 | + | |
| 138 | +export type KaTab = { | |
| 139 | + label: string; | |
| 140 | + icon: KaTabIcon; | |
| 141 | + /** route interne (react-router Link) */ | |
| 142 | + to?: string; | |
| 143 | + /** lien externe (ex. hub univers KA) */ | |
| 144 | + href?: string; | |
| 145 | + /** action locale (ex. ouvrir la recherche) — rend un <button> */ | |
| 146 | + onPress?: () => void; | |
| 147 | + active?: boolean; | |
| 148 | +}; | |
| 149 | + | |
| 150 | +export default function KaTabbar({ | |
| 151 | + tabs, | |
| 152 | + theme = "light", | |
| 153 | + accent, | |
| 154 | + className, | |
| 155 | +}: { | |
| 156 | + tabs: KaTab[]; | |
| 157 | + theme?: "light" | "dark"; | |
| 158 | + /** couleur signature de la marque (défaut : var(--accent) du site) */ | |
| 159 | + accent?: string; | |
| 160 | + className?: string; | |
| 161 | +}) { | |
| 162 | + const cls = | |
| 163 | + "ka-tabbar" + | |
| 164 | + (theme === "dark" ? " ka-tabbar--dark" : "") + | |
| 165 | + (className ? " " + className : ""); | |
| 166 | + const style = accent ? ({ "--ktb-accent": accent } as CSSProperties) : undefined; | |
| 167 | + return ( | |
| 168 | + <nav className={cls} style={style} aria-label="Navigation mobile"> | |
| 169 | + {tabs.map((t) => { | |
| 170 | + const inner = ( | |
| 171 | + <> | |
| 172 | + <KaTabIco name={t.icon} /> | |
| 173 | + {t.label} | |
| 174 | + </> | |
| 175 | + ); | |
| 176 | + const c = t.active ? "active" : ""; | |
| 177 | + if (t.to) | |
| 178 | + return ( | |
| 179 | + <Link key={t.label} to={t.to} className={c} aria-current={t.active ? "page" : undefined}> | |
| 180 | + {inner} | |
| 181 | + </Link> | |
| 182 | + ); | |
| 183 | + if (t.href) | |
| 184 | + return ( | |
| 185 | + <a key={t.label} href={t.href} className={c} target="_blank" rel="noreferrer"> | |
| 186 | + {inner} | |
| 187 | + </a> | |
| 188 | + ); | |
| 189 | + return ( | |
| 190 | + <button key={t.label} type="button" className={c} onClick={t.onPress}> | |
| 191 | + {inner} | |
| 192 | + </button> | |
| 193 | + ); | |
| 194 | + })} | |
| 195 | + </nav> | |
| 196 | + ); | |
| 197 | +} | |
added
frontend/src/ka/ka-tabbar.css
+118 −0
@@ -0,0 +1,118 @@ | ||
| 1 | +/* ============================================================ | |
| 2 | + KA Tabbar v1 — barre de navigation mobile commune Groupe KA | |
| 3 | + Canonique : ka-ui.git/nav/ka-tabbar.css — copiée telle quelle | |
| 4 | + dans chaque app (src/ka/ka-tabbar.css) et importée par le | |
| 5 | + composant KaTabbar. Voir TABBAR-STANDARD.md. | |
| 6 | + | |
| 7 | + Pilule flottante détachée du bas d'écran (langage Immo-Ka), | |
| 8 | + 4-5 onglets, safe-area iOS, thème clair (défaut) ou sombre. | |
| 9 | + Config par app : | |
| 10 | + --ktb-accent couleur signature (trait actif + icône) | |
| 11 | + --ktb-active-label couleur du label actif (défaut : encre) | |
| 12 | + .ka-tabbar--dark variante sombre (fond encre/brand) | |
| 13 | + --ktb-bg fond (surcharge libre, ex. vert profond) | |
| 14 | + ============================================================ */ | |
| 15 | + | |
| 16 | +.ka-tabbar { display: none; } | |
| 17 | + | |
| 18 | +@media (max-width: 760px) { | |
| 19 | + .ka-tabbar { | |
| 20 | + /* thème clair (défaut) — papier off-white légèrement translucide */ | |
| 21 | + --ktb-bg: rgba(250, 249, 245, 0.94); | |
| 22 | + --ktb-ink: var(--ink, #16191a); | |
| 23 | + --ktb-dim: var(--ink-3, #70756d); | |
| 24 | + --ktb-accent: var(--accent, #d6336c); | |
| 25 | + --ktb-line: var(--hairline-strong, rgba(20, 24, 20, 0.16)); | |
| 26 | + --ktb-shadow: 0 10px 30px rgba(20, 24, 20, 0.16), 0 2px 6px rgba(20, 24, 20, 0.07); | |
| 27 | + | |
| 28 | + position: fixed; | |
| 29 | + left: max(12px, env(safe-area-inset-left)); | |
| 30 | + right: max(12px, env(safe-area-inset-right)); | |
| 31 | + bottom: calc(10px + env(safe-area-inset-bottom)); | |
| 32 | + z-index: var(--z-bottombar, 600); | |
| 33 | + display: grid; | |
| 34 | + grid-auto-flow: column; | |
| 35 | + grid-auto-columns: 1fr; | |
| 36 | + max-width: 440px; | |
| 37 | + margin-inline: auto; | |
| 38 | + padding: 5px; | |
| 39 | + background: var(--ktb-bg); | |
| 40 | + -webkit-backdrop-filter: blur(14px) saturate(1.1); | |
| 41 | + backdrop-filter: blur(14px) saturate(1.1); | |
| 42 | + border: 1px solid var(--ktb-line); | |
| 43 | + border-radius: 18px; | |
| 44 | + box-shadow: var(--ktb-shadow); | |
| 45 | + } | |
| 46 | + | |
| 47 | + .ka-tabbar--dark { | |
| 48 | + --ktb-bg: rgba(18, 22, 19, 0.93); | |
| 49 | + --ktb-ink: #f5f3ee; | |
| 50 | + --ktb-dim: rgba(245, 243, 238, 0.62); | |
| 51 | + --ktb-line: rgba(245, 243, 238, 0.16); | |
| 52 | + --ktb-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); | |
| 53 | + } | |
| 54 | + | |
| 55 | + .ka-tabbar a, | |
| 56 | + .ka-tabbar button { | |
| 57 | + appearance: none; | |
| 58 | + background: none; | |
| 59 | + border: 0; | |
| 60 | + cursor: pointer; | |
| 61 | + display: flex; | |
| 62 | + flex-direction: column; | |
| 63 | + align-items: center; | |
| 64 | + justify-content: center; | |
| 65 | + gap: 3px; | |
| 66 | + min-height: 50px; | |
| 67 | + padding: 6px 2px 5px; | |
| 68 | + border-radius: 13px; | |
| 69 | + font-family: var(--font-display, inherit); | |
| 70 | + font-size: 10px; | |
| 71 | + font-weight: 650; | |
| 72 | + letter-spacing: 0.01em; | |
| 73 | + line-height: 1; | |
| 74 | + color: var(--ktb-dim); | |
| 75 | + text-decoration: none; | |
| 76 | + -webkit-tap-highlight-color: transparent; | |
| 77 | + transition: color 0.15s ease; | |
| 78 | + } | |
| 79 | + .ka-tabbar svg { display: block; transition: transform 0.15s ease; } | |
| 80 | + .ka-tabbar a:active svg, | |
| 81 | + .ka-tabbar button:active svg { transform: translateY(1px) scale(0.9); } | |
| 82 | + | |
| 83 | + /* état actif : icône couleur signature, label encre, trait accent */ | |
| 84 | + .ka-tabbar .active { color: var(--ktb-active-label, var(--ktb-ink)); } | |
| 85 | + .ka-tabbar .active svg { color: var(--ktb-accent); animation: ktb-pop 0.25s ease; } | |
| 86 | + .ka-tabbar .active::after { | |
| 87 | + content: ""; | |
| 88 | + width: 16px; | |
| 89 | + height: 2.5px; | |
| 90 | + border-radius: 2px; | |
| 91 | + background: var(--ktb-accent); | |
| 92 | + animation: ktb-under 0.22s ease; | |
| 93 | + } | |
| 94 | + | |
| 95 | + /* le contenu respire sous la pilule (footer compris) */ | |
| 96 | + body:has(.ka-tabbar) { padding-bottom: calc(84px + env(safe-area-inset-bottom)); } | |
| 97 | + | |
| 98 | + /* un CTA sticky de fiche prend le bas d'écran : la pilule s'efface */ | |
| 99 | + body:has(.cta-sticky) .ka-tabbar { display: none; } | |
| 100 | + body:has(.cta-sticky) { padding-bottom: 0; } | |
| 101 | + | |
| 102 | + /* widget KA Agent : dégagé de la pilule (style injecté après le bundle | |
| 103 | + → spécificité doublée pour gagner) */ | |
| 104 | + body:has(.ka-tabbar) .kaa-btn.kaa-btn { bottom: calc(88px + env(safe-area-inset-bottom, 0px)); right: 14px; } | |
| 105 | + body:has(.ka-tabbar) .kaa-panel.kaa-panel:not(.kaa-full) { bottom: calc(154px + env(safe-area-inset-bottom, 0px)); } | |
| 106 | +} | |
| 107 | + | |
| 108 | +@keyframes ktb-under { | |
| 109 | + from { transform: scaleX(0); opacity: 0; } | |
| 110 | +} | |
| 111 | +@keyframes ktb-pop { | |
| 112 | + 40% { transform: translateY(-2px); } | |
| 113 | +} | |
| 114 | + | |
| 115 | +@media (prefers-reduced-motion: reduce) { | |
| 116 | + .ka-tabbar svg { transition: none; } | |
| 117 | + .ka-tabbar .active svg, .ka-tabbar .active::after { animation: none; } | |
| 118 | +} | |
modified
frontend/src/styles.css
+13 −74
@@ -42,7 +42,7 @@ | ||
| 42 | 42 | --maxw: 1280px; |
| 43 | 43 | |
| 44 | 44 | --header-h: 56px; |
| 45 | − --tabbar-h: 58px; | |
| 45 | + --tabbar-h: 74px; | |
| 46 | 46 | --safe-b: env(safe-area-inset-bottom, 0px); |
| 47 | 47 | |
| 48 | 48 | --focus-ring: 0 0 0 3px rgba(196, 83, 46, 0.28); |
@@ -352,67 +352,22 @@ button:focus-visible, | ||
| 352 | 352 | } |
| 353 | 353 | |
| 354 | 354 | /* -------------------------------------------------------------------------- |
| 355 | − Bottom navigation (mobile) | |
| 355 | + Bottom navigation (mobile) — KA Tabbar commune (src/ka/ka-tabbar.css), | |
| 356 | + assortie au masthead : pilule vert profond, actif ambre. | |
| 356 | 357 | -------------------------------------------------------------------------- */ |
| 357 | 358 | |
| 358 | −.bottom-nav { | |
| 359 | − position: fixed; | |
| 360 | − left: 0; | |
| 361 | − right: 0; | |
| 362 | − bottom: 0; | |
| 363 | − z-index: var(--z-bottombar, 600); | |
| 364 | − display: grid; | |
| 365 | − grid-template-columns: repeat(4, 1fr); | |
| 366 | − background: var(--paper); | |
| 367 | − border-top: 1px solid var(--border); | |
| 368 | − padding-bottom: var(--safe-b); | |
| 369 | − height: calc(var(--tabbar-h) + var(--safe-b)); | |
| 370 | −} | |
| 371 | − | |
| 372 | −.bottom-nav-item { | |
| 373 | − appearance: none; | |
| 374 | − background: none; | |
| 375 | − border: none; | |
| 376 | − display: flex; | |
| 377 | − flex-direction: column; | |
| 378 | − align-items: center; | |
| 379 | − justify-content: center; | |
| 380 | − gap: 2px; | |
| 381 | − min-height: 44px; | |
| 382 | − padding: 6px 0 4px; | |
| 383 | − color: var(--muted); | |
| 384 | − font-size: 0.66rem; | |
| 385 | − font-weight: 600; | |
| 386 | − letter-spacing: 0.03em; | |
| 387 | − text-transform: uppercase; | |
| 388 | − cursor: pointer; | |
| 389 | − transition: color 0.15s ease; | |
| 390 | −} | |
| 391 | − | |
| 392 | −.bottom-nav-item svg { | |
| 393 | − transition: transform 0.15s ease; | |
| 394 | −} | |
| 395 | − | |
| 396 | −.bottom-nav-item:active svg { | |
| 397 | − transform: scale(0.9); | |
| 398 | −} | |
| 399 | − | |
| 400 | −.bottom-nav-item.active { | |
| 401 | − color: var(--accent); | |
| 402 | −} | |
| 403 | − | |
| 404 | −@media (hover: hover) { | |
| 405 | − .bottom-nav-item:hover { | |
| 406 | − text-decoration: none; | |
| 407 | − color: var(--accent); | |
| 408 | − } | |
| 359 | +.ka-tabbar--dark { | |
| 360 | + --ktb-bg: rgba(18, 63, 46, 0.95); /* --mast-green */ | |
| 361 | + --ktb-ink: var(--mast-fg, #f5f3ee); | |
| 362 | + --ktb-dim: var(--mast-dim, rgba(245, 243, 238, 0.62)); | |
| 363 | + --ktb-accent: var(--amber, #e8a33d); | |
| 364 | + --ktb-line: rgba(245, 243, 238, 0.18); | |
| 409 | 365 | } |
| 410 | 366 | |
| 411 | −@media (min-width: 768px) { | |
| 412 | − .bottom-nav { | |
| 413 | − display: none; | |
| 414 | − } | |
| 415 | −} | |
| 367 | +/* fiches produit/boutique : le CTA sticky prend le bas, la pilule s efface */ | |
| 368 | +body:has(.pd-cta-bar) .ka-tabbar, | |
| 369 | +body:has(.store-cta-bar) .ka-tabbar { display: none; } | |
| 370 | +.pd-cta-bar, .store-cta-bar { bottom: 0; padding-bottom: calc(0.6rem + var(--safe-b)); } | |
| 416 | 371 | |
| 417 | 372 | /* Mobile search overlay (Recherche tab) */ |
| 418 | 373 | .search-overlay { |
@@ -4739,12 +4694,6 @@ a.card:active { border-color: var(--ink); } | ||
| 4739 | 4694 | box-shadow: 1px 1px 0 var(--ink); |
| 4740 | 4695 | } |
| 4741 | 4696 | |
| 4742 | −/* ---- barre d'onglets mobile ---------------------------------------------- */ | |
| 4743 | −.bottom-nav { | |
| 4744 | − background: rgba(245, 243, 238, 0.96); | |
| 4745 | − border-top: 2px solid var(--ink); | |
| 4746 | −} | |
| 4747 | − | |
| 4748 | 4697 | /* ---- contenu SSR (seo.py) aligné sur le thème ---------------------------- */ |
| 4749 | 4698 | .seo-page h1, .seo-page h2 { font-family: var(--font-display); } |
| 4750 | 4699 | .seo-stats b { color: var(--accent); font-family: var(--font-mono); } |
@@ -5058,16 +5007,6 @@ a.card:active { border-color: var(--ink); } | ||
| 5058 | 5007 | .signup-link { color: var(--mast-dim); } |
| 5059 | 5008 | @media (hover: hover) { .signup-link:hover { color: var(--mast-fg); } } |
| 5060 | 5009 | |
| 5061 | −/* ---- tab bar mobile assortie au masthead --------------------------------- */ | |
| 5062 | −.bottom-nav { | |
| 5063 | − background: var(--mast-green); | |
| 5064 | − border-top: 0; | |
| 5065 | − box-shadow: 0 -1px 0 rgba(245, 243, 238, 0.12); | |
| 5066 | −} | |
| 5067 | −.bottom-nav-item { color: var(--mast-dim); } | |
| 5068 | −.bottom-nav-item.active { color: var(--amber); } | |
| 5069 | −@media (hover: hover) { .bottom-nav-item:hover { color: var(--mast-fg); } } | |
| 5070 | − | |
| 5071 | 5010 | /* ---- héro : filet fort + chiffres serif ---------------------------------- */ |
| 5072 | 5011 | .hero-stats { border-top: 2.5px solid var(--ink); padding-top: 1.1rem; gap: 0 2.25rem; } |
| 5073 | 5012 | .stat { padding-top: 0.15rem; } |
| 5074 | 5013 | |