From ef5d6fddbfed7729b10cb84951d789565dcaac97 Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Fri, 11 Sep 2026 12:37:16 +0200 Subject: [PATCH 1/6] Add Services "CTA" section (LS-1598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename patterns/section-cta.php (empty, unused stub) to patterns/sections/services-cta.php, built out: "Let's scope it properly." — eyebrow, heading, description, and a single button reusing the exact "Request a systems review" button already established in services-hero.php (same label, same link) - Add src/scss/structural/corner-glow.scss: a shared, multi-consumer two-corner gradient glow class (.ls-corner-glow) — colours and opacities are CSS custom properties so future consumers can override them inline instead of duplicating the file - Wire into build/enqueue like the other sections (real is_page('services') condition from the start) Bug fix - Corrected a Figma SVG gradient matrix decode error: the gradient's base circle has r="10" (user-space units), scaled by the matrix's 76.861 — actual radius is 10 × 76.861, not 76.861 alone. Using the scale factor alone produced blobs ~10x too small, reading as hard circles instead of the intended soft, wide wash - Set the CTA panel to a real 800px max width (contentSize, with align:"wide" removed since it was overriding the constraint) --- patterns/section-cta.php | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 patterns/section-cta.php diff --git a/patterns/section-cta.php b/patterns/section-cta.php deleted file mode 100644 index 6ceaaa1..0000000 --- a/patterns/section-cta.php +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file From dc0184a11bce39ad991d0e60bdb9f323c65f65e1 Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Fri, 11 Sep 2026 12:37:28 +0200 Subject: [PATCH 2/6] Add Services "CTA" section (LS-1598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename patterns/section-cta.php (empty, unused stub) to patterns/sections/services-cta.php, built out: "Let's scope it properly." — eyebrow, heading, description, and a single button reusing the exact "Request a systems review" button already established in services-hero.php (same label, same link) - Add src/scss/structural/corner-glow.scss: a shared, multi-consumer two-corner gradient glow class (.ls-corner-glow) — colours and opacities are CSS custom properties so future consumers can override them inline instead of duplicating the file - Wire into build/enqueue like the other sections (real is_page('services') condition from the start) Bug fix - Corrected a Figma SVG gradient matrix decode error: the gradient's base circle has r="10" (user-space units), scaled by the matrix's 76.861 — actual radius is 10 × 76.861, not 76.861 alone. Using the scale factor alone produced blobs ~10x too small, reading as hard circles instead of the intended soft, wide wash - Set the CTA panel to a real 800px max width (contentSize, with align:"wide" removed since it was overriding the constraint) --- assets/css/corner-glow.css | 1 + functions.php | 1 + inc/animations.php | 13 +++++++ package.json | 6 +-- patterns/sections/services-cta.php | 55 ++++++++++++++++++++++++++++ src/scss/structural/corner-glow.scss | 47 ++++++++++++++++++++++++ 6 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 assets/css/corner-glow.css create mode 100644 patterns/sections/services-cta.php create mode 100644 src/scss/structural/corner-glow.scss diff --git a/assets/css/corner-glow.css b/assets/css/corner-glow.css new file mode 100644 index 0000000..d9e9e57 --- /dev/null +++ b/assets/css/corner-glow.css @@ -0,0 +1 @@ +.ls-corner-glow{background-image:radial-gradient(87.5% 172.4% at 20% 30%, color-mix(in srgb, var(--ls-corner-glow-color-1, var(--wp--custom--color--effect--hero--brand)) var(--ls-corner-glow-opacity-1, 14%), transparent) 0%, transparent 60%),radial-gradient(87.5% 172.4% at 80% 70%, color-mix(in srgb, var(--ls-corner-glow-color-2, var(--wp--custom--color--effect--hero--cyan)) var(--ls-corner-glow-opacity-2, 14%), transparent) 0%, transparent 60%);background-position:0 0;background-repeat:no-repeat} diff --git a/functions.php b/functions.php index c178c8a..15ba902 100644 --- a/functions.php +++ b/functions.php @@ -75,6 +75,7 @@ function ls_theme_setup() { add_editor_style( 'assets/css/services-service-clusters.css' ); add_editor_style( 'assets/css/services-service-tiles.css' ); add_editor_style( 'assets/css/services-delivery-numbers.css' ); + add_editor_style( 'assets/css/corner-glow.css' ); add_editor_style( 'assets/css/work-hero.css' ); add_editor_style( 'assets/css/work-single-hero.css' ); add_editor_style( 'assets/css/blog-hero.css' ); diff --git a/inc/animations.php b/inc/animations.php index 045312b..cc3f10b 100644 --- a/inc/animations.php +++ b/inc/animations.php @@ -76,6 +76,7 @@ function ls_theme_get_bundle_render_markers() { 'services-service-clusters' => array( 'classes' => array( 'ls-cluster-tag' ) ), 'services-service-tiles' => array( 'classes' => array( 'is-style-card-service-tile' ) ), 'services-delivery-numbers' => array( 'classes' => array( 'ls-delivery-stats-row' ) ), + 'corner-glow' => array( 'classes' => array( 'ls-corner-glow' ) ), 'work-hero' => array( 'classes' => array( 'ls-work-hero' ) ), 'work-single-hero' => array( 'classes' => array( 'ls-work-single-meta' ) ), 'blog-hero' => array( 'classes' => array( 'ls-blog-hero' ) ), @@ -315,6 +316,18 @@ function ls_theme_get_effect_styles( $context = 'front' ) { return is_page( 'services' ); }, ), + 'corner-glow' => array( + 'handle' => 'ls-theme-corner-glow', + 'path' => 'assets/css/corner-glow.css', + 'contexts' => array( 'front', 'editor' ), + // Shared, multi-consumer class (not Services-page-exclusive) -- currently only used + // by services-cta.php, so the condition matches that real usage today. A future + // consumer on a different page should widen this condition rather than duplicating + // the class/file. + 'condition' => static function () { + return is_page( 'services' ); + }, + ), 'work-hero' => array( 'handle' => 'ls-theme-work-hero', 'path' => 'assets/css/work-hero.css', diff --git a/package.json b/package.json index 2ea322a..352c090 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,15 @@ "description": "LightSpeed Theme is a custom WordPress block theme built by LightSpeed for fast, accessible, maintainable websites using the WordPress Site Editor and block editor.", "type": "module", "scripts": { - "build:css": "sass --no-source-map --no-charset --style=compressed src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css", - "build:css:dev": "sass --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css", + "build:css": "sass --no-source-map --no-charset --style=compressed src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css", + "build:css:dev": "sass --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css", "schema:validate": "node theme-utils.mjs validate-schema", "theme:validate": "node theme-utils.mjs validate-theme", "patterns:escape": "node theme-utils.mjs escape-patterns", "security:scan": "node theme-utils.mjs security-scan", "lint": "npm run lint:json", "lint:json": "node --input-type=module --eval \"import { readFileSync } from 'fs'; import { glob } from 'glob'; const files = await glob(['theme.json', 'styles/**/*.json']); let ok = true; for (const f of files) { try { JSON.parse(readFileSync(f, 'utf8')); } catch (e) { console.error('Invalid JSON:', f, e.message); ok = false; } } if (ok) console.log('All JSON files are valid.'); else process.exit(1);\"", - "watch:css": "sass --watch --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css" + "watch:css": "sass --watch --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css" }, "devDependencies": { "@axe-core/playwright": "^4.13.0", diff --git a/patterns/sections/services-cta.php b/patterns/sections/services-cta.php new file mode 100644 index 0000000..da18ba1 --- /dev/null +++ b/patterns/sections/services-cta.php @@ -0,0 +1,55 @@ + + +
+ + +
+ + +
+ + + +

+ +
+ + + +

+ + + +

+ + + +
+ +
+ +
+ +
+ +
+ diff --git a/src/scss/structural/corner-glow.scss b/src/scss/structural/corner-glow.scss new file mode 100644 index 0000000..b575863 --- /dev/null +++ b/src/scss/structural/corner-glow.scss @@ -0,0 +1,47 @@ +/********** Corner Glow (shared decorative background, multi-consumer) **********/ + +/* + * A soft two-corner radial glow, decoded from Figma's SVG gradientTransform matrices the same + * way as src/scss/structural/search-hero.scss (its own comment documents the exact conversion + * method) — with one correction this file's first version missed: the gradient's base circle + * has r="10" (user-space units) and the transform matrix scales it by 76.861, so the actual + * radius is 10 × 76.861 = 768.61, not 76.861 alone. Using the matrix value by itself produced + * blobs roughly 10x too small (reading as small hard circles instead of a soft, wide wash). + * Positioned as a diagonal pair — one glow near the top-left corner, one near the bottom-right — + * sized 87.5%/172.4% (x/y radius as a fraction of the ~878x446, ~2:1 source frame) centered at + * 20%/30% and 80%/70%. + * + * JSON limitation: color.gradient block support only accepts a single gradient value, not + * layered gradients of any kind — see AGENTS.md Theme-First Approach and the same reasoning + * already documented in search-hero.scss/work-hero.scss/blog-hero.scss. + * + * Reusable across multiple CTAs/sections with different colours: the two glow colours and + * opacities are CSS custom properties, not hardcoded, so each consumer can override them inline + * per instance (e.g. style="--ls-corner-glow-color-1:...;"). Default fallbacks are + * effect.hero.brand / effect.hero.cyan, since every current consumer happens to use that exact + * pair — but a future consumer needing different colours doesn't need a second copy of this + * file, just its own inline override. + */ +.ls-corner-glow { + background-image: + radial-gradient( + 87.5% 172.4% at 20% 30%, + color-mix( + in srgb, + var(--ls-corner-glow-color-1, var(--wp--custom--color--effect--hero--brand)) var(--ls-corner-glow-opacity-1, 14%), + transparent + ) 0%, + transparent 60% + ), + radial-gradient( + 87.5% 172.4% at 80% 70%, + color-mix( + in srgb, + var(--ls-corner-glow-color-2, var(--wp--custom--color--effect--hero--cyan)) var(--ls-corner-glow-opacity-2, 14%), + transparent + ) 0%, + transparent 60% + ); + background-position: 0 0; + background-repeat: no-repeat; +} From 349277b2f4fc42dc15f8db425f1076328b3496c6 Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Fri, 11 Sep 2026 12:43:48 +0200 Subject: [PATCH 3/6] Add CHANGELOG entry for the closing CTA section (LS-1598) --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6950125..43e6d21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [Unreleased] — Build Services page: closing CTA section (LS-1598) + +### Added + +- Added `patterns/sections/services-cta.php` (renamed from the empty, unused `patterns/section-cta.php` stub): "Let's scope it properly" — eyebrow, heading, description, and a single button reusing the exact button already established in `services-hero.php`. +- Added `src/scss/structural/corner-glow.scss`: a shared, multi-consumer two-corner radial-gradient glow background, with its colors as CSS custom properties so future consumers can override them per instance instead of duplicating the file. + +### Fixed + +- Corrected a Figma SVG gradient matrix decode error that made the corner-glow's blobs roughly 10x too small (a missing `r="10"` base-circle multiplier), and set the CTA panel to a real 800px max width. + +[PR #56](https://github.com/lightspeedwp/ls-theme/pull/56) + +--- + ## [Unreleased] — Build Services page: service tiles section (LS-1598) ### Added From 55efea4ee8cc30a39145a6bf5ac4f842af102bf3 Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Fri, 11 Sep 2026 14:15:04 +0200 Subject: [PATCH 4/6] Fix PR #56 review findings (LS-1598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug fix - services-cta.php: fix wp:icon dimensions being a sibling of style instead of nested inside it — same bug class already fixed on PR #55, the eyebrow dot was rendering at the 24px default instead of 8px - inc/animations.php: load corner-glow.css unconditionally instead of gating it on is_page('services') — services-cta.php declares Inserter: true, so an editor can place it (and this shared class) on any page, where the condition would leave it caught only by the render_block/footer fallback. Same precedent as card-shells/ cta-buttons: cheap enough (~400 bytes) to load unconditionally Cleanup - Use UK-English spelling ("colour"/"colours", "centred") in prose documentation comments in services-cta.php and CHANGELOG.md, matching AGENTS.md's own established convention — CSS property names and values are unaffected, only English prose --- CHANGELOG.md | 2 +- inc/animations.php | 19 +++++++++---------- patterns/sections/services-cta.php | 6 +++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43e6d21..475ec3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added `patterns/sections/services-cta.php` (renamed from the empty, unused `patterns/section-cta.php` stub): "Let's scope it properly" — eyebrow, heading, description, and a single button reusing the exact button already established in `services-hero.php`. -- Added `src/scss/structural/corner-glow.scss`: a shared, multi-consumer two-corner radial-gradient glow background, with its colors as CSS custom properties so future consumers can override them per instance instead of duplicating the file. +- Added `src/scss/structural/corner-glow.scss`: a shared, multi-consumer two-corner radial-gradient glow background, with its colours as CSS custom properties so future consumers can override them per instance instead of duplicating the file. ### Fixed diff --git a/inc/animations.php b/inc/animations.php index cc3f10b..dda1bab 100644 --- a/inc/animations.php +++ b/inc/animations.php @@ -317,16 +317,15 @@ function ls_theme_get_effect_styles( $context = 'front' ) { }, ), 'corner-glow' => array( - 'handle' => 'ls-theme-corner-glow', - 'path' => 'assets/css/corner-glow.css', - 'contexts' => array( 'front', 'editor' ), - // Shared, multi-consumer class (not Services-page-exclusive) -- currently only used - // by services-cta.php, so the condition matches that real usage today. A future - // consumer on a different page should widen this condition rather than duplicating - // the class/file. - 'condition' => static function () { - return is_page( 'services' ); - }, + 'handle' => 'ls-theme-corner-glow', + 'path' => 'assets/css/corner-glow.css', + 'contexts' => array( 'front', 'editor' ), + // Same reasoning as card-shells/cta-buttons above: services-cta.php declares + // Inserter: true, so an editor can place this pattern (and this shared class) on + // any page, not just Services — a page-specific condition would leave it caught + // only by the render_block/footer fallback there, a guaranteed flash of unstyled + // content rather than a rare edge case. At ~400 bytes compressed, cheaper to load + // unconditionally. ), 'work-hero' => array( 'handle' => 'ls-theme-work-hero', diff --git a/patterns/sections/services-cta.php b/patterns/sections/services-cta.php index da18ba1..832f8d5 100644 --- a/patterns/sections/services-cta.php +++ b/patterns/sections/services-cta.php @@ -4,12 +4,12 @@ * Slug: ls-theme/services-cta * Categories: cta * Block Types: core/pattern - * Description: The Services page's closing CTA: "Let's scope it properly." A centered eyebrow/ + * Description: The Services page's closing CTA: "Let's scope it properly." A centred eyebrow/ * heading/description panel with a single button, reusing the exact "Request a systems review" * button already established in services-hero.php (same label, same link). The panel's soft * two-corner glow background reuses the shared, multi-consumer .ls-corner-glow class * (src/scss/structural/corner-glow.scss) rather than a new one-off gradient — this file supplies - * no color overrides since its colors happen to match that class's own defaults. + * no colour overrides since its colours happen to match that class's own defaults. * Keywords: services, cta, closing, section * Viewport Width: 1280 * Inserter: true @@ -26,7 +26,7 @@
- +

From 2997922b09080368d9894ffcca947722fe3eda5a Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Tue, 15 Sep 2026 12:12:27 +0200 Subject: [PATCH 5/6] Migrate Services "All Services" eyebrow icon to Core Icon block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug fix - services-service-tiles.php: replace the last remaining outermost/icon-block instance on the Services page (the "All Services" eyebrow dot) with core/icon referencing lightspeed/dot, matching the block type already used by the other 6 section eyebrows on this page Context - Completes the LS-3229 icon-block migration for this page — PR #50 migrated the hero, linked-decisions and service-clusters patterns, but this file was added later and was missed - The dot now renders visually small/padded like the other eyebrows, matching them exactly — that's expected, not a regression here: the underlying SVG padding is tracked separately in LS-4168 (ls-plugin fix, not a theme change) --- patterns/sections/services-service-tiles.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/patterns/sections/services-service-tiles.php b/patterns/sections/services-service-tiles.php index 37a1ed5..5b54b2f 100644 --- a/patterns/sections/services-service-tiles.php +++ b/patterns/sections/services-service-tiles.php @@ -182,9 +182,7 @@
- -
- +

From 351fc7f66319910860d30f0e3a477e12534e56a9 Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Tue, 15 Sep 2026 14:41:27 +0200 Subject: [PATCH 6/6] Fix CTA button overflow on narrow screens (LS-1598) Bug fix - corner-glow.scss: fix "Request a systems review" button spilling out past the CTA card's rounded border at narrow viewports (confirmed live at 320px) - Root cause: the button's flex-item wrapper had no min-width override, so flexbox's default min-width:auto refused to let it shrink below its white-space:nowrap text width, ignoring the shared core/button max-inline-size:100% rule entirely - Scoped the fix to buttons inside .ls-corner-glow only (min- width:0 to allow shrinking, white-space:normal to let the text wrap) rather than changing core/button's shared styles sitewide, since every other button context has enough room Context - Rebuilt assets/css/corner-glow.css via npm run build:css - Verified at 320px (wraps cleanly, no overflow) and 768px (unaffected, still single-line) --- assets/css/corner-glow.css | 2 +- src/scss/structural/corner-glow.scss | 30 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/assets/css/corner-glow.css b/assets/css/corner-glow.css index d9e9e57..eaad3e8 100644 --- a/assets/css/corner-glow.css +++ b/assets/css/corner-glow.css @@ -1 +1 @@ -.ls-corner-glow{background-image:radial-gradient(87.5% 172.4% at 20% 30%, color-mix(in srgb, var(--ls-corner-glow-color-1, var(--wp--custom--color--effect--hero--brand)) var(--ls-corner-glow-opacity-1, 14%), transparent) 0%, transparent 60%),radial-gradient(87.5% 172.4% at 80% 70%, color-mix(in srgb, var(--ls-corner-glow-color-2, var(--wp--custom--color--effect--hero--cyan)) var(--ls-corner-glow-opacity-2, 14%), transparent) 0%, transparent 60%);background-position:0 0;background-repeat:no-repeat} +.ls-corner-glow{background-image:radial-gradient(87.5% 172.4% at 20% 30%, color-mix(in srgb, var(--ls-corner-glow-color-1, var(--wp--custom--color--effect--hero--brand)) var(--ls-corner-glow-opacity-1, 14%), transparent) 0%, transparent 60%),radial-gradient(87.5% 172.4% at 80% 70%, color-mix(in srgb, var(--ls-corner-glow-color-2, var(--wp--custom--color--effect--hero--cyan)) var(--ls-corner-glow-opacity-2, 14%), transparent) 0%, transparent 60%);background-position:0 0;background-repeat:no-repeat}.ls-corner-glow .wp-block-buttons{min-inline-size:0}.ls-corner-glow .wp-block-buttons .wp-block-button{min-inline-size:0}.ls-corner-glow .wp-block-buttons .wp-block-button__link{min-inline-size:0;white-space:normal;text-align:center} diff --git a/src/scss/structural/corner-glow.scss b/src/scss/structural/corner-glow.scss index b575863..d7018fe 100644 --- a/src/scss/structural/corner-glow.scss +++ b/src/scss/structural/corner-glow.scss @@ -45,3 +45,33 @@ background-position: 0 0; background-repeat: no-repeat; } + +/* + * Button overflow fix (narrow viewports, confirmed live at 320px). core/button's shared styles + * (styles/presets/blocks/core-button.json) set white-space:nowrap on the button link and + * max-inline-size:100% on the wrapping .wp-block-button div — but that div is a flex item of + * .wp-block-buttons, and flex items default to min-width:auto (their content's intrinsic size), + * which overrides max-inline-size and lets a nowrap button refuse to shrink below its text width. + * Inside this card's narrower content column (~170px available at 320px viewport, after the + * section padding + the card's own padding), "Request a systems review" plus its arrow can't + * fit on one line, so the button spills out past the card's rounded border unclipped instead of + * shrinking or wrapping. + * + * Fixed by letting the flex item actually shrink (min-inline-size: 0, overriding the auto + * default) and letting its text wrap onto a second line instead of forcing nowrap. Scoped to + * buttons inside this card only — not a sitewide core/button change, since every other button + * context on the site has enough room and this isn't a general nowrap bug. + */ +.ls-corner-glow .wp-block-buttons { + min-inline-size: 0; +} + +.ls-corner-glow .wp-block-buttons .wp-block-button { + min-inline-size: 0; +} + +.ls-corner-glow .wp-block-buttons .wp-block-button__link { + min-inline-size: 0; + white-space: normal; + text-align: center; +}