20 Commits

Author SHA1 Message Date
c8e89e1725 style(home): transparent header at top, opaque navy on scroll
On the home page only, the header sits transparently over the 100vh video
hero so the cinematic background is fully visible. As soon as the user
scrolls, Bricks's native sticky JS adds the `.on-scroll` class to
#brx-header — we fade in the navy background + a soft shadow over 350ms
for a polished cinematic feel.

Implementation : pure CSS via wp_head(), gated on is_front_page() so other
pages keep their solid navy header.

Extras :
- A subtle navy gradient (rgba 0.55 → 0) layered behind the menu at the
  very top via ::before, keeping nav text readable on bright video frames.
  Fades out once .on-scroll kicks in (gradient redundant once bg is solid).
- Box-shadow on scrolled state (0 2px 14px rgba(0,0,0,0.22)) so the
  header lifts off the page content visually.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:26:18 +02:00
98dfa6d8b6 style(home): full-viewport-height video hero (100vh) with vertical centering
Hero section now min-height: 100vh — fills the entire viewport, content
vertically centered via flex-column + justify-content: center. Scrolling
reveals the rest of the page below (3-pillars cards, industries, etc.).

Replaces the previous fixed-padding approach (9rem top, 8rem bottom) which
left visible space below the hero on tall monitors and forced the hero
shorter on mobile.

Padding kept minimal (2rem top/bottom) for breathing room when content
gets close to the viewport edges on very short displays.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:22:48 +02:00
621425025c feat(home): cinematic video-background hero with overlay text
Replaces the home page's plain-navy hero with a full-bleed video-background
section + dark navy overlay (60%) for text readability. The video URL is
read from the WP option `av_home_hero_video_url`. If empty, the hero
gracefully falls back to a solid navy background — same layout, same text,
just no video.

Settings (Bricks-native background.videoUrl pattern from container.php
get_background_video_html) :
  - videoUrl : the configured option value
  - videoScale : 'cover'
  - videoAspectRatio : '16/9'
  - overlay : rgba(11,31,58,0.6) navy 60%
  - color fallback while video loads

Typography :
  - H1 : 3.5rem white, weight 800, tight letter-spacing, responsive
    breakpoints down to 1.875rem on mobile
  - Lead : muted-white rgba 0.85
  - CTAs : gold primary + outline-on-dark secondary

Helper mu-plugin av-set-home-video.php :
  /?av_set_home_video=https://...mp4    sets the URL
  /?av_set_home_video=clear              empties (back to navy)

Workflow :
  1. Upload MP4 to Media Library, copy URL
  2. /?av_set_home_video=<URL>
  3. /?av_generate_home=1
  4. Visit / — cinematic hero with looping muted autoplay video bg

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:17:33 +02:00
ce56b2b936 fix(bricks): enable publicTemplates setting so /template/* URLs resolve
Bricks's frontend.php template_redirect() permanently redirects any
/template/* URL to the homepage (site_url(), 301) when :
  - is_singular(bricks_template)
  - !current_user_can_use_builder()
  - !isset(bricks_global_settings.publicTemplates)
  - !maintenance mode

This kicks in BEFORE the Bricks builder check can run, so clicking
"Edit with Bricks" on a template ends up redirected to home → admin
URL → Bricks's own builder.php sees current_post_type as empty (because
the post wasn't actually queried before the redirect) → final redirect
to wp-admin/edit.php?post_type=&bricks_notice=error_post_type with the
"Invalid post type" notice.

Setting bricks_global_settings.publicTemplates = '1' disables this
preemptive redirect. Templates stay excluded from search but their
permalinks resolve normally → builder can attach.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:54:09 +02:00
aad32fd0f1 fix(bricks): remove bricks_template from REST bridge entirely
Even adding only 'custom-fields' to bricks_template's supports turned out
to break the Bricks builder ("Invalid post type" on Edit with Bricks for
all templates including pre-existing Header / Footer).

bricks_template is now left exactly as Bricks registers it natively :
  supports : author, revisions, thumbnail, title
  show_in_rest : false

The MCP server route to bricks_template was experimental and we don't use
it actively — direct PHP scripts (av-fix-template-meta, av-generate-*,
av-add-submenus) handle template management. Templates are exposed only
to the Bricks builder, not external REST clients.

case_study + scenario CPTs keep REST exposure (used for content type
generators later).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:48:50 +02:00
86cd37ed80 fix(bricks): stop overriding bricks_template supports — only add custom-fields
The REST bridge was rewriting the `supports` array on bricks_template (and
case_study, scenario) by force-adding ['title','editor','author','custom-fields'].
For bricks_template specifically, Bricks's own registration sets supports =
['author','revisions','thumbnail','title'] — deliberately WITHOUT 'editor',
because the post type is meant to be edited only via the Bricks builder, not
the WP block editor.

Adding 'editor' confused Bricks's builder : it would refuse to open the
template with "Invalid post type" because the post type now claimed to support
two incompatible editors.

Fix : keep the original supports list untouched, only append 'custom-fields'
(which IS required for /wp/v2/<type>/<id> to expose the `meta` field). All
templates (Header #25, Footer #46, Single Post #154) should now open in the
Bricks builder again.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:39:44 +02:00
e52a1de268 fix(bricks): correct Single Post template conditions format
Bricks's templateConditions for single posts expects:
  main: 'postType', postType: ['post']      (array of post types)

NOT the singular/object variant I'd used:
  main: 'singular', object: 'post'

The wrong format triggered "Invalid post type" when opening the template
in the Bricks builder editor — Bricks's editor couldn't parse the
condition and refused to load the template.

Source : wp-content/themes/bricks/includes/admin.php line 1101 — the
switch case for 'postType' confirms the expected shape.

For 'any' (entire website, used by Header/Footer templates), no extra
keys are needed beyond main='any'. Section/single templates need this
postType array form.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 07:35:12 +02:00
918c000817 feat(insights): blog setup — hub page + Single Post template + 3 seed posts
Phase 12 (post-launch ready) — Insights blog scaffolding so the /insights/
menu link works and the user can start publishing.

Creates :
1. /insights/ hub page (#153) with hero + Bricks `posts` query-loop
   element + closer CTA. The posts element configured with :
   - query : post_type=post, posts_per_page=9, orderby=date DESC
   - layout=grid, columns=3, linkPost=true, imageDisable=true
   - fields : eyebrow "Insights", h3 post title, date, excerpt
   - _cssCustom for card styling (subtle bg, border, padding, flex column)
2. Single Post Bricks template (#154, template_type=single, conditions=
   singular post) : eyebrow + h1 {post_title} + date · author meta +
   featured image + post-content + closer CTA.
3. Three seed posts publication-ready :
   - the-10-to-15-gap (#155)
   - simulators-for-entertainment-vs-training (#156)
   - sovereign-by-default-gdpr-native (#157)
   Topics aligned with the brand : training gap reality, why
   entertainment-first simulators fail tactical training, GDPR-native
   sovereignty for security forces.

User adds more posts via WP Admin → Posts → Add New. The Bricks Single
template handles layout automatically (matches templateConditions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:29:29 +02:00
1ddde1ffd5 feat(header): add About / Customers / Partners submenu under Why Asterion
Extends av-add-submenus.php to attach 3 editorial pages as children of
the 'Why Asterion' top-level menu item :
  Why Asterion
    ├ About
    ├ Customers
    └ Partners

Re-running ?av_add_submenus=1 is idempotent : Solutions / Industries /
Technology children stay as-is (matched by URL), only the new Why Asterion
children get inserted (menu items #150-152).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:19:03 +02:00
a795fb345f style(footer): align nav-menu links with column heading + restore tagline visibility
Adds wp_head CSS overrides to fix two issues :
1. Footer nav-menu links (under Solutions / Company / Legal columns) were
   indented ~40px due to the browser's default <ul> padding-left. Zero it
   out so links align with the gold eyebrow heading above them.
2. Brand tagline "Your Last Mistake Should Be in VR." was using
   var(--color-text-tertiary) which renders too dark on the navy footer.
   Force rgba(255,255,255,0.65) for visible muted-white.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:07:10 +02:00
094fdbea51 style(lists): replace '— ' dash prefix with vertical gold bar accent
The em-dash prefix on list items felt typographic but unbranded. Now each
list item gets a 3px-wide gold vertical bar on the left, evoking a tactical
breadcrumb. Implementation :
- Builders (av_build_list_section in _av-bricks-shared.php +
  av_build_form_two_col promise list in av-generate-forms.php) emit clean
  text without the '— ' prefix, and set _cssClasses = 'av-list-item'
- New mu-plugin av-list-bullet-style.php injects CSS via wp_head() :
  .av-list-item { position: relative; padding-left: 0.9rem; }
  .av-list-item::before { gold bar, 3px × 1.1em, aligned to first line }

Regen all sections (industries, solutions, technology, editorial, forms,
home) to switch existing pages to the new style.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:05:45 +02:00
1c297b336f style(footer): align + brand sub-title typography across columns
One-shot mu-plugin patches the Footer template (#46) :
- Column sub-titles (Solutions / Company / Legal / Contact) now use the
  eyebrow style : gold, uppercase, 0.75rem, 0.1em letter-spacing — matches
  the section-eyebrows used across content pages.
- Brand heading (ASTERION VR) downsized to 1.125rem so it stops dominating
  the row; tagline muted to text-tertiary 0.875rem.
- Columns wrapper set to align-items: flex-start with consistent 3rem gap
  → all sub-titles sit at the same vertical baseline.
- Each column container tightened to 0.5rem rowGap (less air between
  heading and links).

Patches both content_2 (JSON, source) and footer_2 (serialized, mirrored
by the REST bridge). Idempotent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:02:10 +02:00
a5c15b4c7a feat(header): custom flag-based language switcher
Replaces WPML's default language selector with a compact branded dropdown :
current language flag + 2-letter code + chevron, with a CSS-only hover/focus
dropdown listing other available languages (flag + native name).

Implementation : remove_all_actions on wpml_add_language_selector + register
our own renderer. Bricks's wpml-language-switcher element (hdrlng) fires the
same action so no template edit needed.

Flags via emoji (🇬🇧 EN, 🇫🇷 FR) — no asset path concerns. Dropdown styled
to match the rest of the header (navy bg, gold-on-hover, subtle border +
shadow). Mobile : dropdown anchors left to stay in viewport.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 20:59:52 +02:00
b530b7a76f style(header): compact, branded dropdown for nav-menu submenus
CSS injected via wp_head() overrides Bricks default nav-menu sub-menu
spacing (which inherits a bloated line-height + item padding via the
parent menu's settings, not addressable through Bricks's nav-menu
controls alone). Tight padding (0.55rem 1.25rem), branded navy bg with
subtle gold hover, 16rem min-width, soft shadow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 20:45:35 +02:00
7134b70db9 feat(header): add submenus for Solutions / Industries / Technology + style dropdown
One-shot mu-plugin (?av_add_submenus=1) :
1. Adds child menu items to the Header — Main WP menu (term_id 9) :
   - Solutions → MY PROSERVE, PROSERVE FLEX, PROSERVE ACADEMY, PROSERVE+
   - Industries → Police, Special Forces, Military, Firefighters
   - Technology → VR Hardware, Software & AI, Weapons & Tracking, Scenarios,
     Instructor Cockpit, After-Action Review
   Children are matched by URL → idempotent re-runs.
2. Updates the Bricks nav-menu element settings in template #25 with
   dropdown styling : navy background, gold-on-hover text, padding,
   subtle gold border, indicator arrow. Patches both content_2 (JSON)
   and header_2 (serialized) meta keys.

Bricks's nav-menu CSS automatically handles hover-to-show on .menu-item-has-children.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 20:20:54 +02:00
c4718658d4 fix(header): make Asterion logo link to home
One-shot mu-plugin patches the Bricks heading 'hdrlgo' in template #25 to
add link.type='external' + link.url='/'. Idempotent — re-runs are safe.
Patches both _bricks_page_content_2 (JSON, source) and _bricks_page_header_2
(serialized PHP, mirrored by the REST bridge), so the change takes effect
immediately without re-running av-fix-template-meta.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 20:18:37 +02:00
38c0c5031e feat(pages): generate Phases 8-11 — Technology + Editorial + Forms + Home
Brings the site to its full programmatic page count : 24 EN + 24 FR pages
(48 total), all wired into the WPML CTE workflow established in the previous
commit. Each phase reuses tools/_av-bricks-shared.php builders, adds its own
filter('av_fr_translation_dict') to extend the FR dictionary, and ships a
seed-FR mu-plugin for the initial WPML trid linking.

## Phase 8 — Technology (tools/av-generate-technology.php + seed)
Hub /technology/ + 6 pillar pages (vr-hardware, software-ai, weapons-tracking,
scenarios, instructor-cockpit, after-action-review). Hub uses a 6-card grid
(3+3 layout — added card_count=6 case in av_build_cards_section).
EN : 87-93. FR : 94-100.

## Phase 9 — Editorial (tools/av-generate-editorial.php + seed)
5 top-level pages : /why-asterion/, /about/, /customers/, /trust/, /partners/.
Required adding empty-parent-path support to av_upsert_detail_page() so pages
can be created at the site root (no hub). EN : 107-111. FR : 112-116.

## Phase 10 — Forms (tools/av-generate-forms.php + seed)
4 conversion pages : /request-demo/, /request-te-kit/, /request-quote/,
/contact/. Custom page builder (not the shared detail-page pattern) :
hero + 2-column section (Bricks `form` element on left, promise list on
right) + optional shortcuts row (Contact), eligibility list (T&E Kit), FAQ
accordion (Demo). Form actions=email, emailTo=hello@asterionvr.com.
Field labels, select options, FAQ Q&A all in the FR dict.
EN : 122-125. FR : 126-129.

## Phase 11 — Home page (tools/av-generate-home.php + seed)
Custom-written single page (no data file). Sections : hero + 3-pillar cards
(Operational reality / Modular / Sovereign) + 4 Industries cards + 4
Solutions cards + 4-stat numbers band + Why-Asterion teaser CTA + Customers
teaser CTA + custom navy closer. Set as WP static front via
update_option(show_on_front=page, page_on_front=ID).
EN : 134. FR : 135.

## tools/_av-bricks-shared.php
- av_upsert_detail_page() now accepts empty `$parent_path` → top-level page
- av_build_cards_section() handles card_count=6 → 3-per-row layout

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 19:58:48 +02:00
d2badf49d4 feat(bricks+wpml): full programmatic page generation + native WPML CTE integration
Sessions 3-4 deliverables. Establishes the Asterion content pipeline :
EN pages generated programmatically from content-source/*-data.php, FR
translations rebuilt natively by Bricks's WPML integration from EN structure
+ WPML strings (no direct FR _bricks_page_content_2 writes).

## tools/_av-bricks-shared.php (the library)
Shared helpers + element atoms (eyebrow/heading/text/button/text-link) +
section builders (hero/prose/list/cards/cta/upsell/closer) + page write
pipeline that handles : write EN content via $wpdb (bypass Bricks's filter),
force Bricks::Elements::load_elements() so controls are populated, fire
wpml_page_builder_register_strings, push dict FR into icl_string_translations
(skip user CTE edits, auto-prefix /fr on internal URLs), trigger Bricks
native FR rebuild via wpml_page_builder_string_translated, and ensure a CTE
job exists (icl_translate_job.editor='wpml' + revision=NULL + populate
icl_translate rows with base64+gzip-encoded EN/FR strings).

## tools/av-generate-{industries,solutions}.php
Thin wrappers : URL trigger (template_redirect, not init — Bricks elements
load on 'wp' hook), add_filter('av_fr_translation_dict', ...) to register
FR strings, content-type-specific hub builder. ~150 FR strings per type.

## tools/av-translate-{industries,solutions}-fr.php
One-shot seeds for the initial FR linked posts via WPML trid mapping.

## tools/av-wpml-* operational mu-plugins
- set-cte : switch doc_translation_method to ICL_TM_TMETHOD_EDITOR (=1)
- create-jobs : reset CTE jobs (status=10 + needs_update=1 + editor=wpml +
  revision=NULL). Integrated into pipeline via av_ensure_wpml_cte_job().
- fix-status / repair : align FR posts to correct trid + cleanup orphans.
- push-translations : push dict into icl_string_translations.
- plugins-check / debug / dump-strings / icl-dump / rescan : diagnostics.

## tools/av-fix-link-types.php
One-shot DB migration : convert legacy link.type='internal'+url to 'external'
across all _bricks_page_*_2 meta values (JSON and PHP-serialized). Bricks's
set_link_attributes() only renders href= for type='external' — older session-3
templates lost their href silently.

## Other tools/ mu-plugins
- av-bricks-rest-bridge : pivot — exposes Bricks CPTs over REST, dual-format
  read filter (JSON for MCP / array for renderer), auto-mirror content→header/
  footer for templates.
- av-apply-bricks-styles, av-cleanup-orphans, av-create-wp-menu, av-debug-meta,
  av-dump-bricks, av-fix-template-meta : misc operational scripts.

## Bricks Config/
JSON snapshots of bricks_theme_styles, bricks_color_palette,
bricks_global_settings for diffable inspection.

## .gitignore
Add .mcp.json — holds per-developer WP App Password for the Bricks MCP server.

## wp-content/themes/asterion-bricks/assets/css/utilities.css
Note that all responsive overrides are now emitted natively by the page
generator via Bricks per-breakpoint settings, no custom CSS needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 19:40:28 +02:00
af0ed66122 docs(tools): clarify that Bricks is a theme, not a plugin
The Bricks ZIP cannot be installed via WP admin → Plugins → Add New →
Upload (it returns "No valid plugins were found"). Update tools/README.md
to make the distinction explicit and provide both PowerShell and admin
paths for each install.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:41:43 +02:00
7765d0fab2 chore: add tools/fresh-setup-mu-plugin for clean LocalWP recreation
Helper for resetting the dev environment by deleting the LocalWP site and
creating a fresh one (cleaner than wiping pages/options/transients in place).

tools/fresh-setup-mu-plugin.php
  Drop into wp-content/mu-plugins/ of a brand-new LocalWP install named
  "Asterion 2026". On first hit it:
    - sets siteurl/home to http://localhost:10004 (override AV_TARGET_HOME
      if LocalWP allocates a different port)
    - sets pretty permalinks (/%postname%/)
    - timezone Europe/Paris
    - activates the Bricks parent + asterion-bricks child theme (assumes
      the Junction has been re-made and the Bricks ZIP unpacked)
    - activates WPML core
    - sets Bricks Builder Access postTypes to page/post/case_study/scenario
    - flushes rewrite rules
    - self-deletes

tools/README.md
  Step-by-step procedure for the LocalWP delete → recreate → junction →
  unpack ZIPs → drop mu-plugin → first-hit flow. Plus the manual follow-up
  for Bricks license, WPML wizard, Bricks Theme Styles.

This file path (tools/) is a deliberate sibling of content-source/ and
ThirdParty/, all of them used during setup or migration but never loaded
by the site at runtime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:38:33 +02:00