chore: phase 1 reset — minimalist child theme + content-source extraction

Resets the child theme to its Bricks-first minimalist form (per RESTART-PLAN.md
phases 1a-1d) and extracts the textual copy into a runtime-independent
/content-source/ directory.

Child theme files removed
- header.php, footer.php, page.php, index.php, front-page.php
- template-parts/{solution,industry,conversion-form}.php
- templates/page-*.php (10 Custom Page Templates)
- inc/render-blocks.php, render-blocks-native.php, render-bricks.php
- inc/shortcodes.php, i18n.php, form-handler.php, seo.php
- assets/css/components.css, assets/js/main.js

Reasoning: Bricks Templates (Header / Footer / Single — Page) and Bricks-edited
pages now drive every screen. Anything emitted from the child theme would
fight Bricks' own rendering and waste CSS specificity battles.

Child theme now contains only
- style.css, functions.php (simplified to ~60 lines), theme.json
- inc/cpt.php (case_study + scenario + industry taxonomy)
- assets/css/tokens.css (untouched — design system source of truth)
- assets/css/utilities.css (trimmed to skip-link + sr-only + focus-visible
  + reduced motion — everything else handled by Bricks)
- assets/fonts/Inter-Variable*.woff2 (RGPD self-hosted)
- README.md spelling out the Bricks-first contract

Content moved to /content-source/
- solutions-data.php, industries-data.php, technology-data.php,
  editorial-data.php, forms-data.php — git mv preserves history
- README.md explaining their dual role: copy reference while building
  in Bricks, and source for programmatic page generation when we
  replicate an archetype across its variants.

Root README.md updated with the new repo layout + a pointer to
RESTART-PLAN.md and the archive/session-2-php-templates branch.

Memory file project_asterion_status.md updated for next-session resume.

What's preserved as before
- /BRIEF-Claude-Code.md, both PDFs, all .txt extracts
- /MISSING-ASSETS.md
- /ThirdParty/ (Bricks + WPML ZIPs, gitignored)
- LocalWP site at localhost:10004, Bricks v2.3.4 + WPML 4.9.3 active
- WPML EN/FR with directory URL strategy
- All Git history, both main and archive/session-2-php-templates branches

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 14:36:19 +02:00
parent 026be81373
commit fba223004f
39 changed files with 217 additions and 5025 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,110 +1,13 @@
/**
* Asterion Bricks — Utilities
* Asterion Bricks — Utilities (minimalist)
*
* Modern CSS reset + reusable utility classes.
* Loaded after tokens.css, before components.css.
*
* Naming : prefix `av-` on every custom class.
* Loaded after tokens.css. Holds the small set of helper classes Bricks
* Builder cannot easily provide on its own (skip link, screen-reader-only
* text, focus ring). Everything else — section padding, container widths,
* button design, card styles — is set inside Bricks via tokens.
*/
/* ============================================================================
Modern CSS reset (inspired by Andy Bell's modern-css-reset, Josh Comeau)
============================================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
scroll-behavior: smooth;
text-rendering: optimizeLegibility;
}
body {
font-family: var(--font-body);
font-size: var(--text-body-md);
line-height: var(--leading-body-md);
color: var(--color-text-primary);
background-color: var(--color-bg-default);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-height: 100vh;
}
img, picture, video, canvas, svg {
display: block;
max-width: 100%;
height: auto;
}
input, button, textarea, select { font: inherit; color: inherit; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
a {
color: inherit;
text-decoration: none;
}
ul, ol { list-style: none; }
table { border-collapse: collapse; border-spacing: 0; }
/* ============================================================================
Heading hierarchy — opinionated defaults consumed when an element
carries no Bricks-specific class. Bricks may override, that's expected.
============================================================================ */
h1 {
font-family: var(--font-display);
font-size: var(--text-h1);
line-height: var(--leading-h1);
font-weight: var(--font-weight-bold);
letter-spacing: var(--tracking-snug);
}
h2 {
font-family: var(--font-display);
font-size: var(--text-h2);
line-height: var(--leading-h2);
font-weight: var(--font-weight-bold);
letter-spacing: var(--tracking-snug);
}
h3 {
font-family: var(--font-display);
font-size: var(--text-h3);
line-height: var(--leading-h3);
font-weight: var(--font-weight-semibold);
letter-spacing: var(--tracking-snug);
}
h4 {
font-family: var(--font-display);
font-size: var(--text-h4);
line-height: var(--leading-h4);
font-weight: var(--font-weight-semibold);
}
p {
max-width: 72ch; /* prose readability per Design Handoff section 2.2 */
}
/* ============================================================================
Focus visible — keyboard accessibility
Removes outline only when focus came from the mouse; preserves it for keyboard.
============================================================================ */
:focus { outline: none; }
:focus-visible {
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: var(--focus-ring-offset);
}
/* ============================================================================
Skip link — first focusable element on every page (a11y)
============================================================================ */
/* === A11y skip link — first focusable element on every page === */
.av-skip-link {
position: absolute;
top: -40px;
@@ -114,6 +17,7 @@ p {
color: var(--color-text-on-dark);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
text-decoration: none;
z-index: var(--z-toast);
border-bottom-right-radius: var(--radius-md);
}
@@ -122,10 +26,7 @@ p {
top: 0;
}
/* ============================================================================
Visually hidden — content readable by screen readers, hidden visually
============================================================================ */
/* === Visually hidden — readable by screen readers, hidden visually === */
.av-sr-only {
position: absolute;
width: 1px;
@@ -138,77 +39,25 @@ p {
border: 0;
}
/* ============================================================================
Container — centred max-width with responsive padding
============================================================================ */
.av-container {
max-width: var(--container-max);
margin-inline: auto;
padding-inline: var(--container-padding-mobile);
width: 100%;
/* === Focus visible — keyboard accessibility on every focusable element === */
:focus { outline: none; }
:focus-visible {
outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color, var(--color-info));
outline-offset: var(--focus-ring-offset, 2px);
}
@media (min-width: 768px) {
.av-container { padding-inline: var(--container-padding-tablet); }
}
@media (min-width: 1280px) {
.av-container { padding-inline: var(--container-padding-desktop); }
}
.av-container--narrow {
max-width: 800px; /* article body */
}
/* ============================================================================
Tap target minimum — WCAG AA / Apple HIG (44×44px)
============================================================================ */
/* === Touch target minimum (WCAG AA / Apple HIG) === */
.av-tap-target {
min-width: var(--tap-target-min);
min-height: var(--tap-target-min);
min-width: var(--tap-target-min, 44px);
min-height: var(--tap-target-min, 44px);
}
/* ============================================================================
Stack helpers — vertical rhythm via owl-selector
============================================================================ */
.av-stack > * + * { margin-top: var(--av-stack-gap, var(--space-4)); }
.av-stack--sm > * + * { margin-top: var(--space-2); }
.av-stack--md > * + * { margin-top: var(--space-4); }
.av-stack--lg > * + * { margin-top: var(--space-8); }
.av-stack--xl > * + * { margin-top: var(--space-12); }
/* ============================================================================
Section padding helpers (vertical rhythm between page sections)
============================================================================ */
.av-section {
padding-block: var(--space-16);
}
@media (min-width: 1024px) {
.av-section { padding-block: var(--space-20); }
}
.av-section--hero {
padding-block: var(--space-24);
}
@media (min-width: 1024px) {
.av-section--hero { padding-block: var(--space-32); }
}
.av-section--dark {
background-color: var(--color-bg-dark);
color: var(--color-text-on-dark);
}
/* ============================================================================
Print
============================================================================ */
@media print {
.av-skip-link, .av-no-print { display: none !important; }
body { color: #000; background: #fff; }
a::after { content: " (" attr(href) ")"; font-size: 0.8em; }
/* === Reduced motion — respect user preference === */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}

View File

@@ -1,149 +0,0 @@
/**
* Asterion Bricks — main JS
*
* Vanilla JS, defer-loaded. Wraps everything in DOMContentLoaded.
* Performance budget : initial bundle < 200 KB gzipped.
*
* Modules planned :
* - Header scroll behavior (background swap after 80px)
* - Mega menu trigger (hover desktop, click touch, ESC closes)
* - Mobile drawer (full-screen overlay, accordion sections)
* - Scroll-triggered fade-in (IntersectionObserver, threshold 0.15)
* - Stat callouts count-up (1000ms ease-out)
* - Hero video lazy-load + reduced-motion fallback to poster
*/
(function () {
'use strict';
/**
* Detect reduced motion once and expose a flag for downstream modules.
* Updated reactively if the user toggles the setting mid-session.
*/
const reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
let prefersReducedMotion = reducedMotionQuery.matches;
reducedMotionQuery.addEventListener('change', (e) => {
prefersReducedMotion = e.matches;
});
/**
* Header scroll behavior.
* After 80px scroll, header gets a `is-scrolled` class
* (consumed by .av-header.is-scrolled rule in components.css).
*/
function initHeaderScroll() {
const header = document.querySelector('.av-header');
if (!header) return;
let ticking = false;
const onScroll = () => {
if (!ticking) {
window.requestAnimationFrame(() => {
header.classList.toggle('is-scrolled', window.scrollY > 80);
ticking = false;
});
ticking = true;
}
};
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
}
/**
* Scroll-triggered fade-in (Design Handoff section 5.3).
* Sections fade-in + slide-up 16px on entry, threshold 0.15, trigger once.
* Skipped entirely if user prefers reduced motion.
*/
function initScrollReveal() {
if (prefersReducedMotion) return;
const targets = document.querySelectorAll('[data-av-reveal]');
if (!targets.length) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-revealed');
observer.unobserve(entry.target);
}
});
}, { threshold: 0.15, rootMargin: '0px 0px -10% 0px' });
targets.forEach((target) => observer.observe(target));
}
/**
* Stat count-up (Design Handoff section 5.3).
* Element : <span data-av-countup="0|target|duration">target</span>
* Animates from 0 to target value over duration ms, ease-out.
*/
function initStatCountUp() {
if (prefersReducedMotion) return;
const stats = document.querySelectorAll('[data-av-countup]');
if (!stats.length) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const el = entry.target;
const target = parseFloat(el.dataset.avCountup) || 0;
const duration = parseInt(el.dataset.avCountupDuration || '1000', 10);
const start = performance.now();
const tick = (now) => {
const elapsed = Math.min((now - start) / duration, 1);
// ease-out cubic
const eased = 1 - Math.pow(1 - elapsed, 3);
el.textContent = Math.round(target * eased).toLocaleString();
if (elapsed < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
observer.unobserve(el);
});
}, { threshold: 0.5 });
stats.forEach((s) => observer.observe(s));
}
/**
* Mobile drawer toggle.
* Trigger : <button class="av-drawer-toggle" aria-controls="av-drawer">
* Drawer : <div id="av-drawer" class="av-drawer">
*/
function initMobileDrawer() {
const toggle = document.querySelector('.av-drawer-toggle');
const drawer = document.getElementById('av-drawer');
if (!toggle || !drawer) return;
const open = () => {
drawer.classList.add('is-open');
toggle.setAttribute('aria-expanded', 'true');
document.body.style.overflow = 'hidden';
};
const close = () => {
drawer.classList.remove('is-open');
toggle.setAttribute('aria-expanded', 'false');
document.body.style.overflow = '';
};
toggle.addEventListener('click', () => {
drawer.classList.contains('is-open') ? close() : open();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && drawer.classList.contains('is-open')) close();
});
}
/**
* Boot.
*/
document.addEventListener('DOMContentLoaded', () => {
initHeaderScroll();
initScrollReveal();
initStatCountUp();
initMobileDrawer();
});
})();