Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [Unreleased] — Build Search template (LS-2594)

### Added

- Added `patterns/hero/search-hero.php`: the Search template's hero — breadcrumb trail, eyebrow, a static "Search LightSpeed" heading (intentionally not bound to the query term), supporting copy, and a no-button pill search field (`is-style-search-pill`, reused from the existing Blog All Articles search box). The breadcrumb is embedded here rather than the shared `ls-theme/breadcrumbs` template part, so it shares this hero's own padding instead of stacking a second set on top, matching the `blog-hero`/`work-hero` convention.
- Added `patterns/sections/search-useful-destinations.php`: the "Useful destinations" section — eyebrow, heading, and a 4-card grid (FAQ, Pricing, Website packages, Contact), reusing the existing `is-style-card-category`/`ls-icon-well-brand`/`is-style-link-arrow-accent` styles and the same Phosphor icon markup already used by `404-best-next-routes.php`. Kept as a separate, self-contained file per this repo's one-pattern-per-file convention rather than a shared cross-pattern reference. Always shown below the results list regardless of result count.
- Added `src/scss/structural/search-hero.scss`: the hero's decorative corner-glow background (two radial gradients, layered — `color.gradient` block support only accepts one), reusing the existing `effect.hero.brand`/`effect.hero.cyan` tokens; and `.ls-optical-trim`, a font-leading correction (see Fixed, below).
- Added `src/scss/structural/search-results.scss` additions: whole-row clickable results with a rightward-shift hover, using the same stretched-link technique as Card - Post (`font-size:0` on a real `core/read-more` link, not the core `screen-reader-text` utility — that sets `position:absolute` on the anchor itself, which breaks the stretched-link's `::before{inset:0}` sizing).

### Changed

- Rebuilt `patterns/template-search.php`: hero → results query loop → useful destinations. Each result shows a category eyebrow (`core/post-terms`) above an `H2` title (`core/post-title`, `level:2` — the previous `level:3` skipped a heading level with no `H2` before it) and excerpt, plus a hairline divider (`border.card`) between items. Removed the query loop's unused `postType`/`search`/`exclude` args, which `inherit:true` was already ignoring in favor of the main search query — pages now correctly appear in results alongside posts, matching core behavior.
- `styles/blocks/search/search-pill.json`: added explicit `text.default`/`text.subtle` colours for the input's typed text and placeholder. Neither this file nor `core-search.json` previously set a `color` on the input, so it fell back to the browser's black UA default — invisible against this pill's dark-mode `surface.card` background (only coincidentally legible in light mode). Fixes both consumers of this shared style (the Search hero and Blog All Articles' header search, which had the same latent bug).

### Fixed

- Hover-state title colour on search results used `link.accent` (dark mode: `cta-500`, the same saturated cyan as the CTA buttons — too loud for a hover-only state on heading-sized text). Changed to `link.accent-hover` (dark mode: `cta-300`, same family, softer), the token that exists specifically for this role.
- Added `.ls-optical-trim` (`text-box-trim`/`text-box-edge`, plus a `transform: translateY(calc((1cap - 1lh) / 2))` fallback for broader browser support) to the hero eyebrow/heading and the Useful destinations eyebrow/heading. `line-height` alone can't fully cancel a font's own built-in leading (baked into the font file's vertical metrics), which differs between the body font (Manrope) and the display font (Lexend) — that residual, font-specific leading was making the gap above each heading read larger than the gap below it, even with identical margin values. `cap`/`lh` are real CSS units resolved per-font by the browser, not a guessed pixel offset.

### Notes

- No new colour tokens or font-size presets were needed — every value maps to an existing semantic token or preset, and every reused block style already carries dark-mode parity.
- The results-list "eyebrow" shows the post's category term rather than a post-type label, since WordPress core has no block for rendering a post-type name and this site has no custom taxonomy resembling the Figma mock's placeholder labels (e.g. "Trust", "Commercial").
- Verified against the dev site (`ls-agency.lightspeedwp.dev`, the theme's active environment there): the `category` taxonomy exists on `post` and matches local; all four destination links (`/faq/`, `/pricing/`, `/website-packages/`, `/contact/`) are published there. All links use `esc_url( home_url( '/slug/' ) )` — no hardcoded domains.

---

## [Unreleased] — Fix button.fill color contrast (LS-2937)

### Fixed
Expand Down
1 change: 1 addition & 0 deletions assets/css/search-hero.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion assets/css/search-results.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ function ls_theme_setup() {
add_editor_style( 'assets/css/homepage-card-rows.css' );
add_editor_style( 'assets/css/homepage-why-lightspeed.css' );
add_editor_style( 'assets/css/search-results.css' );
add_editor_style( 'assets/css/search-hero.css' );
}
add_action( 'after_setup_theme', 'ls_theme_setup' );

Expand Down
16 changes: 14 additions & 2 deletions inc/animations.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ function ls_theme_get_bundle_render_markers() {
'homepage-cta' => array( 'classes' => array( 'ls-homepage-cta' ) ),
'stats-bar' => array( 'classes' => array( 'ls-stats-row', 'ls-stat-item' ) ),
'homepage-card-rows' => array( 'classes' => array( 'ls-homepage-card-row', 'ls-what-we-build-row' ) ),
'search-hero' => array( 'classes' => array( 'ls-search-hero', 'ls-optical-trim' ) ),
'search-results' => array( 'classes' => array( 'ls-search-result' ) ),
);
}

Expand Down Expand Up @@ -234,9 +236,13 @@ function ls_theme_get_effect_styles( $context = 'front' ) {
'path' => 'assets/css/work-archive-sections.css',
'contexts' => array( 'front', 'editor' ),
// Icon-well classes are also used by 3 homepage sections (what-we-build,
// where-to-start, where-to-fit) in addition to the Work archive.
// where-to-start, where-to-fit) in addition to the Work archive, and by the
// Search template's "Useful destinations" section (is-style-card-category,
// ls-icon-well-brand) — without is_search() here, that reuse only gets caught by
// the render_block fallback below, which prints in the footer and visibly
// restyles the cards after first paint.
'condition' => static function () {
return is_front_page() || is_post_type_archive( 'project' );
return is_front_page() || is_post_type_archive( 'project' ) || is_search();
},
),
'card-shells' => array(
Expand Down Expand Up @@ -377,6 +383,12 @@ function ls_theme_get_effect_styles( $context = 'front' ) {
'contexts' => array( 'front', 'editor' ),
'condition' => 'is_search',
),
'search-hero' => array(
'handle' => 'ls-theme-search-hero',
'path' => 'assets/css/search-hero.css',
'contexts' => array( 'front', 'editor' ),
'condition' => 'is_search',
),
Comment thread
brandonmarshal marked this conversation as resolved.
);

/**
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
"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",
"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",
"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",
"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"
"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"
},
"devDependencies": {
"@axe-core/playwright": "^4.13.0",
Expand Down
Loading
Loading