SPB Git forge

spb/food-ka

Public

Food-Ka — agrégateur de produits d'épicerie du Québec — www.food-ka.com

55commits 1branches 0releases
10.2 MBsize
maindefault branch
9 days agolast push
Python 53.9% TypeScript 24% CSS 14.9% JavaScript 5.8% HTML 1.4%

DA v3 data-epicerie : filtres pupitre sans boite, onglets rayons soulignes, cartes produits sans cadre (packshot 12px + prix display), echelle de prix a filets, bandeau stats en chiffres, menu mobile vert profond, tuiles stats a filets

Simon-Pierre Boucher committed 1 mo ago (Aug 25, 2026) parent e8932a0

1 changed file +176 −97

modified frontend/src/styles.css +176 −97
@@ -68,14 +68,22 @@ button { font-family: inherit; }
68 68 letter-spacing: 0.08em; text-transform: uppercase; margin-left: 12px;
69 69 }
70 70 @media (max-width: 880px) { .brand-tag { display: none; } }
71 −.nav { margin-left: auto; display: flex; gap: 4px; }
71 +.nav { margin-left: auto; display: flex; gap: 2px; }
72 72 .nav a {
73 − padding: 9px 16px; border-radius: 999px; font-weight: 600; font-size: 14px;
74 − color: var(--ink-2); border: 1.5px solid transparent;
75 − transition: all 0.15s ease; min-height: 40px; display: inline-flex; align-items: center;
73 + position: relative; padding: 9px 13px; min-height: 44px;
74 + display: inline-flex; align-items: center;
75 + font-family: var(--font-mono); font-size: 11.5px; font-weight: 600;
76 + text-transform: uppercase; letter-spacing: 0.09em;
77 + color: var(--ink-2); transition: color 0.15s ease;
78 +}
79 +.nav a::after {
80 + content: ""; position: absolute; left: 13px; right: 13px; bottom: 6px;
81 + height: 2px; background: var(--accent);
82 + transform: scaleX(0); transform-origin: left; transition: transform 0.18s ease;
76 83 }
77 −.nav a:hover { border-color: var(--ink); color: var(--ink); }
78 −.nav a.active { background: var(--accent-deep); color: var(--on-accent); }
84 +.nav a:hover { color: var(--ink); }
85 +.nav a:hover::after, .nav a.active::after { transform: scaleX(1); }
86 +.nav a.active { color: var(--ink); }
79 87
80 88 /* ================= Ticker — bande « ruban de caisse » ================= */
81 89 .ticker {
@@ -113,14 +121,22 @@ button { font-family: inherit; }
113 121 .kicker-sale { color: var(--tomato-deep); }
114 122 .kicker-sale::before { background: var(--tomato); }
115 123 .hero p.lede { color: var(--ink-2); font-size: 16.5px; max-width: 640px; margin: 20px 0 0; }
116 −.stat-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
124 +/* bandeau de données : filet fort + chiffres display (plus de chips-boîtes) */
125 +.stat-row {
126 + display: flex; flex-wrap: wrap; gap: 8px 32px; margin-top: 30px;
127 + border-top: 2.5px solid var(--ink); padding-top: 14px; max-width: 860px;
128 +}
117 129 .stat-chip {
118 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: 999px;
119 − padding: 8px 16px; font-family: var(--font-mono); font-size: 12px;
120 − color: var(--ink-2); display: flex; gap: 8px; align-items: center;
121 − box-shadow: 3px 3px 0 rgba(20, 24, 20, 0.12);
130 + background: transparent; border: 0; border-radius: 0; box-shadow: none;
131 + padding: 0; font-family: var(--font-mono); font-size: 10.5px;
132 + letter-spacing: 0.08em; text-transform: uppercase;
133 + color: var(--ink-3); display: flex; gap: 8px; align-items: baseline;
134 +}
135 +.stat-chip b {
136 + color: var(--ink); font-weight: 700; font-family: var(--font-display);
137 + font-size: clamp(20px, 2.4vw, 30px); letter-spacing: -0.02em;
138 + font-variant-numeric: tabular-nums;
122 139 }
123 −.stat-chip b { color: var(--ink); font-weight: 700; }
124 140 .stat-chip .pulse {
125 141 width: 8px; height: 8px; border-radius: 50%; background: var(--green);
126 142 box-shadow: 0 0 0 4px var(--lime-soft); animation: pulse 2.4s ease infinite;
@@ -129,24 +145,28 @@ button { font-family: inherit; }
129 145
130 146 /* ================= Filter bar ================= */
131 147 .filterbar {
132 − background: var(--surface); border: 2px solid var(--ink); border-radius: var(--r-card);
133 − box-shadow: var(--shadow-off-soft); padding: 14px; margin: 30px 0 6px;
148 + background: transparent; border: 0; border-radius: 0; box-shadow: none;
149 + border-top: 2.5px solid var(--ink); border-bottom: 1px solid var(--line);
150 + padding: 4px 0 14px; margin: 34px 0 6px;
134 151 display: flex; flex-direction: column; gap: 0; min-width: 0;
135 152 }
136 153
137 −/* — rangée principale — */
138 −.f-primary { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; min-width: 0; }
154 +/* — rangée principale : pupitre sans boîtes, séparé par hairlines — */
155 +.f-primary { display: flex; gap: 0; align-items: stretch; flex-wrap: wrap; min-width: 0; }
139 156 .f-search {
140 − flex: 1 1 240px; min-width: 0; display: flex; align-items: center; gap: 9px;
141 − border: 1.5px solid var(--ink); border-radius: 9px; background: var(--surface-2);
142 − padding: 0 13px; min-height: 52px; color: var(--ink-2);
143 − transition: box-shadow 0.15s ease;
157 + flex: 1 1 240px; min-width: 0; display: flex; align-items: center; gap: 11px;
158 + border: 0; border-radius: 0; background: transparent;
159 + padding: 0 16px 0 0; min-height: 56px; color: var(--ink-2);
160 + box-shadow: none; transition: box-shadow 0.15s ease;
144 161 }
145 −.f-search:focus-within { box-shadow: 3px 3px 0 var(--lime); background: var(--surface); }
162 +.f-search:focus-within { box-shadow: inset 0 -2.5px 0 var(--accent); background: transparent; }
146 163 .f-search input {
147 164 border: none; background: none; outline: none; flex: 1; min-width: 0;
148 − font-size: 15px; color: var(--ink); font-family: inherit;
165 + font-family: var(--font-display); font-weight: 600;
166 + font-size: clamp(16px, 2vw, 21px); letter-spacing: -0.01em;
167 + color: var(--ink);
149 168 }
169 +.f-search input::placeholder { color: var(--ink-3); font-weight: 500; }
150 170 .f-clear {
151 171 border: none; background: var(--line); color: var(--ink-2); border-radius: 50%;
152 172 width: 20px; height: 20px; font-size: 10px; cursor: pointer; flex: none;
@@ -154,11 +174,12 @@ button { font-family: inherit; }
154 174 }
155 175 .f-ctl {
156 176 flex: 0 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center;
157 − gap: 2px; border: 1.5px solid var(--ink); border-radius: 9px; background: var(--surface);
158 − padding: 7px 12px 6px; min-height: 52px; cursor: pointer;
177 + gap: 2px; border: 0; border-left: 1px solid var(--line); border-radius: 0;
178 + background: transparent;
179 + padding: 7px 16px 6px; min-height: 56px; cursor: pointer;
159 180 transition: box-shadow 0.15s ease;
160 181 }
161 −.f-ctl:focus-within { box-shadow: 3px 3px 0 var(--lime); }
182 +.f-ctl:focus-within { box-shadow: inset 0 -2.5px 0 var(--accent); }
162 183 .f-ctl > span {
163 184 font-family: var(--font-mono); font-size: 9px; font-weight: 700;
164 185 text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3);
@@ -175,13 +196,17 @@ button { font-family: inherit; }
175 196 .range-pair select { max-width: 86px; }
176 197 .range-sep { color: var(--ink-3); font-family: var(--font-mono); font-size: 11px; }
177 198 .f-more {
178 − flex: none; align-self: stretch; border: 1.5px solid var(--ink); border-radius: 9px;
179 − background: var(--surface); color: var(--ink); padding: 0 18px; cursor: pointer;
180 − font-family: var(--font-display); font-weight: 700; font-size: 14px; min-height: 52px;
181 − transition: all 0.13s ease;
182 −}
183 −.f-more:hover { background: var(--lime-soft); }
184 −.f-more.on { background: var(--accent-deep); color: var(--on-accent); box-shadow: 3px 3px 0 rgba(20,24,20,0.22); }
199 + flex: none; align-self: center; border: 0; border-radius: 0;
200 + background: transparent; color: var(--ink-2); padding: 10px 0 10px 18px; cursor: pointer;
201 + font-family: var(--font-mono); font-weight: 600; font-size: 11px;
202 + text-transform: uppercase; letter-spacing: 0.1em; min-height: 44px;
203 + border-left: 1px solid var(--line);
204 + text-decoration: underline; text-underline-offset: 4px;
205 + text-decoration-color: var(--line-strong);
206 + transition: color 0.13s ease;
207 +}
208 +.f-more:hover { background: transparent; color: var(--accent-deep); text-decoration-color: var(--accent); }
209 +.f-more.on { background: transparent; color: var(--accent-deep); box-shadow: none; text-decoration-color: var(--accent); }
185 210
186 211 /* — panneau avancé — */
187 212 .f-adv {
@@ -268,49 +293,75 @@ button { font-family: inherit; }
268 293 /* ================= Chips ================= */
269 294 .chips { display: flex; gap: 8px; margin: 16px 0 4px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
270 295 .chips::-webkit-scrollbar { display: none; }
296 +/* onglets de rayons : texte souligné plutôt que pilules-boîtes */
271 297 .chip {
272 − border: 1.5px solid var(--ink); background: var(--surface); color: var(--ink);
273 − border-radius: 999px; padding: 8px 18px; font-size: 13.5px; font-weight: 600; cursor: pointer;
274 − font-family: var(--font-display); white-space: nowrap; min-height: 40px;
275 − transition: all 0.13s ease;
298 + position: relative; border: 0; background: transparent; color: var(--ink-2);
299 + border-radius: 0; padding: 8px 2px; font-size: 12px; font-weight: 600; cursor: pointer;
300 + font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.07em;
301 + white-space: nowrap; min-height: 40px; margin-right: 18px;
302 + border-bottom: 2px solid transparent;
303 + transition: color 0.13s ease, border-color 0.13s ease;
276 304 }
277 −.chip:hover { background: var(--lime-soft); transform: translateY(-1px); }
278 −.chip.on { background: var(--accent-deep); color: var(--on-accent); box-shadow: 3px 3px 0 rgba(20,24,20,0.2); }
305 +.chip:hover { background: transparent; transform: none; color: var(--ink); border-bottom-color: var(--line-strong); }
306 +.chip.on { background: transparent; color: var(--accent-deep); box-shadow: none; border-bottom-color: var(--accent); }
279 307
280 308 /* ================= Results ================= */
281 −.results-head { display: flex; align-items: baseline; gap: 14px; margin: 28px 0 18px; }
282 −.results-head h2 { font-size: 22px; text-transform: uppercase; letter-spacing: -0.02em; }
283 −.results-head span { font-family: var(--font-mono); color: var(--ink-3); font-size: 12px; letter-spacing: 0.06em; }
309 +.results-head { display: flex; align-items: baseline; gap: 16px; margin: 28px 0 18px; }
310 +.results-head h2 { font-size: clamp(24px, 3vw, 34px); text-transform: uppercase; letter-spacing: -0.02em; }
311 +.results-head span {
312 + font-family: var(--font-mono); color: var(--ink-2); font-size: 11px;
313 + letter-spacing: 0.08em; text-transform: uppercase; font-variant-numeric: tabular-nums;
314 +}
315 +.results-head span::after {
316 + content: ""; display: inline-block; width: 8px; height: 8px; margin-left: 8px;
317 + border-radius: 999px; background: var(--accent);
318 + animation: livepulse 2.2s ease-in-out infinite;
319 +}
320 +@keyframes livepulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
284 321 .grid {
285 322 display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
286 − gap: 22px; padding-bottom: 26px;
323 + gap: 30px 24px; padding-bottom: 26px;
287 324 }
288 −@media (max-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); gap: 12px; padding-bottom: 24px; } }
325 +@media (max-width: 640px) { .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 14px; padding-bottom: 24px; } }
289 326
290 327 .card {
291 − background: var(--surface); border: 1.5px solid var(--line-strong); border-radius: var(--r-card);
292 − overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--shadow-flat);
293 − transition: transform 0.16s ease, box-shadow 0.16s ease;
328 + background: transparent; border: 0; border-radius: 0; min-width: 0;
329 + overflow: visible; display: flex; flex-direction: column; box-shadow: none;
330 + transition: none;
294 331 }
295 −.card:hover { transform: translate(-3px, -3px); box-shadow: var(--shadow-off); }
332 +.card .avail { min-width: 0; }
333 +.card:hover { transform: none; box-shadow: none; }
296 334 .card:focus-visible { outline: 3px solid var(--lime); outline-offset: 2px; }
297 −.card-img { position: relative; aspect-ratio: 1/1; background: #fff; overflow: hidden; }
298 −.card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
335 +.card-img {
336 + position: relative; aspect-ratio: 1/1; background: #fff; overflow: hidden;
337 + border-radius: 12px;
338 +}
339 +.card-img::after {
340 + content: ""; position: absolute; inset: 0; border-radius: 12px;
341 + box-shadow: inset 0 0 0 1px rgba(20, 24, 20, 0.1); pointer-events: none;
342 +}
343 +.card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.35s cubic-bezier(0.2, 0.6, 0.2, 1); }
299 344 /* packshot produit : image entière sur fond blanc, jamais recadrée */
300 −.card-img.packshot { border-bottom: 1.5px dashed var(--line); }
301 −.card-img.packshot img { object-fit: contain; padding: 14px; }
302 −.card:hover .card-img img { transform: scale(1.05); }
345 +.card-img.packshot { border-bottom: 0; }
346 +.card-img.packshot img { object-fit: contain; padding: 16px; }
347 +.card:hover .card-img img { transform: scale(1.06); }
303 348 .card-img .noimg { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--ink-3); font-size: 34px; }
304 349 .badge {
305 − position: absolute; top: 12px; left: 12px; border-radius: 6px; padding: 4px 10px;
350 + position: absolute; top: 10px; left: 10px; border-radius: 6px; padding: 4px 10px;
306 351 font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em;
307 352 background: rgba(255, 255, 255, 0.95); color: var(--ink); border: 1px solid var(--ink);
308 353 }
309 −.badge.sale { background: var(--tomato); color: #fff; border-color: var(--tomato-deep); }
354 +/* étiquette solde façon autocollant de tablette */
355 +.badge.sale {
356 + background: var(--tomato); color: #fff; border: 0;
357 + transform: rotate(-3deg); box-shadow: 2px 2px 0 rgba(20, 24, 20, 0.22);
358 + font-size: 12.5px; padding: 5px 11px;
359 +}
310 360 .badge.right { left: auto; right: 12px; background: var(--amber-soft); border-color: var(--amber); color: #8a5a12; }
311 −.card-body { padding: 14px 16px 14px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
361 +.card-body { padding: 12px 2px 0; display: flex; flex-direction: column; gap: 5px; flex: 1; }
312 362 .card-price {
313 − font-family: var(--font-display); font-weight: 700; font-size: 21px; letter-spacing: -0.02em;
363 + font-family: var(--font-display); font-weight: 700; font-size: 23px; letter-spacing: -0.02em;
364 + line-height: 1; font-variant-numeric: tabular-nums;
314 365 display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
315 366 }
316 367 .price-old {
@@ -320,10 +371,15 @@ button { font-family: inherit; }
320 371 }
321 372 .price-old.big { font-size: 16px; margin-left: 10px; }
322 373 .card-unit { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); letter-spacing: 0.04em; }
323 −.card-title { font-weight: 600; font-size: 14px; color: var(--ink); }
374 +.card-title {
375 + font-weight: 600; font-size: 14px; color: var(--ink);
376 + text-decoration: underline transparent; text-decoration-thickness: 2px;
377 + text-underline-offset: 3px; transition: text-decoration-color 0.18s ease;
378 +}
379 +.card:hover .card-title { text-decoration-color: var(--accent); }
324 380 .card-meta { color: var(--ink-3); font-size: 12.5px; display: flex; gap: 7px; flex-wrap: wrap; align-items: center; font-family: var(--font-mono); }
325 381 .card-meta .sep { width: 4px; height: 4px; background: var(--lime); border: 1px solid var(--ink); border-radius: 1px; transform: rotate(45deg); }
326 −.card-foot { margin-top: auto; padding-top: 11px; border-top: 1.5px dashed var(--line); display: flex; justify-content: space-between; align-items: center; gap: 8px; }
382 +.card-foot { margin-top: auto; padding-top: 9px; border-top: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; gap: 8px; }
327 383 .source-tag {
328 384 font-family: var(--font-mono); font-size: 10px; font-weight: 700; text-transform: uppercase;
329 385 letter-spacing: 0.08em; color: var(--green-deep); background: var(--lime-soft);
@@ -338,7 +394,7 @@ button { font-family: inherit; }
338 394
339 395 /* ================= Skeletons ================= */
340 396 @keyframes shimmer { 0% { background-position: -400px 0; } 100% { background-position: 400px 0; } }
341 −.skel { border-radius: var(--r-card); border: 1.5px solid var(--line); overflow: hidden; background: var(--surface); }
397 +.skel { border-radius: 12px; border: 0; overflow: hidden; background: var(--surface); }
342 398 .skel .sk-img, .skel .sk-line {
343 399 background: linear-gradient(90deg, #ecebe4 25%, #f7f6f1 50%, #ecebe4 75%);
344 400 background-size: 800px 100%; animation: shimmer 1.4s infinite linear;
@@ -377,8 +433,12 @@ button { font-family: inherit; }
377 433 .f-bloc:empty { display: none; }
378 434
379 435 /* galerie à balayage natif — packshots entiers, fond blanc */
380 −.carousel { position: relative; border-radius: var(--r-card); overflow: hidden;
381 − border: 1.5px solid var(--line-strong); background: #fff; }
436 +.carousel { position: relative; border-radius: 12px; overflow: hidden;
437 + border: 0; background: #fff; }
438 +.carousel::after {
439 + content: ""; position: absolute; inset: 0; border-radius: 12px; z-index: 3;
440 + box-shadow: inset 0 0 0 1px rgba(20, 24, 20, 0.1); pointer-events: none;
441 +}
382 442 .carousel-track {
383 443 display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
384 444 -webkit-overflow-scrolling: touch; scrollbar-width: none; aspect-ratio: 1/1;
@@ -417,8 +477,9 @@ button { font-family: inherit; }
417 477
418 478 /* bandeau prix */
419 479 .f-hero .price {
420 − font-family: var(--font-display); font-size: clamp(34px, 8vw, 44px); font-weight: 700;
421 − letter-spacing: -0.03em; display: flex; align-items: baseline; flex-wrap: wrap;
480 + font-family: var(--font-display); font-size: clamp(38px, 8vw, 52px); font-weight: 700;
481 + letter-spacing: -0.035em; line-height: 1; font-variant-numeric: tabular-nums;
482 + display: flex; align-items: baseline; flex-wrap: wrap;
422 483 }
423 484 .unit-price {
424 485 font-family: var(--font-mono); font-size: 13px; color: var(--ink-2);
@@ -450,9 +511,9 @@ button { font-family: inherit; }
450 511
451 512 .kv { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 20px 0; }
452 513 @media (max-width: 380px) { .kv { grid-template-columns: 1fr; } }
453 −.kv .cell { background: var(--surface-2); border: 1.5px solid var(--line); border-radius: var(--r-ctl); padding: 10px 13px; }
514 +.kv .cell { background: transparent; border: 0; border-top: 1.5px solid var(--ink); border-radius: 0; padding: 9px 2px 4px; }
454 515 .kv .cell .k { font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); font-weight: 700; }
455 −.kv .cell .v { font-weight: 700; font-size: 14.5px; margin-top: 2px; font-family: var(--font-display); }
516 +.kv .cell .v { font-weight: 700; font-size: 15px; margin-top: 2px; font-family: var(--font-display); font-variant-numeric: tabular-nums; }
456 517 .amenity-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 20px; }
457 518 .amenity {
458 519 background: var(--lime-soft); color: var(--green-deep); font-size: 12px; font-weight: 600;
@@ -493,14 +554,17 @@ button { font-family: inherit; }
493 554
494 555 /* ================= Comparer les prix ================= */
495 556 .q-sub { color: var(--ink-3); font-size: 13px; margin: 4px 0 16px; }
496 −.cmp-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
557 +/* échelle de prix : rangées à filet, la meilleure offre marquée d'une barre verte */
558 +.cmp-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; border-top: 2px solid var(--ink); }
497 559 .cmp-list li {
498 − background: var(--surface); border: 1.5px solid var(--line-strong);
499 − border-radius: var(--r-card); overflow: hidden; box-shadow: var(--shadow-flat);
500 − transition: transform 0.14s ease, box-shadow 0.14s ease;
560 + background: transparent; border: 0; border-bottom: 1px solid var(--line);
561 + border-radius: 0; overflow: hidden; box-shadow: none;
562 + transition: background 0.14s ease;
563 +}
564 +.cmp-list li:hover { transform: none; box-shadow: none; background: var(--surface-2); }
565 +.cmp-list li.best {
566 + border-left: 4px solid var(--green); background: var(--lime-soft);
501 567 }
502 −.cmp-list li:hover { transform: translate(-2px, -2px); box-shadow: 4px 4px 0 var(--ink); }
503 −.cmp-list li.best { border-color: var(--green); background: var(--lime-soft); }
504 568 .cmp-link { display: flex; align-items: center; gap: 12px; padding: 10px 14px 10px 10px; }
505 569 .cmp-img {
506 570 flex: 0 0 56px; width: 56px; height: 56px; border: 1px solid var(--line);
@@ -515,7 +579,7 @@ button { font-family: inherit; }
515 579 .cmp-meta { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }
516 580 .cmp-main .source-tag { align-self: flex-start; max-width: 100%; }
517 581 .cmp-price { flex: 0 0 auto; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
518 −.cmp-price b { font-family: var(--font-display); font-size: 17px; letter-spacing: -0.02em; }
582 +.cmp-price b { font-family: var(--font-display); font-size: 19px; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
519 583 .cmp-unit { font-family: var(--font-mono); font-size: 10px; color: var(--ink-3); }
520 584 .cmp-best {
521 585 font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; text-transform: uppercase;
@@ -541,7 +605,7 @@ button { font-family: inherit; }
541 605 .sources { padding: 44px 0 90px; }
542 606 .sources h1 { font-size: clamp(28px, 4vw, 40px); text-transform: uppercase; margin: 10px 0 6px; }
543 607 .sources .sub { color: var(--ink-2); margin-bottom: 30px; max-width: 700px; }
544 −.src-wrap { overflow-x: auto; border: 1.5px solid var(--ink); border-radius: var(--r-card); box-shadow: var(--shadow-off-soft); background: var(--surface); }
608 +.src-wrap { overflow-x: auto; border: 0; border-top: 2px solid var(--ink); border-radius: 0; box-shadow: none; background: transparent; }
545 609 .src-table { width: 100%; border-collapse: separate; border-spacing: 0; min-width: 720px; }
546 610 .src-table th {
547 611 text-align: left; font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
@@ -561,19 +625,20 @@ button { font-family: inherit; }
561 625 .stats-title { font-size: clamp(30px, 4.6vw, 46px); text-transform: uppercase; margin: 10px 0 6px; }
562 626 .stats-page .sub { color: var(--ink-2); max-width: 640px; margin-bottom: 30px; }
563 627
564 −.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 30px; }
628 +.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0 24px; margin-bottom: 34px; }
565 629 .tile {
566 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
567 − padding: 18px 20px; box-shadow: 3px 3px 0 rgba(20, 24, 20, 0.1);
630 + background: transparent; border: 0; border-top: 2.5px solid var(--ink); border-radius: 0;
631 + padding: 12px 0 16px; box-shadow: none;
568 632 }
569 −.tile-v { font-family: var(--font-display); font-weight: 700; font-size: clamp(24px, 3vw, 34px); letter-spacing: -0.03em; line-height: 1.05; }
633 +.tile-v { font-family: var(--font-display); font-weight: 700; font-size: clamp(28px, 3.4vw, 40px); letter-spacing: -0.03em; line-height: 1.05; font-variant-numeric: tabular-nums; }
570 634 .tile-k { font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); margin-top: 6px; }
571 −.hero-tile { background: var(--accent-deep); color: var(--on-accent); border-color: var(--accent-deep); }
572 −.hero-tile .tile-k { color: rgba(255, 255, 255, 0.7); }
635 +.hero-tile { background: transparent; color: var(--ink); border-top-color: var(--accent); }
636 +.hero-tile .tile-v { color: var(--accent-deep); }
637 +.hero-tile .tile-k { color: var(--ink-3); }
573 638
574 639 .viz-card {
575 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
576 − box-shadow: var(--shadow-off-soft); padding: 26px 28px 20px; margin-bottom: 22px;
640 + background: transparent; border: 0; border-top: 2px solid var(--ink); border-radius: 0;
641 + box-shadow: none; padding: 16px 0 8px; margin-bottom: 30px;
577 642 }
578 643 .viz-card h2 { font-size: 19px; text-transform: uppercase; letter-spacing: -0.01em; }
579 644 .viz-sub { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin: 4px 0 20px; }
@@ -653,12 +718,24 @@ button { font-family: inherit; }
653 718 .filterbar.open {
654 719 display: flex; flex-direction: column; gap: 12px;
655 720 position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-modal, 900);
656 − margin: 0; border-radius: 20px 20px 0 0; border-width: 2px 0 0 0;
721 + margin: 0; background: var(--surface); border: 2px solid var(--ink);
722 + border-radius: 20px 20px 0 0; border-width: 2px 0 0 0;
657 723 max-height: 82dvh; overflow-y: auto; -webkit-overflow-scrolling: touch;
658 724 padding: 16px 18px calc(18px + env(safe-area-inset-bottom));
659 725 box-shadow: 0 -16px 48px rgba(16, 18, 16, 0.35);
660 726 animation: sheet-up 0.22s ease;
661 727 }
728 + /* dans la feuille : les contrôles redeviennent des rangées bordées lisibles */
729 + .filterbar.open .f-search {
730 + border: 1.5px solid var(--ink); border-radius: 9px; background: var(--surface-2);
731 + padding: 0 13px; min-height: 52px;
732 + }
733 + .filterbar.open .f-search input { font-size: 16px; font-family: inherit; }
734 + .filterbar.open .f-ctl {
735 + border: 1.5px solid var(--line-strong); border-left-width: 1.5px; border-radius: 9px;
736 + padding: 7px 12px 6px; background: var(--surface);
737 + }
738 + .filterbar.open .f-more { border-left: 0; padding-left: 0; }
662 739 @keyframes sheet-up { from { transform: translateY(30%); opacity: 0.4; } to { transform: none; opacity: 1; } }
663 740 .filterbar.open .sheet-head {
664 741 display: flex; justify-content: space-between; align-items: center;
@@ -746,8 +823,8 @@ button { font-family: inherit; }
746 823 importe le scroll (l'ancien dropdown absolute 480px clippait/se coupait). */
747 824 .mobile-menu {
748 825 display: none; position: fixed; inset: 0;
749 − background: var(--paper);
750 − padding: 76px 16px calc(24px + env(safe-area-inset-bottom));
826 + background: var(--accent-deep); color: #f5f3ee;
827 + padding: 84px 20px calc(24px + env(safe-area-inset-bottom));
751 828 overflow-y: auto; overscroll-behavior: contain;
752 829 }
753 830 .mobile-menu.open { display: block; animation: mm-in 0.16s ease; }
@@ -758,30 +835,32 @@ button { font-family: inherit; }
758 835 .mm-close {
759 836 position: fixed; top: 10px; right: 14px; z-index: 2;
760 837 width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
761 − border: 1.5px solid var(--ink); border-radius: 999px;
762 − background: var(--ink); color: var(--paper);
838 + border: 0; border-radius: 999px;
839 + background: var(--paper); color: var(--accent-deep);
763 840 font-size: 17px; font-weight: 700; line-height: 1; cursor: pointer; padding: 0;
764 841 }
765 842 /* verrou du scroll d'arriere-plan quand le menu est ouvert (CSS pur) */
766 843 html:has(.mobile-menu.open) { overflow: hidden; }
767 844 .mm-link {
768 − display: flex; align-items: center; gap: 12px;
769 − padding: 15px 10px; min-height: 52px;
770 − font-family: var(--font-display); font-weight: 700; font-size: 19px;
771 − letter-spacing: -0.02em; border-bottom: 1.5px dashed var(--line);
845 + display: flex; align-items: center; gap: 14px;
846 + padding: 16px 6px; min-height: 56px; color: #f5f3ee;
847 + font-family: var(--font-display); font-weight: 700; font-size: 24px;
848 + letter-spacing: -0.03em; border-bottom: 1px solid rgba(245, 243, 238, 0.18);
772 849 opacity: 0; transform: translateY(-8px);
773 850 transition: opacity 0.25s ease, transform 0.25s ease;
774 851 }
775 852 .mobile-menu.open .mm-link { opacity: 1; transform: translateY(0); }
776 −.mm-link.active { color: var(--green); }
853 +.mm-link.active { color: #d9f26b; }
777 854 .mm-link.active .mm-arrow { opacity: 1; }
778 855 .mm-ico { width: 26px; text-align: center; font-size: 17px; }
779 −.mm-arrow { margin-left: auto; opacity: 0.25; transition: opacity 0.15s ease; }
780 −.mm-link:active { background: var(--lime-soft); border-radius: var(--r-ctl); }
856 +.mm-arrow { margin-left: auto; opacity: 0.3; transition: opacity 0.15s ease; color: #d9f26b; }
857 +.mm-link:active { background: rgba(245, 243, 238, 0.1); border-radius: var(--r-ctl); }
781 858 .mm-foot {
782 − padding: 12px 10px 4px; font-family: var(--font-mono);
783 − font-size: 10.5px; color: var(--ink-3); letter-spacing: 0.04em;
859 + padding: 14px 6px 4px; font-family: var(--font-mono);
860 + font-size: 10.5px; color: rgba(245, 243, 238, 0.6); letter-spacing: 0.04em;
784 861 }
862 +.mm-badge .gk-badge { background: transparent; border-color: rgba(245, 243, 238, 0.35); color: rgba(245, 243, 238, 0.75); }
863 +.mm-badge .gk-badge b { color: #f5f3ee; }
785 864 .mm-backdrop {
786 865 position: fixed; inset: 0; z-index: var(--z-overlay, 800);
787 866 background: rgba(20, 24, 20, 0.35); backdrop-filter: blur(2px);
@@ -1137,8 +1216,8 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */
1137 1216 .contact-page .lede { color: var(--ink-2); max-width: 640px; margin: 0 0 26px; }
1138 1217 .contact-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; margin: 22px 0; }
1139 1218 .contact-card {
1140 − background: var(--surface); border: 1.5px solid var(--ink); border-radius: var(--r-card);
1141 − padding: 18px 20px; box-shadow: var(--shadow-off-soft);
1219 + background: transparent; border: 0; border-top: 1.5px solid var(--ink); border-radius: 0;
1220 + padding: 14px 0 18px; box-shadow: none;
1142 1221 display: flex; flex-direction: column; gap: 6px; min-width: 0;
1143 1222 }
1144 1223 .contact-card a {
1145 1224