diff --git a/assets/css/animations.css b/assets/css/animations.css index 920b401..91e5940 100644 --- a/assets/css/animations.css +++ b/assets/css/animations.css @@ -1009,6 +1009,46 @@ color: var(--ls-button-arrow-compact-colour-active); } +/* CTA fill buttons on fixed-dark cards: pin text/icon colour to the on-dark + tokens so the fill button's rest and hover states stay readable regardless + of the site's light/dark style variation. The background is also pinned to + a dark surface token — text--on-dark against the default brand/cta fill + colour fails WCAG contrast (~1.2:1) once the fill fully reveals on hover. */ +.ls-cta-band__button .wp-block-button__link, +.ls-cta-inline__button .wp-block-button__link, +.ls-cta-reassurance__button .wp-block-button__link { + color: var(--wp--custom--color--text--on-dark); + --ls-button-fill-background: var(--wp--custom--color--surface--on-dark-card); + --ls-button-fill-icon-colour: var(--wp--custom--color--text--on-dark); + --ls-button-fill-hover-text: var(--wp--custom--color--text--on-dark); +} + +/* CTA band: the secondary link's arrow colours aren't part of the group's + saved block attributes, so they're defined here instead of as an inline + style on the wrapper (which would be dropped on save). */ +.ls-cta-band__actions { + --ls-link-arrow-colour: var(--wp--custom--color--text--on-dark); + --ls-link-arrow-hover-colour: var(--wp--custom--color--text--brand); +} + +/* CTA strip: the arrow sits next to the glass button rather than nested in + its rich text, so it needs its own hover contract tied to the shared + wrapper. */ +.ls-cta-strip__cta-wrap { + position: relative; + display: inline-flex; +} + +.ls-cta-strip__button-arrow { + 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); +} + +.ls-cta-strip__cta-wrap:hover .ls-cta-strip__button-arrow, +.ls-cta-strip__cta-wrap:focus-within .ls-cta-strip__button-arrow { + color: var(--wp--custom--color--text--brand); + transform: translateX(0.25em); +} + @media (prefers-reduced-motion: reduce) { .wp-block-button.is-style-glass-button .wp-block-button__link, .wp-block-button.is-style-button-arrow-compact .wp-block-button__link, @@ -1027,4 +1067,11 @@ :is(.is-style-card-solutions, .is-style-card-solutions-accent):focus-within .wp-block-button.is-style-button-arrow-compact .wp-block-button__link::after { transform: none; } + .ls-cta-strip__button-arrow { + transition: none; + } + .ls-cta-strip__cta-wrap:hover .ls-cta-strip__button-arrow, + .ls-cta-strip__cta-wrap:focus-within .ls-cta-strip__button-arrow { + transform: none; + } } diff --git a/assets/icons/arrow-right.svg b/assets/icons/arrow-right.svg new file mode 100644 index 0000000..0afaf5d --- /dev/null +++ b/assets/icons/arrow-right.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/chat.svg b/assets/icons/chat.svg new file mode 100644 index 0000000..99a8020 --- /dev/null +++ b/assets/icons/chat.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/check.svg b/assets/icons/check.svg new file mode 100644 index 0000000..63acbf0 --- /dev/null +++ b/assets/icons/check.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/phone.svg b/assets/icons/phone.svg new file mode 100644 index 0000000..6d1ebe5 --- /dev/null +++ b/assets/icons/phone.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/star.svg b/assets/icons/star.svg new file mode 100644 index 0000000..e544193 --- /dev/null +++ b/assets/icons/star.svg @@ -0,0 +1 @@ + diff --git a/patterns/cta/cta-consultation-band.php b/patterns/cta/cta-consultation-band.php new file mode 100644 index 0000000..6a6da61 --- /dev/null +++ b/patterns/cta/cta-consultation-band.php @@ -0,0 +1,108 @@ + + +
+ + +
+ + +
+ + +
+ +
+ + + +

+ +
+ + + +

+ + + +

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

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

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

+ +
+ + +
+ + +
+ diff --git a/patterns/cta/cta-consultation-inline.php b/patterns/cta/cta-consultation-inline.php new file mode 100644 index 0000000..d4b733f --- /dev/null +++ b/patterns/cta/cta-consultation-inline.php @@ -0,0 +1,57 @@ + + + + diff --git a/patterns/cta/cta-consultation-reassurance.php b/patterns/cta/cta-consultation-reassurance.php new file mode 100644 index 0000000..b130c3f --- /dev/null +++ b/patterns/cta/cta-consultation-reassurance.php @@ -0,0 +1,105 @@ + + +
+ + +
+ + +
+ +

+ + + +

+ + + +

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

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

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

+ +
+ + +
+ + +
+ diff --git a/patterns/cta/cta-consultation-strip.php b/patterns/cta/cta-consultation-strip.php new file mode 100644 index 0000000..bff01f9 --- /dev/null +++ b/patterns/cta/cta-consultation-strip.php @@ -0,0 +1,61 @@ + + +
+ + +
+ + +
+ + + +
+ + + +
+ +

+ + + +

+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + + + +
+ + +
+ diff --git a/src/scss/animations/_button-motion.scss b/src/scss/animations/_button-motion.scss index 8ea4a28..2db0818 100644 --- a/src/scss/animations/_button-motion.scss +++ b/src/scss/animations/_button-motion.scss @@ -486,6 +486,50 @@ } } +/* CTA fill buttons on fixed-dark cards: pin text/icon colour to the on-dark + tokens so the fill button's rest and hover states stay readable regardless + of the site's light/dark style variation. The background is also pinned to + a dark surface token — text--on-dark against the default brand/cta fill + colour fails WCAG contrast (~1.2:1) once the fill fully reveals on hover. */ +.ls-cta-band__button .wp-block-button__link, +.ls-cta-inline__button .wp-block-button__link, +.ls-cta-reassurance__button .wp-block-button__link { + color: var(--wp--custom--color--text--on-dark); + --ls-button-fill-background: var(--wp--custom--color--surface--on-dark-card); + --ls-button-fill-icon-colour: var(--wp--custom--color--text--on-dark); + --ls-button-fill-hover-text: var(--wp--custom--color--text--on-dark); +} + +/* CTA band: the secondary link's arrow colours aren't part of the group's + saved block attributes, so they're defined here instead of as an inline + style on the wrapper (which would be dropped on save). */ +.ls-cta-band__actions { + --ls-link-arrow-colour: var(--wp--custom--color--text--on-dark); + --ls-link-arrow-hover-colour: var(--wp--custom--color--text--brand); +} + +/* CTA strip: the arrow sits next to the glass button rather than nested in + its rich text, so it needs its own hover contract tied to the shared + wrapper. */ +.ls-cta-strip__cta-wrap { + position: relative; + display: inline-flex; +} + +.ls-cta-strip__button-arrow { + 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); +} + +.ls-cta-strip__cta-wrap:hover .ls-cta-strip__button-arrow, +.ls-cta-strip__cta-wrap:focus-within .ls-cta-strip__button-arrow { + color: var(--wp--custom--color--text--brand); + transform: translateX(0.25em); +} + @include motion.reduced-motion { .wp-block-button.is-style-glass-button .wp-block-button__link, .wp-block-button.is-style-button-arrow-compact .wp-block-button__link, @@ -510,4 +554,13 @@ .wp-block-button__link::after { transform: none; } + + .ls-cta-strip__button-arrow { + transition: none; + } + + .ls-cta-strip__cta-wrap:hover .ls-cta-strip__button-arrow, + .ls-cta-strip__cta-wrap:focus-within .ls-cta-strip__button-arrow { + transform: none; + } } \ No newline at end of file diff --git a/styles/dark.json b/styles/dark.json index 9a14f5b..d64a5c3 100644 --- a/styles/dark.json +++ b/styles/dark.json @@ -10,7 +10,9 @@ "inverse": "var:preset|color|contrast", "muted": "var:preset|color|neutral-400", "brand": "var:preset|color|cta-500", - "brand-strong": "var:preset|color|cta-200" + "brand-strong": "var:preset|color|cta-200", + "on-dark": "var:preset|color|base", + "on-dark-muted": "var:preset|color|neutral-400" }, "surface": { "canvas": "var:preset|color|contrast", @@ -23,7 +25,10 @@ "cta": "var:preset|color|accent-two-500", "accent-light": "var:preset|color|accent-900", "accent-two-light": "var:preset|color|accent-two-900", - "accent-three-light": "var:preset|color|accent-three-900" + "accent-three-light": "var:preset|color|accent-three-900", + "band-start": "var:preset|color|surface-700", + "band-end": "var:preset|color|surface-300", + "on-dark-card": "var:preset|color|surface-200" }, "border": { "card": "var:preset|color|neutral-800" diff --git a/styles/sections/cta/cta-inline-card.json b/styles/sections/cta/cta-inline-card.json new file mode 100644 index 0000000..4c01dc5 --- /dev/null +++ b/styles/sections/cta/cta-inline-card.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "CTA Inline Card", + "slug": "cta-inline-card", + "blockTypes": [ + "core/group" + ], + "description": "Fixed-dark inline CTA card shell with an accent left border, for compact consultation callouts.", + "styles": { + "color": { + "background": "var:custom|color|surface|on-dark-card", + "text": "var:custom|color|text|on-dark" + }, + "border": { + "color": "var:custom|color|text|brand", + "radius": "var:preset|border-radius|200", + "style": "solid", + "width": "1px" + }, + "spacing": { + "blockGap": "var:preset|spacing|20", + "padding": { + "top": "var:preset|spacing|30", + "right": "var:preset|spacing|30", + "bottom": "var:preset|spacing|30", + "left": "var:preset|spacing|30" + } + }, + "css": "&{border-left-width:3px;}" + } +} diff --git a/theme.json b/theme.json index f89a1da..0a91e65 100644 --- a/theme.json +++ b/theme.json @@ -416,7 +416,9 @@ "inverse": "var:preset|color|base", "muted": "var:preset|color|neutral-700", "brand": "var:preset|color|brand-500", - "brand-strong": "var:preset|color|brand-800" + "brand-strong": "var:preset|color|brand-800", + "on-dark": "var:preset|color|base", + "on-dark-muted": "var:preset|color|neutral-400" }, "surface": { "canvas": "var:preset|color|base", @@ -429,7 +431,10 @@ "cta": "var:preset|color|cta-500", "accent-light": "var:preset|color|accent-100", "accent-two-light": "var:preset|color|accent-two-100", - "accent-three-light": "var:preset|color|accent-three-100" + "accent-three-light": "var:preset|color|accent-three-100", + "band-start": "var:preset|color|surface-700", + "band-end": "var:preset|color|surface-300", + "on-dark-card": "var:preset|color|surface-200" }, "border": { "card": "var:preset|color|neutral-300"