Clean white-contrast rollout and sync tracking checks
This commit is contained in:
@@ -94,18 +94,19 @@ Consolider la DA actuelle en version claire, contraste blanc, sans reintroduire
|
||||
- contact direct
|
||||
|
||||
## Backlog P0
|
||||
- [ ] Forcer la cascade sur la DA blanche dans `BaseLayout.astro`, `site.ts`, `global.css`, `home-workbench.css`.
|
||||
- [ ] Relever les derniers blocs sombres restants: `hero-bg-photo`, `photo-strip`, `video-strip`, `contact-minitel`, FAQ focus.
|
||||
- [x] Forcer la cascade sur la DA blanche dans `BaseLayout.astro`, `site.ts`, `global.css`, `home-workbench.css`.
|
||||
- [x] Relever les derniers blocs sombres restants: `hero-bg-photo`, `photo-strip`, `video-strip`, `contact-minitel`, FAQ focus.
|
||||
- [ ] Verifier la lisibilite des CTA sur blanc.
|
||||
- [ ] Verifier que la home et `formation` partagent bien le meme socle visuel.
|
||||
- [ ] Verifier que la home et `formation` partagent bien le meme socle visuel en preview live.
|
||||
|
||||
## Backlog P1
|
||||
- [ ] Supprimer les references documentaires a `#projets`, Malt, GitHub Pages static prod, dual-rail hero, contrast toggle.
|
||||
- [ ] Verifier les events `data-track` sur les CTA actifs uniquement.
|
||||
- [x] Recaler `tracking:check` sur le contrat Astro actif pour sortir des faux positifs legacy.
|
||||
- [ ] Valider preview OVH puis prod.
|
||||
|
||||
## Backlog P2
|
||||
- [ ] Supprimer les reliquats `.site-contrast-toggle` du CSS global.
|
||||
- [x] Supprimer les reliquats `.site-contrast-toggle` du CSS global.
|
||||
- [ ] Evaluer si un vrai theme secondaire doit exister plus tard ou si le mode blanc reste la seule version publique.
|
||||
- [ ] Consolider une archive explicite des anciens artefacts DA pour eviter toute reintroduction.
|
||||
|
||||
|
||||
@@ -22,11 +22,14 @@ Source of truth: this file for execution priorities, plus the current code in `s
|
||||
- [x] Ancienne variante `studio/figma` sortie du runtime actif.
|
||||
- [x] Bouton contraste retire du markup.
|
||||
- [x] Theme blanc contraste force par defaut dans le layout source.
|
||||
- [x] Reliquats CSS `.site-contrast-toggle` supprimes du source actif.
|
||||
- [x] Build preview local `PUBLIC_SITE_URL=/preview/` repasse propre.
|
||||
- [x] Validation tracking recalee sur le contrat Astro actif.
|
||||
- [ ] White-contrast pass verifiee visuellement sur preview.
|
||||
- [ ] White-contrast pass verifiee visuellement sur production.
|
||||
|
||||
## P0 - Bloc de sortie immediate
|
||||
- [ ] Builder le preview avec le theme blanc contraste (`PUBLIC_SITE_URL=https://www.lelectronrare.fr/preview/ npm run build:external`).
|
||||
- [x] Builder le preview avec le theme blanc contraste (`PUBLIC_SITE_URL=https://www.lelectronrare.fr/preview/ npm run build:external`).
|
||||
- [ ] Verifier le rendu de la home: nav, hero, approche, cas clients, missions, FAQ, footer.
|
||||
- [ ] Verifier les surfaces medias: hero photo, photo strip, video strip.
|
||||
- [ ] Verifier la section contact en version claire: tabs, textarea, formulaire, focus clavier, messages d'etat.
|
||||
@@ -55,7 +58,7 @@ Source of truth: this file for execution priorities, plus the current code in `s
|
||||
- [ ] Soumettre ou recontroler Search Console sur la base de la prod actuelle OVH.
|
||||
|
||||
## P3 - Nettoyage et consolidation
|
||||
- [ ] Supprimer les blocs CSS morts `.site-contrast-toggle` encore presents dans `src/styles/global.css`.
|
||||
- [x] Supprimer les blocs CSS morts `.site-contrast-toggle` encore presents dans `src/styles/global.css`.
|
||||
- [ ] Nettoyer les docs qui parlent encore de GitHub Pages static root, `#projets`, Malt, ou du toggle contraste.
|
||||
- [ ] Mesurer LCP et budget media de la variante blanche en conditions reelles.
|
||||
- [ ] Archiver les plans anterieurs devenus purement historiques.
|
||||
|
||||
@@ -1,45 +1,96 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const htmlPath = new URL('../index.html', import.meta.url);
|
||||
const html = fs.readFileSync(htmlPath, 'utf8');
|
||||
|
||||
const expectedPrimary = [
|
||||
'cta_hero_projets',
|
||||
'cta_hero_contact',
|
||||
'cta_hero_profile',
|
||||
'outbound_linkedin_contact',
|
||||
'outbound_malt_contact',
|
||||
'outbound_bandcamp_contact',
|
||||
'outbound_github_contact',
|
||||
'outbound_github_project_rtc_bl_phone',
|
||||
'outbound_github_project_zacus',
|
||||
'outbound_github_project_site',
|
||||
'outbound_github_lab_more',
|
||||
'cta_lab_interactif_open'
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(__dirname, '..');
|
||||
const trackingFile = path.join(repoRoot, 'src/lib/tracking.ts');
|
||||
const sourceRoots = [
|
||||
path.join(repoRoot, 'src/pages'),
|
||||
path.join(repoRoot, 'src/components'),
|
||||
path.join(repoRoot, 'src/content')
|
||||
];
|
||||
|
||||
const expectedLegacy = ['outbound_github_project', 'outbound_github_contact'];
|
||||
|
||||
const dataTrackMatches = [...html.matchAll(/data-track="([^"]+)"/g)].map((m) => m[1]);
|
||||
const dataLegacyMatches = [...html.matchAll(/data-track-legacy="([^"]+)"/g)].map((m) => m[1]);
|
||||
|
||||
const uniqueDataTrack = [...new Set(dataTrackMatches)];
|
||||
const uniqueLegacyTrack = [...new Set(dataLegacyMatches)];
|
||||
|
||||
const missingPrimary = expectedPrimary.filter((eventName) => !uniqueDataTrack.includes(eventName));
|
||||
const missingLegacy = expectedLegacy.filter((eventName) => !uniqueLegacyTrack.includes(eventName));
|
||||
|
||||
if (missingPrimary.length || missingLegacy.length) {
|
||||
console.error('Tracking contract validation failed.');
|
||||
if (missingPrimary.length) {
|
||||
console.error(`Missing primary events: ${missingPrimary.join(', ')}`);
|
||||
function walk(dir) {
|
||||
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
return walk(fullPath);
|
||||
}
|
||||
if (missingLegacy.length) {
|
||||
console.error(`Missing legacy events: ${missingLegacy.join(', ')}`);
|
||||
if (/\.(astro|tsx|ts|jsx|js)$/.test(entry.name)) {
|
||||
return [fullPath];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
function readTrackEvents() {
|
||||
const source = fs.readFileSync(trackingFile, 'utf8');
|
||||
const objectMatch = source.match(/TRACK_EVENTS\s*=\s*\{([\s\S]*?)\}\s*as const/);
|
||||
if (!objectMatch) {
|
||||
throw new Error('Unable to parse TRACK_EVENTS from src/lib/tracking.ts');
|
||||
}
|
||||
|
||||
const entries = [...objectMatch[1].matchAll(/(\w+)\s*:\s*'([^']+)'/g)].map((match) => ({
|
||||
key: match[1],
|
||||
value: match[2]
|
||||
}));
|
||||
|
||||
return new Map(entries.map(({ key, value }) => [key, value]));
|
||||
}
|
||||
|
||||
const knownEvents = readTrackEvents();
|
||||
const usedEventKeys = new Set();
|
||||
const usedRawEvents = new Set();
|
||||
const legacyAttrs = [];
|
||||
|
||||
for (const sourceRoot of sourceRoots) {
|
||||
for (const filePath of walk(sourceRoot)) {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
for (const match of content.matchAll(/TRACK_EVENTS\.(\w+)/g)) {
|
||||
usedEventKeys.add(match[1]);
|
||||
}
|
||||
|
||||
for (const match of content.matchAll(/data-track="([^"]+)"/g)) {
|
||||
usedRawEvents.add(match[1]);
|
||||
}
|
||||
|
||||
if (content.includes('data-track-legacy=')) {
|
||||
legacyAttrs.push(path.relative(repoRoot, filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const usedEvents = new Set(
|
||||
[...usedEventKeys]
|
||||
.filter((key) => knownEvents.has(key))
|
||||
.map((key) => knownEvents.get(key))
|
||||
.concat([...usedRawEvents])
|
||||
);
|
||||
|
||||
const missingEvents = [...knownEvents.entries()]
|
||||
.filter(([_, value]) => !usedEvents.has(value))
|
||||
.map(([key, value]) => `${key}=${value}`);
|
||||
|
||||
const unexpectedEvents = [...usedEvents].filter(
|
||||
(value) => ![...knownEvents.values()].includes(value)
|
||||
);
|
||||
|
||||
if (legacyAttrs.length || missingEvents.length || unexpectedEvents.length) {
|
||||
console.error('Tracking contract validation failed.');
|
||||
if (legacyAttrs.length) {
|
||||
console.error(`Legacy tracking attrs found in: ${legacyAttrs.join(', ')}`);
|
||||
}
|
||||
if (missingEvents.length) {
|
||||
console.error(`Known events missing from active source: ${missingEvents.join(', ')}`);
|
||||
}
|
||||
if (unexpectedEvents.length) {
|
||||
console.error(`Unknown tracking events found in active source: ${unexpectedEvents.join(', ')}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Tracking contract validation passed.');
|
||||
console.log(`Primary events found (${uniqueDataTrack.length}): ${uniqueDataTrack.join(', ')}`);
|
||||
console.log(`Legacy events found (${uniqueLegacyTrack.length}): ${uniqueLegacyTrack.join(', ')}`);
|
||||
console.log(`Known events (${knownEvents.size}): ${[...knownEvents.values()].join(', ')}`);
|
||||
console.log(`Active events used (${usedEvents.size}): ${[...usedEvents].join(', ')}`);
|
||||
|
||||
+2
-145
@@ -786,32 +786,6 @@ h3 {
|
||||
color: color-mix(in oklab, var(--electric) 82%, var(--text) 18%);
|
||||
}
|
||||
|
||||
.site-contrast-toggle {
|
||||
border: 1px solid color-mix(in oklab, var(--trace-cyan) 48%, transparent);
|
||||
}
|
||||
|
||||
.site-contrast-toggle {
|
||||
background: color-mix(in oklab, var(--surface-soft) 74%, transparent);
|
||||
}
|
||||
|
||||
.site-contrast-toggle {
|
||||
color: color-mix(in oklab, var(--electric) 90%, var(--text) 10%);
|
||||
}
|
||||
|
||||
.site-contrast-toggle:hover,
|
||||
.site-contrast-toggle:focus-visible {
|
||||
border-color: color-mix(in oklab, var(--electric) 70%, transparent);
|
||||
}
|
||||
|
||||
.site-contrast-toggle:hover,
|
||||
.site-contrast-toggle:focus-visible {
|
||||
background: color-mix(in oklab, var(--electric) 12%, transparent);
|
||||
}
|
||||
|
||||
.site-contrast-toggle:before {
|
||||
border: 1px solid color-mix(in oklab, var(--text) 70%, transparent);
|
||||
}
|
||||
|
||||
.projects-timeline-item:before {
|
||||
border: 1px solid color-mix(in oklab, var(--trace-cyan) 44%, transparent);
|
||||
}
|
||||
@@ -999,57 +973,6 @@ h3 {
|
||||
.studio-muted {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.site-contrast-toggle {
|
||||
border: 1px solid var(--trace-cyan);
|
||||
border-radius: 999px;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
min-height: 2rem;
|
||||
padding: 0 0.88rem;
|
||||
display: inline-flex;
|
||||
}
|
||||
.site-contrast-toggle {
|
||||
background: var(--surface-soft);
|
||||
}
|
||||
.site-contrast-toggle {
|
||||
color: var(--electric);
|
||||
}
|
||||
.site-contrast-toggle {
|
||||
letter-spacing: 0.04em;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
transition:
|
||||
background 0.2s,
|
||||
border-color 0.2s,
|
||||
transform 0.2s;
|
||||
}
|
||||
.site-contrast-toggle:hover,
|
||||
.site-contrast-toggle:focus-visible {
|
||||
border-color: var(--electric);
|
||||
}
|
||||
.site-contrast-toggle:hover,
|
||||
.site-contrast-toggle:focus-visible {
|
||||
background: var(--electric);
|
||||
}
|
||||
.site-contrast-toggle:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
.site-contrast-toggle:before {
|
||||
content: "";
|
||||
border: 1px solid var(--text);
|
||||
border-radius: 999px;
|
||||
width: 0.55rem;
|
||||
height: 0.55rem;
|
||||
}
|
||||
.site-contrast-toggle:before {
|
||||
background: radial-gradient(
|
||||
circle at 35% 35%,
|
||||
var(--trace-cyan),
|
||||
transparent 58%
|
||||
);
|
||||
}
|
||||
.projects-timeline-item {
|
||||
grid-template-columns: 4.5rem 1fr;
|
||||
gap: 0.32rem;
|
||||
@@ -1224,11 +1147,6 @@ button:focus-visible {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
.site-contrast-toggle {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 14rem;
|
||||
}
|
||||
.site-shell-title {
|
||||
max-width: 12ch;
|
||||
}
|
||||
@@ -1426,7 +1344,6 @@ li {
|
||||
sans-serif;
|
||||
}
|
||||
.site-navlink,
|
||||
.site-contrast-toggle,
|
||||
.lab-kicker,
|
||||
.lab-pill,
|
||||
.studio-chip {
|
||||
@@ -1572,16 +1489,6 @@ li {
|
||||
border-radius: 0.3rem;
|
||||
font-size: 0.61rem;
|
||||
}
|
||||
.site-contrast-toggle {
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
border-radius: 0.28rem;
|
||||
min-height: 1.95rem;
|
||||
font-size: 0.66rem;
|
||||
}
|
||||
.site-contrast-toggle:before {
|
||||
border-radius: 1px;
|
||||
}
|
||||
.circuit-board,
|
||||
.lab-panel,
|
||||
.studio-panel {
|
||||
@@ -3178,25 +3085,6 @@ footer:before {
|
||||
color: #3a2e22;
|
||||
}
|
||||
|
||||
/* HIGH-CONTRAST: contrast toggle */
|
||||
:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle {
|
||||
background: #ffffff;
|
||||
border-color: #333;
|
||||
color: #1a1a1a;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle:hover,
|
||||
:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle:focus-visible {
|
||||
background: #f0e8dd;
|
||||
border-color: #1a1a1a;
|
||||
box-shadow: 0 0 0 2px #1a1a1a;
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle::before {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* HIGH-CONTRAST: pills / CTAs */
|
||||
:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-pill--secondary,
|
||||
:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-cta {
|
||||
@@ -3481,25 +3369,6 @@ footer:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle {
|
||||
min-height: 2.5rem;
|
||||
border-color: rgba(120, 94, 73, 0.18);
|
||||
background: rgba(255, 250, 243, 0.86);
|
||||
color: #4d3a30;
|
||||
box-shadow: 0 8px 20px rgba(99, 74, 54, 0.08);
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle:hover,
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle:focus-visible {
|
||||
background: rgba(255, 253, 249, 0.98);
|
||||
border-color: rgba(120, 94, 73, 0.28);
|
||||
box-shadow: 0 12px 24px rgba(99, 74, 54, 0.12);
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle::before {
|
||||
background: linear-gradient(90deg, rgba(183, 86, 44, 0.18), rgba(47, 104, 118, 0.18));
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-row {
|
||||
min-height: 4.25rem;
|
||||
gap: 1.2rem;
|
||||
@@ -4351,8 +4220,7 @@ details[open] > .faq-question .faq-chevron::after {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link,
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle {
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link {
|
||||
min-height: 2.2rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -4376,9 +4244,7 @@ details[open] > .faq-question .faq-chevron::after {
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link:hover,
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link:focus-visible,
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link.is-active,
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link[aria-current="location"],
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle:hover,
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle:focus-visible {
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link[aria-current="location"] {
|
||||
color: #cbffd0;
|
||||
border-color: rgba(51, 255, 255, 0.3);
|
||||
background:
|
||||
@@ -4390,10 +4256,6 @@ details[open] > .faq-question .faq-chevron::after {
|
||||
text-shadow: 0 0 10px rgba(51, 255, 51, 0.22);
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle::before {
|
||||
background: linear-gradient(90deg, rgba(51, 255, 255, 0.16), rgba(51, 255, 51, 0.16));
|
||||
}
|
||||
|
||||
:root[data-da-variant="v12"] .figma-lab-left,
|
||||
:root[data-da-variant="v12"] .figma-lab-right,
|
||||
:root[data-da-variant="v12"] .circuit-board,
|
||||
@@ -4737,7 +4599,6 @@ details[open] > .faq-question .faq-chevron::after {
|
||||
@media (max-width: 767px) {
|
||||
|
||||
:root[data-da-variant="v12"] .figma-lab-nav-link,
|
||||
:root[data-da-variant="v12"] .site-contrast-toggle,
|
||||
:root[data-da-variant="v12"] .figma-lab-pill,
|
||||
:root[data-da-variant="v12"] .graphic-sprints-cta {
|
||||
width: 100%;
|
||||
@@ -4758,10 +4619,6 @@ details[open] > .faq-question .faq-chevron::after {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.site-contrast-toggle {
|
||||
min-height: 2.75rem; /* 44px */
|
||||
}
|
||||
|
||||
/* About section photo integration */
|
||||
.about-intro {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user