From 7706b90dfc8fce6f7afc16159278f555c69a068e Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Tue, 28 Jul 2026 08:37:48 +0200 Subject: [PATCH 1/6] Add Work archive card components with block bindings (LS-1616) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 4 reusable, individually insertable card patterns: project card, discuss-project checklist, engagement stat, next-steps button - Bind the project card to real Portfolio post data (LS-1617): title, excerpt, taxonomy terms, and permalink via core/post-title, core/post-excerpt, core/post-terms, and core/read-more - Add matching section/block styles for all 4 components, built entirely from existing adaptive tokens — no new theme.json/dark.json tokens needed - Keep computed colour values (tints, translucency) in external style files only, never inline in pattern block attributes, to avoid editor "invalid content" errors - Add hover-lift CSS for the two interactive cards, and extend is-style-link-arrow-accent to support core/read-more --- CHANGELOG.md | 8 +++ assets/css/animations.css | 56 ++++++++++++++++--- patterns/cards/work-discuss-project-list.php | 27 +++++++++ patterns/cards/work-engagement-stat.php | 39 +++++++++++++ patterns/cards/work-next-steps-card.php | 33 +++++++++++ patterns/cards/work-project-card.php | 48 ++++++++++++++++ .../blocks/paragraphs/link-arrow-accent.json | 5 +- styles/blocks/post-terms/badge-brand.json | 22 ++++++++ styles/blocks/post-terms/tag-pills.json | 21 +++++++ styles/sections/cards/card-work-list.json | 31 ++++++++++ .../sections/cards/card-work-next-step.json | 31 ++++++++++ .../cards/card-work-project-banner.json | 21 +++++++ .../cards/card-work-project-chip.json | 27 +++++++++ .../cards/card-work-project-tags.json | 19 +++++++ styles/sections/cards/card-work-project.json | 27 +++++++++ styles/sections/cards/card-work-stat.json | 25 +++++++++ 16 files changed, 431 insertions(+), 9 deletions(-) create mode 100644 patterns/cards/work-discuss-project-list.php create mode 100644 patterns/cards/work-engagement-stat.php create mode 100644 patterns/cards/work-next-steps-card.php create mode 100644 patterns/cards/work-project-card.php create mode 100644 styles/blocks/post-terms/badge-brand.json create mode 100644 styles/blocks/post-terms/tag-pills.json create mode 100644 styles/sections/cards/card-work-list.json create mode 100644 styles/sections/cards/card-work-next-step.json create mode 100644 styles/sections/cards/card-work-project-banner.json create mode 100644 styles/sections/cards/card-work-project-chip.json create mode 100644 styles/sections/cards/card-work-project-tags.json create mode 100644 styles/sections/cards/card-work-project.json create mode 100644 styles/sections/cards/card-work-stat.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 91454dd..1c5776f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added 4 Work archive component patterns (LS-1616), each an individually insertable pattern built entirely from existing adaptive semantic tokens — no new `theme.json`/`dark.json` tokens were needed: + - `patterns/cards/work-project-card.php` — a case-study card bound to real Portfolio post data via WordPress block bindings (LS-1617): `core/post-title`, `core/post-excerpt`, `core/post-terms` (bound to the `ls_plugin_portfolio_industry`/`_project_type`/`_service` taxonomies), and `core/read-more` for the permalink. Intended as the Post Template content inside a Query Loop scoped to `ls_plugin_portfolio`. + - `patterns/cards/work-discuss-project-list.php` — a static checklist card reusing the existing `tick-accent` list style. + - `patterns/cards/work-engagement-stat.php` — a stat segment with a split-colour big number (accent-coloured suffix) and monospace uppercase labels. + - `patterns/cards/work-next-steps-card.php` — a compact related-route button. + - Matching section/block styles: `styles/sections/cards/card-work-project.json`, `card-work-project-banner.json`, `card-work-project-chip.json`, `card-work-project-tags.json`, `card-work-list.json`, `card-work-stat.json`, `card-work-next-step.json`, and two new `core/post-terms` block styles (`styles/blocks/post-terms/badge-brand.json`, `tag-pills.json`) for rendering dynamically-bound taxonomy terms as a badge bar and individual tag pills respectively. + - Colour, computed values (background tints, borders) are kept out of pattern-level block attributes and defined only in these external style files — WordPress's block validator can't reliably round-trip a raw `color-mix()` value placed directly in a block's own `style` attribute. + - Added hover-lift behaviour for the two interactive cards (`is-style-card-work-project`, `is-style-card-work-next-step`) to `assets/css/animations.css`, reusing the existing `card.hover` shadow contract, and extended the `is-style-link-arrow-accent` style/CSS to also support `core/read-more` (previously `core/paragraph` only). - Added a `Menu Item Card` pattern (`patterns/menu/menu-item-card.php`) as the single reusable source of the mega-menu list item structure (icon well, title/description, hover-reveal trailing arrow), used across the Work, Solutions, Pricing, Insights, and About mega menus — Services is excluded, it uses its own per-phase item style. Deliberately a plain registered pattern, not a Synced Pattern, so each insertion stays independently editable per menu item (LS-1618). - Added 6 real mega menu template parts for Ollie Menu Designer's Dropdown Menu block, each with final content, no shared placeholder scaffold: `parts/work-mega-menu.html`, `parts/solutions-mega-menu.html`, `parts/pricing-mega-menu.html`, `parts/insights-mega-menu.html`, `parts/about-mega-menu.html` (Default item styling), and `parts/services-mega-menu.html` (Service item styling, 6 lifecycle-phase columns). All registered in `theme.json` `templateParts` (LS-1618). - Added `Mega Menu Item - Default` and `Mega Menu Item - Service` block styles (`styles/blocks/groups/mega-menu-item-default.json`, `mega-menu-item-service.json`) as the single reusable, registered source of a row's structural styling (padding, radius) — the icon well itself carries no separate style, just plain inline block attributes, so it has no independent interactive behaviour of its own. diff --git a/assets/css/animations.css b/assets/css/animations.css index c1f0a93..7ac38b8 100644 --- a/assets/css/animations.css +++ b/assets/css/animations.css @@ -97,7 +97,7 @@ } /* Link Arrow Accent */ -.wp-block-paragraph.is-style-link-arrow-accent a { +.wp-block-paragraph.is-style-link-arrow-accent a, .wp-block-read-more.is-style-link-arrow-accent a { display: inline-flex; align-items: center; gap: var(--ls-link-arrow-gap, 0.45ch); @@ -107,16 +107,16 @@ transition: color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), gap var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard); transition-delay: var(--wp--custom--animation--delay--none); } -.wp-block-paragraph.is-style-link-arrow-accent a::after { +.wp-block-paragraph.is-style-link-arrow-accent a::after, .wp-block-read-more.is-style-link-arrow-accent a::after { content: "\2192"; display: inline-block; transform: translateX(0); transition: transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--emphasised), color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard); } -.wp-block-paragraph.is-style-link-arrow-accent a:hover, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a { +.wp-block-paragraph.is-style-link-arrow-accent a:hover, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible, .wp-block-read-more.is-style-link-arrow-accent a:hover, .wp-block-read-more.is-style-link-arrow-accent a:focus-visible, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-work-project:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-work-project:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-work-project:hover .wp-block-read-more.is-style-link-arrow-accent a, .is-style-card-work-project:focus-within .wp-block-read-more.is-style-link-arrow-accent a { color: var(--ls-link-arrow-hover-colour, var(--wp--custom--color--link--accent-hover)); } -.wp-block-paragraph.is-style-link-arrow-accent a:hover::after, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible::after, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after { +.wp-block-paragraph.is-style-link-arrow-accent a:hover::after, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible::after, .wp-block-read-more.is-style-link-arrow-accent a:hover::after, .wp-block-read-more.is-style-link-arrow-accent a:focus-visible::after, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-work-project:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-work-project:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-work-project:hover .wp-block-read-more.is-style-link-arrow-accent a::after, .is-style-card-work-project:focus-within .wp-block-read-more.is-style-link-arrow-accent a::after { transform: translateX(var(--ls-link-arrow-offset, 0.35em)); } @@ -600,6 +600,42 @@ margin: 0; } +/* Card - Work Project */ +.is-style-card-work-project { + --ls-card-work-project-border-active: var(--wp--custom--color--link--accent); + --ls-card-work-project-shadow-active: var(--wp--custom--shadow--card--hover); + --ls-card-work-project-lift: -6px; + transition: border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), box-shadow var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard), transform var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--emphasised); +} +.is-style-card-work-project:hover, .is-style-card-work-project:focus-within { + border-color: var(--ls-card-work-project-border-active); + box-shadow: var(--ls-card-work-project-shadow-active); + transform: translateY(var(--ls-card-work-project-lift)); +} + +/* Card - Work Next Step */ +.is-style-card-work-next-step { + --ls-card-work-next-step-border-active: var(--wp--custom--color--link--accent); + --ls-card-work-next-step-shadow-active: var(--wp--custom--shadow--card--hover); + transition: border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), box-shadow var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard); +} +.is-style-card-work-next-step:hover, .is-style-card-work-next-step:focus-within { + border-color: var(--ls-card-work-next-step-border-active); + box-shadow: var(--ls-card-work-next-step-shadow-active); +} + +/* Card - Work Project: equal-height grid cells, CTA pinned to the bottom */ +.wp-block-post-template.is-layout-grid > .is-style-card-work-project { + height: 100%; +} +.is-style-card-work-project .ls-card-work-project__content { + flex: 1 1 auto; +} +.is-style-card-work-project .wp-block-read-more { + margin-top: auto; + margin-bottom: 0; +} + @media (prefers-reduced-motion: reduce) { .wp-block-paragraph.is-style-link-arrow-accent a, .wp-block-paragraph.is-style-link-arrow-accent a::after, @@ -611,7 +647,9 @@ .is-style-card-services :is(.ls-card__icon-shell, .ls-card-services__icon-shell), .is-style-icon-frame-glow, :is(.is-style-card-solutions, .is-style-card-solutions-accent), - :is(.is-style-card-solutions, .is-style-card-solutions-accent) .wp-block-heading { + :is(.is-style-card-solutions, .is-style-card-solutions-accent) .wp-block-heading, + .is-style-card-work-project, + .is-style-card-work-next-step { transition: none; } .is-style-glass-card:hover, @@ -619,7 +657,9 @@ .is-style-card-feature:hover, .is-style-card-feature:focus-within, .is-style-card-services:hover, - .is-style-card-services:focus-within { + .is-style-card-services:focus-within, + .is-style-card-work-project:hover, + .is-style-card-work-project:focus-within { transform: none; } .wp-block-paragraph.is-style-link-arrow-accent a::after, @@ -628,7 +668,9 @@ .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, - .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after { + .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, + .is-style-card-work-project:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, + .is-style-card-work-project:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after { transform: none; } .is-style-card-services:hover::before, diff --git a/patterns/cards/work-discuss-project-list.php b/patterns/cards/work-discuss-project-list.php new file mode 100644 index 0000000..495c5f8 --- /dev/null +++ b/patterns/cards/work-discuss-project-list.php @@ -0,0 +1,27 @@ + + +
+ + + +
+ diff --git a/patterns/cards/work-engagement-stat.php b/patterns/cards/work-engagement-stat.php new file mode 100644 index 0000000..d859f62 --- /dev/null +++ b/patterns/cards/work-engagement-stat.php @@ -0,0 +1,39 @@ + + +
+ + +
+ +

+ + + +

+ +
+ + + +

+ + + +

+ +
+ diff --git a/patterns/cards/work-next-steps-card.php b/patterns/cards/work-next-steps-card.php new file mode 100644 index 0000000..f5e5752 --- /dev/null +++ b/patterns/cards/work-next-steps-card.php @@ -0,0 +1,33 @@ + + +
+ + +
+ +

+ + + +

+ +
+ + + +
+ diff --git a/patterns/cards/work-project-card.php b/patterns/cards/work-project-card.php new file mode 100644 index 0000000..4a63c10 --- /dev/null +++ b/patterns/cards/work-project-card.php @@ -0,0 +1,48 @@ + + +
+ + +
+ +
+ +
+ +
+ + + +
+ + + + + + + + +
+ +
+ + + +
+ +
+ diff --git a/styles/blocks/paragraphs/link-arrow-accent.json b/styles/blocks/paragraphs/link-arrow-accent.json index f2dcbb1..647ecb3 100644 --- a/styles/blocks/paragraphs/link-arrow-accent.json +++ b/styles/blocks/paragraphs/link-arrow-accent.json @@ -4,9 +4,10 @@ "title": "Link Arrow Accent", "slug": "link-arrow-accent", "blockTypes": [ - "core/paragraph" + "core/paragraph", + "core/read-more" ], - "description": "Paragraph links with an inline arrow accent for compact card CTAs.", + "description": "Paragraph or Read More links with an inline arrow accent for compact card CTAs.", "styles": { "elements": { "link": { diff --git a/styles/blocks/post-terms/badge-brand.json b/styles/blocks/post-terms/badge-brand.json new file mode 100644 index 0000000..38b5bf9 --- /dev/null +++ b/styles/blocks/post-terms/badge-brand.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Badge - Brand", + "slug": "badge-brand", + "blockTypes": [ + "core/post-terms" + ], + "description": "Renders linked terms as a full-width brand-tinted bar, for the Work Project Card's project-type badge (bound to the Portfolio Project Type taxonomy).", + "styles": { + "color": { + "text": "var:custom|color|text|brand" + }, + "typography": { + "fontFamily": "var:preset|font-family|monospace", + "fontSize": "var:preset|font-size|100", + "fontWeight": "var:custom|typography|font-weight|bold", + "textTransform": "uppercase" + }, + "css": "&{display:block;width:100%;max-width:100%;box-sizing:border-box;background-color:color-mix(in srgb, var(--wp--custom--color--card--solutions--brand) 8%, transparent);border-radius:var(--wp--preset--border-radius--200);padding:var(--wp--preset--spacing--5) var(--wp--preset--spacing--10);letter-spacing:1px;} & a{display:block;min-width:0;max-width:100%;white-space:normal;word-break:break-word;color:inherit;text-decoration:none;}" + } +} diff --git a/styles/blocks/post-terms/tag-pills.json b/styles/blocks/post-terms/tag-pills.json new file mode 100644 index 0000000..2ee5d13 --- /dev/null +++ b/styles/blocks/post-terms/tag-pills.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Tag Pills", + "slug": "tag-pills", + "blockTypes": [ + "core/post-terms" + ], + "description": "Renders each linked term as an individual pill chip, for the Work Project Card tag row (bound to the Portfolio Service taxonomy).", + "styles": { + "color": { + "text": "var:custom|color|text|muted" + }, + "typography": { + "fontFamily": "var:preset|font-family|monospace", + "fontSize": "var:preset|font-size|100", + "fontWeight": "var:custom|typography|font-weight|bold" + }, + "css": "&{display:flex;flex-wrap:wrap;gap:var(--wp--preset--spacing--5);max-width:100%;} & a{display:inline-block;min-width:0;max-width:100%;box-sizing:border-box;white-space:normal;word-break:break-word;background-color:var(--wp--custom--color--surface--card-raised);color:var(--wp--custom--color--text--muted);border-radius:var(--wp--preset--border-radius--100);padding:var(--wp--preset--spacing--5) var(--wp--preset--spacing--10);text-decoration:none;}" + } +} diff --git a/styles/sections/cards/card-work-list.json b/styles/sections/cards/card-work-list.json new file mode 100644 index 0000000..7908b78 --- /dev/null +++ b/styles/sections/cards/card-work-list.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work List", + "slug": "card-work-list", + "blockTypes": [ + "core/group" + ], + "description": "Card shell wrapping a tick-accent checklist for Work archive CTA panels. Adapts between light and dark mode.", + "styles": { + "color": { + "background": "var:custom|color|surface|card", + "text": "var:custom|color|text|default" + }, + "border": { + "color": "var:custom|color|border|card", + "radius": "var:preset|border-radius|300", + "style": "solid", + "width": "1px" + }, + "spacing": { + "blockGap": "var:preset|spacing|10", + "padding": { + "top": "var:preset|spacing|30", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|30", + "left": "var:preset|spacing|30" + } + } + } +} diff --git a/styles/sections/cards/card-work-next-step.json b/styles/sections/cards/card-work-next-step.json new file mode 100644 index 0000000..66fa51d --- /dev/null +++ b/styles/sections/cards/card-work-next-step.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Next Step", + "slug": "card-work-next-step", + "blockTypes": [ + "core/group" + ], + "description": "Compact horizontal related-route button for the Work archive: white card surface, solid border, trailing arrow.", + "styles": { + "color": { + "background": "var:custom|color|surface|card", + "text": "var:custom|color|text|default" + }, + "border": { + "color": "var:custom|color|border|card", + "radius": "var:preset|border-radius|400", + "style": "solid", + "width": "1px" + }, + "spacing": { + "blockGap": "var:preset|spacing|10", + "padding": { + "top": "var:preset|spacing|20", + "right": "var:preset|spacing|20", + "bottom": "var:preset|spacing|20", + "left": "var:preset|spacing|20" + } + } + } +} diff --git a/styles/sections/cards/card-work-project-banner.json b/styles/sections/cards/card-work-project-banner.json new file mode 100644 index 0000000..8a08612 --- /dev/null +++ b/styles/sections/cards/card-work-project-banner.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Project Banner", + "slug": "card-work-project-banner", + "blockTypes": [ + "core/group" + ], + "description": "Brand-tinted banner zone for the Work Project Card. Background colour lives here (not inline in the pattern) so the block's saved HTML stays a plain className the validator can round-trip cleanly.", + "styles": { + "spacing": { + "padding": { + "top": "var:preset|spacing|40", + "right": "var:preset|spacing|20", + "bottom": "var:preset|spacing|40", + "left": "var:preset|spacing|20" + } + }, + "css": "&{background-color:color-mix(in srgb, var(--wp--custom--color--card--solutions--brand) 7%, transparent);}" + } +} diff --git a/styles/sections/cards/card-work-project-chip.json b/styles/sections/cards/card-work-project-chip.json new file mode 100644 index 0000000..70811b8 --- /dev/null +++ b/styles/sections/cards/card-work-project-chip.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Project Chip", + "slug": "card-work-project-chip", + "blockTypes": [ + "core/group" + ], + "description": "Floating translucent chip shell for the Work Project Card's platform/industry label, sitting on top of the banner tint.", + "styles": { + "border": { + "color": "var:custom|color|border|card", + "radius": "var:preset|border-radius|200", + "style": "solid", + "width": "1px" + }, + "spacing": { + "padding": { + "top": "var:preset|spacing|10", + "right": "var:preset|spacing|10", + "bottom": "var:preset|spacing|10", + "left": "var:preset|spacing|10" + } + }, + "css": "&{background-color:color-mix(in srgb, var(--wp--custom--color--surface--canvas) 85%, transparent);}" + } +} diff --git a/styles/sections/cards/card-work-project-tags.json b/styles/sections/cards/card-work-project-tags.json new file mode 100644 index 0000000..8f1d995 --- /dev/null +++ b/styles/sections/cards/card-work-project-tags.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Project Tags", + "slug": "card-work-project-tags", + "blockTypes": [ + "core/group" + ], + "description": "Tag-row wrapper for the Work Project Card: a single top divider only. Sets border-width explicitly on all four sides to avoid the has-border-color utility class defaulting the other three sides to the browser's default border.", + "styles": { + "spacing": { + "padding": { + "top": "var:preset|spacing|10", + "bottom": "var:preset|spacing|10" + } + }, + "css": "&{border-style:solid;border-color:var(--wp--custom--color--border--card);border-width:1px 0 0 0;}" + } +} diff --git a/styles/sections/cards/card-work-project.json b/styles/sections/cards/card-work-project.json new file mode 100644 index 0000000..a70f68e --- /dev/null +++ b/styles/sections/cards/card-work-project.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Project", + "slug": "card-work-project", + "blockTypes": [ + "core/group" + ], + "description": "Case-study card shell for the Work archive: banner zone, content body, and tag row. Adapts between light and dark mode like every other card style — border uses a translucent tint of the shared card border token.", + "styles": { + "color": { + "background": "var:custom|color|surface|card", + "text": "var:custom|color|text|default" + }, + "border": { + "color": "var:custom|color|border|card", + "radius": "var:preset|border-radius|300", + "style": "solid", + "width": "1px" + }, + "shadow": "var:preset|shadow|100", + "spacing": { + "blockGap": "0" + }, + "css": "&{overflow:hidden;border-color:color-mix(in srgb, var(--wp--custom--color--border--card) 55%, transparent);}" + } +} diff --git a/styles/sections/cards/card-work-stat.json b/styles/sections/cards/card-work-stat.json new file mode 100644 index 0000000..2ecb7bb --- /dev/null +++ b/styles/sections/cards/card-work-stat.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Stat", + "slug": "card-work-stat", + "blockTypes": [ + "core/group" + ], + "description": "Stat segment for the Work archive engagement row: transparent background with a translucent trailing divider border.", + "styles": { + "color": { + "text": "var:custom|color|text|muted" + }, + "spacing": { + "blockGap": "var:preset|spacing|10", + "padding": { + "top": "var:preset|spacing|40", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|40", + "left": "var:preset|spacing|30" + } + }, + "css": "&{border-inline-end:1px solid var(--wp--custom--color--border--card);}" + } +} From 3b9204f3ffb4921cb952dd032b416d6c9f826a3e Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Tue, 28 Jul 2026 10:47:37 +0200 Subject: [PATCH 2/6] Add Work archive Hero section and Work Archive template (LS-1616) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add the Hero section pattern (patterns/hero/work-hero.php): breadcrumb trail, eyebrow badge, heading, description, CTA buttons, and a new Work Capability List card component - Add matching section/block styles: card-work-capability-list, card-work-capability-row, work-hero background, and 3 tinted icon-well styles (brand/commerce/accent) - Add one new token, icon.commerce (warning-foreground), for the WooCommerce icon tint — no orange family exists in the palette - Scaffold a new "Work Archive" custom page template (templates/page-work-archive.html + patterns/template-work-archive.php, registered in theme.json), so sections can be assigned and tested on any page as they're built - Fix icons rendering empty across 3 patterns: outermost/icon-block needs the SVG embedded in its saved markup, not just an iconName attribute — replaced with real SVGs sourced from the official Phosphor package - Fix a duplicate arrow on the "Book a consultation" button (the button style already adds one via CSS) - Fix content collapsing to 800px instead of the theme's wide size: constrained layouts require an explicit alignwide/alignfull class, which the Yoast breadcrumbs block can't carry via align — forced it via className instead - Fix an invisible badge dot icon caused by a viewBox/circle size mismatch at small render sizes --- patterns/cards/work-capability-list.php | 91 +++++++++++++++++++ patterns/cards/work-next-steps-card.php | 4 +- patterns/hero/work-hero.php | 76 ++++++++++++++++ patterns/template-work-archive.php | 19 ++++ styles/blocks/groups/icon-well-accent.json | 13 +++ styles/blocks/groups/icon-well-brand.json | 13 +++ styles/blocks/groups/icon-well-commerce.json | 13 +++ styles/dark.json | 3 +- .../cards/card-work-capability-list.json | 31 +++++++ .../cards/card-work-capability-row.json | 18 ++++ styles/sections/hero/work-hero.json | 21 +++++ templates/page-work-archive.html | 5 + theme.json | 10 +- 13 files changed, 314 insertions(+), 3 deletions(-) create mode 100644 patterns/cards/work-capability-list.php create mode 100644 patterns/hero/work-hero.php create mode 100644 patterns/template-work-archive.php create mode 100644 styles/blocks/groups/icon-well-accent.json create mode 100644 styles/blocks/groups/icon-well-brand.json create mode 100644 styles/blocks/groups/icon-well-commerce.json create mode 100644 styles/sections/cards/card-work-capability-list.json create mode 100644 styles/sections/cards/card-work-capability-row.json create mode 100644 styles/sections/hero/work-hero.json create mode 100644 templates/page-work-archive.html diff --git a/patterns/cards/work-capability-list.php b/patterns/cards/work-capability-list.php new file mode 100644 index 0000000..dc37aa8 --- /dev/null +++ b/patterns/cards/work-capability-list.php @@ -0,0 +1,91 @@ + + +
+ + +
+ +
+ +
+ +
+ + + +
+ +

+ + + +

+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +

+ + + +

+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +

+ + + +

+ +
+ +
+ +
+ diff --git a/patterns/cards/work-next-steps-card.php b/patterns/cards/work-next-steps-card.php index f5e5752..8775099 100644 --- a/patterns/cards/work-next-steps-card.php +++ b/patterns/cards/work-next-steps-card.php @@ -28,6 +28,8 @@ - + +
+ diff --git a/patterns/hero/work-hero.php b/patterns/hero/work-hero.php new file mode 100644 index 0000000..ea9afe9 --- /dev/null +++ b/patterns/hero/work-hero.php @@ -0,0 +1,76 @@ + + +
+ + +
+ + + + + + +
+ + +
+ + +
+ +
+ + + +

+ +
+ + + +

+ + + +

+ + + +
+ +
+ + + +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ diff --git a/patterns/template-work-archive.php b/patterns/template-work-archive.php new file mode 100644 index 0000000..6175677 --- /dev/null +++ b/patterns/template-work-archive.php @@ -0,0 +1,19 @@ + + + +
+ +
+ diff --git a/styles/blocks/groups/icon-well-accent.json b/styles/blocks/groups/icon-well-accent.json new file mode 100644 index 0000000..b1e8315 --- /dev/null +++ b/styles/blocks/groups/icon-well-accent.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Icon Well - Accent", + "slug": "icon-well-accent", + "blockTypes": [ + "core/group" + ], + "description": "Compact tinted square icon well in the accent colour, for capability-list rows.", + "styles": { + "css": "&{display:flex;align-items:center;justify-content:center;inline-size:2.25rem;block-size:2.25rem;flex-shrink:0;border-radius:var(--wp--preset--border-radius--300);background-color:color-mix(in srgb, var(--wp--custom--color--card--solutions--accent) 12%, transparent);color:var(--wp--custom--color--card--solutions--accent);}" + } +} diff --git a/styles/blocks/groups/icon-well-brand.json b/styles/blocks/groups/icon-well-brand.json new file mode 100644 index 0000000..5fba316 --- /dev/null +++ b/styles/blocks/groups/icon-well-brand.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Icon Well - Brand", + "slug": "icon-well-brand", + "blockTypes": [ + "core/group" + ], + "description": "Compact tinted square icon well in the brand colour, for capability-list rows.", + "styles": { + "css": "&{display:flex;align-items:center;justify-content:center;inline-size:2.25rem;block-size:2.25rem;flex-shrink:0;border-radius:var(--wp--preset--border-radius--300);background-color:color-mix(in srgb, var(--wp--custom--color--card--solutions--brand) 10%, transparent);color:var(--wp--custom--color--card--solutions--brand);}" + } +} diff --git a/styles/blocks/groups/icon-well-commerce.json b/styles/blocks/groups/icon-well-commerce.json new file mode 100644 index 0000000..b941194 --- /dev/null +++ b/styles/blocks/groups/icon-well-commerce.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Icon Well - Commerce", + "slug": "icon-well-commerce", + "blockTypes": [ + "core/group" + ], + "description": "Compact tinted square icon well in the commerce (warning/amber) colour, for capability-list rows.", + "styles": { + "css": "&{display:flex;align-items:center;justify-content:center;inline-size:2.25rem;block-size:2.25rem;flex-shrink:0;border-radius:var(--wp--preset--border-radius--300);background-color:color-mix(in srgb, var(--wp--custom--color--icon--commerce) 10%, transparent);color:var(--wp--custom--color--icon--commerce);}" + } +} diff --git a/styles/dark.json b/styles/dark.json index 5a1caf5..f196c3f 100644 --- a/styles/dark.json +++ b/styles/dark.json @@ -36,7 +36,8 @@ }, "icon": { "background": "var:preset|color|cta-500", - "color": "var:preset|color|contrast" + "color": "var:preset|color|contrast", + "commerce": "var:preset|color|warning-foreground" }, "card": { "solutions": { diff --git a/styles/sections/cards/card-work-capability-list.json b/styles/sections/cards/card-work-capability-list.json new file mode 100644 index 0000000..9d15bc7 --- /dev/null +++ b/styles/sections/cards/card-work-capability-list.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Capability List", + "slug": "card-work-capability-list", + "blockTypes": [ + "core/group" + ], + "description": "Bordered card shell wrapping a 3-row icon/title/description capability list, for the Work archive hero.", + "styles": { + "color": { + "background": "var:custom|color|surface|card", + "text": "var:custom|color|text|default" + }, + "border": { + "color": "var:custom|color|border|card", + "radius": "var:preset|border-radius|400", + "style": "solid", + "width": "1px" + }, + "spacing": { + "padding": { + "top": "var:preset|spacing|30", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|30", + "left": "var:preset|spacing|30" + } + }, + "css": "&{inline-size:100%;} & > .wp-block-group > *:last-child{min-width:0;flex:1 1 auto;}" + } +} diff --git a/styles/sections/cards/card-work-capability-row.json b/styles/sections/cards/card-work-capability-row.json new file mode 100644 index 0000000..9100289 --- /dev/null +++ b/styles/sections/cards/card-work-capability-row.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Capability Row", + "slug": "card-work-capability-row", + "blockTypes": [ + "core/group" + ], + "description": "Single capability-list row with a bottom-only divider. Sets border-width explicitly on all four sides to avoid the has-border-color utility class defaulting the other three sides to the browser's default border. Not applied to the last row in a list.", + "styles": { + "spacing": { + "padding": { + "bottom": "var:preset|spacing|20" + } + }, + "css": "&{border-style:solid;border-color:var(--wp--custom--color--border--card);border-width:0 0 1px 0;}" + } +} diff --git a/styles/sections/hero/work-hero.json b/styles/sections/hero/work-hero.json new file mode 100644 index 0000000..e49cc07 --- /dev/null +++ b/styles/sections/hero/work-hero.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Work Hero", + "slug": "work-hero", + "blockTypes": [ + "core/group" + ], + "description": "Full-width hero section shell for the Work archive: two soft radial-gradient glows using the existing hero effect tokens, reused from the CTA band's colour family.", + "styles": { + "spacing": { + "padding": { + "top": "var:preset|spacing|80", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|90", + "left": "var:preset|spacing|30" + } + }, + "css": "&{background-image:radial-gradient(circle at 14% -10%, color-mix(in srgb, var(--wp--custom--color--effect--hero--brand) 16%, transparent) 0%, transparent 60%), radial-gradient(circle at 86% 110%, color-mix(in srgb, var(--wp--custom--color--effect--hero--accent) 12%, transparent) 0%, transparent 60%);background-repeat:no-repeat;}" + } +} diff --git a/templates/page-work-archive.html b/templates/page-work-archive.html new file mode 100644 index 0000000..cc2ac46 --- /dev/null +++ b/templates/page-work-archive.html @@ -0,0 +1,5 @@ + + + + + diff --git a/theme.json b/theme.json index 47b2d30..c3af7c8 100644 --- a/theme.json +++ b/theme.json @@ -506,7 +506,8 @@ }, "icon": { "background": "var:preset|color|brand-500", - "color": "var:preset|color|base" + "color": "var:preset|color|base", + "commerce": "var:preset|color|warning-foreground" }, "card": { "solutions": { @@ -719,6 +720,13 @@ "postTypes": [ "page" ] + }, + { + "name": "page-work-archive", + "title": "Work Archive", + "postTypes": [ + "page" + ] } ] } \ No newline at end of file From 760a9e13e5747715d53a139339bffa5284e53a2e Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Tue, 28 Jul 2026 15:26:42 +0200 Subject: [PATCH 3/6] Add Work archive Categories and Selected Projects sections (LS-1616) - Categories section: eyebrow/heading/intro row + 3 category cards with a new compact `is-style-card-work-category` style - Selected Projects section: eyebrow/heading/intro, a platform filter using ls-plugin/taxonomy-filter (bound to project-group), and a 3-column Query Loop rendering the Work Project Card pattern - Rewired work-project-card.php bindings from the dead ls_plugin_portfolio_* taxonomy names to the real ones (project-group/project-tag) following the ls-plugin CPT/taxonomy rename - Added card.platform.wordpress/woocommerce tokens (real light/dark pairs) and a render_block hook (portfolio-card-colors.php) to swap each card's banner/badge per post, since a Query Loop can't set that statically - Fixed multi-term badge wrapping (core/post-terms forces display:block on links by default, orphaning the separator between terms) - Set enhancedPagination on the Query block so the taxonomy filter navigates client-side instead of reloading the page - Explicit fontSize overrides across both sections to match Figma instead of relying on the theme's default type scale --- assets/css/animations.css | 168 +++++++++++++----- functions.php | 3 + inc/animations.php | 5 + inc/portfolio-card-colors.php | 59 ++++++ patterns/cards/work-project-card.php | 12 +- patterns/content/eyebrow-badge.php | 26 +++ patterns/sections/work-categories.php | 148 +++++++++++++++ patterns/sections/work-selected-projects.php | 74 ++++++++ patterns/template-work-archive.php | 4 +- src/scss/animations.scss | 3 +- src/scss/animations/_card-motion.scss | 86 +++++++++ src/scss/animations/_taxonomy-filter.scss | 47 +++++ styles/blocks/post-terms/badge-brand.json | 6 +- .../blocks/post-terms/badge-woocommerce.json | 22 +++ styles/dark.json | 4 + styles/sections/cards/card-work-category.json | 32 ++++ .../card-work-project-banner-woocommerce.json | 21 +++ .../cards/card-work-project-banner.json | 4 +- styles/sections/content/work-categories.json | 23 +++ .../content/work-selected-projects.json | 23 +++ theme.json | 4 + 21 files changed, 712 insertions(+), 62 deletions(-) create mode 100644 inc/portfolio-card-colors.php create mode 100644 patterns/content/eyebrow-badge.php create mode 100644 patterns/sections/work-categories.php create mode 100644 patterns/sections/work-selected-projects.php create mode 100644 src/scss/animations/_taxonomy-filter.scss create mode 100644 styles/blocks/post-terms/badge-woocommerce.json create mode 100644 styles/sections/cards/card-work-category.json create mode 100644 styles/sections/cards/card-work-project-banner-woocommerce.json create mode 100644 styles/sections/content/work-categories.json create mode 100644 styles/sections/content/work-selected-projects.json diff --git a/assets/css/animations.css b/assets/css/animations.css index 7ac38b8..b94f34c 100644 --- a/assets/css/animations.css +++ b/assets/css/animations.css @@ -97,7 +97,7 @@ } /* Link Arrow Accent */ -.wp-block-paragraph.is-style-link-arrow-accent a, .wp-block-read-more.is-style-link-arrow-accent a { +.wp-block-paragraph.is-style-link-arrow-accent a { display: inline-flex; align-items: center; gap: var(--ls-link-arrow-gap, 0.45ch); @@ -107,16 +107,16 @@ transition: color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), gap var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard); transition-delay: var(--wp--custom--animation--delay--none); } -.wp-block-paragraph.is-style-link-arrow-accent a::after, .wp-block-read-more.is-style-link-arrow-accent a::after { +.wp-block-paragraph.is-style-link-arrow-accent a::after { content: "\2192"; display: inline-block; transform: translateX(0); transition: transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--emphasised), color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard); } -.wp-block-paragraph.is-style-link-arrow-accent a:hover, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible, .wp-block-read-more.is-style-link-arrow-accent a:hover, .wp-block-read-more.is-style-link-arrow-accent a:focus-visible, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-work-project:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-work-project:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-work-project:hover .wp-block-read-more.is-style-link-arrow-accent a, .is-style-card-work-project:focus-within .wp-block-read-more.is-style-link-arrow-accent a { +.wp-block-paragraph.is-style-link-arrow-accent a:hover, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a { color: var(--ls-link-arrow-hover-colour, var(--wp--custom--color--link--accent-hover)); } -.wp-block-paragraph.is-style-link-arrow-accent a:hover::after, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible::after, .wp-block-read-more.is-style-link-arrow-accent a:hover::after, .wp-block-read-more.is-style-link-arrow-accent a:focus-visible::after, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-work-project:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-work-project:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-work-project:hover .wp-block-read-more.is-style-link-arrow-accent a::after, .is-style-card-work-project:focus-within .wp-block-read-more.is-style-link-arrow-accent a::after { +.wp-block-paragraph.is-style-link-arrow-accent a:hover::after, .wp-block-paragraph.is-style-link-arrow-accent a:focus-visible::after, .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after { transform: translateX(var(--ls-link-arrow-offset, 0.35em)); } @@ -377,6 +377,35 @@ transform: rotate(-5deg) scale(0.98); } +/* Card - Work Category */ +.is-style-card-work-category { + --ls-card-work-category-border-rest: var(--wp--custom--color--border--card); + --ls-card-work-category-border-active: var(--wp--custom--color--link--accent); + --ls-card-work-category-shadow-rest: var(--wp--custom--shadow--elevation--100); + --ls-card-work-category-shadow-active: var(--wp--custom--shadow--card--hover); + --ls-card-work-category-lift: -4px; + position: relative; + overflow: hidden; + border: 1px solid var(--ls-card-work-category-border-rest); + border-radius: var(--wp--preset--border-radius--300); + background: var(--wp--custom--color--surface--card); + box-shadow: var(--ls-card-work-category-shadow-rest); + gap: var(--wp--preset--spacing--20); + padding: var(--wp--preset--spacing--20); + transition: border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), box-shadow var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard), transform var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--emphasised); +} +.is-style-card-work-category:hover, .is-style-card-work-category:focus-within { + border-color: var(--ls-card-work-category-border-active); + box-shadow: var(--ls-card-work-category-shadow-active); + transform: translateY(var(--ls-card-work-category-lift)); +} +.is-style-card-work-category .ls-card-work-category__content { + flex: 1 1 auto; + display: flex; + flex-direction: column; + gap: var(--wp--preset--spacing--10); +} + /* Card - Services */ .is-style-card-services { --ls-card-services-border-rest: var(--wp--custom--color--border--card); @@ -600,66 +629,29 @@ margin: 0; } -/* Card - Work Project */ -.is-style-card-work-project { - --ls-card-work-project-border-active: var(--wp--custom--color--link--accent); - --ls-card-work-project-shadow-active: var(--wp--custom--shadow--card--hover); - --ls-card-work-project-lift: -6px; - transition: border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), box-shadow var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard), transform var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--emphasised); -} -.is-style-card-work-project:hover, .is-style-card-work-project:focus-within { - border-color: var(--ls-card-work-project-border-active); - box-shadow: var(--ls-card-work-project-shadow-active); - transform: translateY(var(--ls-card-work-project-lift)); -} - -/* Card - Work Next Step */ -.is-style-card-work-next-step { - --ls-card-work-next-step-border-active: var(--wp--custom--color--link--accent); - --ls-card-work-next-step-shadow-active: var(--wp--custom--shadow--card--hover); - transition: border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), box-shadow var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard); -} -.is-style-card-work-next-step:hover, .is-style-card-work-next-step:focus-within { - border-color: var(--ls-card-work-next-step-border-active); - box-shadow: var(--ls-card-work-next-step-shadow-active); -} - -/* Card - Work Project: equal-height grid cells, CTA pinned to the bottom */ -.wp-block-post-template.is-layout-grid > .is-style-card-work-project { - height: 100%; -} -.is-style-card-work-project .ls-card-work-project__content { - flex: 1 1 auto; -} -.is-style-card-work-project .wp-block-read-more { - margin-top: auto; - margin-bottom: 0; -} - @media (prefers-reduced-motion: reduce) { .wp-block-paragraph.is-style-link-arrow-accent a, .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-glass-card, .is-style-card-feature, .is-style-card-feature :is(.ls-card__icon-shell, .ls-card-feature__icon-shell), + .is-style-card-work-category, .is-style-card-services, .is-style-card-services::before, .is-style-card-services :is(.ls-card__icon-shell, .ls-card-services__icon-shell), .is-style-icon-frame-glow, :is(.is-style-card-solutions, .is-style-card-solutions-accent), - :is(.is-style-card-solutions, .is-style-card-solutions-accent) .wp-block-heading, - .is-style-card-work-project, - .is-style-card-work-next-step { + :is(.is-style-card-solutions, .is-style-card-solutions-accent) .wp-block-heading { transition: none; } .is-style-glass-card:hover, .is-style-glass-card:focus-within, .is-style-card-feature:hover, .is-style-card-feature:focus-within, + .is-style-card-work-category:hover, + .is-style-card-work-category:focus-within, .is-style-card-services:hover, - .is-style-card-services:focus-within, - .is-style-card-work-project:hover, - .is-style-card-work-project:focus-within { + .is-style-card-services:focus-within { transform: none; } .wp-block-paragraph.is-style-link-arrow-accent a::after, @@ -668,9 +660,7 @@ .is-style-card-feature:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-feature:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, .is-style-card-services:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, - .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after, - .is-style-card-work-project:hover .wp-block-paragraph.is-style-link-arrow-accent a::after, - .is-style-card-work-project:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after { + .is-style-card-services:focus-within .wp-block-paragraph.is-style-link-arrow-accent a::after { transform: none; } .is-style-card-services:hover::before, @@ -685,6 +675,49 @@ transform: none; } } +/* Card - Work Project (WooCommerce platform colour) */ +.is-style-card-work-project-banner-woocommerce { + padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--20); + background-color: color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 7%, transparent); +} + +.is-style-badge-woocommerce { + width: 100%; + max-width: 100%; + box-sizing: border-box; + color: var(--wp--custom--color--card--platform--woocommerce); + font-family: var(--wp--preset--font-family--monospace); + font-size: var(--wp--preset--font-size--100); + font-weight: var(--wp--custom--typography--font-weight--bold); + text-transform: uppercase; + background-color: color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 8%, transparent); + border-radius: var(--wp--preset--border-radius--200); + padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--10); + letter-spacing: 1px; +} + +/* Badge - multi-term wrapping (WordPress and WooCommerce both bind to + project-group, which can carry more than one term per post; core/post-terms + forces its links to display:block by default, which stacks each term + onto its own line and leaves the ", " separator orphaned on its own row) */ +:is(.is-style-badge-brand, .is-style-badge-woocommerce) { + display: flex; + flex-wrap: wrap; + align-items: baseline; +} +:is(.is-style-badge-brand, .is-style-badge-woocommerce) a { + display: inline; + min-width: 0; + max-width: 100%; + white-space: normal; + word-break: break-word; + color: inherit; + text-decoration: none; +} +:is(.is-style-badge-brand, .is-style-badge-woocommerce) .wp-block-post-terms__separator { + margin-inline-end: var(--wp--preset--spacing--5); +} + /********** Button Motion **********/ .wp-block-button:not([class*=is-style-]), .wp-block-button.is-style-fill, @@ -1602,3 +1635,40 @@ transition: none; } } +/********** Taxonomy Filter (ls-plugin/taxonomy-filter) **********/ +.wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons { + display: flex; + flex-wrap: wrap; + gap: var(--wp--preset--spacing--10); +} +.wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons .wp-element-button { + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid var(--wp--preset--color--neutral-200); + border-radius: var(--wp--preset--border-radius--500); + padding: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20); + background: transparent; + color: var(--wp--custom--color--text--muted); + font-family: var(--wp--preset--font-family--body); + font-weight: var(--wp--custom--typography--font-weight--semibold); + font-size: var(--wp--preset--font-size--100); + text-decoration: none; + white-space: nowrap; + transition: background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard); +} +.wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons .wp-element-button:hover, .wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons .wp-element-button:focus-visible { + border-color: var(--wp--custom--color--link--accent); + background-color: transparent; + color: var(--wp--custom--color--link--accent); +} +.wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons .wp-element-button.taxonomy-filter-current { + border-color: var(--wp--custom--color--card--platform--wordpress); + background-color: var(--wp--custom--color--card--platform--wordpress); + color: var(--wp--custom--color--text--on-dark); +} +.wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons .wp-element-button.taxonomy-filter-current:hover, .wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons .wp-element-button.taxonomy-filter-current:focus-visible { + border-color: var(--wp--custom--color--card--platform--wordpress); + background-color: var(--wp--custom--color--card--platform--wordpress); + color: var(--wp--custom--color--text--on-dark); +} diff --git a/functions.php b/functions.php index d1e7e1e..a13e320 100644 --- a/functions.php +++ b/functions.php @@ -21,6 +21,9 @@ /** Loads site header assets */ require get_template_directory() . '/inc/header.php'; +/** Loads Portfolio card platform-colour swapping */ +require get_template_directory() . '/inc/portfolio-card-colors.php'; + /** * Sets up theme supports. */ diff --git a/inc/animations.php b/inc/animations.php index ecae05e..d8eebb0 100644 --- a/inc/animations.php +++ b/inc/animations.php @@ -137,6 +137,11 @@ function ls_theme_register_effect_block_styles() { 'name' => 'card-feature', 'label' => __( 'Card - Feature', 'ls-theme' ), ), + array( + 'block_name' => 'core/group', + 'name' => 'card-work-category', + 'label' => __( 'Card - Work Category', 'ls-theme' ), + ), array( 'block_name' => 'core/group', 'name' => 'card-solutions', diff --git a/inc/portfolio-card-colors.php b/inc/portfolio-card-colors.php new file mode 100644 index 0000000..766292b --- /dev/null +++ b/inc/portfolio-card-colors.php @@ -0,0 +1,59 @@ + 'slugs' ) ); + + if ( is_wp_error( $terms ) || empty( $terms ) || ! in_array( 'woocommerce', $terms, true ) ) { + return $block_content; + } + + if ( $is_banner ) { + return str_replace( 'is-style-card-work-project-banner', 'is-style-card-work-project-banner-woocommerce', $block_content ); + } + + return str_replace( 'is-style-badge-brand', 'is-style-badge-woocommerce', $block_content ); +} +add_filter( 'render_block', 'ls_theme_portfolio_card_platform_class', 10, 2 ); diff --git a/patterns/cards/work-project-card.php b/patterns/cards/work-project-card.php index 4a63c10..9f1ec41 100644 --- a/patterns/cards/work-project-card.php +++ b/patterns/cards/work-project-card.php @@ -4,7 +4,7 @@ * Slug: ls-theme/work-project-card * Categories: featured * Block Types: core/pattern - * Description: A single Work archive case-study card: platform banner (Portfolio Industry taxonomy), project-type badge, post title/excerpt, service tag pills, and a "View project" link to the post permalink. Intended as the Post Template content inside a Query Loop scoped to the Portfolio post type (LS-1617). Adapts between light and dark mode using existing semantic tokens. + * Description: A single Work archive case-study card: platform banner (Portfolio project-group taxonomy), platform badge, post title/excerpt, service tag pills (project-tag taxonomy), and a "View project" link to the post permalink. Intended as the Post Template content inside a Query Loop scoped to the `project` post type (LS-1617). Adapts between light and dark mode using existing semantic tokens. * Keywords: work, portfolio, case study, card, query loop, block bindings * Viewport Width: 450 * Inserter: true @@ -20,7 +20,7 @@
- +
@@ -29,19 +29,19 @@
- + - +
- +
- +
diff --git a/patterns/content/eyebrow-badge.php b/patterns/content/eyebrow-badge.php new file mode 100644 index 0000000..f9ec0c7 --- /dev/null +++ b/patterns/content/eyebrow-badge.php @@ -0,0 +1,26 @@ + + +
+ +
+ + + +

+ +
+ diff --git a/patterns/sections/work-categories.php b/patterns/sections/work-categories.php new file mode 100644 index 0000000..078b5e1 --- /dev/null +++ b/patterns/sections/work-categories.php @@ -0,0 +1,148 @@ + + +
+ + +
+ + +
+ + +
+ + + +

+ +
+ + + +
+ +

+ +
+ +
+ + + +
+ + +
+ +
+ +
+ +
+ +
+ + + +
+ +

+ + + +

+ +
+ + + + + +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ + + +
+ +

+ + + +

+ +
+ + + + + +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ + + +
+ +

+ + + +

+ +
+ + + + + +
+ +
+ +
+ +
+ +
+ diff --git a/patterns/sections/work-selected-projects.php b/patterns/sections/work-selected-projects.php new file mode 100644 index 0000000..c1b16cb --- /dev/null +++ b/patterns/sections/work-selected-projects.php @@ -0,0 +1,74 @@ + + +
+ + +
+ + +
+ + +
+ +
+ +
+ + + +

+ +
+ + + +

+ +
+ + + +
+ +

+ +
+ +
+ + + +
+ + + + + + + + + + + + +
+ +
+ +
+ diff --git a/patterns/template-work-archive.php b/patterns/template-work-archive.php index 6175677..18c88f3 100644 --- a/patterns/template-work-archive.php +++ b/patterns/template-work-archive.php @@ -4,7 +4,7 @@ * Slug: ls-theme/template-work-archive * Categories: template * Block Types: core/template-part - * Description: Main-content pattern for the Work Archive custom page template. Injects each Work archive section pattern in sequence — Hero, and more to follow (Selected Projects grid, Across Every Engagement stats, CTA, Where to go next). Not tied to post_content, so it renders the same sections regardless of the assigned page's own content. + * Description: Main-content pattern for the Work Archive custom page template. Injects each Work archive section pattern in sequence — Hero, Categories, Selected Projects, and more to follow (Across Every Engagement stats, CTA, Where to go next). Not tied to post_content, so it renders the same sections regardless of the assigned page's own content. * Inserter: false * * @package ls-theme @@ -15,5 +15,7 @@
+ +
diff --git a/src/scss/animations.scss b/src/scss/animations.scss index 17fc0c5..15d5124 100644 --- a/src/scss/animations.scss +++ b/src/scss/animations.scss @@ -7,4 +7,5 @@ @use "animations/faq-motion"; @use "animations/menu-motion"; @use "animations/footer-motion"; -@use "animations/header-motion"; \ No newline at end of file +@use "animations/header-motion"; +@use "animations/taxonomy-filter"; \ No newline at end of file diff --git a/src/scss/animations/_card-motion.scss b/src/scss/animations/_card-motion.scss index adcf600..7623436 100644 --- a/src/scss/animations/_card-motion.scss +++ b/src/scss/animations/_card-motion.scss @@ -202,6 +202,44 @@ } } +/* Card - Work Category */ +.is-style-card-work-category { + --ls-card-work-category-border-rest: var(--wp--custom--color--border--card); + --ls-card-work-category-border-active: var(--wp--custom--color--link--accent); + --ls-card-work-category-shadow-rest: var(--wp--custom--shadow--elevation--100); + --ls-card-work-category-shadow-active: var(--wp--custom--shadow--card--hover); + --ls-card-work-category-lift: -4px; + @include surface.surface-card( + $radius: var(--wp--preset--border-radius--300), + $border: 1px solid var(--ls-card-work-category-border-rest), + $background: var(--wp--custom--color--surface--card), + $shadow: var(--ls-card-work-category-shadow-rest) + ); + gap: var(--wp--preset--spacing--20); + padding: var(--wp--preset--spacing--20); + transition: + border-color var(--wp--custom--animation--duration--base) + var(--wp--custom--animation--easing--standard), + box-shadow var(--wp--custom--animation--duration--medium) + var(--wp--custom--animation--easing--standard), + transform var(--wp--custom--animation--duration--medium) + var(--wp--custom--animation--easing--emphasised); + + &:hover, + &:focus-within { + border-color: var(--ls-card-work-category-border-active); + box-shadow: var(--ls-card-work-category-shadow-active); + transform: translateY(var(--ls-card-work-category-lift)); + } + + .ls-card-work-category__content { + flex: 1 1 auto; + display: flex; + flex-direction: column; + gap: var(--wp--preset--spacing--10); + } +} + /* Card - Services */ .is-style-card-services { --ls-card-services-border-rest: var(--wp--custom--color--border--card); @@ -486,6 +524,7 @@ .is-style-glass-card, .is-style-card-feature, .is-style-card-feature :is(.ls-card__icon-shell, .ls-card-feature__icon-shell), + .is-style-card-work-category, .is-style-card-services, .is-style-card-services::before, .is-style-card-services :is(.ls-card__icon-shell, .ls-card-services__icon-shell), @@ -500,6 +539,8 @@ .is-style-glass-card:focus-within, .is-style-card-feature:hover, .is-style-card-feature:focus-within, + .is-style-card-work-category:hover, + .is-style-card-work-category:focus-within, .is-style-card-services:hover, .is-style-card-services:focus-within { transform: none; @@ -529,4 +570,49 @@ .is-style-icon-frame-glow { transform: none; } +} + +/* Card - Work Project (WooCommerce platform colour) */ +.is-style-card-work-project-banner-woocommerce { + padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--20); + background-color: color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 7%, transparent); +} + +.is-style-badge-woocommerce { + width: 100%; + max-width: 100%; + box-sizing: border-box; + color: var(--wp--custom--color--card--platform--woocommerce); + font-family: var(--wp--preset--font-family--monospace); + font-size: var(--wp--preset--font-size--100); + font-weight: var(--wp--custom--typography--font-weight--bold); + text-transform: uppercase; + background-color: color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 8%, transparent); + border-radius: var(--wp--preset--border-radius--200); + padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--10); + letter-spacing: 1px; +} + +/* Badge - multi-term wrapping (WordPress and WooCommerce both bind to + project-group, which can carry more than one term per post; core/post-terms + forces its links to display:block by default, which stacks each term + onto its own line and leaves the ", " separator orphaned on its own row) */ +:is(.is-style-badge-brand, .is-style-badge-woocommerce) { + display: flex; + flex-wrap: wrap; + align-items: baseline; + + a { + display: inline; + min-width: 0; + max-width: 100%; + white-space: normal; + word-break: break-word; + color: inherit; + text-decoration: none; + } + + .wp-block-post-terms__separator { + margin-inline-end: var(--wp--preset--spacing--5); + } } \ No newline at end of file diff --git a/src/scss/animations/_taxonomy-filter.scss b/src/scss/animations/_taxonomy-filter.scss new file mode 100644 index 0000000..87108b5 --- /dev/null +++ b/src/scss/animations/_taxonomy-filter.scss @@ -0,0 +1,47 @@ +/********** Taxonomy Filter (ls-plugin/taxonomy-filter) **********/ + +.wp-block-ls-plugin-taxonomy-filter.taxonomy-filter--buttons { + display: flex; + flex-wrap: wrap; + gap: var(--wp--preset--spacing--10); + + .wp-element-button { + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid var(--wp--preset--color--neutral-200); + border-radius: var(--wp--preset--border-radius--500); + padding: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20); + background: transparent; + color: var(--wp--custom--color--text--muted); + font-family: var(--wp--preset--font-family--body); + font-weight: var(--wp--custom--typography--font-weight--semibold); + font-size: var(--wp--preset--font-size--100); + text-decoration: none; + white-space: nowrap; + transition: + background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), + border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), + color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard); + + &:hover, + &:focus-visible { + border-color: var(--wp--custom--color--link--accent); + background-color: transparent; + color: var(--wp--custom--color--link--accent); + } + + &.taxonomy-filter-current { + border-color: var(--wp--custom--color--card--platform--wordpress); + background-color: var(--wp--custom--color--card--platform--wordpress); + color: var(--wp--custom--color--text--on-dark); + + &:hover, + &:focus-visible { + border-color: var(--wp--custom--color--card--platform--wordpress); + background-color: var(--wp--custom--color--card--platform--wordpress); + color: var(--wp--custom--color--text--on-dark); + } + } + } +} diff --git a/styles/blocks/post-terms/badge-brand.json b/styles/blocks/post-terms/badge-brand.json index 38b5bf9..a162cb3 100644 --- a/styles/blocks/post-terms/badge-brand.json +++ b/styles/blocks/post-terms/badge-brand.json @@ -6,10 +6,10 @@ "blockTypes": [ "core/post-terms" ], - "description": "Renders linked terms as a full-width brand-tinted bar, for the Work Project Card's project-type badge (bound to the Portfolio Project Type taxonomy).", + "description": "Renders linked terms as a full-width WordPress-tinted bar, for the Work Project Card's platform badge (bound to the Portfolio project-group taxonomy). Default/fallback variant for any project-group term other than WooCommerce.", "styles": { "color": { - "text": "var:custom|color|text|brand" + "text": "var:custom|color|card|platform|wordpress" }, "typography": { "fontFamily": "var:preset|font-family|monospace", @@ -17,6 +17,6 @@ "fontWeight": "var:custom|typography|font-weight|bold", "textTransform": "uppercase" }, - "css": "&{display:block;width:100%;max-width:100%;box-sizing:border-box;background-color:color-mix(in srgb, var(--wp--custom--color--card--solutions--brand) 8%, transparent);border-radius:var(--wp--preset--border-radius--200);padding:var(--wp--preset--spacing--5) var(--wp--preset--spacing--10);letter-spacing:1px;} & a{display:block;min-width:0;max-width:100%;white-space:normal;word-break:break-word;color:inherit;text-decoration:none;}" + "css": "&{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;max-width:100%;box-sizing:border-box;background-color:color-mix(in srgb, var(--wp--custom--color--card--platform--wordpress) 8%, transparent);border-radius:var(--wp--preset--border-radius--200);padding:var(--wp--preset--spacing--5) var(--wp--preset--spacing--10);letter-spacing:1px;} & a{display:inline;min-width:0;max-width:100%;white-space:normal;word-break:break-word;color:inherit;text-decoration:none;} & .wp-block-post-terms__separator{margin-inline-end:var(--wp--preset--spacing--5);}" } } diff --git a/styles/blocks/post-terms/badge-woocommerce.json b/styles/blocks/post-terms/badge-woocommerce.json new file mode 100644 index 0000000..b4537bc --- /dev/null +++ b/styles/blocks/post-terms/badge-woocommerce.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Badge - WooCommerce", + "slug": "badge-woocommerce", + "blockTypes": [ + "core/post-terms" + ], + "description": "Renders linked terms as a full-width WooCommerce-tinted bar, for the Work Project Card's platform badge (bound to the Portfolio project-group taxonomy) when the post's term is WooCommerce.", + "styles": { + "color": { + "text": "var:custom|color|card|platform|woocommerce" + }, + "typography": { + "fontFamily": "var:preset|font-family|monospace", + "fontSize": "var:preset|font-size|100", + "fontWeight": "var:custom|typography|font-weight|bold", + "textTransform": "uppercase" + }, + "css": "&{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;max-width:100%;box-sizing:border-box;background-color:color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 8%, transparent);border-radius:var(--wp--preset--border-radius--200);padding:var(--wp--preset--spacing--5) var(--wp--preset--spacing--10);letter-spacing:1px;} & a{display:inline;min-width:0;max-width:100%;white-space:normal;word-break:break-word;color:inherit;text-decoration:none;} & .wp-block-post-terms__separator{margin-inline-end:var(--wp--preset--spacing--5);}" + } +} diff --git a/styles/dark.json b/styles/dark.json index f196c3f..bc08418 100644 --- a/styles/dark.json +++ b/styles/dark.json @@ -43,6 +43,10 @@ "solutions": { "brand": "var:preset|color|cta-500", "accent": "var:preset|color|accent-three-500" + }, + "platform": { + "wordpress": "var:preset|color|brand-400", + "woocommerce": "var:preset|color|cta-400" } }, "phase": { diff --git a/styles/sections/cards/card-work-category.json b/styles/sections/cards/card-work-category.json new file mode 100644 index 0000000..3d6d779 --- /dev/null +++ b/styles/sections/cards/card-work-category.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Category", + "slug": "card-work-category", + "blockTypes": [ + "core/group" + ], + "description": "Compact card shell for the Work archive's category row: tinted icon well, H3 heading, supporting copy, and inline CTA sitting close to the copy (no bottom-anchored CTA, unlike Card - Feature).", + "styles": { + "color": { + "background": "var:custom|color|surface|card", + "text": "var:custom|color|text|default" + }, + "border": { + "color": "var:custom|color|border|card", + "radius": "var:preset|border-radius|300", + "style": "solid", + "width": "1px" + }, + "shadow": "var:preset|shadow|100", + "spacing": { + "blockGap": "var:preset|spacing|20", + "padding": { + "top": "var:preset|spacing|20", + "right": "var:preset|spacing|20", + "bottom": "var:preset|spacing|20", + "left": "var:preset|spacing|20" + } + } + } +} diff --git a/styles/sections/cards/card-work-project-banner-woocommerce.json b/styles/sections/cards/card-work-project-banner-woocommerce.json new file mode 100644 index 0000000..b38c809 --- /dev/null +++ b/styles/sections/cards/card-work-project-banner-woocommerce.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Card - Work Project Banner (WooCommerce)", + "slug": "card-work-project-banner-woocommerce", + "blockTypes": [ + "core/group" + ], + "description": "WooCommerce-tinted banner zone for the Work Project Card, applied when the post's project-group term is WooCommerce.", + "styles": { + "spacing": { + "padding": { + "top": "var:preset|spacing|40", + "right": "var:preset|spacing|20", + "bottom": "var:preset|spacing|40", + "left": "var:preset|spacing|20" + } + }, + "css": "&{background-color:color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 7%, transparent);}" + } +} diff --git a/styles/sections/cards/card-work-project-banner.json b/styles/sections/cards/card-work-project-banner.json index 8a08612..17b16b7 100644 --- a/styles/sections/cards/card-work-project-banner.json +++ b/styles/sections/cards/card-work-project-banner.json @@ -6,7 +6,7 @@ "blockTypes": [ "core/group" ], - "description": "Brand-tinted banner zone for the Work Project Card. Background colour lives here (not inline in the pattern) so the block's saved HTML stays a plain className the validator can round-trip cleanly.", + "description": "WordPress-tinted banner zone for the Work Project Card. Default/fallback variant for any project-group term other than WooCommerce. Background colour lives here (not inline in the pattern) so the block's saved HTML stays a plain className the validator can round-trip cleanly.", "styles": { "spacing": { "padding": { @@ -16,6 +16,6 @@ "left": "var:preset|spacing|20" } }, - "css": "&{background-color:color-mix(in srgb, var(--wp--custom--color--card--solutions--brand) 7%, transparent);}" + "css": "&{background-color:color-mix(in srgb, var(--wp--custom--color--card--platform--wordpress) 7%, transparent);}" } } diff --git a/styles/sections/content/work-categories.json b/styles/sections/content/work-categories.json new file mode 100644 index 0000000..5a4a851 --- /dev/null +++ b/styles/sections/content/work-categories.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Work Categories Section", + "slug": "work-categories", + "blockTypes": [ + "core/group" + ], + "description": "Full-width content band for the Work archive's category grid: flat near-white background, standard section padding. No gradient, unlike the Hero section's effect.hero tokens.", + "styles": { + "color": { + "background": "var:custom|color|surface|canvas" + }, + "spacing": { + "padding": { + "top": "var:preset|spacing|80", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|90", + "left": "var:preset|spacing|30" + } + } + } +} diff --git a/styles/sections/content/work-selected-projects.json b/styles/sections/content/work-selected-projects.json new file mode 100644 index 0000000..8f0b9ca --- /dev/null +++ b/styles/sections/content/work-selected-projects.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Work Selected Projects Section", + "slug": "work-selected-projects", + "blockTypes": [ + "core/group" + ], + "description": "Full-width content band for the Work archive's Selected Projects query loop: flat canvas background, standard section padding.", + "styles": { + "color": { + "background": "var:custom|color|surface|canvas" + }, + "spacing": { + "padding": { + "top": "var:preset|spacing|80", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|90", + "left": "var:preset|spacing|30" + } + } + } +} diff --git a/theme.json b/theme.json index c3af7c8..fc3a088 100644 --- a/theme.json +++ b/theme.json @@ -513,6 +513,10 @@ "solutions": { "brand": "var:preset|color|brand-500", "accent": "var:preset|color|accent-500" + }, + "platform": { + "wordpress": "var:preset|color|brand-500", + "woocommerce": "var:preset|color|cta-800" } }, "phase": { From a174ee306f15e5e8815e57c05891d8ce62f3079e Mon Sep 17 00:00:00 2001 From: Brandonma21 Date: Tue, 28 Jul 2026 16:32:44 +0200 Subject: [PATCH 4/6] Rename Work archive card styles to generic, reusable names (LS-1616) The new card-work-* style variations were scoped to a single page by name, breaking the existing card-feature/card-services/card-spotlight convention of naming styles after their shape rather than where they're used. Renamed all 11 to purpose-based slugs (card-category, card-case-study, card-chip, card-divider-top/bottom, card-list-shell, card-link-row, card-checklist, stat-segment, card-banner-tint(-woocommerce)) and updated every reference across patterns, inc/animations.php, inc/portfolio-card-colors.php, and the compiled animations.css so they read as reusable theme styles rather than Work-archive-only assets. --- CHANGELOG.md | 4 +-- assets/css/animations.css | 34 +++++++++---------- inc/animations.php | 4 +-- inc/portfolio-card-colors.php | 4 +-- patterns/cards/work-capability-list.php | 12 +++---- patterns/cards/work-discuss-project-list.php | 4 +-- patterns/cards/work-engagement-stat.php | 4 +-- patterns/cards/work-next-steps-card.php | 4 +-- patterns/cards/work-project-card.php | 20 +++++------ patterns/sections/work-categories.php | 24 ++++++------- src/scss/animations/_card-motion.scss | 32 ++++++++--------- ...json => card-banner-tint-woocommerce.json} | 4 +-- ...ject-banner.json => card-banner-tint.json} | 4 +-- ...work-project.json => card-case-study.json} | 4 +-- ...-work-category.json => card-category.json} | 6 ++-- ...ard-work-list.json => card-checklist.json} | 4 +-- ...-work-project-chip.json => card-chip.json} | 4 +-- ...lity-row.json => card-divider-bottom.json} | 4 +-- ...roject-tags.json => card-divider-top.json} | 6 ++-- ...work-next-step.json => card-link-row.json} | 4 +-- ...ability-list.json => card-list-shell.json} | 4 +-- ...{card-work-stat.json => stat-segment.json} | 4 +-- 22 files changed, 97 insertions(+), 97 deletions(-) rename styles/sections/cards/{card-work-project-banner-woocommerce.json => card-banner-tint-woocommerce.json} (84%) rename styles/sections/cards/{card-work-project-banner.json => card-banner-tint.json} (90%) rename styles/sections/cards/{card-work-project.json => card-case-study.json} (92%) rename styles/sections/cards/{card-work-category.json => card-category.json} (70%) rename styles/sections/cards/{card-work-list.json => card-checklist.json} (92%) rename styles/sections/cards/{card-work-project-chip.json => card-chip.json} (90%) rename styles/sections/cards/{card-work-capability-row.json => card-divider-bottom.json} (88%) rename styles/sections/cards/{card-work-project-tags.json => card-divider-top.json} (52%) rename styles/sections/cards/{card-work-next-step.json => card-link-row.json} (91%) rename styles/sections/cards/{card-work-capability-list.json => card-list-shell.json} (90%) rename styles/sections/cards/{card-work-stat.json => stat-segment.json} (91%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5776f..0f39d80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `patterns/cards/work-discuss-project-list.php` — a static checklist card reusing the existing `tick-accent` list style. - `patterns/cards/work-engagement-stat.php` — a stat segment with a split-colour big number (accent-coloured suffix) and monospace uppercase labels. - `patterns/cards/work-next-steps-card.php` — a compact related-route button. - - Matching section/block styles: `styles/sections/cards/card-work-project.json`, `card-work-project-banner.json`, `card-work-project-chip.json`, `card-work-project-tags.json`, `card-work-list.json`, `card-work-stat.json`, `card-work-next-step.json`, and two new `core/post-terms` block styles (`styles/blocks/post-terms/badge-brand.json`, `tag-pills.json`) for rendering dynamically-bound taxonomy terms as a badge bar and individual tag pills respectively. + - Matching section/block styles: `styles/sections/cards/card-case-study.json`, `card-banner-tint.json`, `card-chip.json`, `card-divider-top.json`, `card-checklist.json`, `stat-segment.json`, `card-link-row.json`, and two new `core/post-terms` block styles (`styles/blocks/post-terms/badge-brand.json`, `tag-pills.json`) for rendering dynamically-bound taxonomy terms as a badge bar and individual tag pills respectively. - Colour, computed values (background tints, borders) are kept out of pattern-level block attributes and defined only in these external style files — WordPress's block validator can't reliably round-trip a raw `color-mix()` value placed directly in a block's own `style` attribute. - - Added hover-lift behaviour for the two interactive cards (`is-style-card-work-project`, `is-style-card-work-next-step`) to `assets/css/animations.css`, reusing the existing `card.hover` shadow contract, and extended the `is-style-link-arrow-accent` style/CSS to also support `core/read-more` (previously `core/paragraph` only). + - Added hover-lift behaviour for the two interactive cards (`is-style-card-case-study`, `is-style-card-link-row`) to `assets/css/animations.css`, reusing the existing `card.hover` shadow contract, and extended the `is-style-link-arrow-accent` style/CSS to also support `core/read-more` (previously `core/paragraph` only). - Added a `Menu Item Card` pattern (`patterns/menu/menu-item-card.php`) as the single reusable source of the mega-menu list item structure (icon well, title/description, hover-reveal trailing arrow), used across the Work, Solutions, Pricing, Insights, and About mega menus — Services is excluded, it uses its own per-phase item style. Deliberately a plain registered pattern, not a Synced Pattern, so each insertion stays independently editable per menu item (LS-1618). - Added 6 real mega menu template parts for Ollie Menu Designer's Dropdown Menu block, each with final content, no shared placeholder scaffold: `parts/work-mega-menu.html`, `parts/solutions-mega-menu.html`, `parts/pricing-mega-menu.html`, `parts/insights-mega-menu.html`, `parts/about-mega-menu.html` (Default item styling), and `parts/services-mega-menu.html` (Service item styling, 6 lifecycle-phase columns). All registered in `theme.json` `templateParts` (LS-1618). - Added `Mega Menu Item - Default` and `Mega Menu Item - Service` block styles (`styles/blocks/groups/mega-menu-item-default.json`, `mega-menu-item-service.json`) as the single reusable, registered source of a row's structural styling (padding, radius) — the icon well itself carries no separate style, just plain inline block attributes, so it has no independent interactive behaviour of its own. diff --git a/assets/css/animations.css b/assets/css/animations.css index b94f34c..50d5317 100644 --- a/assets/css/animations.css +++ b/assets/css/animations.css @@ -378,28 +378,28 @@ } /* Card - Work Category */ -.is-style-card-work-category { - --ls-card-work-category-border-rest: var(--wp--custom--color--border--card); - --ls-card-work-category-border-active: var(--wp--custom--color--link--accent); - --ls-card-work-category-shadow-rest: var(--wp--custom--shadow--elevation--100); - --ls-card-work-category-shadow-active: var(--wp--custom--shadow--card--hover); - --ls-card-work-category-lift: -4px; +.is-style-card-category { + --ls-card-category-border-rest: var(--wp--custom--color--border--card); + --ls-card-category-border-active: var(--wp--custom--color--link--accent); + --ls-card-category-shadow-rest: var(--wp--custom--shadow--elevation--100); + --ls-card-category-shadow-active: var(--wp--custom--shadow--card--hover); + --ls-card-category-lift: -4px; position: relative; overflow: hidden; - border: 1px solid var(--ls-card-work-category-border-rest); + border: 1px solid var(--ls-card-category-border-rest); border-radius: var(--wp--preset--border-radius--300); background: var(--wp--custom--color--surface--card); - box-shadow: var(--ls-card-work-category-shadow-rest); + box-shadow: var(--ls-card-category-shadow-rest); gap: var(--wp--preset--spacing--20); padding: var(--wp--preset--spacing--20); transition: border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard), box-shadow var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard), transform var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--emphasised); } -.is-style-card-work-category:hover, .is-style-card-work-category:focus-within { - border-color: var(--ls-card-work-category-border-active); - box-shadow: var(--ls-card-work-category-shadow-active); - transform: translateY(var(--ls-card-work-category-lift)); +.is-style-card-category:hover, .is-style-card-category:focus-within { + border-color: var(--ls-card-category-border-active); + box-shadow: var(--ls-card-category-shadow-active); + transform: translateY(var(--ls-card-category-lift)); } -.is-style-card-work-category .ls-card-work-category__content { +.is-style-card-category .ls-card-category__content { flex: 1 1 auto; display: flex; flex-direction: column; @@ -635,7 +635,7 @@ .is-style-glass-card, .is-style-card-feature, .is-style-card-feature :is(.ls-card__icon-shell, .ls-card-feature__icon-shell), - .is-style-card-work-category, + .is-style-card-category, .is-style-card-services, .is-style-card-services::before, .is-style-card-services :is(.ls-card__icon-shell, .ls-card-services__icon-shell), @@ -648,8 +648,8 @@ .is-style-glass-card:focus-within, .is-style-card-feature:hover, .is-style-card-feature:focus-within, - .is-style-card-work-category:hover, - .is-style-card-work-category:focus-within, + .is-style-card-category:hover, + .is-style-card-category:focus-within, .is-style-card-services:hover, .is-style-card-services:focus-within { transform: none; @@ -676,7 +676,7 @@ } } /* Card - Work Project (WooCommerce platform colour) */ -.is-style-card-work-project-banner-woocommerce { +.is-style-card-banner-tint-woocommerce { padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--20); background-color: color-mix(in srgb, var(--wp--custom--color--card--platform--woocommerce) 7%, transparent); } diff --git a/inc/animations.php b/inc/animations.php index d8eebb0..8ebe1d2 100644 --- a/inc/animations.php +++ b/inc/animations.php @@ -139,8 +139,8 @@ function ls_theme_register_effect_block_styles() { ), array( 'block_name' => 'core/group', - 'name' => 'card-work-category', - 'label' => __( 'Card - Work Category', 'ls-theme' ), + 'name' => 'card-category', + 'label' => __( 'Card - Category', 'ls-theme' ), ), array( 'block_name' => 'core/group', diff --git a/inc/portfolio-card-colors.php b/inc/portfolio-card-colors.php index 766292b..23efe79 100644 --- a/inc/portfolio-card-colors.php +++ b/inc/portfolio-card-colors.php @@ -31,7 +31,7 @@ function ls_theme_portfolio_card_platform_class( $block_content, $block ) { $class_name = $block['attrs']['className'] ?? ''; - $is_banner = false !== strpos( $class_name, 'is-style-card-work-project-banner' ); + $is_banner = false !== strpos( $class_name, 'is-style-card-banner-tint' ); $is_badge = false !== strpos( $class_name, 'is-style-badge-brand' ); if ( ! $is_banner && ! $is_badge ) { @@ -51,7 +51,7 @@ function ls_theme_portfolio_card_platform_class( $block_content, $block ) { } if ( $is_banner ) { - return str_replace( 'is-style-card-work-project-banner', 'is-style-card-work-project-banner-woocommerce', $block_content ); + return str_replace( 'is-style-card-banner-tint', 'is-style-card-banner-tint-woocommerce', $block_content ); } return str_replace( 'is-style-badge-brand', 'is-style-badge-woocommerce', $block_content ); diff --git a/patterns/cards/work-capability-list.php b/patterns/cards/work-capability-list.php index dc37aa8..9566438 100644 --- a/patterns/cards/work-capability-list.php +++ b/patterns/cards/work-capability-list.php @@ -13,11 +13,11 @@ */ ?> - -
+ +
- -
+ +
@@ -40,8 +40,8 @@
- -
+ +
diff --git a/patterns/cards/work-discuss-project-list.php b/patterns/cards/work-discuss-project-list.php index 495c5f8..b3acf93 100644 --- a/patterns/cards/work-discuss-project-list.php +++ b/patterns/cards/work-discuss-project-list.php @@ -13,8 +13,8 @@ */ ?> - -
+ +