diff --git a/.github/reports/theme-colour-variables-google-doc.txt b/.github/reports/theme-colour-variables-google-doc.txt
new file mode 100644
index 0000000..e72b7a6
--- /dev/null
+++ b/.github/reports/theme-colour-variables-google-doc.txt
@@ -0,0 +1,391 @@
+Theme Colour Variables
+
+- Base
+Slug: base
+Hex: #F8F8F8
+Variable: var(--wp--preset--color--base)
+
+- Contrast
+Slug: contrast
+Hex: #080808
+Variable: var(--wp--preset--color--contrast)
+
+- Neutral 100
+Slug: neutral-100
+Hex: #F8F8F8
+Variable: var(--wp--preset--color--neutral-100)
+
+- Neutral 200
+Slug: neutral-200
+Hex: #E8E8E8
+Variable: var(--wp--preset--color--neutral-200)
+
+- Neutral 300
+Slug: neutral-300
+Hex: #D8D8D8
+Variable: var(--wp--preset--color--neutral-300)
+
+- Neutral 400
+Slug: neutral-400
+Hex: #B8B8B8
+Variable: var(--wp--preset--color--neutral-400)
+
+- Neutral 500
+Slug: neutral-500
+Hex: #909090
+Variable: var(--wp--preset--color--neutral-500)
+
+- Neutral 600
+Slug: neutral-600
+Hex: #707070
+Variable: var(--wp--preset--color--neutral-600)
+
+- Neutral 700
+Slug: neutral-700
+Hex: #505050
+Variable: var(--wp--preset--color--neutral-700)
+
+- Neutral 800
+Slug: neutral-800
+Hex: #303030
+Variable: var(--wp--preset--color--neutral-800)
+
+- Neutral 900
+Slug: neutral-900
+Hex: #181818
+Variable: var(--wp--preset--color--neutral-900)
+
+- Surface 100
+Slug: surface-100
+Hex: #2A2A30
+Variable: var(--wp--preset--color--surface-100)
+
+- Surface 200
+Slug: surface-200
+Hex: #202028
+Variable: var(--wp--preset--color--surface-200)
+
+- Surface 300
+Slug: surface-300
+Hex: #181820
+Variable: var(--wp--preset--color--surface-300)
+
+- Surface 400
+Slug: surface-400
+Hex: #12121A
+Variable: var(--wp--preset--color--surface-400)
+
+- Surface 500
+Slug: surface-500
+Hex: #101018
+Variable: var(--wp--preset--color--surface-500)
+
+- Surface 600
+Slug: surface-600
+Hex: #0C0C14
+Variable: var(--wp--preset--color--surface-600)
+
+- Surface 700
+Slug: surface-700
+Hex: #080810
+Variable: var(--wp--preset--color--surface-700)
+
+- Surface 800
+Slug: surface-800
+Hex: #05050A
+Variable: var(--wp--preset--color--surface-800)
+
+- Surface 900
+Slug: surface-900
+Hex: #000000
+Variable: var(--wp--preset--color--surface-900)
+
+- Brand 100
+Slug: brand-100
+Hex: #D6E4FF
+Variable: var(--wp--preset--color--brand-100)
+
+- Brand 200
+Slug: brand-200
+Hex: #ADC8FF
+Variable: var(--wp--preset--color--brand-200)
+
+- Brand 300
+Slug: brand-300
+Hex: #85ACFF
+Variable: var(--wp--preset--color--brand-300)
+
+- Brand 400
+Slug: brand-400
+Hex: #5C90FF
+Variable: var(--wp--preset--color--brand-400)
+
+- Brand 500
+Slug: brand-500
+Hex: #1E6AFF
+Variable: var(--wp--preset--color--brand-500)
+
+- Brand 600
+Slug: brand-600
+Hex: #1C5EE4
+Variable: var(--wp--preset--color--brand-600)
+
+- Brand 700
+Slug: brand-700
+Hex: #184FBF
+Variable: var(--wp--preset--color--brand-700)
+
+- Brand 800
+Slug: brand-800
+Hex: #123B8F
+Variable: var(--wp--preset--color--brand-800)
+
+- Brand 900
+Slug: brand-900
+Hex: #0B255F
+Variable: var(--wp--preset--color--brand-900)
+
+- Cta 100
+Slug: cta-100
+Hex: #DDFBFF
+Variable: var(--wp--preset--color--cta-100)
+
+- Cta 200
+Slug: cta-200
+Hex: #B8F5FF
+Variable: var(--wp--preset--color--cta-200)
+
+- Cta 300
+Slug: cta-300
+Hex: #8DEEFF
+Variable: var(--wp--preset--color--cta-300)
+
+- Cta 400
+Slug: cta-400
+Hex: #5AE3F5
+Variable: var(--wp--preset--color--cta-400)
+
+- Cta 500
+Slug: cta-500
+Hex: #00FCFC
+Variable: var(--wp--preset--color--cta-500)
+
+- Cta 600
+Slug: cta-600
+Hex: #00D9D9
+Variable: var(--wp--preset--color--cta-600)
+
+- Cta 700
+Slug: cta-700
+Hex: #00A8A8
+Variable: var(--wp--preset--color--cta-700)
+
+- Cta 800
+Slug: cta-800
+Hex: #007476
+Variable: var(--wp--preset--color--cta-800)
+
+- Cta 900
+Slug: cta-900
+Hex: #003D3F
+Variable: var(--wp--preset--color--cta-900)
+
+- Accent 100
+Slug: accent-100
+Hex: #DDFBF1
+Variable: var(--wp--preset--color--accent-100)
+
+- Accent 200
+Slug: accent-200
+Hex: #B8F5DE
+Variable: var(--wp--preset--color--accent-200)
+
+- Accent 300
+Slug: accent-300
+Hex: #86EDC4
+Variable: var(--wp--preset--color--accent-300)
+
+- Accent 400
+Slug: accent-400
+Hex: #4FDEAA
+Variable: var(--wp--preset--color--accent-400)
+
+- Accent 500
+Slug: accent-500
+Hex: #22C78A
+Variable: var(--wp--preset--color--accent-500)
+
+- Accent 600
+Slug: accent-600
+Hex: #17A974
+Variable: var(--wp--preset--color--accent-600)
+
+- Accent 700
+Slug: accent-700
+Hex: #11865B
+Variable: var(--wp--preset--color--accent-700)
+
+- Accent 800
+Slug: accent-800
+Hex: #0B6243
+Variable: var(--wp--preset--color--accent-800)
+
+- Accent 900
+Slug: accent-900
+Hex: #063828
+Variable: var(--wp--preset--color--accent-900)
+
+- Accent Two 100
+Slug: accent-two-100
+Hex: #FFDDFB
+Variable: var(--wp--preset--color--accent-two-100)
+
+- Accent Two 200
+Slug: accent-two-200
+Hex: #FFB8F5
+Variable: var(--wp--preset--color--accent-two-200)
+
+- Accent Two 300
+Slug: accent-two-300
+Hex: #FF85EE
+Variable: var(--wp--preset--color--accent-two-300)
+
+- Accent Two 400
+Slug: accent-two-400
+Hex: #FF4FE3
+Variable: var(--wp--preset--color--accent-two-400)
+
+- Accent Two 500
+Slug: accent-two-500
+Hex: #FC00FC
+Variable: var(--wp--preset--color--accent-two-500)
+
+- Accent Two 600
+Slug: accent-two-600
+Hex: #D400D4
+Variable: var(--wp--preset--color--accent-two-600)
+
+- Accent Two 700
+Slug: accent-two-700
+Hex: #A600A6
+Variable: var(--wp--preset--color--accent-two-700)
+
+- Accent Two 800
+Slug: accent-two-800
+Hex: #760076
+Variable: var(--wp--preset--color--accent-two-800)
+
+- Accent Two 900
+Slug: accent-two-900
+Hex: #3F003F
+Variable: var(--wp--preset--color--accent-two-900)
+
+- Accent Three 100
+Slug: accent-three-100
+Hex: #E5FFE5
+Variable: var(--wp--preset--color--accent-three-100)
+
+- Accent Three 200
+Slug: accent-three-200
+Hex: #BEFFBE
+Variable: var(--wp--preset--color--accent-three-200)
+
+- Accent Three 300
+Slug: accent-three-300
+Hex: #8FFF8F
+Variable: var(--wp--preset--color--accent-three-300)
+
+- Accent Three 400
+Slug: accent-three-400
+Hex: #4FFF4F
+Variable: var(--wp--preset--color--accent-three-400)
+
+- Accent Three 500
+Slug: accent-three-500
+Hex: #00FC00
+Variable: var(--wp--preset--color--accent-three-500)
+
+- Accent Three 600
+Slug: accent-three-600
+Hex: #00D400
+Variable: var(--wp--preset--color--accent-three-600)
+
+- Accent Three 700
+Slug: accent-three-700
+Hex: #00A300
+Variable: var(--wp--preset--color--accent-three-700)
+
+- Accent Three 800
+Slug: accent-three-800
+Hex: #007000
+Variable: var(--wp--preset--color--accent-three-800)
+
+- Accent Three 900
+Slug: accent-three-900
+Hex: #003D00
+Variable: var(--wp--preset--color--accent-three-900)
+
+- Accent Four 100
+Slug: accent-four-100
+Hex: #FFFFDD
+Variable: var(--wp--preset--color--accent-four-100)
+
+- Accent Four 200
+Slug: accent-four-200
+Hex: #FFFFB8
+Variable: var(--wp--preset--color--accent-four-200)
+
+- Accent Four 300
+Slug: accent-four-300
+Hex: #FFFF85
+Variable: var(--wp--preset--color--accent-four-300)
+
+- Accent Four 400
+Slug: accent-four-400
+Hex: #FFFF4F
+Variable: var(--wp--preset--color--accent-four-400)
+
+- Accent Four 500
+Slug: accent-four-500
+Hex: #FCFC00
+Variable: var(--wp--preset--color--accent-four-500)
+
+- Accent Four 600
+Slug: accent-four-600
+Hex: #D4D400
+Variable: var(--wp--preset--color--accent-four-600)
+
+- Accent Four 700
+Slug: accent-four-700
+Hex: #A6A600
+Variable: var(--wp--preset--color--accent-four-700)
+
+- Accent Four 800
+Slug: accent-four-800
+Hex: #767600
+Variable: var(--wp--preset--color--accent-four-800)
+
+- Accent Four 900
+Slug: accent-four-900
+Hex: #3F3F00
+Variable: var(--wp--preset--color--accent-four-900)
+
+- Error Foreground
+Slug: error-foreground
+Hex: #EF4444
+Variable: var(--wp--preset--color--error-foreground)
+
+- Warning Foreground
+Slug: warning-foreground
+Hex: #F59E0B
+Variable: var(--wp--preset--color--warning-foreground)
+
+- Information Foreground
+Slug: information-foreground
+Hex: #3B82F6
+Variable: var(--wp--preset--color--information-foreground)
+
+- Success Foreground
+Slug: success-foreground
+Hex: #10B981
+Variable: var(--wp--preset--color--success-foreground)
\ No newline at end of file
diff --git a/.github/reports/theme-colour-variables.md b/.github/reports/theme-colour-variables.md
new file mode 100644
index 0000000..9879925
--- /dev/null
+++ b/.github/reports/theme-colour-variables.md
@@ -0,0 +1,393 @@
+# Theme Colour Variables
+
+Extracted from `theme.json` `settings.color.palette`.
+
+- Name: Base
+ Slug: base
+ Hex: #F8F8F8
+ Variable: var(--wp--preset--color--base)
+
+- Name: Contrast
+ Slug: contrast
+ Hex: #080808
+ Variable: var(--wp--preset--color--contrast)
+
+- Name: Neutral 100
+ Slug: neutral-100
+ Hex: #F8F8F8
+ Variable: var(--wp--preset--color--neutral-100)
+
+- Name: Neutral 200
+ Slug: neutral-200
+ Hex: #E8E8E8
+ Variable: var(--wp--preset--color--neutral-200)
+
+- Name: Neutral 300
+ Slug: neutral-300
+ Hex: #D8D8D8
+ Variable: var(--wp--preset--color--neutral-300)
+
+- Name: Neutral 400
+ Slug: neutral-400
+ Hex: #B8B8B8
+ Variable: var(--wp--preset--color--neutral-400)
+
+- Name: Neutral 500
+ Slug: neutral-500
+ Hex: #909090
+ Variable: var(--wp--preset--color--neutral-500)
+
+- Name: Neutral 600
+ Slug: neutral-600
+ Hex: #707070
+ Variable: var(--wp--preset--color--neutral-600)
+
+- Name: Neutral 700
+ Slug: neutral-700
+ Hex: #505050
+ Variable: var(--wp--preset--color--neutral-700)
+
+- Name: Neutral 800
+ Slug: neutral-800
+ Hex: #303030
+ Variable: var(--wp--preset--color--neutral-800)
+
+- Name: Neutral 900
+ Slug: neutral-900
+ Hex: #181818
+ Variable: var(--wp--preset--color--neutral-900)
+
+- Name: Surface 100
+ Slug: surface-100
+ Hex: #2A2A30
+ Variable: var(--wp--preset--color--surface-100)
+
+- Name: Surface 200
+ Slug: surface-200
+ Hex: #202028
+ Variable: var(--wp--preset--color--surface-200)
+
+- Name: Surface 300
+ Slug: surface-300
+ Hex: #181820
+ Variable: var(--wp--preset--color--surface-300)
+
+- Name: Surface 400
+ Slug: surface-400
+ Hex: #12121A
+ Variable: var(--wp--preset--color--surface-400)
+
+- Name: Surface 500
+ Slug: surface-500
+ Hex: #101018
+ Variable: var(--wp--preset--color--surface-500)
+
+- Name: Surface 600
+ Slug: surface-600
+ Hex: #0C0C14
+ Variable: var(--wp--preset--color--surface-600)
+
+- Name: Surface 700
+ Slug: surface-700
+ Hex: #080810
+ Variable: var(--wp--preset--color--surface-700)
+
+- Name: Surface 800
+ Slug: surface-800
+ Hex: #05050A
+ Variable: var(--wp--preset--color--surface-800)
+
+- Name: Surface 900
+ Slug: surface-900
+ Hex: #000000
+ Variable: var(--wp--preset--color--surface-900)
+
+- Name: Brand 100
+ Slug: brand-100
+ Hex: #D6E4FF
+ Variable: var(--wp--preset--color--brand-100)
+
+- Name: Brand 200
+ Slug: brand-200
+ Hex: #ADC8FF
+ Variable: var(--wp--preset--color--brand-200)
+
+- Name: Brand 300
+ Slug: brand-300
+ Hex: #85ACFF
+ Variable: var(--wp--preset--color--brand-300)
+
+- Name: Brand 400
+ Slug: brand-400
+ Hex: #5C90FF
+ Variable: var(--wp--preset--color--brand-400)
+
+- Name: Brand 500
+ Slug: brand-500
+ Hex: #1E6AFF
+ Variable: var(--wp--preset--color--brand-500)
+
+- Name: Brand 600
+ Slug: brand-600
+ Hex: #1C5EE4
+ Variable: var(--wp--preset--color--brand-600)
+
+- Name: Brand 700
+ Slug: brand-700
+ Hex: #184FBF
+ Variable: var(--wp--preset--color--brand-700)
+
+- Name: Brand 800
+ Slug: brand-800
+ Hex: #123B8F
+ Variable: var(--wp--preset--color--brand-800)
+
+- Name: Brand 900
+ Slug: brand-900
+ Hex: #0B255F
+ Variable: var(--wp--preset--color--brand-900)
+
+- Name: Cta 100
+ Slug: cta-100
+ Hex: #DDFBFF
+ Variable: var(--wp--preset--color--cta-100)
+
+- Name: Cta 200
+ Slug: cta-200
+ Hex: #B8F5FF
+ Variable: var(--wp--preset--color--cta-200)
+
+- Name: Cta 300
+ Slug: cta-300
+ Hex: #8DEEFF
+ Variable: var(--wp--preset--color--cta-300)
+
+- Name: Cta 400
+ Slug: cta-400
+ Hex: #5AE3F5
+ Variable: var(--wp--preset--color--cta-400)
+
+- Name: Cta 500
+ Slug: cta-500
+ Hex: #00FCFC
+ Variable: var(--wp--preset--color--cta-500)
+
+- Name: Cta 600
+ Slug: cta-600
+ Hex: #00D9D9
+ Variable: var(--wp--preset--color--cta-600)
+
+- Name: Cta 700
+ Slug: cta-700
+ Hex: #00A8A8
+ Variable: var(--wp--preset--color--cta-700)
+
+- Name: Cta 800
+ Slug: cta-800
+ Hex: #007476
+ Variable: var(--wp--preset--color--cta-800)
+
+- Name: Cta 900
+ Slug: cta-900
+ Hex: #003D3F
+ Variable: var(--wp--preset--color--cta-900)
+
+- Name: Accent 100
+ Slug: accent-100
+ Hex: #DDFBF1
+ Variable: var(--wp--preset--color--accent-100)
+
+- Name: Accent 200
+ Slug: accent-200
+ Hex: #B8F5DE
+ Variable: var(--wp--preset--color--accent-200)
+
+- Name: Accent 300
+ Slug: accent-300
+ Hex: #86EDC4
+ Variable: var(--wp--preset--color--accent-300)
+
+- Name: Accent 400
+ Slug: accent-400
+ Hex: #4FDEAA
+ Variable: var(--wp--preset--color--accent-400)
+
+- Name: Accent 500
+ Slug: accent-500
+ Hex: #22C78A
+ Variable: var(--wp--preset--color--accent-500)
+
+- Name: Accent 600
+ Slug: accent-600
+ Hex: #17A974
+ Variable: var(--wp--preset--color--accent-600)
+
+- Name: Accent 700
+ Slug: accent-700
+ Hex: #11865B
+ Variable: var(--wp--preset--color--accent-700)
+
+- Name: Accent 800
+ Slug: accent-800
+ Hex: #0B6243
+ Variable: var(--wp--preset--color--accent-800)
+
+- Name: Accent 900
+ Slug: accent-900
+ Hex: #063828
+ Variable: var(--wp--preset--color--accent-900)
+
+- Name: Accent Two 100
+ Slug: accent-two-100
+ Hex: #FFDDFB
+ Variable: var(--wp--preset--color--accent-two-100)
+
+- Name: Accent Two 200
+ Slug: accent-two-200
+ Hex: #FFB8F5
+ Variable: var(--wp--preset--color--accent-two-200)
+
+- Name: Accent Two 300
+ Slug: accent-two-300
+ Hex: #FF85EE
+ Variable: var(--wp--preset--color--accent-two-300)
+
+- Name: Accent Two 400
+ Slug: accent-two-400
+ Hex: #FF4FE3
+ Variable: var(--wp--preset--color--accent-two-400)
+
+- Name: Accent Two 500
+ Slug: accent-two-500
+ Hex: #FC00FC
+ Variable: var(--wp--preset--color--accent-two-500)
+
+- Name: Accent Two 600
+ Slug: accent-two-600
+ Hex: #D400D4
+ Variable: var(--wp--preset--color--accent-two-600)
+
+- Name: Accent Two 700
+ Slug: accent-two-700
+ Hex: #A600A6
+ Variable: var(--wp--preset--color--accent-two-700)
+
+- Name: Accent Two 800
+ Slug: accent-two-800
+ Hex: #760076
+ Variable: var(--wp--preset--color--accent-two-800)
+
+- Name: Accent Two 900
+ Slug: accent-two-900
+ Hex: #3F003F
+ Variable: var(--wp--preset--color--accent-two-900)
+
+- Name: Accent Three 100
+ Slug: accent-three-100
+ Hex: #E5FFE5
+ Variable: var(--wp--preset--color--accent-three-100)
+
+- Name: Accent Three 200
+ Slug: accent-three-200
+ Hex: #BEFFBE
+ Variable: var(--wp--preset--color--accent-three-200)
+
+- Name: Accent Three 300
+ Slug: accent-three-300
+ Hex: #8FFF8F
+ Variable: var(--wp--preset--color--accent-three-300)
+
+- Name: Accent Three 400
+ Slug: accent-three-400
+ Hex: #4FFF4F
+ Variable: var(--wp--preset--color--accent-three-400)
+
+- Name: Accent Three 500
+ Slug: accent-three-500
+ Hex: #00FC00
+ Variable: var(--wp--preset--color--accent-three-500)
+
+- Name: Accent Three 600
+ Slug: accent-three-600
+ Hex: #00D400
+ Variable: var(--wp--preset--color--accent-three-600)
+
+- Name: Accent Three 700
+ Slug: accent-three-700
+ Hex: #00A300
+ Variable: var(--wp--preset--color--accent-three-700)
+
+- Name: Accent Three 800
+ Slug: accent-three-800
+ Hex: #007000
+ Variable: var(--wp--preset--color--accent-three-800)
+
+- Name: Accent Three 900
+ Slug: accent-three-900
+ Hex: #003D00
+ Variable: var(--wp--preset--color--accent-three-900)
+
+- Name: Accent Four 100
+ Slug: accent-four-100
+ Hex: #FFFFDD
+ Variable: var(--wp--preset--color--accent-four-100)
+
+- Name: Accent Four 200
+ Slug: accent-four-200
+ Hex: #FFFFB8
+ Variable: var(--wp--preset--color--accent-four-200)
+
+- Name: Accent Four 300
+ Slug: accent-four-300
+ Hex: #FFFF85
+ Variable: var(--wp--preset--color--accent-four-300)
+
+- Name: Accent Four 400
+ Slug: accent-four-400
+ Hex: #FFFF4F
+ Variable: var(--wp--preset--color--accent-four-400)
+
+- Name: Accent Four 500
+ Slug: accent-four-500
+ Hex: #FCFC00
+ Variable: var(--wp--preset--color--accent-four-500)
+
+- Name: Accent Four 600
+ Slug: accent-four-600
+ Hex: #D4D400
+ Variable: var(--wp--preset--color--accent-four-600)
+
+- Name: Accent Four 700
+ Slug: accent-four-700
+ Hex: #A6A600
+ Variable: var(--wp--preset--color--accent-four-700)
+
+- Name: Accent Four 800
+ Slug: accent-four-800
+ Hex: #767600
+ Variable: var(--wp--preset--color--accent-four-800)
+
+- Name: Accent Four 900
+ Slug: accent-four-900
+ Hex: #3F3F00
+ Variable: var(--wp--preset--color--accent-four-900)
+
+- Name: Error Foreground
+ Slug: error-foreground
+ Hex: #EF4444
+ Variable: var(--wp--preset--color--error-foreground)
+
+- Name: Warning Foreground
+ Slug: warning-foreground
+ Hex: #F59E0B
+ Variable: var(--wp--preset--color--warning-foreground)
+
+- Name: Information Foreground
+ Slug: information-foreground
+ Hex: #3B82F6
+ Variable: var(--wp--preset--color--information-foreground)
+
+- Name: Success Foreground
+ Slug: success-foreground
+ Hex: #10B981
+ Variable: var(--wp--preset--color--success-foreground)
diff --git a/.github/tasks/task-list.md b/.github/tasks/task-list.md
index 70b329d..7d3edd0 100644
--- a/.github/tasks/task-list.md
+++ b/.github/tasks/task-list.md
@@ -20,6 +20,7 @@ Update this file as tasks are created, started, or completed.
## Development
+- [ ] Execute the detailed Figma Make implementation plan in `.github/tasks/2026-04-07-figma-make-implementation-checklist.md`
- [ ] Build `parts/header.html`
- [ ] Build `parts/footer.html`
- [ ] Build `templates/index.html`
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8bd99a7..cb453e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,15 +11,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- Registered the theme font-family presets as `body`, `heading`, and `monospace`, and applied the `monospace` preset to code elements in `theme.json`.
- Added a GSAP asset bootstrap in `inc/gsap.php` for class-based interactive effects.
- Added a GSAP-driven `is-style-card-spotlight` group effect using theme surface and accent colours.
- Added usage documentation for the spotlight card class.
- Added a registered `Card Spotlight` Group block style for easy editor application.
- Added a CSS-only sliding icon treatment for the core outline button variation.
+- Added a GSAP-powered front-page hero with rotating proof points, interactive network background, and primary / outline CTAs.
+- Added a dedicated `front-page.html` template that renders the marketing hero before editable page content.
### Changed
+- Enabled root-padding-aware alignments, added theme typography writing-mode support, and applied a default spacing-20 horizontal page gutter in `theme.json`.
+- Moved block-style visual tokens into `theme.json` and `styles/blocks/**/*.json`, leaving `assets/css/animations.css` as the interaction layer for the heading, link, and button treatments.
+- Re-aligned the home hero GSAP wiring to the reusable `Home Hero Section` block style and dropped the abandoned cycling heading path.
+- Moved theme and heading line heights in `theme.json` onto shared custom tokens, with H1 using a tighter value and H2 through H6 sharing a common heading rhythm.
- Refined the GSAP spotlight card glow alignment and switched the card shell to a lighter theme palette.
+- Refined the GSAP front-page hero so the network background sits behind the headline, responds more directly to pointer movement, and swaps words with a right-to-left character stagger.
+- Reduced the default H1 weight in `theme.json` and rebuilt the hero word loop so longer words no longer clip, overlap, or reset with a blank frame.
+- Fixed the homepage template so sites using `show_on_front = posts` render the posts query beneath the hero instead of an empty static-page `post-content` block.
+- Tightened the hero word-stage measurement, removed the empty transition frame, and added smaller-screen layout rules so the hero scales more cleanly on mobile.
+- Softened the hero word transition so the letters stagger vertically from right to left without the word shifting too far sideways during the swap.
+- Replaced the hero's stacked-word repeat timeline with a two-layer word controller so the active word sits slightly higher and the loop no longer starts with an empty frame.
+- Added a subtle character gap to the animated hero word so the rotating terms read a little more cleanly.
- Simplified the spotlight effect configuration so live tuning happens directly in `assets/css/gsap-animations.css`.
- Moved GSAP-specific spotlight styling from `assets/css/animations.css` to `assets/css/gsap-animations.css`.
- Removed glow hover styling from default and outline buttons so only the dedicated glow button style blooms.
diff --git a/assets/css/animations.css b/assets/css/animations.css
index 3ca5dac..6ac6d91 100644
--- a/assets/css/animations.css
+++ b/assets/css/animations.css
@@ -1,6 +1,6 @@
-/********** Text **********/
+/********** Text Motion **********/
-/* Gradient Text: Gradient Accent */
+/* Gradient Accent */
@keyframes ls-gradient-text-clip {
to {
background-position: var(--ls-gradient-end-position, 100%) center;
@@ -62,17 +62,22 @@
}
}
-/********** Links **********/
-/* Paragraph Link: Link Underline Accent */
+/********** Link Motion **********/
+
+/* Link Underline Accent */
.wp-block-paragraph.is-style-link-underline-accent a {
- text-decoration: none;
- padding-bottom: 5px;
- background-image: linear-gradient(var(--wp--preset--color--brand-500),
- var(--wp--preset--color--accent-500));
+ padding-bottom: var(--ls-link-underline-padding-bottom, 5px);
+ background-image: var(
+ --ls-link-underline-image,
+ linear-gradient(
+ var(--wp--preset--color--brand-500),
+ var(--wp--preset--color--accent-500)
+ )
+ );
background-position: 0 100%;
background-repeat: no-repeat;
- background-size: 0 2px;
+ background-size: 0 var(--ls-link-underline-thickness, 2px);
transition: background-size 220ms ease, color 220ms ease;
transition-delay: 0s;
}
@@ -83,10 +88,11 @@
.wp-block-paragraph.is-style-link-underline-accent a:hover,
.wp-block-paragraph.is-style-link-underline-accent a:focus-visible {
- background-size: 100% 2px;
+ background-size: 100% var(--ls-link-underline-thickness, 2px);
}
-/********** Buttons **********/
+
+/********** Button Motion **********/
.wp-block-button:not([class*="is-style-"]),
.wp-block-button.is-style-fill,
@@ -94,7 +100,7 @@
max-inline-size: 100%;
}
-/* Shared Button Transition */
+/* Shared button motion primitives */
.wp-element-button,
.wp-block-button__link {
transition:
@@ -105,23 +111,13 @@
outline-color 220ms ease,
outline-offset 220ms ease,
transform 180ms ease;
- transition-delay: 0s;
- box-shadow: none;
- outline-offset: 0;
- text-shadow: none;
-}
-
-
-.wp-element-button:hover,
-.wp-block-button__link:hover {
- transition-delay: 0s;
+ transition-delay: 80ms;
}
.wp-element-button:hover,
.wp-element-button:focus-visible,
.wp-block-button__link:hover,
.wp-block-button__link:focus-visible {
- box-shadow: none;
outline-offset: 0;
}
@@ -130,9 +126,12 @@
transform: scale(var(--ls-button-active-scale, 0.98));
}
-/* Default Fill Button */
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link,
-.wp-block-button.is-style-fill .wp-block-button__link {
+/* Shared button shell for the default fill and outline treatments. */
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill,
+ .wp-block-button.is-style-outline
+) .wp-block-button__link {
position: relative;
display: inline-flex;
align-items: center;
@@ -141,24 +140,43 @@
white-space: nowrap;
overflow: hidden;
isolation: isolate;
+}
+
+/* Fill button motion */
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link {
+ --ls-button-fill-icon-well-size: 3rem;
+ --ls-button-fill-icon-inline-end: 0.625rem;
+ --ls-button-fill-icon-font-size: 1.25rem;
+ --ls-button-fill-icon-block-inset: calc(
+ 50% - (var(--ls-button-fill-icon-well-size) / 2)
+ );
+ --ls-button-fill-icon-inline-start: calc(
+ 100% - var(--ls-button-fill-icon-well-size) - var(--ls-button-fill-icon-inline-end)
+ );
background: transparent;
border: 0;
- color: var(--ls-button-fill-text, var(--wp--preset--color--base));
transition:
transform var(--ls-button-fill-duration, 500ms)
cubic-bezier(0.4, 0, 0.2, 1),
color var(--ls-button-fill-duration, 500ms)
cubic-bezier(0.4, 0, 0.2, 1);
- transition-delay: 0s;
}
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link::before,
-.wp-block-button.is-style-fill .wp-block-button__link::before {
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
- background: var(--ls-button-fill-background, var(--wp--preset--color--brand-500));
+ background: var(
+ --ls-button-fill-background,
+ var(--wp--preset--color--brand-500)
+ );
transition:
inset-inline-start 350ms
cubic-bezier(0.4, 0, 0.2, 1),
@@ -170,211 +188,121 @@
cubic-bezier(0.4, 0, 0.2, 1),
border-radius 350ms
cubic-bezier(0.4, 0, 0.2, 1);
- transition-delay: 0s;
- pointer-events: none;
z-index: -1;
}
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link::after,
-.wp-block-button.is-style-fill .wp-block-button__link::after {
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link::after {
content: "\2192";
position: absolute;
- inset-block-start: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 3rem) / 2)
- );
- inset-block-end: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 3rem) / 2)
- );
- inset-inline-end: 0.625rem;
- width: var(--ls-button-fill-icon-well-size, 3rem);
+ inset-block: var(--ls-button-fill-icon-block-inset);
+ inset-inline-end: var(--ls-button-fill-icon-inline-end);
+ width: var(--ls-button-fill-icon-well-size);
display: grid;
place-items: center;
- color: var(--ls-button-fill-icon-colour, var(--wp--preset--color--base));
- font-size: 1.25rem;
+ color: var(--ls-button-fill-icon-colour, currentColor);
+ font-size: var(--ls-button-fill-icon-font-size);
font-weight: 700;
line-height: 1;
transition:
color 500ms
cubic-bezier(0.4, 0, 0.2, 1);
- pointer-events: none;
}
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover,
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover::before,
-.wp-block-button.is-style-fill .wp-block-button__link:hover,
-.wp-block-button.is-style-fill .wp-block-button__link:hover::before {
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link:hover,
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link:hover::before {
transition-delay: var(--ls-button-fill-enter-delay, 80ms);
}
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover::before,
-.wp-block-button:not([class*="is-style-"])
- .wp-block-button__link:focus-visible::before,
-.wp-block-button.is-style-fill .wp-block-button__link:hover::before,
-.wp-block-button.is-style-fill .wp-block-button__link:focus-visible::before {
- inset-block-start: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 3rem) / 2)
- );
- inset-inline-end: 0.625rem;
- inset-block-end: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 3rem) / 2)
- );
- inset-inline-start: calc(
- 100% - var(--ls-button-fill-icon-well-size, 3rem) - 0.625rem
- );
- border-radius: var(--wp--preset--border-radius--200);
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link:hover::before,
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link:focus-visible::before {
+ inset-block: var(--ls-button-fill-icon-block-inset);
+ inset-inline-end: var(--ls-button-fill-icon-inline-end);
+ inset-inline-start: var(--ls-button-fill-icon-inline-start);
+ border-radius: inherit;
}
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover,
-.wp-block-button:not([class*="is-style-"])
- .wp-block-button__link:focus-visible,
-.wp-block-button.is-style-fill .wp-block-button__link:hover,
-.wp-block-button.is-style-fill .wp-block-button__link:focus-visible {
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link:hover,
+:is(
+ .wp-block-button:not([class*="is-style-"]),
+ .wp-block-button.is-style-fill
+) .wp-block-button__link:focus-visible {
color: var(--ls-button-fill-hover-text, var(--wp--preset--color--contrast));
}
-.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:active,
-.wp-block-button.is-style-fill .wp-block-button__link:active {
- transform: scale(0.98);
-}
-
-/* Outline Button */
+/* Outline button motion */
.wp-block-button.is-style-outline .wp-block-button__link {
- position: relative;
- display: inline-flex;
- align-items: center;
- box-sizing: border-box;
- max-inline-size: 100%;
- white-space: nowrap;
- overflow: hidden;
- isolation: isolate;
- border: 2px solid var(--wp--preset--color--brand-500);
- border-radius: var(--wp--preset--border-radius--200);
- background-color: var(--wp--preset--color--base);
- color: var(--wp--preset--color--contrast);
+ --ls-button-outline-icon-well-size: 3rem;
+ --ls-button-outline-icon-inset: 4px;
+ --ls-button-outline-icon-font-size: 1.25rem;
+ --ls-button-outline-hover-padding-start: 4rem;
+ --ls-button-outline-hover-padding-end: 1.5rem;
+ --ls-button-outline-icon-inline-start: calc(
+ 100% - var(--ls-button-outline-icon-well-size) - var(--ls-button-outline-icon-inset)
+ );
transition:
padding-inline-start 500ms
cubic-bezier(0.4, 0, 0.2, 1),
padding-inline-end 500ms
cubic-bezier(0.4, 0, 0.2, 1),
- border-color 280ms ease,
- color 280ms ease,
- transform 180ms ease;
- transition-delay: 0s;
- box-shadow: none;
+ transform 500ms ease-in-out;
}
.wp-block-button.is-style-outline .wp-block-button__link::after {
content: "\2192";
position: absolute;
- inset-block: 4px;
- inset-inline-end: 4px;
- width: 3rem;
+ inset-block: var(--ls-button-outline-icon-inset);
+ inset-inline-end: var(--ls-button-outline-icon-inset);
+ width: var(--ls-button-outline-icon-well-size);
display: grid;
place-items: center;
- border-radius: calc(var(--wp--preset--border-radius--200) - 2px);
- background-color: var(--wp--preset--color--brand-500);
- color: var(--wp--preset--color--base);
- font-size: 1.25rem;
+ border-radius: var(--ls-button-outline-icon-radius, var(--wp--preset--border-radius--100));
+ background-color: var(
+ --ls-button-outline-accent-background,
+ var(--wp--preset--color--brand-500)
+ );
+ color: var(--ls-button-outline-accent-colour, var(--wp--preset--color--base));
+ font-size: var(--ls-button-outline-icon-font-size);
font-weight: 700;
- line-height: 1.25;
+ line-height: 1;
transition:
inset-inline-end 500ms
cubic-bezier(0.4, 0, 0.2, 1),
background-color 280ms ease,
color 280ms ease;
- transition-delay: 0s;
- pointer-events: none;
z-index: 1;
}
.wp-block-button.is-style-outline .wp-block-button__link:hover,
.wp-block-button.is-style-outline .wp-block-button__link:focus-visible {
- padding-inline-start: 4rem;
- padding-inline-end: 1.5rem;
+ padding-inline-start: var(--ls-button-outline-hover-padding-start);
+ padding-inline-end: var(--ls-button-outline-hover-padding-end);
}
.wp-block-button.is-style-outline .wp-block-button__link:hover::after,
.wp-block-button.is-style-outline .wp-block-button__link:focus-visible::after {
- inset-inline-end: calc(100% - 3rem - 4px);
+ inset-inline-end: var(--ls-button-outline-icon-inline-start);
}
-@media (max-width: 680px) {
- .wp-block-button:not([class*="is-style-"]) .wp-block-button__link,
- .wp-block-button.is-style-fill .wp-block-button__link {
- --ls-button-fill-icon-well-size: 2.75rem;
- max-inline-size: 100%;
- white-space: normal;
- text-wrap: pretty;
- font-size: 0.95rem;
- line-height: 1.35;
- padding-top: 0.875rem;
- padding-right: 3.5rem;
- padding-bottom: 0.875rem;
- padding-left: 1rem;
- }
-
- .wp-block-button:not([class*="is-style-"]) .wp-block-button__link::after,
- .wp-block-button.is-style-fill .wp-block-button__link::after {
- inset-block-start: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 2.75rem) / 2)
- );
- inset-block-end: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 2.75rem) / 2)
- );
- inset-inline-end: 0.5rem;
- width: var(--ls-button-fill-icon-well-size, 2.75rem);
- font-size: 1.125rem;
- }
-
- .wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover::before,
- .wp-block-button:not([class*="is-style-"])
- .wp-block-button__link:focus-visible::before,
- .wp-block-button.is-style-fill .wp-block-button__link:hover::before,
- .wp-block-button.is-style-fill .wp-block-button__link:focus-visible::before {
- inset-block-start: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 2.75rem) / 2)
- );
- inset-inline-end: 0.5rem;
- inset-block-end: calc(
- 50% - (var(--ls-button-fill-icon-well-size, 2.75rem) / 2)
- );
- inset-inline-start: calc(
- 100% - var(--ls-button-fill-icon-well-size, 2.75rem) - 0.5rem
- );
- }
- .wp-block-button.is-style-outline .wp-block-button__link {
- max-inline-size: 100%;
- white-space: normal;
- text-wrap: pretty;
- font-size: 0.95rem;
- line-height: 1.35;
- padding-top: 0.875rem;
- padding-right: 3.5rem;
- padding-bottom: 0.875rem;
- padding-left: 1rem;
- }
-
- .wp-block-button.is-style-outline .wp-block-button__link::after {
- inset-block: 3px;
- inset-inline-end: 3px;
- width: 2.75rem;
- font-size: 1.125rem;
- }
-
- .wp-block-button.is-style-outline .wp-block-button__link:hover,
- .wp-block-button.is-style-outline .wp-block-button__link:focus-visible {
- padding-inline-start: 3.5rem;
- padding-inline-end: 1rem;
- }
-
- .wp-block-button.is-style-outline .wp-block-button__link:hover::after,
- .wp-block-button.is-style-outline .wp-block-button__link:focus-visible::after {
- inset-inline-end: calc(100% - 2.75rem - 3px);
- }
-}
-
-/* Button Glow: Button Glow Accent */
+/* Button Glow Accent */
.wp-block-button.is-style-button-glow-accent .wp-block-button__link {
transition:
box-shadow 900ms cubic-bezier(0.19, 1, 0.22, 1),
@@ -383,33 +311,50 @@
transform 180ms ease;
transition-delay: 0s;
box-shadow: inset 0 0 20px
- color-mix(in srgb, var(--wp--preset--color--brand-500) 0%, transparent);
- outline: 1px solid
- color-mix(in srgb, var(--wp--preset--color--brand-500) 45%, transparent);
- outline-offset: 0;
- text-shadow: none;
+ color-mix(
+ in srgb,
+ var(--ls-button-glow-colour, var(--wp--preset--color--brand-500))
+ var(--ls-button-glow-resting-strength, 0%),
+ transparent
+ );
+ outline: var(--ls-button-glow-outline-width, 1px) solid
+ color-mix(
+ in srgb,
+ var(--ls-button-glow-colour, var(--wp--preset--color--brand-500))
+ var(--ls-button-glow-outline-strength, 45%),
+ transparent
+ );
}
.wp-block-button.is-style-button-glow-accent .wp-block-button__link:hover {
- transition-delay: 80ms;
+ transition-delay: var(--ls-button-glow-enter-delay, 80ms);
}
.wp-block-button.is-style-button-glow-accent .wp-block-button__link:hover,
.wp-block-button.is-style-button-glow-accent
.wp-block-button__link:focus-visible {
- background-color: var(--wp--preset--color--brand-500);
- color: var(--wp--preset--color--base);
+ background-color: var(
+ --ls-button-glow-hover-background,
+ var(--wp--preset--color--brand-500)
+ );
+ color: var(--ls-button-glow-hover-text, var(--wp--preset--color--base));
box-shadow:
inset 0 0 20px
- color-mix(in srgb, var(--wp--preset--color--brand-500) 35%, transparent),
+ color-mix(
+ in srgb,
+ var(--ls-button-glow-colour, var(--wp--preset--color--brand-500))
+ var(--ls-button-glow-inner-strength, 35%),
+ transparent
+ ),
0 0 20px
- color-mix(in srgb, var(--wp--preset--color--brand-500) 20%, transparent);
+ color-mix(
+ in srgb,
+ var(--ls-button-glow-colour, var(--wp--preset--color--brand-500))
+ var(--ls-button-glow-outer-strength, 20%),
+ transparent
+ );
outline-color: transparent;
- outline-offset: 12px;
-}
-
-.wp-block-button.is-style-button-glow-accent .wp-block-button__link:active {
- transform: scale(0.98);
+ outline-offset: var(--ls-button-glow-outline-offset, 12px);
}
diff --git a/assets/css/gsap-animations.css b/assets/css/gsap-animations.css
index d3c5c49..f153b4c 100644
--- a/assets/css/gsap-animations.css
+++ b/assets/css/gsap-animations.css
@@ -134,4 +134,113 @@
.is-style-card-spotlight::after {
transition: none;
}
+}
+
+/* Home Hero Section: background-only Group block style. */
+.is-style-home-hero-section {
+ --ls-home-hero-surface: var(--wp--preset--color--base);
+ --ls-home-hero-brand: var(--wp--preset--color--brand-500);
+ --ls-home-hero-cta: var(--wp--preset--color--cta-500);
+ --ls-home-hero-accent: var(--wp--preset--color--accent-two-500);
+ position: relative;
+ overflow: hidden;
+ isolation: isolate;
+ background:
+ radial-gradient(
+ circle at 16% 14%,
+ color-mix(in srgb, var(--ls-home-hero-brand) 12%, transparent) 0%,
+ transparent 34%
+ ),
+ radial-gradient(
+ circle at 84% 18%,
+ color-mix(in srgb, var(--ls-home-hero-cta) 14%, transparent) 0%,
+ transparent 28%
+ ),
+ radial-gradient(
+ circle at 50% 100%,
+ color-mix(in srgb, var(--ls-home-hero-accent) 7%, transparent) 0%,
+ transparent 36%
+ ),
+ linear-gradient(
+ 180deg,
+ color-mix(in srgb, var(--ls-home-hero-surface) 98%, #fff 2%) 0%,
+ var(--ls-home-hero-surface) 100%
+ );
+}
+
+.is-style-home-hero-section > :not(.ls-home-hero-section__background) {
+ position: relative;
+ z-index: 1;
+}
+
+.ls-home-hero-section__background,
+.ls-home-hero-section__network {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ overflow: hidden;
+}
+
+.ls-home-hero-section__background {
+ z-index: 0;
+}
+
+.ls-home-hero-section__network {
+ z-index: 1;
+ opacity: 0.92;
+}
+
+.ls-home-hero-section__orb {
+ position: absolute;
+ border-radius: 999px;
+ filter: blur(80px);
+ opacity: 0.8;
+ transform: translate3d( 0, 0, 0 );
+ will-change: transform;
+ z-index: 0;
+}
+
+.ls-home-hero-section__orb--brand {
+ top: 8%;
+ left: -8rem;
+ width: 24rem;
+ height: 24rem;
+ background: color-mix(in srgb, var(--ls-home-hero-brand) 24%, transparent);
+}
+
+.ls-home-hero-section__orb--cta {
+ right: -6rem;
+ bottom: 10%;
+ width: 20rem;
+ height: 20rem;
+ background: color-mix(in srgb, var(--ls-home-hero-cta) 22%, transparent);
+}
+
+.ls-home-hero-section__canvas {
+ display: block;
+ inline-size: 100%;
+ block-size: 100%;
+}
+
+@media (max-width: 781px) {
+ .ls-home-hero-section__network {
+ opacity: 1;
+ }
+
+ .ls-home-hero-section__orb {
+ filter: blur(64px);
+ opacity: 0.62;
+ }
+
+ .ls-home-hero-section__orb--brand {
+ left: -10rem;
+ width: 18rem;
+ height: 18rem;
+ }
+
+ .ls-home-hero-section__orb--cta {
+ right: -8rem;
+ width: 16rem;
+ height: 16rem;
+ }
}
\ No newline at end of file
diff --git a/assets/fonts/lexend/Lexend-100-normal.woff2 b/assets/fonts/lexend/Lexend-100-normal.woff2
deleted file mode 100644
index 30013a4..0000000
Binary files a/assets/fonts/lexend/Lexend-100-normal.woff2 and /dev/null differ
diff --git a/assets/fonts/roboto-mono/roboto-mono-latin-ext-wght-normal.woff2 b/assets/fonts/roboto-mono/roboto-mono-latin-ext-wght-normal.woff2
new file mode 100644
index 0000000..532a888
Binary files /dev/null and b/assets/fonts/roboto-mono/roboto-mono-latin-ext-wght-normal.woff2 differ
diff --git a/assets/fonts/roboto-mono/roboto-mono-latin-wght-normal.woff2 b/assets/fonts/roboto-mono/roboto-mono-latin-wght-normal.woff2
new file mode 100644
index 0000000..bfa169c
Binary files /dev/null and b/assets/fonts/roboto-mono/roboto-mono-latin-wght-normal.woff2 differ
diff --git a/assets/js/gsap-effects.js b/assets/js/gsap-effects.js
index 4b017ca..9a24df2 100644
--- a/assets/js/gsap-effects.js
+++ b/assets/js/gsap-effects.js
@@ -53,6 +53,388 @@
} );
}
+ function parseCssColour( value ) {
+ const trimmedValue = value.trim();
+
+ if ( /^#(?:[0-9a-f]{3}){1,2}$/i.test( trimmedValue ) ) {
+ let normalisedValue = trimmedValue.slice( 1 );
+
+ if ( 3 === normalisedValue.length ) {
+ normalisedValue = normalisedValue
+ .split( '' )
+ .map( ( character ) => character + character )
+ .join( '' );
+ }
+
+ return {
+ r: Number.parseInt( normalisedValue.slice( 0, 2 ), 16 ),
+ g: Number.parseInt( normalisedValue.slice( 2, 4 ), 16 ),
+ b: Number.parseInt( normalisedValue.slice( 4, 6 ), 16 ),
+ };
+ }
+
+ const rgbMatch = trimmedValue.match( /^rgba?\(\s*([0-9.]+)\s*,\s*([0-9.]+)\s*,\s*([0-9.]+)/i );
+
+ if ( rgbMatch ) {
+ return {
+ r: Number( rgbMatch[ 1 ] ),
+ g: Number( rgbMatch[ 2 ] ),
+ b: Number( rgbMatch[ 3 ] ),
+ };
+ }
+
+ return {
+ r: 30,
+ g: 106,
+ b: 255,
+ };
+ }
+
+ function mixColours( startColour, endColour, amount ) {
+ const clampedAmount = Math.min( 1, Math.max( 0, amount ) );
+
+ return {
+ r: Math.round( startColour.r + ( ( endColour.r - startColour.r ) * clampedAmount ) ),
+ g: Math.round( startColour.g + ( ( endColour.g - startColour.g ) * clampedAmount ) ),
+ b: Math.round( startColour.b + ( ( endColour.b - startColour.b ) * clampedAmount ) ),
+ };
+ }
+
+ function rgbaString( colour, alpha ) {
+ return `rgba(${ colour.r }, ${ colour.g }, ${ colour.b }, ${ alpha })`;
+ }
+
+ function getDirectChildByClass( element, className ) {
+ return Array.from( element.children ).find( ( child ) => {
+ return child.classList.contains( className );
+ } ) || null;
+ }
+
+ function createEffectCanvas( network ) {
+ const existingCanvas = network.querySelector( '.ls-home-hero-section__canvas' );
+
+ if ( existingCanvas ) {
+ return existingCanvas;
+ }
+
+ const canvas = document.createElement( 'canvas' );
+
+ canvas.className = 'ls-home-hero-section__canvas';
+ canvas.setAttribute( 'aria-hidden', 'true' );
+ network.appendChild( canvas );
+
+ return canvas;
+ }
+
+ function ensureHomeHeroSectionBackground( section ) {
+ let background = getDirectChildByClass( section, 'ls-home-hero-section__background' );
+
+ if ( ! background ) {
+ background = document.createElement( 'div' );
+ background.className = 'ls-home-hero-section__background';
+ section.insertBefore( background, section.firstChild );
+ }
+
+ if ( ! background.querySelector( '.ls-home-hero-section__orb--brand' ) ) {
+ const brandOrb = document.createElement( 'div' );
+
+ brandOrb.className = 'ls-home-hero-section__orb ls-home-hero-section__orb--brand';
+ background.appendChild( brandOrb );
+ }
+
+ if ( ! background.querySelector( '.ls-home-hero-section__orb--cta' ) ) {
+ const ctaOrb = document.createElement( 'div' );
+
+ ctaOrb.className = 'ls-home-hero-section__orb ls-home-hero-section__orb--cta';
+ background.appendChild( ctaOrb );
+ }
+
+ let network = background.querySelector( '.ls-home-hero-section__network' );
+
+ if ( ! network ) {
+ network = document.createElement( 'div' );
+ network.className = 'ls-home-hero-section__network';
+ background.appendChild( network );
+ }
+
+ return network;
+ }
+
+ function initHomeHeroSectionNetwork( section, reduceMotion, finePointer ) {
+ const network = ensureHomeHeroSectionBackground( section );
+ const canvas = createEffectCanvas( network );
+ const context = canvas.getContext( '2d' );
+
+ if ( ! context ) {
+ return () => {};
+ }
+
+ const rootStyles = getComputedStyle( document.documentElement );
+ const brandColour = parseCssColour( rootStyles.getPropertyValue( '--wp--preset--color--brand-600' ) || rootStyles.getPropertyValue( '--wp--preset--color--brand-500' ) || '#1E6AFF' );
+ const ctaColour = parseCssColour( rootStyles.getPropertyValue( '--wp--preset--color--cta-600' ) || rootStyles.getPropertyValue( '--wp--preset--color--cta-500' ) || '#00FCFC' );
+ const interaction = {
+ x: 0,
+ y: 0,
+ strength: 0,
+ };
+ const moveX = gsapInstance.quickTo( interaction, 'x', {
+ duration: reduceMotion ? 0 : 0.18,
+ ease: 'power3.out',
+ } );
+ const moveY = gsapInstance.quickTo( interaction, 'y', {
+ duration: reduceMotion ? 0 : 0.18,
+ ease: 'power3.out',
+ } );
+ const moveStrength = gsapInstance.quickTo( interaction, 'strength', {
+ duration: reduceMotion ? 0 : 0.16,
+ ease: 'power2.out',
+ } );
+ const size = {
+ width: 0,
+ height: 0,
+ dpr: 1,
+ };
+ let particles = [];
+ let resizeObserver = null;
+
+ function isCompactViewport() {
+ return size.width <= 781;
+ }
+
+ function createParticles() {
+ const compactViewport = isCompactViewport();
+ const particleCount = reduceMotion
+ ? Math.min( compactViewport ? 24 : 20, Math.max( compactViewport ? 16 : 12, Math.round( ( size.width * size.height ) / ( compactViewport ? 44000 : 52000 ) ) ) )
+ : Math.min( compactViewport ? 56 : 48, Math.max( compactViewport ? 28 : 22, Math.round( ( size.width * size.height ) / ( compactViewport ? 18000 : 24000 ) ) ) );
+
+ particles = Array.from( { length: particleCount }, ( value, index ) => {
+ const driftX = reduceMotion ? 0 : ( ( Math.random() - 0.5 ) * 0.26 );
+ const driftY = reduceMotion ? 0 : ( ( Math.random() - 0.5 ) * 0.26 );
+ const mix = 1 === particleCount ? 0.5 : ( index / ( particleCount - 1 ) );
+
+ return {
+ x: Math.random() * size.width,
+ y: Math.random() * size.height,
+ vx: driftX,
+ vy: driftY,
+ baseVx: driftX,
+ baseVy: driftY,
+ radius: 1.55 + ( Math.random() * 2.1 ),
+ mix,
+ seed: Math.random() * Math.PI * 2,
+ };
+ } );
+ }
+
+ function resizeCanvas() {
+ const bounds = network.getBoundingClientRect();
+
+ size.width = Math.max( Math.round( bounds.width ), 1 );
+ size.height = Math.max( Math.round( bounds.height ), 1 );
+ size.dpr = Math.min( window.devicePixelRatio || 1, 1.5 );
+
+ canvas.width = size.width * size.dpr;
+ canvas.height = size.height * size.dpr;
+ canvas.style.width = `${ size.width }px`;
+ canvas.style.height = `${ size.height }px`;
+
+ context.setTransform( 1, 0, 0, 1, 0, 0 );
+ context.scale( size.dpr, size.dpr );
+ createParticles();
+
+ if ( ! interaction.strength ) {
+ moveX( size.width / 2 );
+ moveY( size.height * 0.35 );
+ }
+ }
+
+ function drawFrame( time ) {
+ const compactViewport = isCompactViewport();
+ const connectionDistance = compactViewport
+ ? Math.min( 250, Math.max( 150, Math.min( size.width, size.height ) * 0.42 ) )
+ : Math.min( 220, Math.max( 130, Math.min( size.width, size.height ) * 0.3 ) );
+ const connectionDistanceSquared = connectionDistance * connectionDistance;
+ const influenceRadius = compactViewport
+ ? Math.max( 260, Math.min( size.width, size.height ) * 0.46 )
+ : Math.max( 220, Math.min( size.width, size.height ) * 0.36 );
+
+ context.clearRect( 0, 0, size.width, size.height );
+
+ for ( let index = 0; index < particles.length; index += 1 ) {
+ const particle = particles[ index ];
+
+ if ( ! reduceMotion ) {
+ const deltaX = particle.x - interaction.x;
+ const deltaY = particle.y - interaction.y;
+ const distance = Math.max( Math.hypot( deltaX, deltaY ), 1 );
+
+ if ( finePointer && interaction.strength > 0.01 && distance < influenceRadius ) {
+ const force = ( 1 - ( distance / influenceRadius ) ) * 0.11 * interaction.strength;
+
+ particle.vx += ( deltaX / distance ) * force;
+ particle.vy += ( deltaY / distance ) * force;
+ }
+
+ particle.vx += ( particle.baseVx - particle.vx ) * 0.03;
+ particle.vy += ( particle.baseVy - particle.vy ) * 0.03;
+ particle.x += particle.vx;
+ particle.y += particle.vy;
+
+ if ( particle.x <= 0 || particle.x >= size.width ) {
+ particle.baseVx *= -1;
+ particle.vx *= -0.92;
+ particle.x = Math.min( Math.max( particle.x, 0 ), size.width );
+ }
+
+ if ( particle.y <= 0 || particle.y >= size.height ) {
+ particle.baseVy *= -1;
+ particle.vy *= -0.92;
+ particle.y = Math.min( Math.max( particle.y, 0 ), size.height );
+ }
+ }
+ }
+
+ for ( let sourceIndex = 0; sourceIndex < particles.length; sourceIndex += 1 ) {
+ for ( let targetIndex = sourceIndex + 1; targetIndex < particles.length; targetIndex += 1 ) {
+ const sourceParticle = particles[ sourceIndex ];
+ const targetParticle = particles[ targetIndex ];
+ const deltaX = sourceParticle.x - targetParticle.x;
+ const deltaY = sourceParticle.y - targetParticle.y;
+ const distanceSquared = ( deltaX * deltaX ) + ( deltaY * deltaY );
+
+ if ( distanceSquared > connectionDistanceSquared ) {
+ continue;
+ }
+
+ const distance = Math.sqrt( distanceSquared );
+ const connectionStrength = 1 - ( distance / connectionDistance );
+ const lineColour = mixColours(
+ brandColour,
+ ctaColour,
+ ( ( sourceParticle.mix + targetParticle.mix ) / 2 ) + ( Math.sin( time + sourceParticle.seed + targetParticle.seed ) * 0.05 )
+ );
+
+ context.beginPath();
+ context.moveTo( sourceParticle.x, sourceParticle.y );
+ context.lineTo( targetParticle.x, targetParticle.y );
+ context.strokeStyle = rgbaString(
+ lineColour,
+ compactViewport
+ ? 0.2 + ( connectionStrength * 0.3 ) + ( interaction.strength * connectionStrength * 0.14 )
+ : 0.13 + ( connectionStrength * 0.24 ) + ( interaction.strength * connectionStrength * 0.12 )
+ );
+ context.lineWidth = compactViewport
+ ? ( distance < ( connectionDistance * 0.4 ) ? 1.6 : 1.15 )
+ : ( distance < ( connectionDistance * 0.4 ) ? 1.35 : 0.95 );
+ context.stroke();
+ }
+ }
+
+ for ( let index = 0; index < particles.length; index += 1 ) {
+ const particle = particles[ index ];
+ const dotColour = mixColours(
+ brandColour,
+ ctaColour,
+ particle.mix + ( Math.sin( time + particle.seed ) * 0.08 )
+ );
+
+ context.beginPath();
+ context.arc( particle.x, particle.y, particle.radius, 0, Math.PI * 2, false );
+ context.fillStyle = rgbaString(
+ dotColour,
+ compactViewport
+ ? 0.84 + ( interaction.strength * 0.16 )
+ : 0.72 + ( interaction.strength * 0.16 )
+ );
+ context.fill();
+ }
+ }
+
+ function handlePointerMove( event ) {
+ const bounds = network.getBoundingClientRect();
+ const pointerX = event.clientX - bounds.left;
+ const pointerY = event.clientY - bounds.top;
+
+ if ( pointerX < 0 || pointerY < 0 || pointerX > bounds.width || pointerY > bounds.height ) {
+ return;
+ }
+
+ moveX( pointerX );
+ moveY( pointerY );
+ moveStrength( 1.2 );
+ }
+
+ function resetPointer() {
+ moveStrength( 0 );
+ moveX( size.width / 2 );
+ moveY( size.height * 0.35 );
+ }
+
+ resizeCanvas();
+
+ if ( window.ResizeObserver ) {
+ resizeObserver = new window.ResizeObserver( resizeCanvas );
+ resizeObserver.observe( network );
+ } else {
+ window.addEventListener( 'resize', resizeCanvas );
+ }
+
+ if ( finePointer && ! reduceMotion ) {
+ section.addEventListener( 'pointerenter', handlePointerMove );
+ section.addEventListener( 'pointermove', handlePointerMove );
+ section.addEventListener( 'pointerleave', resetPointer );
+ }
+
+ if ( reduceMotion ) {
+ drawFrame( 0 );
+ } else {
+ gsapInstance.ticker.add( drawFrame );
+ }
+
+ return () => {
+ if ( resizeObserver ) {
+ resizeObserver.disconnect();
+ } else {
+ window.removeEventListener( 'resize', resizeCanvas );
+ }
+
+ section.removeEventListener( 'pointerenter', handlePointerMove );
+ section.removeEventListener( 'pointermove', handlePointerMove );
+ section.removeEventListener( 'pointerleave', resetPointer );
+ gsapInstance.ticker.remove( drawFrame );
+ };
+ }
+
+ function initHomeHeroSection( section ) {
+ if ( section.dataset.lsHomeHeroSection === 'true' ) {
+ return;
+ }
+
+ section.dataset.lsHomeHeroSection = 'true';
+
+ const media = gsapInstance.matchMedia ? gsapInstance.matchMedia( section ) : null;
+
+ if ( ! media ) {
+ return;
+ }
+
+ media.add(
+ {
+ reduceMotion: '(prefers-reduced-motion: reduce)',
+ finePointer: '(pointer: fine)',
+ },
+ ( context ) => {
+ const reduceMotion = Boolean( context.conditions.reduceMotion );
+ const finePointer = Boolean( context.conditions.finePointer );
+ const teardownNetwork = initHomeHeroSectionNetwork( section, reduceMotion, finePointer );
+
+ return () => {
+ teardownNetwork();
+ };
+ }
+ );
+ }
+
function setFocusState( card ) {
const bounds = card.getBoundingClientRect();
@@ -118,6 +500,7 @@
function initEffects() {
document.querySelectorAll( '.is-style-card-spotlight' ).forEach( initSpotlightCard );
+ document.querySelectorAll( '.is-style-home-hero-section' ).forEach( initHomeHeroSection );
}
function boot() {
diff --git a/inc/animations.php b/inc/animations.php
index d819ca2..453ee03 100644
--- a/inc/animations.php
+++ b/inc/animations.php
@@ -28,9 +28,6 @@ function ls_theme_get_local_asset_version( $path ) {
/**
* Returns effect stylesheet definitions.
*
- * Each effect can declare the contexts where it should load so the theme can
- * later split or gate effects without changing the main bootstrap flow.
- *
* @param string $context Load context. Accepts 'front' or 'editor'.
* @return array>
*/
diff --git a/inc/gsap.php b/inc/gsap.php
index 5293b66..4d2cea3 100644
--- a/inc/gsap.php
+++ b/inc/gsap.php
@@ -143,6 +143,14 @@ function ls_theme_register_gsap_block_styles() {
return;
}
+ register_block_style(
+ 'core/group',
+ array(
+ 'name' => 'home-hero-section',
+ 'label' => __( 'Home Hero Section', 'ls-theme' ),
+ )
+ );
+
register_block_style(
'core/group',
array(
diff --git a/patterns/home-hero.php b/patterns/home-hero.php
index cc5d4e2..7b89fa5 100644
--- a/patterns/home-hero.php
+++ b/patterns/home-hero.php
@@ -4,7 +4,19 @@
* Slug: ls-theme/hero
* Categories: hero
* Block Types: core/template-part/hero
- * Description: A hero section for the homepage with a background image, title, and call-to-action button.
+ * Description: Minimal home hero section using the reusable GSAP section background style.
*/
-?>
\ No newline at end of file
+?>
+
+
+
+
\ No newline at end of file
diff --git a/style.css b/style.css
index 4b4a824..2ad7025 100644
--- a/style.css
+++ b/style.css
@@ -13,3 +13,9 @@ License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: ls-theme
Tags: block-theme, full-site-editing, custom-colors, custom-typography
*/
+
+code,
+pre {
+ font-family: var(--wp--preset--font-family--monospace);
+ font-size: var(--wp--preset--font-size--200);
+}
\ No newline at end of file
diff --git a/styles/blocks/buttons/button-glow-accent.json b/styles/blocks/buttons/button-glow-accent.json
index 9f49dbb..aff27ab 100644
--- a/styles/blocks/buttons/button-glow-accent.json
+++ b/styles/blocks/buttons/button-glow-accent.json
@@ -31,6 +31,6 @@
"fontWeight": "600",
"letterSpacing": "0.08em"
},
- "css": "&{--ls-button-glow-enter-delay: 80ms;}"
+ "css": "&{--ls-button-glow-colour:var(--wp--preset--color--brand-500);--ls-button-glow-hover-background:var(--wp--preset--color--brand-500);--ls-button-glow-hover-text:var(--wp--preset--color--base);--ls-button-glow-enter-delay:80ms;--ls-button-glow-outline-width:1px;--ls-button-glow-outline-offset:12px;--ls-button-glow-resting-strength:0%;--ls-button-glow-outline-strength:45%;--ls-button-glow-inner-strength:35%;--ls-button-glow-outer-strength:20%;--ls-button-active-scale:0.98;}"
}
}
diff --git a/styles/blocks/headings/gradient-accent.json b/styles/blocks/headings/gradient-accent.json
index 805866f..7d4ae0e 100644
--- a/styles/blocks/headings/gradient-accent.json
+++ b/styles/blocks/headings/gradient-accent.json
@@ -9,15 +9,15 @@
"description": "Animated gradient text for headings using the LightSpeed Theme accent presets.",
"styles": {
"color": {
- "text": "var:preset|color|accent-500"
+ "text": "var:preset|color|brand-500"
},
"elements": {
"link": {
"color": {
- "text": "var:preset|color|accent-500"
+ "text": "var:preset|color|brand-500"
}
}
},
- "css": "&{--ls-gradient-image: linear-gradient(to right, var(--wp--preset--color--accent-500) 0%, var(--wp--preset--color--contrast) 25%, var(--wp--preset--color--accent-500) 50%, var(--wp--preset--color--contrast) 75%, var(--wp--preset--color--accent-500) 100%); --ls-gradient-size: 200% auto; --ls-gradient-start-position: 0%; --ls-gradient-end-position: 100%; --ls-gradient-duration: 6s; --ls-gradient-timing: ease-in-out; --ls-gradient-direction: alternate; --ls-gradient-focus-color: var(--wp--preset--color--contrast);}"
+ "css": "&{--ls-gradient-width:fit-content;--ls-gradient-image:linear-gradient(to right,var(--wp--preset--color--brand-500) 0%,var(--wp--preset--color--contrast) 25%,var(--wp--preset--color--brand-700) 50%,var(--wp--preset--color--contrast) 75%,var(--wp--preset--color--brand-500) 100%);--ls-gradient-size:200% auto;--ls-gradient-start-position:0%;--ls-gradient-end-position:100%;--ls-gradient-duration:6s;--ls-gradient-delay:0s;--ls-gradient-timing:ease-in-out;--ls-gradient-direction:alternate;--ls-gradient-focus-width:2px;--ls-gradient-focus-color:var(--wp--preset--color--contrast);--ls-gradient-focus-offset:4px;--ls-gradient-reduced-position:100%;}"
}
}
diff --git a/styles/blocks/paragraphs/link-underline-accent.json b/styles/blocks/paragraphs/link-underline-accent.json
index 5459fe1..16cd12f 100644
--- a/styles/blocks/paragraphs/link-underline-accent.json
+++ b/styles/blocks/paragraphs/link-underline-accent.json
@@ -18,6 +18,6 @@
}
}
},
- "css": "&{--ls-link-underline-enter-delay: 80ms;}"
+ "css": "&{--ls-link-underline-image:linear-gradient(var(--wp--preset--color--brand-500),var(--wp--preset--color--accent-500));--ls-link-underline-padding-bottom:5px;--ls-link-underline-thickness:2px;--ls-link-underline-enter-delay:80ms;}"
}
}
diff --git a/styles/sections/home-hero-section.json b/styles/sections/home-hero-section.json
new file mode 100644
index 0000000..19c4c96
--- /dev/null
+++ b/styles/sections/home-hero-section.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "https://schemas.wp.org/wp/6.9/theme.json",
+ "version": 3,
+ "title": "Home Hero Section",
+ "slug": "home-hero-section",
+ "blockTypes": [
+ "core/group"
+ ],
+ "description": "Light full-width group style with the animated network background used for the homepage hero.",
+ "styles": {}
+}
\ No newline at end of file
diff --git a/templates/front-page.html b/templates/front-page.html
new file mode 100644
index 0000000..2415d6d
--- /dev/null
+++ b/templates/front-page.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
No posts found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/home.html b/templates/home.html
deleted file mode 100644
index 3ef6d44..0000000
--- a/templates/home.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/theme.json b/theme.json
index cbe4c87..a32c28d 100644
--- a/theme.json
+++ b/theme.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://schemas.wp.org/wp/6.9/theme.json",
+ "$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"appearanceTools": true,
@@ -473,20 +473,14 @@
},
"typography": {
"defaultFontSizes": false,
+ "fluid": true,
+ "writingMode": true,
"fontFamilies": [
{
"name": "Lexend",
"slug": "heading",
"fontFamily": "Lexend, sans-serif",
"fontFace": [
- {
- "fontFamily": "Lexend",
- "fontStyle": "normal",
- "fontWeight": "100",
- "src": [
- "file:./assets/fonts/lexend/Lexend-100-normal.woff2"
- ]
- },
{
"fontFamily": "Lexend",
"fontStyle": "normal",
@@ -615,6 +609,31 @@
]
}
]
+ },
+ {
+ "name": "Roboto Mono",
+ "slug": "monospace",
+ "fontFamily": "Roboto Mono, monospace",
+ "fontFace": [
+ {
+ "fontFamily": "Roboto Mono",
+ "fontStyle": "normal",
+ "fontWeight": "100 700",
+ "unicodeRange": "U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF",
+ "src": [
+ "file:./assets/fonts/roboto-mono/roboto-mono-latin-ext-wght-normal.woff2"
+ ]
+ },
+ {
+ "fontFamily": "Roboto Mono",
+ "fontStyle": "normal",
+ "fontWeight": "100 700",
+ "unicodeRange": "U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD",
+ "src": [
+ "file:./assets/fonts/roboto-mono/roboto-mono-latin-wght-normal.woff2"
+ ]
+ }
+ ]
}
],
"fontSizes": [
@@ -684,29 +703,36 @@
{
"name": "Gigantic",
"slug": "800",
- "size": "4rem",
+ "size": "3.75rem",
"fluid": {
"min": "2.625rem",
- "max": "4rem"
+ "max": "3.75rem"
}
},
{
"name": "Colossal",
"slug": "900",
- "size": "5rem",
+ "size": "4.5rem",
"fluid": {
- "min": "3rem",
- "max": "5rem"
+ "min": "2.75rem",
+ "max": "4.5rem"
}
}
]
},
"custom": {
- "lineHeight": {
- "large-heading": "125%",
- "small-heading": "135%",
- "button": "130%",
- "paragraph": "150%"
+ "line-height": {
+ "heading-snug": "1.1",
+ "heading-default": "1.25",
+ "heading-loose": "1.35",
+ "button": "1.3",
+ "paragraph": "1.5"
+ },
+ "button-padding": {
+ "top": "1rem",
+ "right": "4rem",
+ "bottom": "1rem",
+ "left": "1.5rem"
}
},
"shadow": {
@@ -778,9 +804,9 @@
"size": "9999px"
}
]
- }
+ },
+ "useRootPaddingAwareAlignments": true
},
- "blocks": {},
"styles": {
"color": {
"background": "var(--wp--preset--color--base)",
@@ -789,11 +815,17 @@
"typography": {
"fontFamily": "var(--wp--preset--font-family--body, system-ui, sans-serif)",
"fontSize": "var(--wp--preset--font-size--200)",
- "lineHeight": "1.6"
+ "lineHeight": "var(--wp--custom--line-height--paragraph)"
},
"spacing": {
- "blockGap": "var(--wp--preset--spacing--30)"
- },
+ "blockGap": "var(--wp--preset--spacing--30)",
+ "padding": {
+ "bottom": "0",
+ "left": "var(--wp--preset--spacing--20)",
+ "right": "var(--wp--preset--spacing--20)",
+ "top": "0"
+ }
+ },
"elements": {
"button": {
"color": {
@@ -814,7 +846,8 @@
"fontSize": "var:preset|font-size|200",
"fontWeight": "700",
"letterSpacing": "0.08em"
- }
+ },
+ "css": "&{--ls-button-fill-background:var(--wp--preset--color--brand-500);--ls-button-fill-icon-colour:var(--wp--preset--color--base);--ls-button-fill-hover-text:var(--wp--preset--color--contrast);--ls-button-fill-duration:500ms;--ls-button-fill-enter-delay:80ms;--ls-button-active-scale:0.98;}"
},
"link": {
"color": {
@@ -826,22 +859,52 @@
}
}
},
+ "heading": {
+ "typography": {
+ "fontFamily": "var(--wp--preset--font-family--heading, sans-serif)"
+ }
+ },
"h1": {
"typography": {
- "fontSize": "var(--wp--preset--font-size--600)",
- "lineHeight": "1.2"
+ "fontSize": "var(--wp--preset--font-size--900)",
+ "fontWeight": "700",
+ "lineHeight": "var(--wp--custom--line-height--heading-snug)"
}
},
"h2": {
"typography": {
- "fontSize": "var(--wp--preset--font-size--500)",
- "lineHeight": "1.25"
+ "fontSize": "var(--wp--preset--font-size--700)",
+ "fontWeight": "600",
+ "lineHeight": "var(--wp--custom--line-height--heading-default)"
}
},
"h3": {
+ "typography": {
+ "fontSize": "var(--wp--preset--font-size--500)",
+ "fontWeight": "500",
+ "lineHeight": "var(--wp--custom--line-height--heading-default)"
+ }
+ },
+ "h4": {
"typography": {
"fontSize": "var(--wp--preset--font-size--400)",
- "lineHeight": "1.3"
+ "fontWeight": "500",
+ "lineHeight": "var(--wp--custom--line-height--heading-loose)"
+ }
+ },
+ "h5": {
+ "typography": {
+ "fontSize": "var(--wp--preset--font-size--300)",
+ "fontWeight": "500",
+ "lineHeight": "var(--wp--custom--line-height--heading-loose)"
+ }
+ },
+ "h6": {
+ "typography": {
+ "fontSize": "var(--wp--preset--font-size--300)",
+ "fontWeight": "500",
+ "lineHeight": "var(--wp--custom--line-height--heading-default)",
+ "textDecoration": "uppercase"
}
}
},
@@ -850,6 +913,9 @@
"variations": {
"outline": {
"border": {
+ "color": "var:preset|color|brand-500",
+ "style": "solid",
+ "width": "2px",
"radius": "var:preset|border-radius|200"
},
"color": {
@@ -868,7 +934,8 @@
"fontSize": "var:preset|font-size|200",
"fontWeight": "700",
"letterSpacing": "0.08em"
- }
+ },
+ "css": "&{--ls-button-outline-accent-background:var(--wp--preset--color--brand-500);--ls-button-outline-accent-colour:var(--wp--preset--color--base);--ls-button-outline-icon-radius:var(--wp--preset--border-radius--100);}"
}
}
}