From 00160f671187ddd17458a67157441fd6eea3f802 Mon Sep 17 00:00:00 2001 From: alexsoyes Date: Wed, 24 Jun 2026 13:42:01 +0200 Subject: [PATCH 1/3] Refine cover and signature layouts --- ...24T11-10-02Z__app-src-pages-index-astro.md | 94 +++++++++++++++ AGENTS.md | 99 ++++++++++++++++ PRODUCT.md | 33 ++++++ .../components/definition/VersusSchemas.astro | 16 +-- app/src/components/sections/Values.astro | 4 +- .../components/signature/SignatureWall.astro | 82 +++++++------ app/src/styles/sections/base.css | 3 + app/src/styles/sections/cover.css | 110 +++++++++++++----- app/src/styles/sections/definition.css | 11 +- app/src/styles/sections/footer.css | 3 +- app/src/styles/sections/layout.css | 4 +- app/src/styles/sections/principles.css | 20 +++- app/src/styles/sections/signature.css | 108 ++++++++++++++++- app/src/styles/sections/terminal.css | 3 + app/src/styles/sections/value-art.css | 6 + app/src/styles/sections/values.css | 68 +++++++---- app/src/styles/tokens.css | 2 +- 17 files changed, 550 insertions(+), 116 deletions(-) create mode 100644 .impeccable/critique/2026-06-24T11-10-02Z__app-src-pages-index-astro.md create mode 100644 AGENTS.md create mode 100644 PRODUCT.md diff --git a/.impeccable/critique/2026-06-24T11-10-02Z__app-src-pages-index-astro.md b/.impeccable/critique/2026-06-24T11-10-02Z__app-src-pages-index-astro.md new file mode 100644 index 0000000..066ba00 --- /dev/null +++ b/.impeccable/critique/2026-06-24T11-10-02Z__app-src-pages-index-astro.md @@ -0,0 +1,94 @@ +--- +target: app/src/pages/index.astro +total_score: 34 +p0_count: 0 +p1_count: 0 +timestamp: 2026-06-24T11-10-02Z +slug: app-src-pages-index-astro +--- +# Design Health Score + +| # | Heuristic | Score | Key Issue | +|---|-----------|-------|-----------| +| 1 | Visibility of System Status | 3 | Signing affordances are clear; animated reveal needed to keep content visible during load. | +| 2 | Match System / Real World | 4 | The citable-standard metaphor fits the manifesto well. | +| 3 | User Control and Freedom | 3 | Anchor links and GitHub exit are clear; long-scroll orientation depends on desktop index. | +| 4 | Consistency and Standards | 4 | Tokens, spacing, and document sections are coherent. | +| 5 | Error Prevention | 3 | Mobile overflow risk could cause accidental horizontal panning. | +| 6 | Recognition Rather Than Recall | 3 | Values and principles are strongly structured; signature wall needed more robust mobile wrapping. | +| 7 | Flexibility and Efficiency | 3 | Desktop sticky index works; mobile relies on linear reading. | +| 8 | Aesthetic and Minimalist Design | 4 | Distinct standard/document register without generic AI landing tropes. | +| 9 | Error Recovery | 3 | External signing path is explicit; no major in-page recovery issues found. | +| 10 | Help and Documentation | 4 | GitHub/signing links and manifesto structure are direct. | +| **Total** | | **34/40** | **Strong, with responsive robustness fixes applied.** | + +# Anti-Patterns Verdict + +The surface does not read as generic AI slop. The strongest qualities are the restrained black-and-blue document system, the citable structure, and the refusal of purple gradients, glass cards, and metric hero tropes. + +Deterministic scan: clean. `detect.mjs --json app/src/pages/index.astro app/src/components app/src/styles/sections app/src/styles/tokens.css` returned `[]`. + +Browser evidence: Playwright screenshots and DOM measurements found mobile horizontal overflow before fixes, mainly from full-width signature cards and focus panels with gutter bleed. Immediate screenshots also showed hero copy could be temporarily invisible while reveal animations completed. + +# Overall Impression + +The page already has a strong product-positioned brand register: a manifesto as a published standard. The biggest opportunity was not reinvention, but hardening: keep the visual conviction while removing fragile responsive behavior and animation-gated readability. + +# What's Working + +- The cover has a confident typographic identity and a single clear signing CTA. +- The document layout makes the manifesto feel citable rather than promotional. +- The palette is restrained but specific: ice paper, navy ink, electric blue accent. + +# Priority Issues + +## [P2] Animation-gated hero readability + +Why it matters: screenshots, slow tabs, or paused animations could show blank hero/CTA text during the first load moment. + +Fix: keep cover words visible by default and animate transform only. + +Status: fixed in `app/src/styles/sections/cover.css`. + +## [P2] Mobile horizontal overflow + +Why it matters: a manifesto should feel stable and readable on phones; horizontal panning undermines trust. + +Fix: remove horizontal focus-panel bleed, add `min-width: 0` / `max-width: 100%` to grid and panel children, and make signature cards fluid. + +Status: fixed in `values.css`, `principles.css`, `value-art.css`, `terminal.css`, and `signature.css`. + +## [P3] Display typography exceeded the skill ceiling + +Why it matters: the hero was visually strong but slightly over-scaled and tightly tracked, risking cramped letterforms and lower polish. + +Fix: lower the desktop and mobile clamp ceiling and relax letter-spacing to `-0.035em`. + +Status: fixed in `cover.css` and value folio spacing. + +## [P3] Values intro copy was awkward + +Why it matters: small grammar defects reduce authority on a standards page. + +Fix: rewrite the heading and lede to cleaner English. + +Status: fixed in `Values.astro`. + +# Persona Red Flags + +**First-time AI-assisted developer**: before the fix, the mobile page could feel horizontally unstable in the signature wall. That is now fixed; the main remaining risk is that the page is long and linear without the desktop index. + +**Engineering lead evaluating credibility**: grammar in the values intro and over-tight hero type weakened authority. Both were tightened. + +**Keyboard-only reader**: focus states and skip link are present. The critique did not find a blocking keyboard issue in the inspected surface. + +# Minor Observations + +- The decorative watermark still extends beyond the viewport visually on mobile, but it no longer creates page scroll width. +- Desktop sticky index remains hidden on mobile; acceptable for now, but a compact section jumper could improve long-scroll navigation. +- Terminal/code panels intentionally keep internal horizontal scrolling for preformatted code. + +# Questions to Consider + +- Should mobile get a compact section index, or is the manifesto intended to read strictly top-to-bottom there? +- Should the signature wall be shortened or progressively expanded on mobile to reduce the very long final section? diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..106d878 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,99 @@ +# AGENTS.md + +This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. + +## Ce que c'est + +Manifesto for AI-Driven Development — Astro 4 SSR app, dockerisée, avec store +en mémoire (signatures, votes, feedback). Le worktree d'origine contenait un +seul HTML monolithique : il a été migré vers `app/` (Astro + TypeScript + +Vitest + Playwright). La migration est terminée — l'app Astro est désormais sa +propre source de vérité (plus de parité 1:1 avec l'ancien `index.html`). + +Cousin de `../website/` (Astro, ai-driven-dev.fr) mais **totalement +indépendant** : ne partage aucun asset ni config. Ne pas importer depuis +`../website`. + +## Lancer / prévisualiser + +```bash +# Dev (HMR) +cd app && npm install && npm run dev + +# Production locale +cd app && npm run build && PORT=4321 HOST=127.0.0.1 node ./dist/server/entry.mjs + +# Docker +cd app && docker compose up -d --build +# → http://localhost:4321 +``` + +## Tests + +```bash +cd app +npm test # Vitest unit (store) +npx playwright test # Playwright e2e (api, sign, vote, visual) +``` + +## Architecture + +``` +app/ +├── Dockerfile, compose.yaml, .dockerignore +├── astro.config.mjs SSR + @astrojs/node standalone +├── src/ +│ ├── content/ Données éditoriales : principles.ts, values.ts, terms.ts, seeds.ts +│ ├── styles/ +│ │ ├── tokens.css :root tokens oklch (uniquement) +│ │ └── sections/*.css Styles par section (cover, values, principles, …) +│ ├── lib/ +│ │ ├── store/ Interface + impl mémoire + provider singleton +│ │ ├── api/client.ts Fetch helpers typés (sign, vote, feedback, count) +│ │ └── observers.ts Reveal / terminal / value-art / parallax +│ ├── components/ +│ │ ├── layout/Page.astro +│ │ ├── sections/{Cover,Preamble,Values,Principles,Signature}.astro +│ │ ├── values/{ValueArt,Quadrant}.astro +│ │ ├── principles/{PrincipleGrid,PrincipleCard}.astro +│ │ ├── terminal/TerminalAnim.astro +│ │ ├── signature/{SignDialog,SignatureWall}.astro +│ │ ├── voting/{VoteWidget,DownvoteDialog}.astro +│ │ ├── tweaks/TweaksPanel.astro +│ │ └── ClientApp.astro Single client island (hydratation tweaks + sign + vote + observers) +│ └── pages/ +│ ├── index.astro Composition (≤ 60 LOC) +│ └── api/ +│ ├── signatures.ts GET count, POST sign +│ ├── votes.ts POST +1/-1 +│ └── feedback.ts POST reason + alternative +└── tests/ + ├── check-component-loc.sh AC-6 — LOC budget + └── e2e/{api,sign,vote,visual}.spec.ts +``` + +## Règles d'architecture (voir `aidd_docs/rules/architecture/`) + +- `astro-components.md` — `.astro` ≤ 200 LOC, `index.astro` ≤ 60 LOC, VoteWidget réutilisé. +- `api-routes.md` — JSON in/out, validation stricte, contrats versionnés. +- `store-provider.md` — interface-first, swappable, framework-agnostic. +- `styles-tokens.md` — `oklch()` uniquement, pas de hex/HSL hors `tokens.css`. +- `docker.md` — multi-stage Node 22 alpine, non-root, port 4321. +- `testing.md` — Vitest unit + Playwright e2e + régression visuelle du cover ≤ 1 % (snapshot Astro, plus de baseline). + +## Conventions + +- Couleurs : `oklch()` exclusivement, via variables CSS (`var(--accent)` etc.). +- Données éditoriales : tableaux TypeScript dans `src/content/`, pas de hard-code dans le HTML. +- Tweaks panel : écrit sur `documentElement` (indirection préservée). +- Edit mode parent iframe : sentinelle `/*EDITMODE-BEGIN*/…/*EDITMODE-END*/` + préservée dans `src/components/ClientApp.astro` (ne pas renommer). + +## Édition du contenu + +- Ajouter/modifier un principe : `app/src/content/principles.ts`. +- Ajouter/modifier une valeur : `app/src/content/values.ts` (le champ `quad` alimente le quadrant 2×2 de `Quadrant.astro`) + ASCII art dans `ValueArt.astro`. +- Ajouter/modifier un terminal : `app/src/content/terms.ts`. +- Modifier la palette par défaut : `app/src/styles/tokens.css`. + +Manifeste monolingue : anglais uniquement. Pas d'I18N. diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 0000000..b572604 --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,33 @@ +# Product + +## Register + +brand + +## Users + +Software practitioners, engineering leads, product builders, and AI-assisted developers who want a shared standard for building software with AI while keeping human judgment, craft, and responsibility in the loop. They arrive to read, cite, share, or publicly sign the manifesto. + +## Product Purpose + +The site publishes the canonical Manifesto for AI-Driven Development, frames its four values and twelve principles, and turns agreement into a public Git-based signature. Success means visitors understand the standard quickly, trust the text enough to share or cite it, and can sign without ambiguity. + +## Brand Personality + +Precise, principled, and developer-native. The interface should feel like a citable standard with enough visual conviction to be memorable, not like a SaaS landing page or a generic AI tool. + +## Anti-references + +Avoid AI-product cliché: purple gradients, glass panels, hero metric blocks, generic dashboard chrome, decorative card grids, and empty "AI magic" language. Avoid editorial affectation that makes the manifesto feel like a magazine instead of a standard. Avoid hiding the text behind spectacle. + +## Design Principles + +- Treat the manifesto as the artifact: make the text readable, durable, and easy to cite. +- Signal conviction without hype: strong hierarchy, restrained interaction, no generic AI theatrics. +- Make signing feel public and intentional, not like a marketing conversion trick. +- Keep developer trust high: visible structure, direct copy, clear GitHub affordances. +- Preserve accessibility as part of the standard: keyboard paths, reduced motion, robust contrast, and responsive reading. + +## Accessibility & Inclusion + +Target WCAG AA for text contrast and interaction states. Motion must respect `prefers-reduced-motion`; the manifesto must remain readable with animations disabled, on narrow screens, and for keyboard-only users. diff --git a/app/src/components/definition/VersusSchemas.astro b/app/src/components/definition/VersusSchemas.astro index 21ec868..5ef728a 100644 --- a/app/src/components/definition/VersusSchemas.astro +++ b/app/src/components/definition/VersusSchemas.astro @@ -8,7 +8,7 @@
Method
- @@ -33,15 +33,15 @@ review prod - + - VIBE CODING - - - - prompt - prod + VIBE CODING + + + + prompt + prod

Do not care about code quality.

diff --git a/app/src/components/sections/Values.astro b/app/src/components/sections/Values.astro index 37597a2..05521ef 100644 --- a/app/src/components/sections/Values.astro +++ b/app/src/components/sections/Values.astro @@ -6,13 +6,13 @@ import Icon from '~/components/Icon.astro';
-

4 values of the
AI-Driven Development

+

4 values of
AI-Driven Development

-

Despite being non technical, those values will guide you everytime you are using AI to code.

+

These non-technical values guide every AI-assisted coding session.

diff --git a/app/src/components/signature/SignatureWall.astro b/app/src/components/signature/SignatureWall.astro index 9c0bb68..d5f7cbd 100644 --- a/app/src/components/signature/SignatureWall.astro +++ b/app/src/components/signature/SignatureWall.astro @@ -27,49 +27,55 @@ const humanDate = (iso: string) => (iso ? dateFmt.format(new Date(`${iso}T00:00: {count > 0 && ( )} diff --git a/app/src/styles/sections/base.css b/app/src/styles/sections/base.css index 410aba4..9ac3a9c 100644 --- a/app/src/styles/sections/base.css +++ b/app/src/styles/sections/base.css @@ -85,6 +85,9 @@ summary:focus-visible{ /* Skip link — visible only on focus */ .skip-link{ position: absolute; left: 12px; top: -100px; z-index: 100; + min-height: 44px; + display: inline-flex; + align-items: center; padding: 10px 16px; background: var(--accent); color: var(--accent-ink); font-family: var(--sans); font-size: 12px; letter-spacing: 0.04em; text-decoration: none; border-radius: 4px; diff --git a/app/src/styles/sections/cover.css b/app/src/styles/sections/cover.css index 4828fad..ba48382 100644 --- a/app/src/styles/sections/cover.css +++ b/app/src/styles/sections/cover.css @@ -10,18 +10,41 @@ overflow: hidden; isolation: isolate; border-bottom: 1px solid var(--rule); + background: var(--paper); +} + +.cover::before{ + content: ""; + position: absolute; + top: clamp(40px, 7vh, 72px); + left: clamp(24px, 6vw, 96px); + width: clamp(92px, 14vw, 188px); + height: clamp(8px, 1vw, 13px); + background: var(--accent); + z-index: 4; + transform: scaleX(0); + transform-origin: left; + animation: cover-rule-draw 1.1s var(--ease-out) .35s forwards; +} + +.cover::after{ + content: ""; + position: absolute; + inset: 0 0 0 58%; + background: var(--paper-3); + z-index: 0; } /* AIDD mark — faint watermark, parallax hook (transform set by JS). */ .cover-watermark{ position: absolute; left: 50%; top: 50%; - width: min(70vmin, 720px); - height: min(70vmin, 720px); - transform: translate(calc(-50% + 24vw), calc(-50% - 4vh)); - color: oklch(from var(--ink) l c h / 0.05); + width: min(92vmin, 940px); + height: min(92vmin, 940px); + transform: translate(calc(-50% + 31vw), calc(-50% - 3vh)); + color: oklch(from var(--accent) l c h / 0.13); pointer-events: none; - z-index: -1; + z-index: 1; user-select: none; -webkit-user-select: none; overflow: visible; } @@ -38,7 +61,7 @@ .cover-rule{ position: absolute; left: clamp(24px, 6vw, 96px); right: clamp(24px, 6vw, 96px); - height: 1px; background: var(--rule); + height: 2px; background: oklch(from var(--ink) l c h / 0.14); z-index: 3; transform: scaleX(0); transform-origin: left; animation: cover-rule-draw 1.4s var(--ease-out) .15s forwards; } @@ -46,14 +69,15 @@ .cover-rule-bottom{ bottom: clamp(40px, 7vh, 72px); } @keyframes cover-rule-draw{ to{ transform: scaleX(1); } } -.cover-stage{ position: relative; width: 100%; max-width: 1160px; } +.cover-stage{ position: relative; width: 100%; max-width: 1280px; z-index: 2; } /* Standard header line. */ .cover-std{ font-family: var(--sans); font-size: clamp(11px, 1.05vw, 13px); letter-spacing: .2em; text-transform: uppercase; - color: var(--ink-3); + font-weight: 650; + color: var(--ink-2); margin-bottom: clamp(20px, 3vh, 34px); } .cover-std .cs-sep{ color: var(--accent); margin: 0 .35em; } @@ -63,33 +87,34 @@ font-family: var(--display); font-weight: 800; /* vh-aware so the hero always fits a single 100dvh fold on desktop */ - font-size: clamp(44px, min(9vw, 13.5vh), 124px); - line-height: 0.9; - letter-spacing: -0.045em; + font-size: clamp(48px, min(8.6vw, 12vh), 96px); + line-height: 0.89; + letter-spacing: -0.035em; color: var(--ink); - max-width: 16ch; + max-width: 12ch; overflow-wrap: anywhere; min-width: 0; + text-wrap: balance; } .cover-title .line{ display: block; } .cover-title .word{ display: inline-block; } .reveal-word{ - opacity: 0; transform: translateY(0.4em); + opacity: 1; transform: translateY(0.4em); animation: word-rise 0.95s var(--ease-out) forwards; animation-delay: var(--d, 0s); } -@keyframes word-rise{ to{ opacity: 1; transform: none; } } +@keyframes word-rise{ to{ transform: none; } } -/* "Manifesto" line — slightly quieter, the descriptor. */ -.cover-title .for{ color: var(--ink-2); } +/* "Manifesto" line — still secondary, but present enough to anchor the title. */ +.cover-title .for{ color: var(--ink); opacity: .76; } /* "AI-Driven" — one restrained accent moment: a thin accent underline sweeps in. */ .cover-title .ai{ position: relative; display: inline-block; color: var(--ink); } .cover-title .ai-text{ position: relative; z-index: 1; } .cover-title .ai-strike{ position: absolute; - left: 0.02em; right: 0.02em; bottom: 0.06em; - height: 0.07em; + left: 0.02em; right: 0.02em; bottom: 0.04em; + height: 0.1em; background: var(--accent); border-radius: 2px; transform: scaleX(0); transform-origin: left; @@ -100,24 +125,25 @@ /* Foot — lede + two entry links. */ .cover-foot{ - margin-top: clamp(32px, 5vh, 60px); + margin-top: clamp(34px, 5.5vh, 66px); display: flex; flex-direction: column; gap: clamp(20px, 3vh, 32px); - max-width: 56ch; + max-width: 50ch; } .cover-lede{ font-family: var(--sans); - font-size: clamp(16px, 1.5vw, 21px); - line-height: 1.5; - color: var(--ink-2); + font-size: clamp(18px, 1.55vw, 22px); + line-height: 1.45; + color: var(--ink); + text-wrap: pretty; } .cover-cta{ display: flex; flex-wrap: wrap; gap: 14px 20px; align-items: center; } .cover-link{ display: inline-flex; align-items: center; gap: .5em; - min-height: 44px; padding: 0 18px; + min-height: 50px; padding: 0 22px; font-family: var(--sans); font-size: clamp(14px, 1.1vw, 15px); - font-weight: 500; letter-spacing: -0.005em; + font-weight: 650; letter-spacing: 0; color: var(--ink); text-decoration: none; border: 1px solid var(--rule); border-radius: var(--radius-pill); transition: border-color .2s var(--ease-out), color .2s var(--ease-out), background .2s var(--ease-out); @@ -130,22 +156,46 @@ @media (max-width: 760px){ .cover{ padding: clamp(64px, 12vh, 96px) clamp(20px, 6vw, 40px); } + .cover::before{ + left: clamp(20px, 6vw, 40px); + width: clamp(80px, 28vw, 128px); + } + .cover::after{ inset: 62% 0 0 0; } .cover-rule{ left: clamp(20px, 6vw, 40px); right: clamp(20px, 6vw, 40px); } - .cover-title{ font-size: clamp(46px, 15vw, 92px); } + .cover-title{ font-size: clamp(44px, 13.5vw, 80px); line-height: 0.92; max-width: 11ch; } .cover-watermark{ - width: min(120vmin, 520px); height: min(120vmin, 520px); - transform: translate(-50%, calc(-50% + 10vh)); - color: oklch(from var(--ink) l c h / 0.04); + width: min(118vmin, 520px); height: min(118vmin, 520px); + transform: translate(calc(-50% + 16vw), calc(-50% + 13vh)); + color: oklch(from var(--accent) l c h / 0.09); } + .cover-lede{ max-width: 31ch; } .cover-cta{ width: 100%; } .cover-link{ flex: 1 1 auto; justify-content: center; } } +@media (prefers-reduced-motion: reduce){ + .cover::before, + .cover-rule, + .cover-watermark line, + .cover-watermark circle, + .reveal-word, + .cover-title .ai-strike{ + animation: none !important; + transform: none !important; + } + .cover-watermark line, + .cover-watermark circle{ + opacity: 1; + } +} + @media print{ .cover{ height: auto; min-height: 0; padding: 0 0 16mm; page-break-after: always; border: none; } + .cover::before, + .cover::after{ display: none; } .cover-rule{ animation: none !important; transform: none !important; } .cover-watermark{ display: none; } - .cover-title{ font-size: clamp(48px, 10vw, 110px); } + .cover-title{ font-size: clamp(48px, 10vw, 96px); } .cover-title .word{ opacity: 1; transform: none; animation: none; } .cover-title .ai-strike{ transform: scaleX(1); animation: none; } .cover-foot{ opacity: 1; transform: none; animation: none; } diff --git a/app/src/styles/sections/definition.css b/app/src/styles/sections/definition.css index 5f0fd86..eec8224 100644 --- a/app/src/styles/sections/definition.css +++ b/app/src/styles/sections/definition.css @@ -129,13 +129,13 @@ } .vsch{ margin: 0; - padding: clamp(16px, 1.8vw, 22px); + padding: clamp(20px, 2.2vw, 28px); background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius-card); display: flex; flex-direction: column; - gap: 14px; + gap: clamp(16px, 2vw, 22px); } .vsch-cap{ font-family: var(--sans); @@ -145,7 +145,12 @@ color: var(--ink-3); font-weight: 600; } -.vsch-svg{ width: 100%; height: auto; display: block; } +.vsch-svg{ + width: 100%; + height: auto; + display: block; + margin: 2px 0 4px; +} .vsch-note{ margin: 0; font-family: var(--display); diff --git a/app/src/styles/sections/footer.css b/app/src/styles/sections/footer.css index bf4272e..86ae89d 100644 --- a/app/src/styles/sections/footer.css +++ b/app/src/styles/sections/footer.css @@ -25,6 +25,7 @@ display: inline-flex; align-items: center; gap: 8px; + min-width: 44px; min-height: 44px; color: var(--ink-3); text-decoration: none; @@ -64,5 +65,5 @@ flex-direction: column; gap: 2px; } - .footer-link{ min-height: 40px; } + .footer-link{ min-height: 44px; } } diff --git a/app/src/styles/sections/layout.css b/app/src/styles/sections/layout.css index ddb29fe..3d0b8bc 100644 --- a/app/src/styles/sections/layout.css +++ b/app/src/styles/sections/layout.css @@ -47,7 +47,7 @@ .si-nav{ display: flex; flex-direction: column; } .si-link{ display: flex; align-items: baseline; gap: 10px; - min-height: 40px; padding: 9px 0 9px 12px; margin-left: -14px; + min-height: 44px; padding: 11px 0 11px 12px; margin-left: -14px; font-family: var(--sans); font-size: 14px; color: var(--ink-3); text-decoration: none; border-left: 2px solid transparent; @@ -116,7 +116,7 @@ .si-contact-links{ display: flex; gap: 8px; } .si-contact-link{ display: inline-flex; align-items: center; justify-content: center; - width: 34px; height: 34px; + width: 44px; height: 44px; color: var(--ink-2); border: 1px solid var(--rule); border-radius: 8px; diff --git a/app/src/styles/sections/principles.css b/app/src/styles/sections/principles.css index 1c66f17..bce1492 100644 --- a/app/src/styles/sections/principles.css +++ b/app/src/styles/sections/principles.css @@ -11,13 +11,15 @@ /* ---- Row: number · statement · code panel, side by side ---- */ .principle{ + --row-inset: clamp(18px, 2.2vw, 28px); position: relative; display: grid; - grid-template-columns: clamp(48px, 5vw, 64px) minmax(0, 1fr) minmax(300px, 460px); - gap: clamp(20px, 3vw, 56px); + grid-template-columns: clamp(48px, 5vw, 64px) minmax(0, 1fr) minmax(280px, 420px); + gap: clamp(18px, 2vw, 28px); align-items: start; + min-width: 0; /* Generous breathing room — rows were too cramped. */ - padding: clamp(40px, 6.5vh, 78px) 0; + padding: clamp(40px, 6.5vh, 78px) var(--row-inset); scroll-margin-top: clamp(20px, 8vh, 80px); border-bottom: 1px solid var(--rule); background: var(--paper); @@ -31,7 +33,7 @@ .principle::before{ content: ""; position: absolute; - inset: clamp(12px, 2vh, 22px) calc(-1 * clamp(14px, 1.6vw, 26px)); + inset: clamp(12px, 2vh, 22px) 0; border-radius: var(--radius-card); border: 1px solid var(--accent-soft); background: var(--paper-2); @@ -52,6 +54,8 @@ grid-column: 3; margin-top: 4px; align-self: start; + min-width: 0; + max-width: 100%; } /* Number + statement live in the first two columns */ .principle .p-num{ grid-column: 1; } @@ -64,6 +68,11 @@ /* ---- Number — a self-permalink (jumps to this principle's anchor) ---- */ .p-num{ + display: inline-flex; + align-items: flex-start; + justify-content: flex-start; + min-width: 44px; + min-height: 44px; font-family: var(--display); font-style: normal; font-weight: 700; @@ -173,9 +182,10 @@ /* ---- Mobile: number over statement, panel below ---- */ @media (max-width: 560px){ .principle{ + --row-inset: clamp(18px, 5vw, 22px); grid-template-columns: 44px 1fr; gap: 14px; - padding: clamp(24px, 6vw, 36px) 0; + padding: clamp(24px, 6vw, 36px) var(--row-inset); } .p-num{ font-size: clamp(32px, 8vw, 44px); } .p-num .p-icon{ diff --git a/app/src/styles/sections/signature.css b/app/src/styles/sections/signature.css index 7eea5e6..22372b7 100644 --- a/app/src/styles/sections/signature.css +++ b/app/src/styles/sections/signature.css @@ -88,7 +88,7 @@ .sign-btn--sidebar{ display: flex; width: 100%; - min-height: 0; + min-height: 44px; gap: 0; padding: 0; margin-top: clamp(10px, 1.8vh, 16px); @@ -259,8 +259,9 @@ list-style: none; margin: 0; padding: 0; display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr)); gap: clamp(10px, 1.4vw, 18px); + min-width: 0; } /* ---- Signature card — light panel, hairline border ---- */ @@ -269,27 +270,46 @@ display: flex; flex-direction: column; gap: 10px; + min-width: 0; + max-width: 100%; padding: 14px 14px 14px 12px; background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius-card); + overflow: hidden; transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) var(--ease-out), border-color var(--dur-short) var(--ease-out), background var(--dur-short) var(--ease-out); } -.sig-card:hover{ +.sig-card::before{ + content: ""; + position: absolute; + inset: 0 12px auto; + height: 2px; + background: var(--accent); + transform: scaleX(0); + transform-origin: left; + transition: transform var(--dur-med) var(--ease-out); +} +.sig-card:hover, +.sig-card:focus-within{ transform: translateY(-2px); background: var(--paper-3); border-color: var(--accent-soft); box-shadow: var(--shadow-card); } +.sig-card:hover::before, +.sig-card:focus-within::before{ + transform: scaleX(1); +} .sig-top{ display: flex; align-items: center; gap: 12px; + min-width: 0; } .sig-link{ @@ -310,6 +330,16 @@ background: var(--paper); border: 1px solid var(--rule); object-fit: cover; + transition: + transform var(--dur-med) var(--ease-out), + border-color var(--dur-med) var(--ease-out), + filter var(--dur-med) var(--ease-out); +} +.sig-card:hover .sig-avatar, +.sig-card:focus-within .sig-avatar{ + transform: scale(1.04); + border-color: oklch(from var(--accent) l c h / 0.42); + filter: saturate(1.08); } .sig-meta{ @@ -329,6 +359,11 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + transition: color var(--dur-short) var(--ease-out); +} +.sig-card:hover .sig-name, +.sig-card:focus-within .sig-name{ + color: var(--accent); } .sig-affil{ font-family: var(--sans); @@ -351,6 +386,7 @@ line-height: 1.55; color: var(--ink-2); border-top: 1px solid var(--rule); + overflow-wrap: anywhere; } /* Date stamp */ @@ -362,26 +398,86 @@ color: var(--ink-3); } +.sig-card-foot{ + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-top: auto; + min-width: 0; +} +.sig-entry{ + display: inline-flex; + align-items: center; + min-height: 22px; + padding: 0 8px; + border: 1px solid var(--rule); + border-radius: var(--radius-input); + font-family: var(--sans); + font-size: 10px; + font-weight: 700; + letter-spacing: 0.08em; + color: var(--ink-3); + background: var(--paper); + white-space: nowrap; + font-variant-numeric: tabular-nums; + transform: rotate(0deg); + transition: + transform var(--dur-med) var(--ease-out), + border-color var(--dur-med) var(--ease-out), + color var(--dur-med) var(--ease-out), + background var(--dur-med) var(--ease-out); +} +.sig-card:hover .sig-entry, +.sig-card:focus-within .sig-entry{ + transform: rotate(-2deg) translateY(-1px); + border-color: oklch(from var(--accent) l c h / 0.42); + color: var(--accent); + background: var(--accent-soft); +} + /* LinkedIn icon — subtle, no fill */ .sig-linkedin{ display: inline-flex; align-items: center; justify-content: center; - width: 30px; height: 30px; + width: 44px; height: 44px; border-radius: 6px; color: var(--ink-3); background: transparent; flex: none; transition: color var(--dur-short) var(--ease-out), - background var(--dur-short) var(--ease-out); + background var(--dur-short) var(--ease-out), + transform var(--dur-short) var(--ease-out); } .sig-linkedin:hover{ color: var(--accent); background: var(--accent-soft); + transform: translateY(-1px); } .sig-linkedin svg{ width: 14px; height: 14px; } +@media (prefers-reduced-motion: reduce){ + .sig-card, + .sig-card::before, + .sig-avatar, + .sig-name, + .sig-entry, + .sig-linkedin{ + transition: none; + } + .sig-card:hover, + .sig-card:focus-within, + .sig-card:hover .sig-avatar, + .sig-card:focus-within .sig-avatar, + .sig-card:hover .sig-entry, + .sig-card:focus-within .sig-entry, + .sig-linkedin:hover{ + transform: none; + } +} + /* ---- Print ---- */ @media print{ .sign-cta, @@ -392,7 +488,7 @@ /* ---- Mobile: stack signatories one under another (full-width cards) ---- */ @media (max-width: 640px){ .sig-grid{ - grid-template-columns: 1fr; + grid-template-columns: minmax(0, 1fr); } } diff --git a/app/src/styles/sections/terminal.css b/app/src/styles/sections/terminal.css index 719cc9c..6cd7b30 100644 --- a/app/src/styles/sections/terminal.css +++ b/app/src/styles/sections/terminal.css @@ -17,6 +17,8 @@ line-height: 1.65; overflow: hidden; position: relative; + min-width: 0; + max-width: 100%; box-shadow: 0 0 0 1px oklch(0.28 0.06 272), 0 12px 32px -20px oklch(0.10 0.08 268 / 0.45); @@ -65,6 +67,7 @@ padding: clamp(10px, 1.4vw, 14px) clamp(18px, 2.2vw, 24px) clamp(16px, 2vw, 20px); position: relative; z-index: 2; + overflow-x: auto; } /* ---- Line reveal animation ---- */ diff --git a/app/src/styles/sections/value-art.css b/app/src/styles/sections/value-art.css index a11f843..dea7f1c 100644 --- a/app/src/styles/sections/value-art.css +++ b/app/src/styles/sections/value-art.css @@ -12,6 +12,8 @@ align-self: stretch; position: relative; overflow: hidden; + min-width: 0; + max-width: 100%; /* Hairline outline only — no heavy shadow */ box-shadow: 0 0 0 1px oklch(0.181 0.117 266 / 0.6); } @@ -47,6 +49,8 @@ position: relative; z-index: 1; min-height: clamp(260px, 32vh, 340px); + min-width: 0; + max-width: 100%; } /* ---- Column layout ---- */ @@ -95,6 +99,7 @@ font-family: var(--mono); white-space: pre; overflow-x: auto; + max-width: 100%; margin: 0; font-size: inherit; line-height: inherit; @@ -157,6 +162,7 @@ margin: 0; white-space: pre; overflow-x: auto; + max-width: 100%; color: inherit; font-family: var(--mono); font-size: inherit; diff --git a/app/src/styles/sections/values.css b/app/src/styles/sections/values.css index 71d7349..f455957 100644 --- a/app/src/styles/sections/values.css +++ b/app/src/styles/sections/values.css @@ -8,15 +8,17 @@ .plate{ display: grid; gap: 0; - padding: clamp(20px, 4vh, 40px) 0 clamp(40px, 7vh, 72px); + padding: clamp(12px, 2.5vh, 28px) 0 clamp(40px, 7vh, 72px); } .plate-row{ + --row-inset: clamp(18px, 2.2vw, 28px); display: grid; - grid-template-columns: clamp(70px, 8vw, 120px) 1fr; - gap: clamp(14px, 2vh, 22px) clamp(32px, 5vw, 72px); + grid-template-columns: clamp(56px, 6vw, 92px) minmax(0, 1fr); + gap: clamp(14px, 2vh, 22px) clamp(28px, 4vw, 52px); align-items: start; position: relative; - padding: clamp(44px, 7vh, 80px) 0 clamp(40px, 6vh, 64px); + min-width: 0; + padding: clamp(44px, 7vh, 80px) var(--row-inset) clamp(40px, 6vh, 64px); scroll-margin-top: clamp(20px, 8vh, 80px); } /* Spotlight highlight — soft card panel fades + lifts in when the row is centred @@ -26,7 +28,7 @@ display: block; content: ""; position: absolute; - inset: clamp(16px, 2vh, 26px) calc(-1 * clamp(14px, 1.6vw, 26px)); + inset: clamp(16px, 2vh, 26px) 0; border-radius: var(--radius-card); border: 1px solid var(--accent-soft); background: var(--paper-2); @@ -44,13 +46,15 @@ .plate-row .pr-art{ grid-column: 1 / -1; margin-top: clamp(18px, 3vh, 32px); + min-width: 0; + max-width: 100%; } /* Hairline rule above each row — clean, no ornament */ .plate-row::before{ content: ""; position: absolute; - top: 0; left: 0; right: 0; + top: 0; left: var(--row-inset); right: var(--row-inset); height: 1px; background: var(--rule); pointer-events: none; @@ -63,7 +67,7 @@ .plate-row .pr-icon{ position: absolute; top: clamp(20px, 4vh, 42px); - right: 0; + right: var(--row-inset); width: clamp(60px, 5.8vw, 80px); height: clamp(60px, 5.8vw, 80px); padding: clamp(15px, 1.5vw, 21px); @@ -75,18 +79,22 @@ /* ---- Folio numeral — a self-permalink (ghost by default, lifts on hover) ---- */ .pr-folio{ - display: block; - width: fit-content; + display: inline-flex; + align-items: flex-start; + justify-content: flex-end; + width: 100%; + min-width: 44px; + min-height: 44px; font-family: var(--display); font-weight: 800; font-style: normal; /* no italic — design rule */ - font-size: clamp(52px, 7vw, 104px); + font-size: clamp(48px, 6.3vw, 86px); line-height: 0.82; color: var(--ink); - opacity: 0.10; /* ghost numeral — structural, not decorative */ + opacity: 0.14; /* ghost numeral — structural, not decorative */ align-self: start; padding-top: clamp(6px, 1vh, 14px); - letter-spacing: -0.05em; + letter-spacing: -0.035em; user-select: none; text-decoration: none; cursor: pointer; @@ -217,20 +225,40 @@ /* ---- Mobile: single column ---- */ @media (max-width: 820px){ .plate-row{ - grid-template-columns: 1fr; - gap: clamp(18px, 2.5vh, 28px); - padding: clamp(36px, 6vh, 52px) 0 clamp(24px, 4vh, 36px); + --row-inset: clamp(18px, 5vw, 22px); + grid-template-columns: clamp(34px, 10vw, 46px) minmax(0, 1fr); + gap: clamp(12px, 3vw, 18px); + padding: clamp(30px, 6vh, 46px) var(--row-inset) clamp(28px, 5vh, 42px); + } + .plate-row::before{ + left: var(--row-inset); + right: var(--row-inset); } .pr-folio{ - font-size: clamp(40px, 10vw, 60px); - padding-top: 0; - line-height: 0.9; + justify-content: flex-start; + width: 44px; + font-size: clamp(30px, 8.5vw, 40px); + line-height: 0.88; + padding-top: 5px; + } + .pr-text{ + grid-column: 2; + min-width: 0; + } + .plate-row .pr-art{ + grid-column: 1 / -1; + margin-top: clamp(12px, 2.5vh, 22px); } .pr-text .left{ - font-size: clamp(32px, 8vw, 48px); + font-size: clamp(32px, 8.2vw, 46px); + line-height: 0.94; + } + .pr-text .over{ + margin-top: 2px; } .plate-row .pr-icon{ - top: clamp(0px, 1vh, 6px); + top: clamp(16px, 4vw, 22px); + right: var(--row-inset); width: clamp(50px, 13vw, 60px); height: clamp(50px, 13vw, 60px); padding: clamp(12px, 3.2vw, 15px); diff --git a/app/src/styles/tokens.css b/app/src/styles/tokens.css index 6bde955..d65eab6 100644 --- a/app/src/styles/tokens.css +++ b/app/src/styles/tokens.css @@ -49,7 +49,7 @@ one colour moment. Derived from --accent / --ink so they track the tweaks. */ --shadow-cta: 0 1px 0 0 oklch(1 0 0 / 0.12) inset, 0 8px 24px -8px oklch(from var(--accent) l c h / 0.45); --shadow-cta-hover: 0 1px 0 0 oklch(1 0 0 / 0.15) inset, 0 14px 32px -8px oklch(from var(--accent) l c h / 0.55); - --shadow-card: 0 12px 32px -18px oklch(from var(--ink) l c h / 0.22); + --shadow-card: 0 6px 8px -7px oklch(from var(--ink) l c h / 0.24); --shadow-modal: 0 24px 64px -24px oklch(from var(--ink) l c h / 0.45); --scrim: oklch(from var(--ink) l c h / 0.45); } From 6cd491ed9c285cd830527f8ba5e4907eb29a3cbd Mon Sep 17 00:00:00 2001 From: alexsoyes Date: Wed, 24 Jun 2026 13:53:09 +0200 Subject: [PATCH 2/3] feat(signature): add public registry treatment --- app/src/components/sections/Signature.astro | 41 +++-- app/src/styles/sections/signature.css | 179 ++++++++++++++++++++ 2 files changed, 209 insertions(+), 11 deletions(-) diff --git a/app/src/components/sections/Signature.astro b/app/src/components/sections/Signature.astro index bb61794..6e44849 100644 --- a/app/src/components/sections/Signature.astro +++ b/app/src/components/sections/Signature.astro @@ -1,20 +1,39 @@ --- +import { getCollection } from 'astro:content'; import SignButton from '~/components/signature/SignButton.astro'; import SignatureWall from '~/components/signature/SignatureWall.astro'; + +const count = (await getCollection('signatories')).length; +const registryCount = String(count).padStart(3, '0'); ---
-
-
-

Be part of the movement!

-
- -

- Be among the first to sign the AI-Driven Development Manifesto and help shape the future of software development. -

+
+ + +
+
+

Public signature registry

+

Be part of the movement!

+
+ +

+ Be among the first to sign the AI-Driven Development Manifesto and help shape the future of software development. +

+
+ +
diff --git a/app/src/styles/sections/signature.css b/app/src/styles/sections/signature.css index 22372b7..26e6490 100644 --- a/app/src/styles/sections/signature.css +++ b/app/src/styles/sections/signature.css @@ -3,6 +3,149 @@ .signature{ padding: 0 0 clamp(56px, 9vh, 100px); } + +.signature-open{ + min-height: clamp(300px, 34vh, 410px); + padding: clamp(52px, 8vh, 88px) 0 clamp(38px, 6vh, 62px); + isolation: isolate; + overflow: hidden; +} +.signature-open::before{ + height: 3px; + background: var(--ink); +} +.signature-open::after{ + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 1px; + background: var(--rule); +} + +.signature-open-mark{ + position: absolute; + right: clamp(-72px, -4vw, -28px); + top: 50%; + width: clamp(240px, 30vw, 390px); + height: clamp(240px, 30vw, 390px); + color: oklch(from var(--accent) l c h / 0.12); + transform: translateY(-50%) rotate(-8deg); + z-index: -1; + pointer-events: none; +} +.signature-open-mark line, +.signature-open-mark circle{ + transform-box: fill-box; + transform-origin: center; +} +.signature-open:hover .som-bar-small, +.signature-open:hover .som-bar-big{ + animation: signature-mark-draw .9s var(--ease-out) both; +} +.signature-open:hover .som-dot{ + animation: signature-mark-pulse .9s var(--ease-out) both; +} +@keyframes signature-mark-draw{ + from{ opacity: .35; transform: translateY(10px) scale(.96); } + to{ opacity: 1; transform: none; } +} +@keyframes signature-mark-pulse{ + 0%, 100%{ transform: scale(1); } + 50%{ transform: scale(1.14); } +} + +.signature-open-body{ + position: relative; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(124px, 174px); + gap: clamp(24px, 5vw, 72px); + align-items: end; + max-width: 100%; + z-index: 1; +} +.signature-open-copy{ + min-width: 0; + max-width: 780px; +} +.signature-kicker{ + display: inline-flex; + align-items: center; + gap: 12px; + margin-bottom: clamp(18px, 2.5vh, 28px); + font-family: var(--sans); + font-size: 11px; + font-weight: 700; + letter-spacing: .18em; + text-transform: uppercase; + color: var(--accent); +} +.signature-kicker::before{ + content: ""; + width: clamp(56px, 8vw, 104px); + height: 2px; + background: var(--accent); +} +.signature-open .chapter-lede{ + max-width: 720px; +} +.signature-open .chapter-lede p{ + color: var(--ink); +} + +.signature-seal{ + position: relative; + display: grid; + justify-items: center; + align-content: center; + aspect-ratio: 1; + min-width: 0; + padding: clamp(16px, 2vw, 22px); + border: 2px solid oklch(from var(--ink) l c h / 0.22); + border-radius: 50%; + color: var(--ink); + background: oklch(from var(--paper) l c h / 0.72); + transform: rotate(-6deg); +} +.signature-seal::before, +.signature-seal::after{ + content: ""; + position: absolute; + inset: 10px; + border: 1px solid oklch(from var(--accent) l c h / 0.34); + border-radius: 50%; + pointer-events: none; +} +.signature-seal::after{ + inset: 18px; + border-color: var(--rule); +} +.signature-seal-label, +.signature-seal-caption{ + position: relative; + z-index: 1; + font-family: var(--sans); + font-size: clamp(9px, .9vw, 11px); + font-weight: 700; + letter-spacing: .16em; + line-height: 1.2; + text-transform: uppercase; + color: var(--ink-3); + text-align: center; +} +.signature-seal strong{ + position: relative; + z-index: 1; + font-family: var(--display); + font-size: clamp(44px, 6vw, 76px); + font-weight: 800; + line-height: .9; + letter-spacing: -0.035em; + color: var(--accent); + font-variant-numeric: tabular-nums; +} + /* Contribute links under the CTA — organisation, then repository. */ .sign-contribute{ margin-top: 14px; @@ -173,6 +316,11 @@ animation: logo-draw 0.8s var(--ease-out) both; } @media (prefers-reduced-motion: reduce){ + .signature-open:hover .som-bar-small, + .signature-open:hover .som-bar-big, + .signature-open:hover .som-dot{ + animation: none; + } .sign-logo .sl-bar-small, .sign-logo .sl-bar-big{ animation: none; stroke-dashoffset: 0; } .sign-logo .sl-dot{ animation: none; } @@ -487,6 +635,37 @@ /* ---- Mobile: stack signatories one under another (full-width cards) ---- */ @media (max-width: 640px){ + .signature-open{ + min-height: 0; + padding: clamp(56px, 9vh, 80px) 0 clamp(36px, 7vh, 56px); + } + .signature-open-mark{ + right: -126px; + top: auto; + bottom: -132px; + width: 310px; + height: 310px; + transform: rotate(-8deg); + color: oklch(from var(--accent) l c h / 0.09); + } + .signature-open-body{ + grid-template-columns: minmax(0, 1fr); + gap: 26px; + } + .signature-kicker{ + margin-bottom: 18px; + font-size: 10px; + letter-spacing: .14em; + } + .signature-kicker::before{ width: 52px; } + .signature-seal{ + justify-self: start; + width: 128px; + transform: rotate(-4deg); + } + .signature-seal strong{ + font-size: 44px; + } .sig-grid{ grid-template-columns: minmax(0, 1fr); } From e901e6a10964f1ae130cae379cb1cf2dbcc21745 Mon Sep 17 00:00:00 2001 From: alexsoyes Date: Wed, 24 Jun 2026 14:03:00 +0200 Subject: [PATCH 3/3] Refresh cover and spec styling for v1.1 --- app/src/components/layout/SpecIndex.astro | 2 +- app/src/components/sections/Cover.astro | 21 ++++++++++-- app/src/styles/sections/cover.css | 41 +++++++++++++++++++++-- app/src/styles/sections/terminal.css | 4 ++- app/src/styles/sections/value-art.css | 6 +++- 5 files changed, 65 insertions(+), 9 deletions(-) diff --git a/app/src/components/layout/SpecIndex.astro b/app/src/components/layout/SpecIndex.astro index f8405a0..b0c07cf 100644 --- a/app/src/components/layout/SpecIndex.astro +++ b/app/src/components/layout/SpecIndex.astro @@ -16,7 +16,7 @@ const count = (await getCollection('signatories')).length; AIDD - v1.0 + v1.1