diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f0d9e0..b707591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [Unreleased] — Phase page review fixes + +### Fixed + +- Load phase hero styles wherever the pattern renders and redirect bare phase URLs only to published pages. +- Correct introduction heading levels, journey navigation label serialization, current-page semantics, and inactive-link contrast. +- Scale the outline button's circle reveal to cover the button's corners without animating layout dimensions; retain reduced-motion behavior. + +--- + ## [Unreleased] — Fix WCAG color-contrast violations for captions and blog filter pill (LS-2934) ### Fixed diff --git a/assets/css/animations.css b/assets/css/animations.css index 10d9bd1..4882418 100644 --- a/assets/css/animations.css +++ b/assets/css/animations.css @@ -1 +1 @@ -.ls-footer-nav-link a{color:inherit;text-decoration-line:underline;text-decoration-color:rgba(0,0,0,0);text-underline-offset:3px}.ls-footer-nav-link a:hover,.ls-footer-nav-link a:focus-visible{color:var(--wp--custom--color--phase--create);text-decoration-color:var(--wp--custom--color--phase--create)}.ls-footer-proof-card:hover,.ls-footer-proof-card:focus-within,.ls-footer-social-icon:hover,.ls-footer-social-icon:focus-within{background-color:var(--wp--custom--color--surface--card-raised) !important;border-color:var(--wp--custom--color--phase--create) !important}.ls-footer-social-icon{min-inline-size:var(--wp--custom--spacing--tap-target-min)}.ls-footer-proof-card{height:100%}.site-logo--for-light{display:var(--wp--custom--visibility--logo-for-light)}.site-logo--for-dark{display:var(--wp--custom--visibility--logo-for-dark)}.site-logo--for-light img,.site-logo--for-dark img{display:block;width:var(--wp--custom--layout--logo-width);height:auto}@media(max-width: 1023.98px){.site-header{padding-left:var(--wp--preset--spacing--60) !important;padding-right:var(--wp--preset--spacing--60) !important}}@media(max-width: 599.98px){.site-header{padding-left:var(--wp--preset--spacing--20) !important;padding-right:var(--wp--preset--spacing--20) !important}}.ls-button-cta-gradient .wp-block-button__link:hover,.ls-button-cta-gradient .wp-block-button__link:focus-visible{box-shadow:var(--wp--custom--shadow--interactive--accent),var(--wp--custom--shadow--elevation--300)}.site-header .wp-block-navigation__responsive-container-close{position:absolute;top:var(--wp--preset--spacing--20);right:var(--wp--preset--spacing--20);display:flex;align-items:center;justify-content:center;min-inline-size:var(--wp--custom--spacing--tap-target-min);min-block-size:var(--wp--custom--spacing--tap-target-min);padding:var(--wp--preset--spacing--10);border:1px solid var(--wp--custom--color--border--card);border-radius:var(--wp--preset--border-radius--500);background-color:color-mix(in srgb, var(--wp--custom--color--surface--card) 4%, transparent)}.site-header .wp-block-navigation__responsive-container-close svg{inline-size:20px;block-size:20px}.site-header .wp-block-navigation-item{position:static}.site-header .wp-block-navigation__submenu-container{left:50%;right:auto;transform:translateX(-50%)}.site-header .wp-block-ollie-mega-menu__menu-container{background:rgba(0,0,0,0)}.ls-mega-menu-panel-services{width:fit-content;max-width:100vw;box-sizing:border-box}.ls-mega-menu-panel-services .wp-block-columns{display:grid;grid-template-columns:repeat(6, minmax(0, 1fr));gap:var(--wp--style--block-gap)}.ls-mega-menu-panel-services .wp-block-column{width:auto}.ls-mega-menu-panel-services .wp-block-column>.wp-block-group p{white-space:nowrap}.ls-simple-submenu-links>.is-style-mega-menu-item-service,.ls-services-phase-links>.is-style-mega-menu-item-service{padding:var(--wp--preset--spacing--5)}.ls-services-phase-links{display:grid;grid-template-columns:1fr;row-gap:0}.ls-services-phase-links>*{margin:0}.ls-services-phase-links{padding-left:calc(8px + var(--wp--preset--spacing--5))}.is-style-mega-menu-item-default{position:relative}.is-style-mega-menu-item-default h5 a::after{content:"";position:absolute;inset:0;z-index:1}.is-style-mega-menu-item-default:hover .wp-block-outermost-icon-block,.is-style-mega-menu-item-default:focus-within .wp-block-outermost-icon-block,.is-style-mega-menu-item-default:hover .wp-block-icon,.is-style-mega-menu-item-default:focus-within .wp-block-icon{color:var(--wp--custom--color--text--subtle)}.is-style-mega-menu-item-service{position:relative}.is-style-mega-menu-item-service a::after{content:"";position:absolute;inset:0;z-index:1}.is-style-mega-menu-item-service:hover,.is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--link--accent) 8%, transparent);border-left-color:var(--wp--custom--color--link--accent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--discover) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--discover) 15%, transparent);border-left-color:var(--wp--custom--color--phase--discover)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--discover)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--create) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--create) 15%, transparent);border-left-color:var(--wp--custom--color--phase--create)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--create)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--build) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--build) 15%, transparent);border-left-color:var(--wp--custom--color--phase--build)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--build)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--launch) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--launch) 15%, transparent);border-left-color:var(--wp--custom--color--phase--launch)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--launch)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--grow) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--grow) 15%, transparent);border-left-color:var(--wp--custom--color--phase--grow)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--grow)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--evolve) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--evolve) 15%, transparent);border-left-color:var(--wp--custom--color--phase--evolve)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--evolve)}@keyframes ls-accent-gradient-shift{to{background-position:var(--ls-accent-gradient-end-position) center}}.site-header__search .wp-block-search__button,.site-header .wp-block-navigation__responsive-container-close,.ls-footer-proof-card,.ls-footer-social-icon{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)}.site-header__search .wp-block-search__button:hover,.site-header__search .wp-block-search__button:focus-visible,.site-header .wp-block-navigation__responsive-container-close:hover,.site-header .wp-block-navigation__responsive-container-close:focus-visible{background-color:var(--wp--custom--color--surface--card-raised);border-color:var(--wp--custom--color--phase--create)}.is-style-mega-menu-item-default{transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.is-style-mega-menu-item-default:hover,.is-style-mega-menu-item-default:focus-within{background-color:var(--wp--custom--color--surface--card-raised)}.is-style-mega-menu-item-service{transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),border-left-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.site-header__search .wp-block-search__button,.site-header .wp-block-navigation__responsive-container-close,.ls-footer-proof-card,.ls-footer-social-icon,.is-style-mega-menu-item-default,.is-style-mega-menu-item-service{transition:none}}.wp-block-details{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),box-shadow var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.wp-block-details>summary{transition:inherit}.wp-block-details>summary::after{transform:translateY(-1px) rotate(45deg);transition:transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--emphasised),border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.wp-block-details:not(.is-style-mobile-menu-accordion)>summary{padding:var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);font:inherit;font-weight:var(--wp--custom--typography--font-weight--normal)}.wp-block-details:hover:not(.is-style-mobile-menu-accordion){background:var(--wp--custom--color--surface--card-raised);border-color:var(--wp--custom--color--link--accent)}.wp-block-details[open]:not(.is-style-mobile-menu-accordion),.wp-block-details[open]:hover:not(.is-style-mobile-menu-accordion){background:var(--wp--custom--color--surface--card);border-color:var(--wp--custom--color--link--accent)}.wp-block-details:not(.is-style-mobile-menu-accordion)[open]>summary{border-bottom:1px solid var(--wp--custom--color--link--accent)}.wp-block-details[open]>summary::after{transform:translateY(1px) rotate(-135deg)}.wp-block-details:focus-within:not(.is-style-mobile-menu-accordion){border-color:var(--wp--custom--color--link--accent);box-shadow:0 0 0 2px var(--wp--custom--color--focus--ring)}.wp-element-button,.wp-block-button__link{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),box-shadow 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),outline-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),outline-offset var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),transform var(--wp--custom--animation--duration--fast) var(--wp--custom--animation--easing--standard);transition-delay:var(--wp--custom--animation--delay--enter)}.wp-element-button:hover,.wp-element-button:focus-visible,.wp-block-button__link:hover,.wp-block-button__link:focus-visible{outline-offset:0}.wp-element-button:active,.wp-block-button__link:active{transform:scale(var(--ls-button-active-scale, var(--wp--custom--animation--scale--active)))}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link{--ls-button-fill-icon-well-size: 3rem;--ls-button-fill-icon-inline-end: 0.625rem;--ls-button-fill-icon-font-size: 1.25rem;--ls-button-fill-icon-block-inset: calc( 50% - (var(--ls-button-fill-icon-well-size) / 2) );--ls-button-fill-icon-inline-start: calc( 100% - var(--ls-button-fill-icon-well-size) - var(--ls-button-fill-icon-inline-end) );background:rgba(0,0,0,0);border:0;transition:transform var(--ls-button-fill-duration, var(--wp--custom--animation--duration--emphasised)) var(--wp--custom--animation--easing--emphasised),color var(--ls-button-fill-duration, var(--wp--custom--animation--duration--emphasised)) var(--wp--custom--animation--easing--emphasised)}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link::before{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--ls-button-fill-background, var(--wp--custom--color--button--fill--background));transition:inset-inline-start var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),inset-inline-end var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),inset-block-start var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),inset-block-end var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),border-radius var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised);z-index:var(--wp--custom--z-index--behind)}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link::after{content:"\2192";position:absolute;inset-block:var(--ls-button-fill-icon-block-inset);inset-inline-end:var(--ls-button-fill-icon-inline-end);width:var(--ls-button-fill-icon-well-size);display:grid;place-items:center;color:var(--ls-button-fill-icon-colour, currentColor);font-size:var(--ls-button-fill-icon-font-size);font-weight:700;line-height:1;transition:color var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised)}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover,:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover::before{transition-delay:var(--ls-button-fill-enter-delay, var(--wp--custom--animation--delay--enter))}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover::before,:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:focus-visible::before{inset-block:var(--ls-button-fill-icon-block-inset);inset-inline-end:var(--ls-button-fill-icon-inline-end);inset-inline-start:var(--ls-button-fill-icon-inline-start);border-radius:inherit}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover,:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:focus-visible{color:var(--ls-button-fill-hover-text, var(--wp--custom--color--text--default))}.wp-block-button.is-style-outline .wp-block-button__link{--ls-button-outline-icon-well-size: calc(3rem - 4px);--ls-button-outline-icon-inset: 4px;--ls-button-outline-icon-font-size: 1.25rem;--ls-button-outline-hover-padding-start: calc(4rem - 4px);--ls-button-outline-hover-padding-end: 1.5rem;--ls-button-outline-icon-inline-start: calc( 100% - var(--ls-button-outline-icon-well-size) - var(--ls-button-outline-icon-inset) );transition:padding-inline-start var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),padding-inline-end var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),transform var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--smooth)}.wp-block-button.is-style-outline .wp-block-button__link::after{content:"\2192";position:absolute;inset-block:var(--ls-button-outline-icon-inset);inset-inline-end:var(--ls-button-outline-icon-inset);width:var(--ls-button-outline-icon-well-size);display:grid;place-items:center;border-radius:var(--ls-button-outline-icon-radius, var(--wp--preset--border-radius--100));background-color:var(--ls-button-outline-accent-background, var(--wp--custom--color--button--outline--border));color:var(--ls-button-outline-accent-colour, var(--wp--custom--color--button--outline--text-hover));font-size:var(--ls-button-outline-icon-font-size);font-weight:700;line-height:1;transition:inset-inline-end var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),background-color var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard),color var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard);z-index:var(--wp--custom--z-index--content)}.wp-block-button.is-style-outline .wp-block-button__link:hover,.wp-block-button.is-style-outline .wp-block-button__link:focus-visible{padding-inline-start:var(--ls-button-outline-hover-padding-start);padding-inline-end:var(--ls-button-outline-hover-padding-end)}.wp-block-button.is-style-outline .wp-block-button__link:hover::after,.wp-block-button.is-style-outline .wp-block-button__link:focus-visible::after{inset-inline-end:var(--ls-button-outline-icon-inline-start)}.is-style-mega-menu-item-default .wp-block-outermost-icon-block,.is-style-mega-menu-item-default .wp-block-icon{transition:color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.is-style-mega-menu-item-default .wp-block-outermost-icon-block,.is-style-mega-menu-item-default .wp-block-icon{transition:none}}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.ls-mega-menu-panel-services .wp-block-column>.wp-block-group:first-child{transition:none}}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns{display:grid;grid-template-columns:repeat(2, 1fr);column-gap:var(--wp--style--block-gap);row-gap:var(--wp--preset--spacing--20)}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column{width:auto}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column:nth-child(-n+4){border-bottom:1px dashed var(--wp--custom--color--border--card);padding-bottom:var(--wp--preset--spacing--20)}@media(min-width: 650px){.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns{grid-template-columns:repeat(3, 1fr)}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column:nth-child(-n+4){border-bottom:none;padding-bottom:0}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column:nth-child(-n+3){border-bottom:1px dashed var(--wp--custom--color--border--card);padding-bottom:var(--wp--preset--spacing--20)}}.site-header .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) .wp-block-navigation__responsive-container-content{padding-top:var(--wp--preset--spacing--20)}.site-header .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay){background-color:var(--wp--custom--color--surface--canvas)}.site-header .wp-block-navigation:not(.has-text-color) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay){color:var(--wp--custom--color--text--default)}.mobile-menu-brand .site-logo--for-light img,.mobile-menu-brand .site-logo--for-dark img{display:block;max-block-size:32px;width:auto;inline-size:auto}.mobile-menu-actions .wp-block-button{width:100%}.mobile-menu-actions .wp-block-button__link{display:block;width:100%;text-align:center}.footer-notes-badge{width:fit-content}.site-footer{position:relative;overflow:clip;background:radial-gradient(ellipse 480px 420px at 12% 0%, color-mix(in srgb, var(--wp--custom--color--effect--spotlight--primary) 16%, transparent) 0%, transparent 60%),radial-gradient(ellipse 460px 400px at 92% 22%, color-mix(in srgb, var(--wp--custom--color--phase--create) 12%, transparent) 0%, transparent 60%),var(--wp--custom--color--surface--canvas)}.site-footer::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;block-size:4px;z-index:var(--wp--custom--z-index--content);background-image:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--wp--custom--color--phase--create) 60%, transparent) 24%, var(--wp--custom--color--phase--create) 50%, color-mix(in srgb, var(--wp--custom--color--phase--create) 60%, transparent) 76%, transparent 100%);box-shadow:0 0 16px 0 color-mix(in srgb, var(--wp--custom--color--phase--create) 70%, transparent),0 8px 32px 0 color-mix(in srgb, var(--wp--custom--color--phase--create) 30%, transparent)}.site-footer__columns{position:relative}.site-footer__columns::after{content:"";position:absolute;inset-block-start:10%;inset-inline-end:8%;inline-size:min(38vw,520px);block-size:min(30vw,360px);background:radial-gradient(ellipse closest-side, color-mix(in srgb, var(--wp--custom--color--phase--create) 14%, transparent) 0%, transparent 70%);filter:blur(40px);pointer-events:none;z-index:0}.site-footer__columns>*{position:relative;z-index:1}.ls-footer-nav-link a{transition:color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),text-decoration-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.ls-footer-nav-link a{transition:none}}@media(max-width: 781px){.footer-nav-columns{display:grid;grid-template-columns:repeat(2, 1fr);column-gap:var(--wp--preset--spacing--40);row-gap:var(--wp--preset--spacing--40)}.footer-nav-columns>.wp-block-columns{display:contents}}.site-header+*{margin-block-start:0}@media(max-width: 599.98px){.site-header__actions .wp-block-buttons{display:none}}@media(max-width: 1023.98px){.site-header .wp-block-navigation{margin-inline-start:auto}}.ls-button-cta-gradient .wp-block-button__link{transition:transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),box-shadow var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-button-cta-gradient .wp-block-button__link:hover,.ls-button-cta-gradient .wp-block-button__link:focus-visible{transform:translateY(-1px)}.site-header__search .wp-block-search__button{display:flex;align-items:center;justify-content:center;min-inline-size:var(--wp--custom--spacing--tap-target-min);min-block-size:var(--wp--custom--spacing--tap-target-min);padding:var(--wp--preset--spacing--10);background-color:color-mix(in srgb, var(--wp--custom--color--surface--card) 4%, transparent)}.site-header__search .wp-block-search__input{inline-size:0;min-inline-size:0;padding-inline:0;border-width:0;opacity:0;transition:inline-size var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard),opacity var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),padding-inline var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard)}.site-header__search.site-header__search--expanded .wp-block-search__input{inline-size:12rem;padding-inline:var(--wp--preset--spacing--10);border-width:1px;opacity:1}@media(prefers-reduced-motion: reduce){.ls-button-cta-gradient .wp-block-button__link,.site-header__search .wp-block-search__input{transition:none}} +.ls-footer-nav-link a{color:inherit;text-decoration-line:underline;text-decoration-color:rgba(0,0,0,0);text-underline-offset:3px}.ls-footer-nav-link a:hover,.ls-footer-nav-link a:focus-visible{color:var(--wp--custom--color--phase--create);text-decoration-color:var(--wp--custom--color--phase--create)}.ls-footer-proof-card:hover,.ls-footer-proof-card:focus-within,.ls-footer-social-icon:hover,.ls-footer-social-icon:focus-within{background-color:var(--wp--custom--color--surface--card-raised) !important;border-color:var(--wp--custom--color--phase--create) !important}.ls-footer-social-icon{min-inline-size:var(--wp--custom--spacing--tap-target-min)}.ls-footer-proof-card{height:100%}.site-logo--for-light{display:var(--wp--custom--visibility--logo-for-light)}.site-logo--for-dark{display:var(--wp--custom--visibility--logo-for-dark)}.site-logo--for-light img,.site-logo--for-dark img{display:block;width:var(--wp--custom--layout--logo-width);height:auto}@media(max-width: 1023.98px){.site-header{padding-left:var(--wp--preset--spacing--60) !important;padding-right:var(--wp--preset--spacing--60) !important}}@media(max-width: 599.98px){.site-header{padding-left:var(--wp--preset--spacing--20) !important;padding-right:var(--wp--preset--spacing--20) !important}}.ls-button-cta-gradient .wp-block-button__link:hover,.ls-button-cta-gradient .wp-block-button__link:focus-visible{box-shadow:var(--wp--custom--shadow--interactive--accent),var(--wp--custom--shadow--elevation--300)}.site-header .wp-block-navigation__responsive-container-close{position:absolute;top:var(--wp--preset--spacing--20);right:var(--wp--preset--spacing--20);display:flex;align-items:center;justify-content:center;min-inline-size:var(--wp--custom--spacing--tap-target-min);min-block-size:var(--wp--custom--spacing--tap-target-min);padding:var(--wp--preset--spacing--10);border:1px solid var(--wp--custom--color--border--card);border-radius:var(--wp--preset--border-radius--500);background-color:color-mix(in srgb, var(--wp--custom--color--surface--card) 4%, transparent)}.site-header .wp-block-navigation__responsive-container-close svg{inline-size:20px;block-size:20px}.site-header .wp-block-navigation-item{position:static}.site-header .wp-block-navigation__submenu-container{left:50%;right:auto;transform:translateX(-50%)}.site-header .wp-block-ollie-mega-menu__menu-container{background:rgba(0,0,0,0)}.ls-mega-menu-panel-services{width:fit-content;max-width:100vw;box-sizing:border-box}.ls-mega-menu-panel-services .wp-block-columns{display:grid;grid-template-columns:repeat(6, minmax(0, 1fr));gap:var(--wp--style--block-gap)}.ls-mega-menu-panel-services .wp-block-column{width:auto}.ls-mega-menu-panel-services .wp-block-column>.wp-block-group p{white-space:nowrap}.ls-simple-submenu-links>.is-style-mega-menu-item-service,.ls-services-phase-links>.is-style-mega-menu-item-service{padding:var(--wp--preset--spacing--5)}.ls-services-phase-links{display:grid;grid-template-columns:1fr;row-gap:0}.ls-services-phase-links>*{margin:0}.ls-services-phase-links{padding-left:calc(8px + var(--wp--preset--spacing--5))}.is-style-mega-menu-item-default{position:relative}.is-style-mega-menu-item-default h5 a::after{content:"";position:absolute;inset:0;z-index:1}.is-style-mega-menu-item-default:hover .wp-block-outermost-icon-block,.is-style-mega-menu-item-default:focus-within .wp-block-outermost-icon-block,.is-style-mega-menu-item-default:hover .wp-block-icon,.is-style-mega-menu-item-default:focus-within .wp-block-icon{color:var(--wp--custom--color--text--subtle)}.is-style-mega-menu-item-service{position:relative}.is-style-mega-menu-item-service a::after{content:"";position:absolute;inset:0;z-index:1}.is-style-mega-menu-item-service:hover,.is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--link--accent) 8%, transparent);border-left-color:var(--wp--custom--color--link--accent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--discover) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--discover) 15%, transparent);border-left-color:var(--wp--custom--color--phase--discover)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--discover)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--create) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--create) 15%, transparent);border-left-color:var(--wp--custom--color--phase--create)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--create)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--build) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--build) 15%, transparent);border-left-color:var(--wp--custom--color--phase--build)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--build)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--launch) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--launch) 15%, transparent);border-left-color:var(--wp--custom--color--phase--launch)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--launch)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--grow) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--grow) 15%, transparent);border-left-color:var(--wp--custom--color--phase--grow)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--grow)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6)>.wp-block-group:first-child:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6)>.wp-block-group:first-child:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--evolve) 15%, transparent)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:hover,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--phase--evolve) 15%, transparent);border-left-color:var(--wp--custom--color--phase--evolve)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:hover a,.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6) .is-style-mega-menu-item-service:focus-within a{color:var(--wp--custom--color--phase--evolve)}@keyframes ls-accent-gradient-shift{to{background-position:var(--ls-accent-gradient-end-position) center}}.site-header__search .wp-block-search__button,.site-header .wp-block-navigation__responsive-container-close,.ls-footer-proof-card,.ls-footer-social-icon{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)}.site-header__search .wp-block-search__button:hover,.site-header__search .wp-block-search__button:focus-visible,.site-header .wp-block-navigation__responsive-container-close:hover,.site-header .wp-block-navigation__responsive-container-close:focus-visible{background-color:var(--wp--custom--color--surface--card-raised);border-color:var(--wp--custom--color--phase--create)}.is-style-mega-menu-item-default{transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.is-style-mega-menu-item-default:hover,.is-style-mega-menu-item-default:focus-within{background-color:var(--wp--custom--color--surface--card-raised)}.is-style-mega-menu-item-service{transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),border-left-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.site-header__search .wp-block-search__button,.site-header .wp-block-navigation__responsive-container-close,.ls-footer-proof-card,.ls-footer-social-icon,.is-style-mega-menu-item-default,.is-style-mega-menu-item-service{transition:none}}.wp-block-details{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),box-shadow var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.wp-block-details>summary{transition:inherit}.wp-block-details>summary::after{transform:translateY(-1px) rotate(45deg);transition:transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--emphasised),border-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.wp-block-details:not(.is-style-mobile-menu-accordion)>summary{padding:var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);font:inherit;font-weight:var(--wp--custom--typography--font-weight--normal)}.wp-block-details:hover:not(.is-style-mobile-menu-accordion){background:var(--wp--custom--color--surface--card-raised);border-color:var(--wp--custom--color--link--accent)}.wp-block-details[open]:not(.is-style-mobile-menu-accordion),.wp-block-details[open]:hover:not(.is-style-mobile-menu-accordion){background:var(--wp--custom--color--surface--card);border-color:var(--wp--custom--color--link--accent)}.wp-block-details:not(.is-style-mobile-menu-accordion)[open]>summary{border-bottom:1px solid var(--wp--custom--color--link--accent)}.wp-block-details[open]>summary::after{transform:translateY(1px) rotate(-135deg)}.wp-block-details:focus-within:not(.is-style-mobile-menu-accordion){border-color:var(--wp--custom--color--link--accent);box-shadow:0 0 0 2px var(--wp--custom--color--focus--ring)}.wp-element-button,.wp-block-button__link{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),box-shadow 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),outline-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),outline-offset var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),transform var(--wp--custom--animation--duration--fast) var(--wp--custom--animation--easing--standard);transition-delay:var(--wp--custom--animation--delay--enter)}.wp-element-button:hover,.wp-element-button:focus-visible,.wp-block-button__link:hover,.wp-block-button__link:focus-visible{outline-offset:0}.wp-element-button:active,.wp-block-button__link:active{transform:scale(var(--ls-button-active-scale, var(--wp--custom--animation--scale--active)))}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link{--ls-button-fill-icon-well-size: 3rem;--ls-button-fill-icon-inline-end: 0.625rem;--ls-button-fill-icon-font-size: 1.25rem;--ls-button-fill-icon-block-inset: calc( 50% - (var(--ls-button-fill-icon-well-size) / 2) );--ls-button-fill-icon-inline-start: calc( 100% - var(--ls-button-fill-icon-well-size) - var(--ls-button-fill-icon-inline-end) );background:rgba(0,0,0,0);border:0;transition:transform var(--ls-button-fill-duration, var(--wp--custom--animation--duration--emphasised)) var(--wp--custom--animation--easing--emphasised),color var(--ls-button-fill-duration, var(--wp--custom--animation--duration--emphasised)) var(--wp--custom--animation--easing--emphasised)}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link::before{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--ls-button-fill-background, var(--wp--custom--color--button--fill--background));transition:inset-inline-start var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),inset-inline-end var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),inset-block-start var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),inset-block-end var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised),border-radius var(--wp--custom--animation--duration--slow) var(--wp--custom--animation--easing--emphasised);z-index:var(--wp--custom--z-index--behind)}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link::after{content:"\2192";position:absolute;inset-block:var(--ls-button-fill-icon-block-inset);inset-inline-end:var(--ls-button-fill-icon-inline-end);width:var(--ls-button-fill-icon-well-size);display:grid;place-items:center;color:var(--ls-button-fill-icon-colour, currentColor);font-size:var(--ls-button-fill-icon-font-size);font-weight:700;line-height:1;transition:color var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised)}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover,:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover::before{transition-delay:var(--ls-button-fill-enter-delay, var(--wp--custom--animation--delay--enter))}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover::before,:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:focus-visible::before{inset-block:var(--ls-button-fill-icon-block-inset);inset-inline-end:var(--ls-button-fill-icon-inline-end);inset-inline-start:var(--ls-button-fill-icon-inline-start);border-radius:inherit}:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:hover,:is(.wp-block-button:not([class*=is-style-]):not(.ls-glass-button):not(.ls-button-cta-gradient),.wp-block-button.is-style-fill) .wp-block-button__link:focus-visible{color:var(--ls-button-fill-hover-text, var(--wp--custom--color--text--default))}.wp-block-button.is-style-outline .wp-block-button__link{--ls-button-outline-icon-well-size: calc(3rem - 4px);--ls-button-outline-icon-inset: 4px;--ls-button-outline-icon-font-size: 1.25rem;--ls-button-outline-hover-padding-start: calc(4rem - 4px);--ls-button-outline-hover-padding-end: 1.5rem;--ls-button-outline-icon-inline-start: calc( 100% - var(--ls-button-outline-icon-well-size) - var(--ls-button-outline-icon-inset) );transition:padding-inline-start var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),padding-inline-end var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),transform var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--smooth)}.wp-block-button.is-style-outline .wp-block-button__link::after{content:"\2192";position:absolute;inset-block:var(--ls-button-outline-icon-inset);inset-inline-end:var(--ls-button-outline-icon-inset);width:var(--ls-button-outline-icon-well-size);display:grid;place-items:center;border-radius:var(--ls-button-outline-icon-radius, var(--wp--preset--border-radius--100));background-color:var(--ls-button-outline-accent-background, var(--wp--custom--color--button--outline--border));color:var(--ls-button-outline-accent-colour, var(--wp--custom--color--button--outline--text-hover));font-size:var(--ls-button-outline-icon-font-size);font-weight:700;line-height:1;transition:inset-inline-end var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),background-color var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard),color var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard);z-index:var(--wp--custom--z-index--content)}.wp-block-button.is-style-outline .wp-block-button__link:hover,.wp-block-button.is-style-outline .wp-block-button__link:focus-visible{padding-inline-start:var(--ls-button-outline-hover-padding-start);padding-inline-end:var(--ls-button-outline-hover-padding-end)}.wp-block-button.is-style-outline .wp-block-button__link:hover::after,.wp-block-button.is-style-outline .wp-block-button__link:focus-visible::after{inset-inline-end:var(--ls-button-outline-icon-inline-start)}.wp-block-button.is-style-button-phase-primary,.wp-block-button.is-style-button-phase-outline{transition:border-radius var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised)}.wp-block-button.is-style-button-phase-primary .wp-block-button__link{transition:border-radius var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised)}.wp-block-button.is-style-button-phase-outline .wp-block-button__link{transition:border-radius var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),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)}.wp-block-button.is-style-button-phase-primary .wp-block-button__link:hover::after,.wp-block-button.is-style-button-phase-primary .wp-block-button__link:focus-visible::after{transform:translateX(var(--wp--preset--spacing--5))}.wp-block-button.is-style-button-phase-primary .wp-block-button__link::after{transition:transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.wp-block-button.is-style-button-phase-outline .wp-block-button__link::before{transition:transform var(--wp--custom--animation--duration--emphasised) var(--wp--custom--animation--easing--emphasised),opacity var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.wp-block-button.is-style-button-phase-primary,.wp-block-button.is-style-button-phase-outline,.wp-block-button.is-style-button-phase-primary .wp-block-button__link,.wp-block-button.is-style-button-phase-outline .wp-block-button__link,.wp-block-button.is-style-button-phase-primary .wp-block-button__link::after,.wp-block-button.is-style-button-phase-outline .wp-block-button__link::before{transition:none}}.is-style-mega-menu-item-default .wp-block-outermost-icon-block,.is-style-mega-menu-item-default .wp-block-icon{transition:color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.is-style-mega-menu-item-default .wp-block-outermost-icon-block,.is-style-mega-menu-item-default .wp-block-icon{transition:none}}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(1)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(2)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(3)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(4)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(5)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-mega-menu-panel-services .wp-block-columns>.wp-block-column:nth-child(6)>.wp-block-group:first-child{border-radius:var(--wp--preset--border-radius--300);transition:background-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.ls-mega-menu-panel-services .wp-block-column>.wp-block-group:first-child{transition:none}}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns{display:grid;grid-template-columns:repeat(2, 1fr);column-gap:var(--wp--style--block-gap);row-gap:var(--wp--preset--spacing--20)}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column{width:auto}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column:nth-child(-n+4){border-bottom:1px dashed var(--wp--custom--color--border--card);padding-bottom:var(--wp--preset--spacing--20)}@media(min-width: 650px){.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns{grid-template-columns:repeat(3, 1fr)}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column:nth-child(-n+4){border-bottom:none;padding-bottom:0}.mobile-menu-accordion .is-style-mega-menu-item-service.wp-block-columns>.wp-block-column:nth-child(-n+3){border-bottom:1px dashed var(--wp--custom--color--border--card);padding-bottom:var(--wp--preset--spacing--20)}}.site-header .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) .wp-block-navigation__responsive-container-content{padding-top:var(--wp--preset--spacing--20)}.site-header .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay){background-color:var(--wp--custom--color--surface--canvas)}.site-header .wp-block-navigation:not(.has-text-color) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay){color:var(--wp--custom--color--text--default)}.mobile-menu-brand .site-logo--for-light img,.mobile-menu-brand .site-logo--for-dark img{display:block;max-block-size:32px;width:auto;inline-size:auto}.mobile-menu-actions .wp-block-button{width:100%}.mobile-menu-actions .wp-block-button__link{display:block;width:100%;text-align:center}.footer-notes-badge{width:fit-content}.site-footer{position:relative;overflow:clip;background:radial-gradient(ellipse 480px 420px at 12% 0%, color-mix(in srgb, var(--wp--custom--color--effect--spotlight--primary) 16%, transparent) 0%, transparent 60%),radial-gradient(ellipse 460px 400px at 92% 22%, color-mix(in srgb, var(--wp--custom--color--phase--create) 12%, transparent) 0%, transparent 60%),var(--wp--custom--color--surface--canvas)}.site-footer::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;block-size:4px;z-index:var(--wp--custom--z-index--content);background-image:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--wp--custom--color--phase--create) 60%, transparent) 24%, var(--wp--custom--color--phase--create) 50%, color-mix(in srgb, var(--wp--custom--color--phase--create) 60%, transparent) 76%, transparent 100%);box-shadow:0 0 16px 0 color-mix(in srgb, var(--wp--custom--color--phase--create) 70%, transparent),0 8px 32px 0 color-mix(in srgb, var(--wp--custom--color--phase--create) 30%, transparent)}.site-footer__columns{position:relative}.site-footer__columns::after{content:"";position:absolute;inset-block-start:10%;inset-inline-end:8%;inline-size:min(38vw,520px);block-size:min(30vw,360px);background:radial-gradient(ellipse closest-side, color-mix(in srgb, var(--wp--custom--color--phase--create) 14%, transparent) 0%, transparent 70%);filter:blur(40px);pointer-events:none;z-index:0}.site-footer__columns>*{position:relative;z-index:1}.ls-footer-nav-link a{transition:color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),text-decoration-color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}@media(prefers-reduced-motion: reduce){.ls-footer-nav-link a{transition:none}}@media(max-width: 781px){.footer-nav-columns{display:grid;grid-template-columns:repeat(2, 1fr);column-gap:var(--wp--preset--spacing--40);row-gap:var(--wp--preset--spacing--40)}.footer-nav-columns>.wp-block-columns{display:contents}}.site-header+*{margin-block-start:0}@media(max-width: 599.98px){.site-header__actions .wp-block-buttons{display:none}}@media(max-width: 1023.98px){.site-header .wp-block-navigation{margin-inline-start:auto}}.ls-button-cta-gradient .wp-block-button__link{transition:transform var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),box-shadow var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-button-cta-gradient .wp-block-button__link:hover,.ls-button-cta-gradient .wp-block-button__link:focus-visible{transform:translateY(-1px)}.site-header__search .wp-block-search__button{display:flex;align-items:center;justify-content:center;min-inline-size:var(--wp--custom--spacing--tap-target-min);min-block-size:var(--wp--custom--spacing--tap-target-min);padding:var(--wp--preset--spacing--10);background-color:color-mix(in srgb, var(--wp--custom--color--surface--card) 4%, transparent)}.site-header__search .wp-block-search__input{inline-size:0;min-inline-size:0;padding-inline:0;border-width:0;opacity:0;transition:inline-size var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard),opacity var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard),padding-inline var(--wp--custom--animation--duration--medium) var(--wp--custom--animation--easing--standard)}.site-header__search.site-header__search--expanded .wp-block-search__input{inline-size:12rem;padding-inline:var(--wp--preset--spacing--10);border-width:1px;opacity:1}@media(prefers-reduced-motion: reduce){.ls-button-cta-gradient .wp-block-button__link,.site-header__search .wp-block-search__input{transition:none}} diff --git a/assets/css/button-phase.css b/assets/css/button-phase.css new file mode 100644 index 0000000..0ee6cf4 --- /dev/null +++ b/assets/css/button-phase.css @@ -0,0 +1 @@ +.wp-block-button.is-style-button-phase-primary,.wp-block-button.is-style-button-phase-outline{border-radius:var(--wp--preset--border-radius--500)}.wp-block-button.is-style-button-phase-primary:hover,.wp-block-button.is-style-button-phase-outline:hover{border-radius:var(--wp--preset--border-radius--300)}.wp-block-button.is-style-button-phase-primary .wp-block-button__link,.wp-block-button.is-style-button-phase-outline .wp-block-button__link{border-radius:inherit}.wp-block-button.is-style-button-phase-primary:hover .wp-block-button__link,.wp-block-button.is-style-button-phase-outline:hover .wp-block-button__link{border-radius:var(--wp--preset--border-radius--300)}.wp-block-button.is-style-button-phase-outline:hover .wp-block-button__link{color:var(--wp--custom--color--text--on-light);border-color:rgba(0,0,0,0)}.wp-block-button.is-style-button-phase-outline .wp-block-button__link::before{content:"";position:absolute;top:50%;left:50%;min-width:100%;min-height:100%;aspect-ratio:1;transform:translate(-50%, -50%) scale(0);border-radius:50%;background-color:var(--wp--custom--color--phase--discover-on-dark);opacity:0;z-index:-1}.wp-block-button.is-style-button-phase-outline:hover .wp-block-button__link::before{transform:translate(-50%, -50%) scale(1.42);opacity:1} diff --git a/assets/css/phase-hero.css b/assets/css/phase-hero.css new file mode 100644 index 0000000..efd1230 --- /dev/null +++ b/assets/css/phase-hero.css @@ -0,0 +1 @@ +.ls-phase-hero{position:relative;overflow:hidden;background-image:linear-gradient(color-mix(in srgb, var(--wp--custom--color--text--on-dark) 2%, transparent) 1px, transparent 1px),linear-gradient(90deg, color-mix(in srgb, var(--wp--custom--color--text--on-dark) 2%, transparent) 1px, transparent 1px),radial-gradient(60% 50% at 50% 22%, color-mix(in srgb, var(--wp--custom--color--phase--discover-on-dark) 14%, transparent) 0%, transparent 70%),linear-gradient(158deg, var(--wp--custom--color--surface--band-start) 0%, var(--wp--custom--color--surface--band-end) 100%);background-position:0 0,0 0,0 0,0 0;background-repeat:repeat,repeat,no-repeat,no-repeat;background-size:32px 32px,32px 32px,auto,auto}.ls-phase-hero .ls-breadcrumbs-on-dark a{color:var(--wp--custom--color--text--on-dark-muted)}.ls-phase-hero .breadcrumb_last{color:var(--wp--custom--color--phase--discover-on-dark)}.ls-phase-hero__share{background-color:color-mix(in srgb, var(--wp--custom--color--text--on-dark) 5%, transparent);border-color:color-mix(in srgb, var(--wp--custom--color--text--on-dark) 8%, transparent);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)}.ls-phase-hero__share:hover,.ls-phase-hero__share:focus-within{background-color:color-mix(in srgb, var(--wp--custom--color--text--on-dark) 9%, transparent);border-color:color-mix(in srgb, var(--wp--custom--color--text--on-dark) 16%, transparent)}@media(prefers-reduced-motion: reduce){.ls-phase-hero__share{transition:none}} diff --git a/assets/css/phase-journey-nav.css b/assets/css/phase-journey-nav.css new file mode 100644 index 0000000..ce40130 --- /dev/null +++ b/assets/css/phase-journey-nav.css @@ -0,0 +1 @@ +.ls-phase-journey-nav__step--discover{--ls-phase-item-accent: var(--wp--custom--color--phase--discover-on-dark, var(--wp--custom--color--phase--discover))}.ls-phase-journey-nav__step--create{--ls-phase-item-accent: var(--wp--custom--color--phase--create-on-dark, var(--wp--custom--color--phase--create))}.ls-phase-journey-nav__step--build{--ls-phase-item-accent: var(--wp--custom--color--phase--build-on-dark, var(--wp--custom--color--phase--build))}.ls-phase-journey-nav__step--launch{--ls-phase-item-accent: var(--wp--custom--color--phase--launch-on-dark, var(--wp--custom--color--phase--launch))}.ls-phase-journey-nav__step--grow{--ls-phase-item-accent: var(--wp--custom--color--phase--grow-on-dark, var(--wp--custom--color--phase--grow))}.ls-phase-journey-nav__step--evolve{--ls-phase-item-accent: var(--wp--custom--color--phase--evolve-on-dark, var(--wp--custom--color--phase--evolve))}.ls-phase-journey-nav__link a{transition:color var(--wp--custom--animation--duration--base) var(--wp--custom--animation--easing--standard)}.ls-phase-journey-nav__step:not(.is-active) .ls-phase-journey-nav__link a{color:var(--wp--custom--color--text--on-dark-muted)}.ls-phase-journey-nav__step:not(.is-active) .ls-phase-journey-nav__link a:hover,.ls-phase-journey-nav__step:not(.is-active) .ls-phase-journey-nav__link a:focus-visible{color:var(--wp--custom--color--text--on-dark)}.ls-phase-journey-nav__step.is-active .ls-phase-journey-nav__link a{color:var(--ls-phase-item-accent)}.ls-phase-journey-nav__step.is-active .ls-phase-journey-nav__link a:hover,.ls-phase-journey-nav__step.is-active .ls-phase-journey-nav__link a:focus-visible{color:var(--wp--custom--color--text--on-dark)}.ls-phase-journey-nav__link a:focus-visible{outline:2px solid var(--wp--custom--color--text--on-dark);outline-offset:3px;border-radius:var(--wp--preset--border-radius--100)}@media(prefers-reduced-motion: reduce){.ls-phase-journey-nav__link a{transition:none}}@media(max-width: 781px){.ls-phase-journey-nav__items{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.ls-phase-journey-nav__items::-webkit-scrollbar{display:none}.ls-phase-journey-nav__step{flex-shrink:0}} diff --git a/functions.php b/functions.php index ffa521f..e43ccbf 100644 --- a/functions.php +++ b/functions.php @@ -39,6 +39,9 @@ /** Loads Blog Single "Related Reading" query filtering */ require get_template_directory() . '/inc/blog-single-related-query.php'; +/** Loads bare phase-slug (e.g. /discover/) redirects to their real nested URL */ +require get_template_directory() . '/inc/phase-page-redirects.php'; + /** * Sets up theme supports. */ @@ -71,6 +74,7 @@ function ls_theme_setup() { add_editor_style( 'assets/css/card-shells.css' ); add_editor_style( 'assets/css/cta-buttons.css' ); add_editor_style( 'assets/css/home-hero.css' ); + add_editor_style( 'assets/css/phase-hero.css' ); add_editor_style( 'assets/css/services-hero.css' ); add_editor_style( 'assets/css/services-linked-decisions.css' ); add_editor_style( 'assets/css/services-service-clusters.css' ); @@ -85,6 +89,8 @@ function ls_theme_setup() { add_editor_style( 'assets/css/faq.css' ); add_editor_style( 'assets/css/links.css' ); add_editor_style( 'assets/css/button-secondary.css' ); + add_editor_style( 'assets/css/button-phase.css' ); + add_editor_style( 'assets/css/phase-journey-nav.css' ); add_editor_style( 'assets/css/featured-work.css' ); add_editor_style( 'assets/css/where-to-fit.css' ); add_editor_style( 'assets/css/homepage-cta.css' ); diff --git a/inc/animations.php b/inc/animations.php index 273e8e8..15480e8 100644 --- a/inc/animations.php +++ b/inc/animations.php @@ -71,6 +71,7 @@ function ls_theme_get_bundle_render_markers() { ), ), 'home-hero' => array( 'classes' => array( 'ls-home-hero-section' ) ), + 'phase-hero' => array( 'classes' => array( 'ls-phase-hero' ) ), 'services-hero' => array( 'classes' => array( 'ls-service-pill' ) ), 'services-linked-decisions' => array( 'classes' => array( 'ls-process-pill' ) ), 'services-service-clusters' => array( 'classes' => array( 'ls-cluster-tag' ) ), @@ -83,6 +84,8 @@ function ls_theme_get_bundle_render_markers() { 'blog-all-articles' => array( 'classes' => array( 'is-style-card-post', 'ls-post-card-cta' ) ), 'blog-writing-cta' => array( 'classes' => array( 'ls-writing-cta', 'ls-code-panel' ) ), 'button-secondary' => array( 'classes' => array( 'is-style-button-secondary' ) ), + 'button-phase' => array( 'classes' => array( 'is-style-button-phase-primary', 'is-style-button-phase-outline' ) ), + 'phase-journey-nav' => array( 'classes' => array( 'ls-phase-journey-nav' ) ), 'featured-work' => array( 'classes' => array( 'ls-featured-work-grid', 'ls-featured-work-card__divider' ) ), 'where-to-fit' => array( 'classes' => array( 'ls-package-card' ) ), 'homepage-cta' => array( 'classes' => array( 'ls-homepage-cta' ) ), @@ -283,6 +286,16 @@ function ls_theme_get_effect_styles( $context = 'front' ) { 'contexts' => array( 'front', 'editor' ), 'condition' => 'is_front_page', ), + 'phase-hero' => array( + 'handle' => 'ls-theme-phase-hero', + 'path' => 'assets/css/phase-hero.css', + 'contexts' => array( 'front', 'editor' ), + // Load early on all six phase pages; the render-marker fallback also covers + // this pattern when inserted on any other page. + 'condition' => static function () { + return is_page( array( 'discover', 'create', 'build', 'launch', 'grow', 'evolve' ) ); + }, + ), 'services-hero' => array( 'handle' => 'ls-theme-services-hero', 'path' => 'assets/css/services-hero.css', @@ -408,6 +421,29 @@ function ls_theme_get_effect_styles( $context = 'front' ) { return is_front_page() || is_post_type_archive( 'project' ) || is_404(); }, ), + 'button-phase' => array( + 'handle' => 'ls-theme-button-phase', + 'path' => 'assets/css/button-phase.css', + 'contexts' => array( 'front', 'editor' ), + // Fast path for its only known placement so far (the Discover hero and its CTAs). + // Also registered in ls_theme_get_bundle_render_markers() below so it still loads once + // this same button style is reused on the Create/Build/Launch/Grow/Evolve phase pages, + // without needing this condition updated first. + 'condition' => static function () { + return is_page( 'discover' ); + }, + ), + 'phase-journey-nav' => array( + 'handle' => 'ls-theme-phase-journey-nav', + 'path' => 'assets/css/phase-journey-nav.css', + 'contexts' => array( 'front', 'editor' ), + // Same reasoning as button-phase above: fast path for Discover today, plus the + // render_block fallback registered in ls_theme_get_bundle_render_markers() so it keeps + // working once this same pattern is reused on the other five phase pages. + 'condition' => static function () { + return is_page( 'discover' ); + }, + ), 'featured-work' => array( 'handle' => 'ls-theme-featured-work', 'path' => 'assets/css/featured-work.css', diff --git a/inc/phase-page-redirects.php b/inc/phase-page-redirects.php new file mode 100644 index 0000000..f746052 --- /dev/null +++ b/inc/phase-page-redirects.php @@ -0,0 +1,42 @@ +post_status ) { + wp_safe_redirect( get_permalink( $ls_target ), 301 ); + exit; + } +} +add_action( 'template_redirect', 'ls_theme_redirect_bare_phase_slugs', 0 ); diff --git a/package.json b/package.json index be8dee5..2ac8839 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,15 @@ "description": "LightSpeed Theme is a custom WordPress block theme built by LightSpeed for fast, accessible, maintainable websites using the WordPress Site Editor and block editor.", "type": "module", "scripts": { - "build:css": "sass --no-source-map --no-charset --style=compressed src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css src/scss/structural/image-captions.scss:assets/css/image-captions.css", - "build:css:dev": "sass --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css src/scss/structural/image-captions.scss:assets/css/image-captions.css", + "build:css": "sass --no-source-map --no-charset --style=compressed src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css src/scss/structural/image-captions.scss:assets/css/image-captions.css src/scss/structural/phase-hero.scss:assets/css/phase-hero.css src/scss/structural/button-phase.scss:assets/css/button-phase.css src/scss/structural/phase-journey-nav.scss:assets/css/phase-journey-nav.css", + "build:css:dev": "sass --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css src/scss/structural/image-captions.scss:assets/css/image-captions.css src/scss/structural/phase-hero.scss:assets/css/phase-hero.css src/scss/structural/button-phase.scss:assets/css/button-phase.css src/scss/structural/phase-journey-nav.scss:assets/css/phase-journey-nav.css", "schema:validate": "node theme-utils.mjs validate-schema", "theme:validate": "node theme-utils.mjs validate-theme", "patterns:escape": "node theme-utils.mjs escape-patterns", "security:scan": "node theme-utils.mjs security-scan", "lint": "npm run lint:json", "lint:json": "node --input-type=module --eval \"import { readFileSync } from 'fs'; import { glob } from 'glob'; const files = await glob(['theme.json', 'styles/**/*.json']); let ok = true; for (const f of files) { try { JSON.parse(readFileSync(f, 'utf8')); } catch (e) { console.error('Invalid JSON:', f, e.message); ok = false; } } if (ok) console.log('All JSON files are valid.'); else process.exit(1);\"", - "watch:css": "sass --watch --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css src/scss/structural/image-captions.scss:assets/css/image-captions.css" + "watch:css": "sass --watch --no-source-map --no-charset --style=expanded src/scss/animations.scss:assets/css/animations.css src/scss/gsap-animations.scss:assets/css/gsap-animations.css src/scss/structural/taxonomy-filter.scss:assets/css/taxonomy-filter.css src/scss/structural/work-project-card.scss:assets/css/work-project-card.css src/scss/structural/work-archive-sections.scss:assets/css/work-archive-sections.css src/scss/structural/card-shells.scss:assets/css/card-shells.css src/scss/structural/cta-buttons.scss:assets/css/cta-buttons.css src/scss/structural/home-hero.scss:assets/css/home-hero.css src/scss/structural/work-hero.scss:assets/css/work-hero.css src/scss/structural/work-single-hero.scss:assets/css/work-single-hero.css src/scss/structural/blog-hero.scss:assets/css/blog-hero.css src/scss/structural/blog-all-articles.scss:assets/css/blog-all-articles.css src/scss/structural/blog-writing-cta.scss:assets/css/blog-writing-cta.css src/scss/structural/faq.scss:assets/css/faq.css src/scss/structural/links.scss:assets/css/links.css src/scss/structural/button-secondary.scss:assets/css/button-secondary.css src/scss/structural/featured-work.scss:assets/css/featured-work.css src/scss/structural/where-to-fit.scss:assets/css/where-to-fit.css src/scss/structural/homepage-cta.scss:assets/css/homepage-cta.css src/scss/structural/stats-bar.scss:assets/css/stats-bar.css src/scss/structural/homepage-card-rows.scss:assets/css/homepage-card-rows.css src/scss/structural/homepage-why-lightspeed.scss:assets/css/homepage-why-lightspeed.css src/scss/structural/search-results.scss:assets/css/search-results.css src/scss/structural/search-hero.scss:assets/css/search-hero.css src/scss/structural/services-hero.scss:assets/css/services-hero.css src/scss/structural/services-linked-decisions.scss:assets/css/services-linked-decisions.css src/scss/structural/services-service-clusters.scss:assets/css/services-service-clusters.css src/scss/structural/services-service-tiles.scss:assets/css/services-service-tiles.css src/scss/structural/services-delivery-numbers.scss:assets/css/services-delivery-numbers.css src/scss/structural/corner-glow.scss:assets/css/corner-glow.css src/scss/structural/image-captions.scss:assets/css/image-captions.css src/scss/structural/phase-hero.scss:assets/css/phase-hero.css src/scss/structural/button-phase.scss:assets/css/button-phase.css src/scss/structural/phase-journey-nav.scss:assets/css/phase-journey-nav.css" }, "devDependencies": { "@axe-core/playwright": "^4.13.0", diff --git a/patterns/hero/phase-hero.php b/patterns/hero/phase-hero.php new file mode 100644 index 0000000..3970bf7 --- /dev/null +++ b/patterns/hero/phase-hero.php @@ -0,0 +1,100 @@ + + +
+ + + +
+ +
+ + + + +
+ + +
+ + + +

+ +
+ + + +
+ +

+ +
+ + + +
+ +

+ +
+ + + +

+ + + +
+ +
+ + + +
+ +
+ + + +
+ + + +
+ +
+ +
+ diff --git a/patterns/sections/phase-delivery-numbers.php b/patterns/sections/phase-delivery-numbers.php new file mode 100644 index 0000000..38783d2 --- /dev/null +++ b/patterns/sections/phase-delivery-numbers.php @@ -0,0 +1,94 @@ + '6', + 'suffix' => __( '+', 'ls-theme' ), + 'label' => __( 'Complex CMS migration types', 'ls-theme' ), + 'description' => __( 'WordPress, WooCommerce, Drupal, Shopify, custom CMS and bespoke stacks.', 'ls-theme' ), + ), + array( + 'value' => '120,000', + 'suffix' => __( '+', 'ls-theme' ), + 'label' => __( 'Legacy posts migrated', 'ls-theme' ), + 'description' => __( 'Audited, restructured and brought into a maintainable WordPress system.', 'ls-theme' ), + ), + array( + 'value' => '∞', + 'suffix' => '', + 'label' => __( 'Analysis speed', 'ls-theme' ), + 'description' => __( 'AI-assisted research lets us understand a platform in a fraction of the usual time.', 'ls-theme' ), + ), +); + +$ls_phase_stats_count = count( $ls_phase_stats ); +?> + +
+ + +
+ $ls_stat ) : + $ls_is_last_column = ( $ls_stat_index === $ls_phase_stats_count - 1 ); + ?> + + +
+ + +
+ + +
+ + +

+ + + +

+ + + +
+ +

+ +
+ +
+ +
+ + + +
+ +
+ diff --git a/patterns/sections/phase-introduction.php b/patterns/sections/phase-introduction.php new file mode 100644 index 0000000..f7915f9 --- /dev/null +++ b/patterns/sections/phase-introduction.php @@ -0,0 +1,74 @@ + + +
+ + +
+ + +
+ +

+ + + +

+ + + +

+ + + +

+ + + +

+ +
+ + + +
+ +

+ + + +

+ + + +

+ + + +

+ +
+ +
+ +
+ diff --git a/patterns/sections/phase-journey-nav.php b/patterns/sections/phase-journey-nav.php new file mode 100644 index 0000000..c0606f4 --- /dev/null +++ b/patterns/sections/phase-journey-nav.php @@ -0,0 +1,128 @@ +` reference block. WordPress's + * normal "click to insert from the pattern library" flow instead flattens a file-registered + * pattern into a static copy of whatever get_queried_object() resolved to at insertion time (which + * is frequently no page at all, e.g. inside the REST endpoint that serves the inserter panel) — + * baking in a permanently-wrong or permanently-blank active state that can never update again, + * confirmed empirically while building this page. Use the pattern/reference block, or the Insert + * Pattern flow if a future WP version changes this default, but verify the rendered HTML actually + * contains "is-active" before treating a phase page as done. + * Keywords: phase, journey, lifecycle, navigation, section + * Viewport Width: 1280 + * Inserter: true + * + * @package ls-theme + */ + +$ls_journey_phases = array( + array( + 'index' => '01', + 'label' => __( 'Discover', 'ls-theme' ), + 'phase' => 'discover', + 'url' => '/services/discover/', + ), + array( + 'index' => '02', + 'label' => __( 'Create', 'ls-theme' ), + 'phase' => 'create', + 'url' => '/services/create/', + ), + array( + 'index' => '03', + 'label' => __( 'Build', 'ls-theme' ), + 'phase' => 'build', + 'url' => '/services/build/', + ), + array( + 'index' => '04', + 'label' => __( 'Launch', 'ls-theme' ), + 'phase' => 'launch', + 'url' => '/services/launch/', + ), + array( + 'index' => '05', + 'label' => __( 'Grow', 'ls-theme' ), + 'phase' => 'grow', + 'url' => '/services/grow/', + ), + array( + 'index' => '06', + 'label' => __( 'Evolve', 'ls-theme' ), + 'phase' => 'evolve', + 'url' => '/services/evolve/', + ), +); + +$ls_journey_label = __( 'Journey phases', 'ls-theme' ); +$ls_current_phase_slug = ''; +$ls_queried_object = get_queried_object(); +if ( $ls_queried_object instanceof WP_Post ) { + $ls_current_phase_slug = $ls_queried_object->post_name; +} +?> + + + diff --git a/src/scss/animations/_button-motion.scss b/src/scss/animations/_button-motion.scss index c97f56c..1d32446 100644 --- a/src/scss/animations/_button-motion.scss +++ b/src/scss/animations/_button-motion.scss @@ -220,3 +220,66 @@ * transition above still applies (that's genuinely universal); the hover colour swap itself * lives in src/scss/structural/button-secondary.scss, its own standalone bundle. */ + +/* + * Button - Phase Primary / Button - Phase Outline (phase-page heroes/CTAs): transition timing and + * the arrow's animated transform only — the actual rest/hover colour, size and shape values live in + * src/scss/structural/button-phase.scss instead, since AGENTS.md restricts animation-folder files + * to @keyframes/transition/transform/animation/will-change rules (plus their reduced-motion + * companions) and nothing else, the same split already used for Button - Secondary + * (src/scss/structural/button-secondary.scss). Primary's arrow is a normal inline flex item after + * the label (gap-based spacing, declared in styles/blocks/buttons/button-phase-primary.json) with + * only a small hover nudge — an earlier version made it enter/exit via absolute positioning, which + * needed ever-larger padding just to keep it clear of the text and was reverted for exactly that + * reason (do not reintroduce it). Outline has no arrow, at rest or on hover — deliberately removed + * per explicit direction (it's the secondary, lower-emphasis CTA); do not extend Primary's arrow + * treatment to it. + */ +.wp-block-button.is-style-button-phase-primary, +.wp-block-button.is-style-button-phase-outline { + transition: border-radius var(--wp--custom--animation--duration--emphasised) + var(--wp--custom--animation--easing--emphasised); +} + +.wp-block-button.is-style-button-phase-primary .wp-block-button__link { + transition: border-radius var(--wp--custom--animation--duration--emphasised) + var(--wp--custom--animation--easing--emphasised); +} + +.wp-block-button.is-style-button-phase-outline .wp-block-button__link { + transition: border-radius var(--wp--custom--animation--duration--emphasised) + var(--wp--custom--animation--easing--emphasised), + 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); +} + +.wp-block-button.is-style-button-phase-primary .wp-block-button__link:hover::after, +.wp-block-button.is-style-button-phase-primary .wp-block-button__link:focus-visible::after { + transform: translateX(var(--wp--preset--spacing--5)); +} + +.wp-block-button.is-style-button-phase-primary .wp-block-button__link::after { + transition: transform var(--wp--custom--animation--duration--base) + var(--wp--custom--animation--easing--standard); +} + +// JSON limitation: pseudo-element transitions have no theme.json equivalent. +.wp-block-button.is-style-button-phase-outline .wp-block-button__link::before { + transition: transform var(--wp--custom--animation--duration--emphasised) + var(--wp--custom--animation--easing--emphasised), + opacity var(--wp--custom--animation--duration--base) + var(--wp--custom--animation--easing--standard); +} + +@media (prefers-reduced-motion: reduce) { + .wp-block-button.is-style-button-phase-primary, + .wp-block-button.is-style-button-phase-outline, + .wp-block-button.is-style-button-phase-primary .wp-block-button__link, + .wp-block-button.is-style-button-phase-outline .wp-block-button__link, + .wp-block-button.is-style-button-phase-primary .wp-block-button__link::after, + .wp-block-button.is-style-button-phase-outline .wp-block-button__link::before { + transition: none; + } +} diff --git a/src/scss/structural/button-phase.scss b/src/scss/structural/button-phase.scss new file mode 100644 index 0000000..a6f52f0 --- /dev/null +++ b/src/scss/structural/button-phase.scss @@ -0,0 +1,64 @@ +/********** Button - Phase Primary / Button - Phase Outline (phase-page heroes/CTAs) **********/ + +/* + * Rest-state shape and hover END-STATE values for the phase-hero button variants (Discover, and + * eventually Create/Build/Launch/Grow/Evolve) — not sitewide-exclusive/header-or-footer content, + * so per AGENTS.md this doesn't belong in assets/css/animations.css, and per its "Motion/animation + * files may contain only @keyframes/transition/transform/animation/will-change" restriction it + * doesn't belong in src/scss/animations/_button-motion.scss either, even though it's hover- + * triggered — only the transition timing and the arrow's animated transform live there; the actual + * colour/size/shape values being transitioned to live here, same split already used for + * Button - Secondary (src/scss/structural/button-secondary.scss). + */ +.wp-block-button.is-style-button-phase-primary, +.wp-block-button.is-style-button-phase-outline { + border-radius: var(--wp--preset--border-radius--500); +} + +.wp-block-button.is-style-button-phase-primary:hover, +.wp-block-button.is-style-button-phase-outline:hover { + border-radius: var(--wp--preset--border-radius--300); +} + +.wp-block-button.is-style-button-phase-primary .wp-block-button__link, +.wp-block-button.is-style-button-phase-outline .wp-block-button__link { + border-radius: inherit; +} + +.wp-block-button.is-style-button-phase-primary:hover .wp-block-button__link, +.wp-block-button.is-style-button-phase-outline:hover .wp-block-button__link { + border-radius: var(--wp--preset--border-radius--300); +} + +.wp-block-button.is-style-button-phase-outline:hover .wp-block-button__link { + color: var(--wp--custom--color--text--on-light); + border-color: transparent; +} + +/* + * Centre-out circle reveal (outline only — see button-phase-outline.json for why the primary, + * always-filled button can't use this). Rest state is invisible and pinned to the button's centre; + * its square uses the larger button dimension, then scales beyond the diagonal to cover + * every corner. Its layout size stays constant throughout the transform/opacity transition. + */ +// JSON limitation: pseudo-element geometry and transforms have no theme.json equivalent. +.wp-block-button.is-style-button-phase-outline .wp-block-button__link::before { + content: ""; + position: absolute; + top: 50%; + left: 50%; + min-width: 100%; + min-height: 100%; + aspect-ratio: 1; + transform: translate(-50%, -50%) scale(0); + border-radius: 50%; + background-color: var(--wp--custom--color--phase--discover-on-dark); + opacity: 0; + z-index: -1; +} + +// JSON limitation: parent hover targeting a pseudo-element has no theme.json equivalent. +.wp-block-button.is-style-button-phase-outline:hover .wp-block-button__link::before { + transform: translate(-50%, -50%) scale(1.42); + opacity: 1; +} diff --git a/src/scss/structural/phase-hero.scss b/src/scss/structural/phase-hero.scss new file mode 100644 index 0000000..6b6b43f --- /dev/null +++ b/src/scss/structural/phase-hero.scss @@ -0,0 +1,79 @@ +/********** Discover Hero (Discover phase page only) **********/ + +/* + * Discover Hero background: a faint 32px crossed-gradient grid (same technique as + * .ls-card-banner-tint in src/scss/structural/work-project-card.scss — two 1px linear-gradients, + * one per axis, repeated) layered over a soft radial phase-colour glow behind the upper-middle + * content, over the same permanently-dark band-start/band-end diagonal base already used by + * src/scss/structural/blog-hero.scss. Combined into one background-image list rather than left as + * the block's own inline color.gradient attribute, for the same reason documented in + * blog-hero.scss: an inline `style="background:..."` always wins the cascade over any external + * stylesheet's background-image, so the two can't coexist on this block. + * + * Hardwired to phase.discover-on-dark rather than a CSS custom property — this file only needs to + * serve the Discover hero today. When Create/Build/Launch/Grow/Evolve heroes are built, either + * duplicate this file per phase (fast, proven-safe) or generalise it to a shared --ls-phase-accent + * custom property at that point, once it's clear which is actually needed — not guessed now. + */ +.ls-phase-hero { + position: relative; + overflow: hidden; + background-image: + linear-gradient(color-mix(in srgb, var(--wp--custom--color--text--on-dark) 2%, transparent) 1px, transparent 1px), + linear-gradient(90deg, color-mix(in srgb, var(--wp--custom--color--text--on-dark) 2%, transparent) 1px, transparent 1px), + radial-gradient(60% 50% at 50% 22%, color-mix(in srgb, var(--wp--custom--color--phase--discover-on-dark) 14%, transparent) 0%, transparent 70%), + linear-gradient(158deg, var(--wp--custom--color--surface--band-start) 0%, var(--wp--custom--color--surface--band-end) 100%); + background-position: 0 0, 0 0, 0 0, 0 0; + background-repeat: repeat, repeat, no-repeat, no-repeat; + background-size: 32px 32px, 32px 32px, auto, auto; +} + +/* + * Breadcrumb (Discover Hero): reuses the existing .ls-breadcrumbs-on-dark class name from + * blog-hero.php, but NOT its `a` colour fix — that rule lives in blog-hero.scss/blog-hero.css, + * which is only enqueued on the Blog archive template (see the is_page_template() condition in + * inc/animations.php's ls_theme_get_effect_styles()), so it never loads on this page at all. Left + * unstyled, "Home" fell back to the sitewide global link colour (bright cyan in the active dark + * style variation) instead of a muted grey. The fix below is scoped to `.ls-phase-hero` — this + * file's own already-page-scoped selector — so it can never affect the Blog archive's identical + * class name or any other page. + */ +.ls-phase-hero .ls-breadcrumbs-on-dark a { + color: var(--wp--custom--color--text--on-dark-muted); +} + +.ls-phase-hero .breadcrumb_last { + color: var(--wp--custom--color--phase--discover-on-dark); +} + +/* + * "Send to a friend" (Discover Hero): rest-state background/border colour moved here from + * phase-hero.php's inline block attributes, specifically so the hover swap below can work at + * all — an inline `style="background-color:...;border-color:..."` always wins the cascade over + * any external stylesheet rule for the same property (same class of bug documented in + * blog-hero.scss), so a `:hover` rule here could never have overridden an inline rest colour. + * Border width/style/radius and spacing stay as inline block attributes; only the two colours that + * need a hover state moved out. Kept deliberately quiet — a touch more border/background opacity + * only, no motion/transform — since this control is meant to stay lower-priority than the CTAs + * above it. + */ +.ls-phase-hero__share { + background-color: color-mix(in srgb, var(--wp--custom--color--text--on-dark) 5%, transparent); + border-color: color-mix(in srgb, var(--wp--custom--color--text--on-dark) 8%, transparent); + 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); +} + +.ls-phase-hero__share:hover, +.ls-phase-hero__share:focus-within { + background-color: color-mix(in srgb, var(--wp--custom--color--text--on-dark) 9%, transparent); + border-color: color-mix(in srgb, var(--wp--custom--color--text--on-dark) 16%, transparent); +} + +@media (prefers-reduced-motion: reduce) { + .ls-phase-hero__share { + transition: none; + } +} diff --git a/src/scss/structural/phase-journey-nav.scss b/src/scss/structural/phase-journey-nav.scss new file mode 100644 index 0000000..59cab9c --- /dev/null +++ b/src/scss/structural/phase-journey-nav.scss @@ -0,0 +1,117 @@ +/********** Section - Phase Journey Nav (phase-page heroes' journey bar) **********/ + +/* + * Inactive / hover / active / hover-active / focus-visible states for the six phase links. + * Rest-state box model (padding, dividers, background) lives as inline block attributes in + * phase-journey-nav.php; this file owns only the parts that need a pseudo-class, since a bare + * :hover/:focus-visible in a style JSON's css field is silently stripped by WordPress, and an + * inline `style="color:..."` on the link would always win the cascade over any external :hover + * rule for the same property (same class of bug already documented for the hero's "Send to a + * friend" control) — so `color` is left for this file to own entirely. + * + * The `--ls-phase-item-accent` custom property is set here, per phase, via each step's + * `ls-phase-journey-nav__step--{phase}` modifier class, rather than as an inline custom property + * on the block itself: a raw CSS custom property has no equivalent in core/group's declared style + * attributes, so WordPress's block validator has no way to reconstruct it and always flags the + * block as invalid ("Attempt Recovery") the moment it's parsed back into editable blocks. Setting + * it from a plain className instead keeps the block's own style attribute limited to properties + * WordPress actually knows how to round-trip. + * + * Not sitewide-exclusive/header-or-footer content, so per AGENTS.md this doesn't belong in + * assets/css/animations.css even though a couple of these rules include a transition — that + * restriction is specific to the src/scss/animations/** folder, not to structural files in + * general (same reasoning already applied to button-phase.scss). + */ +.ls-phase-journey-nav__step--discover { + --ls-phase-item-accent: var(--wp--custom--color--phase--discover-on-dark, var(--wp--custom--color--phase--discover)); +} + +.ls-phase-journey-nav__step--create { + --ls-phase-item-accent: var(--wp--custom--color--phase--create-on-dark, var(--wp--custom--color--phase--create)); +} + +.ls-phase-journey-nav__step--build { + --ls-phase-item-accent: var(--wp--custom--color--phase--build-on-dark, var(--wp--custom--color--phase--build)); +} + +.ls-phase-journey-nav__step--launch { + --ls-phase-item-accent: var(--wp--custom--color--phase--launch-on-dark, var(--wp--custom--color--phase--launch)); +} + +.ls-phase-journey-nav__step--grow { + --ls-phase-item-accent: var(--wp--custom--color--phase--grow-on-dark, var(--wp--custom--color--phase--grow)); +} + +.ls-phase-journey-nav__step--evolve { + --ls-phase-item-accent: var(--wp--custom--color--phase--evolve-on-dark, var(--wp--custom--color--phase--evolve)); +} + +.ls-phase-journey-nav__link a { + transition: color var(--wp--custom--animation--duration--base) + var(--wp--custom--animation--easing--standard); +} + +// JSON limitation: selecting inactive steps via :not(.is-active) has no theme.json equivalent. +.ls-phase-journey-nav__step:not(.is-active) .ls-phase-journey-nav__link a { + color: var(--wp--custom--color--text--on-dark-muted); +} + +/* Inactive hover/focus: brighter and clearly interactive — never the active phase colour, never the dot. */ +.ls-phase-journey-nav__step:not(.is-active) .ls-phase-journey-nav__link a:hover, +.ls-phase-journey-nav__step:not(.is-active) .ls-phase-journey-nav__link a:focus-visible { + color: var(--wp--custom--color--text--on-dark); +} + +/* Active (rest): the current phase's own accent colour, passed down per item as a custom property. */ +.ls-phase-journey-nav__step.is-active .ls-phase-journey-nav__link a { + color: var(--ls-phase-item-accent); +} + +/* + * Active hover/focus: text lightens to the same "on-dark" white used for inactive hover, but the + * dot (a separate icon element, styled independently) is untouched by this rule and keeps reading + * in the phase colour — preserving "this is still the current page" rather than looking like a + * plain hovered-inactive item. + */ +.ls-phase-journey-nav__step.is-active .ls-phase-journey-nav__link a:hover, +.ls-phase-journey-nav__step.is-active .ls-phase-journey-nav__link a:focus-visible { + color: var(--wp--custom--color--text--on-dark); +} + +/* + * Focus-visible outline: uses text.on-dark rather than the sitewide focus.ring token, which + * resolves to a near-black colour in the light style variation — invisible against this + * permanently-dark bar. Same "on-dark family" reasoning already used throughout this component. + */ +.ls-phase-journey-nav__link a:focus-visible { + outline: 2px solid var(--wp--custom--color--text--on-dark); + outline-offset: 3px; + border-radius: var(--wp--preset--border-radius--100); +} + +@media (prefers-reduced-motion: reduce) { + .ls-phase-journey-nav__link a { + transition: none; + } +} + +/* + * Responsive: six phase links plus the "Journey Phases" label don't fit a narrow viewport without + * either wrapping onto multiple messy lines or shrinking illegibly. A horizontal scroll strip + * keeps every item on one line, in order, and still usable — preferred over awkward wrapping. + */ +@media (max-width: 781px) { + .ls-phase-journey-nav__items { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + } + + .ls-phase-journey-nav__items::-webkit-scrollbar { + display: none; + } + + .ls-phase-journey-nav__step { + flex-shrink: 0; + } +} diff --git a/styles/blocks/buttons/button-phase-outline.json b/styles/blocks/buttons/button-phase-outline.json new file mode 100644 index 0000000..a6076e5 --- /dev/null +++ b/styles/blocks/buttons/button-phase-outline.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Button - Phase Outline", + "slug": "button-phase-outline", + "blockTypes": [ + "core/button" + ], + "description": "Outline pill CTA pairing Button - Phase Primary on the phase-page heroes and CTAs. Uses the exact same horizontal padding token (spacing|40) as Button - Phase Primary so both buttons share one spacing system — this one simply reads wider because its label is longer, not because of a mismatched padding scale. Rest state: transparent background, thin phase-colour border, phase-colour text, no arrow glyph — deliberately arrow-free (this is the secondary/lower-emphasis action; only Primary carries an arrow). On hover: a centre-out circle reveal (adapted from the 'Flow Button' component, https://21st.dev/@xubohuah/components/flow-button) fills the button, the border fades to transparent, text flips to a contrasting colour, and the corners tighten slightly — none of that depends on an arrow, so it works cleanly without one. All hover-dependent CSS lives in src/scss/animations/_button-motion.scss, since a bare :hover in a style JSON's css field is silently stripped by WordPress. Same on-dark-constant reasoning and 'hardwired to Discover for now' note as button-phase-primary.json.", + "styles": { + "color": { + "background": "transparent", + "text": "var:custom|color|phase|discover-on-dark" + }, + "border": { + "color": "var:custom|color|phase|discover-on-dark", + "radius": "var:preset|border-radius|500", + "style": "solid", + "width": "1px" + }, + "spacing": { + "padding": { + "top": "var:preset|spacing|20", + "right": "var:preset|spacing|40", + "bottom": "var:preset|spacing|20", + "left": "var:preset|spacing|40" + } + }, + "typography": { + "fontSize": "var:preset|font-size|200", + "fontWeight": "var:custom|typography|font-weight|semibold", + "letterSpacing": "normal" + }, + "css": "&{display:inline-flex;align-items:center;position:relative;overflow:hidden;}" + } +} diff --git a/styles/blocks/buttons/button-phase-primary.json b/styles/blocks/buttons/button-phase-primary.json new file mode 100644 index 0000000..a7ec53a --- /dev/null +++ b/styles/blocks/buttons/button-phase-primary.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.9/theme.json", + "version": 3, + "title": "Button - Phase Primary", + "slug": "button-phase-primary", + "blockTypes": [ + "core/button" + ], + "description": "Pill CTA for the phase-page heroes and CTAs (Discover, and eventually Create/Build/Launch/Grow/Evolve). Background/text stay constant across the light/dark style variation toggle, matching the on-dark token family — the hero itself is permanently dark, so this can't use the sitewide button.fill tokens, which flip colour with the variation. Stays filled at all times (approved design decision). Uses the exact same horizontal padding token (spacing|40) as Button - Phase Outline so both buttons share one spacing system and only their content — not an artificial equal-width rule — determines each one's width. The arrow is a normal inline flex item after the label (gap-based spacing, not an absolutely-positioned overlay) with a small hover nudge; earlier attempts at an absolutely-positioned enter/exit arrow swap needed ever-larger padding just to keep the arrow clear of the text and were reverted for exactly that reason — do not reintroduce that approach. Border-radius tightens slightly on hover, matching Button - Phase Outline's own hover treatment. Rest state (colour, shape, arrow glyph) lives here; the hover states live in src/scss/animations/_button-motion.scss, since a bare :hover in a style JSON's css field is silently stripped by WordPress. Currently hardwired to phase.discover-on-dark rather than a CSS custom property — narrowed to what Discover actually needs now; generalise to a shared --ls-button-phase-accent custom property (set by whichever hero uses it) once a second phase page needs this same style, rather than guessing at that shape today.", + "styles": { + "color": { + "background": "var:custom|color|phase|discover-on-dark", + "text": "var:custom|color|text|on-light" + }, + "border": { + "radius": "var:preset|border-radius|500", + "style": "none", + "width": "0" + }, + "spacing": { + "padding": { + "top": "var:preset|spacing|20", + "right": "var:preset|spacing|40", + "bottom": "var:preset|spacing|20", + "left": "var:preset|spacing|40" + } + }, + "typography": { + "fontSize": "var:preset|font-size|200", + "fontWeight": "var:custom|typography|font-weight|semibold", + "letterSpacing": "normal" + }, + "css": "&{display:inline-flex;align-items:center;justify-content:center;gap:var(--wp--preset--spacing--10);}\n\n&::after{content:\"\\2192\";display:inline-block;}" + } +} diff --git a/styles/dark.json b/styles/dark.json index ad49919..824dc54 100644 --- a/styles/dark.json +++ b/styles/dark.json @@ -73,6 +73,7 @@ }, "phase": { "discover": "var:preset|color|phase-one", + "discover-on-dark": "var:preset|color|phase-one", "create": "var:preset|color|phase-two", "build": "var:preset|color|phase-three", "launch": "var:preset|color|phase-four", diff --git a/styles/presets/typography.json b/styles/presets/typography.json index 394a1a1..60c883b 100644 --- a/styles/presets/typography.json +++ b/styles/presets/typography.json @@ -279,6 +279,7 @@ }, "custom": { "line-height": { + "heading-tight": "0.95", "heading-snug": "1.1", "heading-default": "1.25", "heading-loose": "1.35", diff --git a/theme.json b/theme.json index 6a29b81..674f5a6 100644 --- a/theme.json +++ b/theme.json @@ -573,6 +573,7 @@ }, "phase": { "discover": "var:preset|color|phase-one-strong", + "discover-on-dark": "var:preset|color|phase-one", "create": "var:preset|color|phase-two-strong", "build": "var:preset|color|phase-three-strong", "launch": "var:preset|color|phase-four-strong",