From a607feda60a179474e3dd0e4988dee57fa4838ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sun, 1 Mar 2026 21:50:31 +0100 Subject: [PATCH] feat: apply pro creative-lab art direction and validate astro pipeline --- .github/workflows/deploy-pages.yml | 55 + .gitignore | 9 + .storybook/main.ts | 25 + .storybook/preview.ts | 17 + .../site-github-pages-architecture.md | 35 + .../architect/2026-03-01/g1-arch-freeze-v2.md | 5 + .../architect/2026-03-01/g1-arch-freeze.md | 5 + .../2026-03-01/index.legacy.html | 259 + .../2026-03-01/og-cover.legacy.jpg | Bin 0 -> 22436 bytes .../2026-03-01/robots.legacy.txt | 4 + .../2026-03-01/sitemap.legacy.xml | 9 + .../2026-03-01/styles.legacy.css | 424 + .../pm-spec/2026-03-01/g0-spec-freeze-v2.md | 5 + .../pm-spec/2026-03-01/g0-spec-freeze.md | 6 + .../qa-test/2026-03-01/g2-implement-v2.md | 6 + .../qa-test/2026-03-01/g2-implement-v3.md | 39 + .../2026-03-01/g2-implement-v4-astro.md | 38 + .../qa-test/2026-03-01/g3-verification-v2.md | 7 + .../qa-test/2026-03-01/g3-verification-v3.md | 28 + .../qa-test/2026-03-01/g3-verification-v4.md | 37 + .../qa-test/2026-03-01/g3-verification-v5.md | 34 + .../2026-03-01/g3-verification-v6-astro.md | 21 + .../qa-test/2026-03-01/g3-verification.md | 7 + .../lighthouse-home-desktop-v1.json | 7835 ++++++++++++ .../2026-03-01/lighthouse-home-mobile-v1.json | 7930 ++++++++++++ astro.config.mjs | 11 + docs/acquisition-seo-plan.md | 92 + docs/github-pages-deploy.md | 67 + docs/migration-legacy-to-astro.md | 23 + docs/webdesign-responsive-modern.md | 47 + evidence/manifest.json | 55 + package-lock.json | 10467 ++++++++++++++++ package.json | 37 + public/assets/og-cover.jpg | Bin 0 -> 22436 bytes public/robots.txt | 4 + public/sitemap.xml | 9 + specs/site-github-pages-spec.md | 67 + src/components/sections/About.stories.tsx | 19 + src/components/sections/About.tsx | 20 + src/components/sections/Contact.stories.tsx | 19 + src/components/sections/Contact.tsx | 64 + src/components/sections/Hero.stories.tsx | 19 + src/components/sections/Hero.tsx | 131 + src/components/sections/Projects.stories.tsx | 19 + src/components/sections/Projects.tsx | 85 + src/components/ui/button.stories.tsx | 32 + src/components/ui/button.tsx | 37 + src/components/ui/card.stories.tsx | 20 + src/components/ui/card.tsx | 14 + src/layouts/BaseLayout.astro | 113 + src/lib/site.ts | 17 + src/lib/tracking.ts | 26 + src/lib/types.ts | 9 + src/lib/utils.ts | 6 + src/pages/index.astro | 42 + src/styles/global.css | 201 + tsconfig.json | 10 + 57 files changed, 28622 insertions(+) create mode 100644 .github/workflows/deploy-pages.yml create mode 100644 .gitignore create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.ts create mode 100644 architecture/site-github-pages-architecture.md create mode 100644 artifacts/architect/2026-03-01/g1-arch-freeze-v2.md create mode 100644 artifacts/architect/2026-03-01/g1-arch-freeze.md create mode 100644 artifacts/legacy-snapshot/2026-03-01/index.legacy.html create mode 100644 artifacts/legacy-snapshot/2026-03-01/og-cover.legacy.jpg create mode 100644 artifacts/legacy-snapshot/2026-03-01/robots.legacy.txt create mode 100644 artifacts/legacy-snapshot/2026-03-01/sitemap.legacy.xml create mode 100644 artifacts/legacy-snapshot/2026-03-01/styles.legacy.css create mode 100644 artifacts/pm-spec/2026-03-01/g0-spec-freeze-v2.md create mode 100644 artifacts/pm-spec/2026-03-01/g0-spec-freeze.md create mode 100644 artifacts/qa-test/2026-03-01/g2-implement-v2.md create mode 100644 artifacts/qa-test/2026-03-01/g2-implement-v3.md create mode 100644 artifacts/qa-test/2026-03-01/g2-implement-v4-astro.md create mode 100644 artifacts/qa-test/2026-03-01/g3-verification-v2.md create mode 100644 artifacts/qa-test/2026-03-01/g3-verification-v3.md create mode 100644 artifacts/qa-test/2026-03-01/g3-verification-v4.md create mode 100644 artifacts/qa-test/2026-03-01/g3-verification-v5.md create mode 100644 artifacts/qa-test/2026-03-01/g3-verification-v6-astro.md create mode 100644 artifacts/qa-test/2026-03-01/g3-verification.md create mode 100644 artifacts/qa-test/2026-03-01/lighthouse-home-desktop-v1.json create mode 100644 artifacts/qa-test/2026-03-01/lighthouse-home-mobile-v1.json create mode 100644 astro.config.mjs create mode 100644 docs/acquisition-seo-plan.md create mode 100644 docs/github-pages-deploy.md create mode 100644 docs/migration-legacy-to-astro.md create mode 100644 docs/webdesign-responsive-modern.md create mode 100644 evidence/manifest.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/assets/og-cover.jpg create mode 100644 public/robots.txt create mode 100644 public/sitemap.xml create mode 100644 specs/site-github-pages-spec.md create mode 100644 src/components/sections/About.stories.tsx create mode 100644 src/components/sections/About.tsx create mode 100644 src/components/sections/Contact.stories.tsx create mode 100644 src/components/sections/Contact.tsx create mode 100644 src/components/sections/Hero.stories.tsx create mode 100644 src/components/sections/Hero.tsx create mode 100644 src/components/sections/Projects.stories.tsx create mode 100644 src/components/sections/Projects.tsx create mode 100644 src/components/ui/button.stories.tsx create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/card.stories.tsx create mode 100644 src/components/ui/card.tsx create mode 100644 src/layouts/BaseLayout.astro create mode 100644 src/lib/site.ts create mode 100644 src/lib/tracking.ts create mode 100644 src/lib/types.ts create mode 100644 src/lib/utils.ts create mode 100644 src/pages/index.astro create mode 100644 src/styles/global.css create mode 100644 tsconfig.json diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..b0884d3 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,55 @@ +name: Deploy Astro to GitHub Pages + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + env: + PUBLIC_GTM_CONTAINER_ID: GTM-5SLM67QF + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./dist + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3550c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Internal private notes +notes-interne/ + +# Node / tooling +node_modules/ +dist/ +storybook-static/ +.astro/ +.DS_Store diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..86376a3 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,25 @@ +import type { StorybookConfig } from '@storybook/react-vite'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const config: StorybookConfig = { + stories: ['../src/**/*.stories.@(ts|tsx)'], + addons: ['@storybook/addon-onboarding', '@storybook/addon-docs', '@storybook/addon-a11y', '@storybook/addon-vitest'], + framework: { + name: '@storybook/react-vite', + options: {} + }, + viteFinal: async (config) => { + config.resolve = config.resolve || {}; + config.resolve.alias = { + ...(typeof config.resolve.alias === 'object' ? config.resolve.alias : {}), + '@': path.resolve(fileURLToPath(new URL('../src', import.meta.url))) + }; + return config; + }, + docs: { + autodocs: 'tag' + } +}; + +export default config; diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 0000000..fa12844 --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,17 @@ +import type { Preview } from '@storybook/react-vite'; +import '../src/styles/global.css'; + +const preview: Preview = { + parameters: { + layout: 'fullscreen', + backgrounds: { + default: 'studio-dark', + values: [ + { name: 'studio-dark', value: '#0f0e17' }, + { name: 'studio-deep', value: '#151325' } + ] + } + } +}; + +export default preview; diff --git a/architecture/site-github-pages-architecture.md b/architecture/site-github-pages-architecture.md new file mode 100644 index 0000000..5bded03 --- /dev/null +++ b/architecture/site-github-pages-architecture.md @@ -0,0 +1,35 @@ +# Architecture — Site personnel statique GitHub Pages + +- **Date**: 2026-03-01 +- **Gate visée**: G1 Arch Freeze +- **Responsable (agent)**: Architect + +## Vue d'ensemble +Architecture front statique en 2 fichiers: +- `index.html`: structure sémantique (header/nav/main/sections/footer) +- `assets/styles.css`: thème, layout responsive, composants visuels + +## Interfaces +- **Entrée**: navigateur web moderne +- **Sortie**: rendu d'un site vitrine personnel +- **Hébergement**: GitHub Pages (branch `main`, root) + +## Structure UI +- Bloc `hero` avec CTA. +- Section `#a-propos` pour la présentation. +- Section `#projets` avec grille de cartes. +- Section `#contact` avec liens sortants. + +## Contraintes techniques +- Aucun JS requis pour la version initiale. +- Chemins relatifs uniquement (`assets/styles.css`). +- CSS pur (variables, grid, media queries). + +## Budgets +- Poids page + CSS < 80KB (source non compressée). +- Temps de chargement perçu < 1s sur connexion standard (contenu statique). + +## Validation +- Smoke test HTTP local. +- Vérification ancres + rendu responsive. +- Capture visuelle de preuve. diff --git a/artifacts/architect/2026-03-01/g1-arch-freeze-v2.md b/artifacts/architect/2026-03-01/g1-arch-freeze-v2.md new file mode 100644 index 0000000..325b977 --- /dev/null +++ b/artifacts/architect/2026-03-01/g1-arch-freeze-v2.md @@ -0,0 +1,5 @@ +# G1 Arch Freeze Evidence (v2) + +- Architecture UI détaillée: hero, about, projets, contact. +- Contraintes GitHub Pages (chemins relatifs, statique sans build) confirmées. +- Budgets et stratégie de validation ajustés. diff --git a/artifacts/architect/2026-03-01/g1-arch-freeze.md b/artifacts/architect/2026-03-01/g1-arch-freeze.md new file mode 100644 index 0000000..0a3a68f --- /dev/null +++ b/artifacts/architect/2026-03-01/g1-arch-freeze.md @@ -0,0 +1,5 @@ +# G1 Arch Freeze Evidence + +- Architecture statique validée: `index.html` + `assets/styles.css` +- Interfaces et contraintes de chemins relatifs définies +- Budgets simplifiés documentés diff --git a/artifacts/legacy-snapshot/2026-03-01/index.legacy.html b/artifacts/legacy-snapshot/2026-03-01/index.legacy.html new file mode 100644 index 0000000..f6263af --- /dev/null +++ b/artifacts/legacy-snapshot/2026-03-01/index.legacy.html @@ -0,0 +1,259 @@ + + + + + + Clément Saillant — L'électron rare + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Performance • Noise • Audiovisuel

+

Clément Saillant, alias L'électron rare.

+

+ Projet artistique orienté expérimentations sonores et visuelles: + performances live, textures noise et collaborations entre scène et + image. +

+
    +
  • Live sets
  • +
  • Textures bruitistes
  • +
  • Collab vidéo
  • +
+

+ Voir mes projets + Me contacter +

+
+ +
+
+ +
+

À propos

+

+ Je suis Clément Saillant, artiste et créateur sous le + nom L'électron rare. J'explore les liens entre matière + sonore, récit visuel et énergie live, avec une approche artisanale et + directe. +

+
+ +
+

Projets

+
+
+

L'électron rare

+

+ Univers principal: performances et créations expérimentales entre + musique électronique et visuel. +

+

+ Profil LinkedIn +

+
+
+

Collaborations vidéo

+

+ Travail autour du VJing et des formats hybrides live, notamment avec + des collaborations type VJ Clearscreen. +

+
+
+

Électron Fou (noise)

+

+ Projet noise affilié à la scène expérimentale, avec sorties publiées + et présence sur plateformes audio. +

+

+ Bandcamp +

+
+
+
+ +
+

Contact

+

+ Pour booking, collaboration artistique ou production audiovisuelle, + contactez-moi via les plateformes ci-dessous. +

+ + +
+
+ + + + + + diff --git a/artifacts/legacy-snapshot/2026-03-01/og-cover.legacy.jpg b/artifacts/legacy-snapshot/2026-03-01/og-cover.legacy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..355032bb2457ebf3fc5da7935d5a6148acf4ea54 GIT binary patch literal 22436 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 F{{iVG3P}I} literal 0 HcmV?d00001 diff --git a/artifacts/legacy-snapshot/2026-03-01/robots.legacy.txt b/artifacts/legacy-snapshot/2026-03-01/robots.legacy.txt new file mode 100644 index 0000000..6f1c95a --- /dev/null +++ b/artifacts/legacy-snapshot/2026-03-01/robots.legacy.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://electron-rare.github.io/sitemap.xml diff --git a/artifacts/legacy-snapshot/2026-03-01/sitemap.legacy.xml b/artifacts/legacy-snapshot/2026-03-01/sitemap.legacy.xml new file mode 100644 index 0000000..40c7434 --- /dev/null +++ b/artifacts/legacy-snapshot/2026-03-01/sitemap.legacy.xml @@ -0,0 +1,9 @@ + + + + https://electron-rare.github.io/ + 2026-03-01 + weekly + 1.0 + + diff --git a/artifacts/legacy-snapshot/2026-03-01/styles.legacy.css b/artifacts/legacy-snapshot/2026-03-01/styles.legacy.css new file mode 100644 index 0000000..335e63e --- /dev/null +++ b/artifacts/legacy-snapshot/2026-03-01/styles.legacy.css @@ -0,0 +1,424 @@ +:root { + --bg: #f7f4ec; + --surface: #fffdf7; + --surface-soft: #f2eee3; + --text: #171614; + --muted: #625d50; + --primary: #d74b2a; + --primary-strong: #b83c1f; + --border: #d8d1c1; +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + -webkit-text-size-adjust: 100%; +} + +body { + margin: 0; + font-family: "Avenir Next", "Segoe UI", "Helvetica Neue", sans-serif; + line-height: 1.6; + background: + radial-gradient(circle at 10% 10%, #ffddbf 0%, rgba(255, 221, 191, 0) 40%), + radial-gradient(circle at 90% 0%, #f0d8bf 0%, rgba(240, 216, 191, 0) 35%), + var(--bg); + color: var(--text); + text-rendering: optimizeLegibility; +} + +.skip-link { + position: absolute; + left: -9999px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; +} + +.skip-link:focus { + left: 0.8rem; + top: 0.8rem; + width: auto; + height: auto; + z-index: 40; + background: #111; + color: #fff; + padding: 0.45rem 0.7rem; + border-radius: 0.45rem; +} + +.container { + width: min(1000px, 92vw); + margin: 0 auto; +} + +section[id] { + scroll-margin-top: 6.2rem; +} + +.site-header { + position: sticky; + top: 0; + z-index: 20; + backdrop-filter: blur(8px); + background: rgba(247, 244, 236, 0.86); + border-bottom: 1px solid var(--border); +} + +.nav-wrap { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.8rem 0; +} + +.brand { + color: var(--text); + text-decoration: none; + font-weight: 800; + letter-spacing: 0.01em; +} + +nav ul { + list-style: none; + display: flex; + gap: 1rem; + margin: 0; + padding: 0; +} + +nav a { + display: inline-flex; + align-items: center; + min-height: 2rem; + color: var(--muted); + text-decoration: none; + font-weight: 500; + padding: 0.35rem 0.55rem; + border-radius: 0.45rem; +} + +nav a:hover, +nav a:focus-visible { + color: var(--text); + background: rgba(255, 255, 255, 0.66); +} + +.hero { + padding: clamp(3.2rem, 7vw, 4.8rem) 0 2.2rem; +} + +.hero-grid { + display: grid; + grid-template-columns: 1.25fr 0.8fr; + gap: 1.1rem; + align-items: end; +} + +.eyebrow { + color: var(--primary); + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + margin: 0; + font-size: 0.8rem; +} + +h1 { + font-size: clamp(2rem, 5vw, 3.2rem); + line-height: 1.12; + margin: 0.6rem 0 1rem; + max-width: 18ch; + text-wrap: balance; +} + +.hero-text { + max-width: 64ch; + margin: 0 0 1.4rem; + color: var(--muted); +} + +.hero-metrics { + list-style: none; + display: flex; + flex-wrap: wrap; + gap: 0.55rem; + margin: 0 0 1.3rem; + padding: 0; +} + +.hero-metrics li { + background: rgba(255, 255, 255, 0.76); + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.3rem 0.65rem; + font-size: 0.92rem; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + gap: 0.7rem; +} + +.btn { + min-height: 2.75rem; + display: inline-block; + padding: 0.7rem 1.02rem; + border-radius: 0.7rem; + text-decoration: none; + font-weight: 600; + transition: transform 140ms ease, box-shadow 140ms ease, background-color 140ms ease; +} + +.btn-primary { + background: var(--primary); + color: #fff7f1; +} + +.btn-primary:hover, +.btn-primary:focus-visible { + background: var(--primary-strong); + transform: translateY(-1px); + box-shadow: 0 8px 18px rgba(183, 60, 31, 0.22); +} + +.btn-secondary { + border: 1px solid var(--border); + color: var(--text); + background: rgba(255, 255, 255, 0.65); +} + +.btn-secondary:hover, +.btn-secondary:focus-visible { + transform: translateY(-1px); +} + +.hero-card { + background: linear-gradient(180deg, #fff6eb 0%, #f3e6d4 100%); + border: 1px solid #ddc8ab; + border-radius: 14px; + padding: 1rem 1rem 1.1rem; + box-shadow: 0 12px 26px rgba(30, 18, 6, 0.11); +} + +.hero-card-kicker { + margin: 0; + color: #90633d; + font-size: 0.78rem; + text-transform: uppercase; + letter-spacing: 0.06em; +} + +.hero-card h2 { + margin: 0.35rem 0 0.45rem; + font-size: 1.4rem; +} + +.hero-card p { + margin: 0 0 0.7rem; + color: #4f4639; +} + +.hero-card a { + color: var(--primary-strong); + font-weight: 700; + text-decoration: none; +} + +.hero-card a:hover, +.hero-card a:focus-visible { + text-decoration: underline; +} + +.panel { + background: linear-gradient(180deg, var(--surface) 0%, var(--surface-soft) 100%); + border: 1px solid var(--border); + border-radius: 14px; + padding: 1.1rem 1.2rem 1.25rem; + margin: 1rem 0; + box-shadow: 0 10px 24px rgba(30, 18, 6, 0.07); + content-visibility: auto; + contain-intrinsic-size: 1px 500px; +} + +h2 { + margin-top: 0.2rem; + text-wrap: balance; +} + +.cards { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 0.9rem; +} + +.card { + grid-column: span 4; + background: rgba(255, 252, 246, 0.86); + border: 1px solid var(--border); + border-radius: 10px; + padding: 0.9rem; + transition: transform 140ms ease, box-shadow 140ms ease; +} + +.card h3 { + margin-top: 0.1rem; + margin-bottom: 0.45rem; +} + +.card p { + margin-top: 0; +} + +.card a { + color: var(--primary); + font-weight: 600; + text-decoration: none; +} + +.card a:hover, +.card a:focus-visible { + text-decoration: underline; +} + +.card:hover { + transform: translateY(-2px); + box-shadow: 0 10px 18px rgba(30, 18, 6, 0.08); +} + +.contact-list { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 0.3rem; +} + +.contact-list a { + display: inline-flex; + align-items: center; + min-height: 2rem; + color: var(--primary); + text-decoration: none; + font-weight: 600; +} + +.contact-list a:hover, +.contact-list a:focus-visible { + text-decoration: underline; +} + +.contact-intro { + margin-top: 0; + color: var(--muted); + max-width: 62ch; +} + +.trust-points { + margin: 0.95rem 0 0; + padding-left: 1.1rem; + color: var(--muted); +} + +.trust-points li + li { + margin-top: 0.3rem; +} + +.site-footer { + border-top: 1px solid var(--border); + color: var(--muted); + padding: 1.2rem 0 2.2rem; + margin-top: 1.6rem; +} + +a:focus-visible, +button:focus-visible { + outline: 3px solid var(--primary); + outline-offset: 2px; + border-radius: 4px; +} + +@media (max-width: 960px) { + .hero-grid { + grid-template-columns: 1fr; + } + + .hero-card { + max-width: 38rem; + } + + .cards { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .card { + grid-column: auto; + } +} + +@media (max-width: 760px) { + .nav-wrap { + flex-direction: column; + gap: 0.7rem; + } + + nav ul { + flex-wrap: wrap; + justify-content: center; + gap: 0.45rem; + } + + nav a { + display: inline-block; + padding: 0.42rem 0.62rem; + } + + .cards { + grid-template-columns: 1fr; + } + + .hero { + padding-top: 2.4rem; + } +} + +@media (max-width: 390px) { + .container { + width: min(1000px, 94vw); + } + + h1 { + font-size: clamp(1.72rem, 9vw, 2.25rem); + } + + .hero-actions { + gap: 0.55rem; + } + + .btn { + width: 100%; + text-align: center; + } +} + +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 1ms !important; + animation-iteration-count: 1 !important; + transition-duration: 1ms !important; + scroll-behavior: auto !important; + } +} + +@media (prefers-contrast: more) { + :root { + --muted: #453f33; + --border: #8b816d; + } +} diff --git a/artifacts/pm-spec/2026-03-01/g0-spec-freeze-v2.md b/artifacts/pm-spec/2026-03-01/g0-spec-freeze-v2.md new file mode 100644 index 0000000..20fd2b6 --- /dev/null +++ b/artifacts/pm-spec/2026-03-01/g0-spec-freeze-v2.md @@ -0,0 +1,5 @@ +# G0 Spec Freeze Evidence (v2) + +- Spécification orientée « site personnel » finalisée. +- AC mis à jour avec navigation ancrée et contenu vitrine. +- Non-goals, risques et TODO de personnalisation documentés. diff --git a/artifacts/pm-spec/2026-03-01/g0-spec-freeze.md b/artifacts/pm-spec/2026-03-01/g0-spec-freeze.md new file mode 100644 index 0000000..dc03a59 --- /dev/null +++ b/artifacts/pm-spec/2026-03-01/g0-spec-freeze.md @@ -0,0 +1,6 @@ +# G0 Spec Freeze Evidence + +- Spec créée: `specs/site-github-pages-spec.md` +- AC définis: AC1..AC4 +- Non-goals et risques documentés +- TODO ajoutés pour informations manquantes diff --git a/artifacts/qa-test/2026-03-01/g2-implement-v2.md b/artifacts/qa-test/2026-03-01/g2-implement-v2.md new file mode 100644 index 0000000..c03ab24 --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g2-implement-v2.md @@ -0,0 +1,6 @@ +# G2 Implement Evidence (v2) + +Implémentation livrée: +- `index.html` transformé en template de site personnel complet. +- `assets/styles.css` enrichi (navigation sticky, sections, cartes projets, responsive). +- Documentation de déploiement mise à jour. diff --git a/artifacts/qa-test/2026-03-01/g2-implement-v3.md b/artifacts/qa-test/2026-03-01/g2-implement-v3.md new file mode 100644 index 0000000..a8d2549 --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g2-implement-v3.md @@ -0,0 +1,39 @@ +# G2 Implement Evidence (v3) - SEO + Acquisition + +Date: 2026-03-01 + +## Portée implémentée +- SEO technique: canonical, robots, sitemap, OG/Twitter image. +- Tracking contract: événements CTA/outbound avec `event_category`, `event_label`, `destination`. +- Bootstrap GTM prêt à brancher (`GTM-REPLACE_ME`). +- Conversion UX: section contact enrichie + trust points. +- Accessibilité/réactivité: skip-link déjà présent + réglage ultra-mobile (`<=390px`). + +## Fichiers modifiés +- `index.html` +- `assets/styles.css` +- `docs/github-pages-deploy.md` +- `robots.txt` (nouveau) +- `sitemap.xml` (nouveau) +- `assets/og-cover.jpg` (nouveau) + +## Mapping tracking (event -> destination) +| Event | Type | Destination | Usage | +|---|---|---|---| +| `cta_hero_projets` | CTA interne | `#projets` | Navigation vers section projets | +| `cta_hero_contact` | CTA interne | `#contact` | Navigation vers section contact | +| `cta_hero_profile` | CTA interne | `#a-propos` | Navigation vers section profil | +| `outbound_linkedin_project` | Sortant | `linkedin.com` | Preuve sociale projet | +| `outbound_linkedin_contact` | Sortant | `linkedin.com` | Conversion primaire | +| `outbound_malt_contact` | Sortant | `malt.com` | Conversion secondaire | +| `outbound_bandcamp_project` | Sortant | `bandcamp.com` | Projet musical | +| `outbound_bandcamp_contact` | Sortant | `bandcamp.com` | Contact alternatif | + +Paramètres communs poussés: +- `event_category=engagement` +- `event_label=` +- `destination=` + +## Notes +- Pour activer GTM en production: remplacer `GTM-REPLACE_ME` dans le script head et le bloc noscript. +- URL canonique actuelle: `https://electron-rare.github.io/`. diff --git a/artifacts/qa-test/2026-03-01/g2-implement-v4-astro.md b/artifacts/qa-test/2026-03-01/g2-implement-v4-astro.md new file mode 100644 index 0000000..002d5fb --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g2-implement-v4-astro.md @@ -0,0 +1,38 @@ +# G2 Implement Evidence (v4) - Astro Studio Migration Foundation + +Date: 2026-03-01 + +## Scope implémenté +- Mise en place stack primaire: + - Astro + TypeScript strict + - React integration + - Tailwind 4 (via plugin Vite) + - Motion + - Radix/shadcn-like base (`Button` with Radix Slot + CVA) + - Storybook React-Vite +- Création architecture `src/` composantisée: + - `src/layouts/BaseLayout.astro` + - `src/pages/index.astro` + - sections React (`Hero`, `About`, `Projects`, `Contact`) + - composants UI (`Button`, `Card`) +- Conservation contrat SEO/analytics: + - metadata canonical/OG/Twitter + - JSON-LD Person + - contrat `dataLayer` (`event_category`, `event_label`, `destination`) + - GTM ID `GTM-5SLM67QF` via `PUBLIC_GTM_CONTAINER_ID` fallback +- Préparation déploiement Pages via GitHub Actions: + - `.github/workflows/deploy-pages.yml` +- Storybook full coverage initiale des composants/sections clés. + +## Fichiers clés ajoutés/modifiés +- `package.json`, `package-lock.json` +- `astro.config.mjs`, `tsconfig.json` +- `src/**` (layouts/components/styles/pages) +- `.storybook/main.ts`, `.storybook/preview.ts` +- `.github/workflows/deploy-pages.yml` +- `public/robots.txt`, `public/sitemap.xml`, `public/assets/og-cover.jpg` +- `docs/github-pages-deploy.md` +- `specs/site-github-pages-spec.md` + +## Note +- L'ancien socle statique (`index.html`, `assets/styles.css`) est conservé temporairement dans le repo pour transition contrôlée. diff --git a/artifacts/qa-test/2026-03-01/g3-verification-v2.md b/artifacts/qa-test/2026-03-01/g3-verification-v2.md new file mode 100644 index 0000000..5c020d1 --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g3-verification-v2.md @@ -0,0 +1,7 @@ +# G3 Verification Evidence (v2) + +Vérifications exécutées: +- `python3 -m http.server 4173` +- `curl -I http://127.0.0.1:4173/` -> `HTTP/1.0 200 OK` +- `rg 'href="/' index.html` (attendu: aucune occurrence) +- Capture Playwright: `artifacts/qa-test/2026-03-01/site-home-v2.png` diff --git a/artifacts/qa-test/2026-03-01/g3-verification-v3.md b/artifacts/qa-test/2026-03-01/g3-verification-v3.md new file mode 100644 index 0000000..37271ae --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g3-verification-v3.md @@ -0,0 +1,28 @@ +# G3 Verification Evidence (v3) - SEO + Tracking + +Date: 2026-03-01 + +## Vérifications exécutées +- `rg -n "canonical|og:image|twitter:image|application/ld\+json|GTM_CONTAINER_ID|event_category|event_label|destination" index.html` +- `rg -n "data-track=|data-destination=" index.html` +- `sips -g pixelWidth -g pixelHeight assets/og-cover.jpg` +- `cat robots.txt` +- `cat sitemap.xml` +- `python3 -m http.server 4173` puis: + - `curl -I http://127.0.0.1:4173/` + - `curl -s http://127.0.0.1:4173/robots.txt` + - `curl -s http://127.0.0.1:4173/sitemap.xml` + +## Résultats attendus/observés +- Canonical présent et fixé sur `https://electron-rare.github.io/`. +- OG/Twitter image renseignée vers `assets/og-cover.jpg` (URL absolue). +- JSON-LD `Person` enrichi (`jobTitle`, `description`, `sameAs`). +- Contrat dataLayer conforme (`event_category`, `event_label`, `destination`). +- `assets/og-cover.jpg` présent en `1200x630`. +- `robots.txt` et `sitemap.xml` accessibles. +- HTTP local `/` retourne `200 OK`. + +## Contrôles manuels restants (production) +- Publier le conteneur GTM réel et remplacer `GTM-REPLACE_ME`. +- Vérifier la remontée GA4 Realtime des événements clés. +- Valider les aperçus sociaux via LinkedIn Post Inspector/Facebook Sharing Debugger. diff --git a/artifacts/qa-test/2026-03-01/g3-verification-v4.md b/artifacts/qa-test/2026-03-01/g3-verification-v4.md new file mode 100644 index 0000000..5c8fe18 --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g3-verification-v4.md @@ -0,0 +1,37 @@ +# G3 Verification Evidence (v4) - Full TODO Validation Pass + +Date: 2026-03-01 + +## Lighthouse (local) +Source URL testée: `http://127.0.0.1:4173/` + +### Mobile +- performance: **93** +- accessibility: **95** +- best-practices: **96** +- seo: **100** + +### Desktop +- performance: **100** +- accessibility: **95** +- best-practices: **96** +- seo: **100** + +Artifacts JSON: +- `artifacts/qa-test/2026-03-01/lighthouse-home-mobile-v1.json` +- `artifacts/qa-test/2026-03-01/lighthouse-home-desktop-v1.json` + +## Validations structurelles +- JSON-LD `Person`: **OK** (`jobTitle`, `description`, `sameAs` présents) +- `sitemap.xml` parse XML: **OK** +- `robots.txt` présent et exploitable: **OK** +- `assets/og-cover.jpg` dimensions: **1200x630** +- Contrat tracking (`event_category`, `event_label`, `destination`): **OK** + +## TODO status final +- ✅ Canonical / OG / Twitter / sitemap / robots +- ✅ Tracking contract côté front +- ✅ Lighthouse archivé +- ✅ GTM réel configuré (`GTM-5SLM67QF`) +- ⏳ Validation GA4 Realtime en production +- ⏳ Debugger aperçu social en production (action externe) diff --git a/artifacts/qa-test/2026-03-01/g3-verification-v5.md b/artifacts/qa-test/2026-03-01/g3-verification-v5.md new file mode 100644 index 0000000..7245ef1 --- /dev/null +++ b/artifacts/qa-test/2026-03-01/g3-verification-v5.md @@ -0,0 +1,34 @@ +# G3 Verification Evidence (v5) - Tracking Contract + GTM ID + +Date: 2026-03-01 + +## Validation locale du contrat tracking +Commandes exécutées: +- extraction `data-track` et `data-destination` depuis `index.html` +- vérification présence des champs dataLayer (`event_category`, `event_label`, `destination`) + +Résultats: +- `tracked_links`: 8 +- `missing_destination_count`: 0 +- `js_contract_ok`: true +- `missing_required_events`: [] + +Événements détectés: +- `cta_hero_projets` +- `cta_hero_contact` +- `cta_hero_profile` +- `outbound_linkedin_project` +- `outbound_linkedin_contact` +- `outbound_malt_contact` +- `outbound_bandcamp_project` +- `outbound_bandcamp_contact` + +## GTM +- ID configuré: `GTM-5SLM67QF` +- emplacements validés: + - `window.GTM_CONTAINER_ID` + - bloc `