diff --git a/website/app.js b/website/app.js index 8d90ea6a..16225750 100644 --- a/website/app.js +++ b/website/app.js @@ -114,6 +114,7 @@ function createAposConfig() { 'contact-widget': {}, 'page-intro-widget': {}, 'whitespace-widget': {}, + 'big-block-widget': {}, /* * 'links-buttons-widget': {}, * 'team-carousel-widget': {}, diff --git a/website/lib/mainWidgets.js b/website/lib/mainWidgets.js index e73b9a7c..d7317aa9 100644 --- a/website/lib/mainWidgets.js +++ b/website/lib/mainWidgets.js @@ -16,6 +16,7 @@ module.exports = { 'buttons': {}, 'whitespace': {}, 'container': {}, + 'big-block': {}, '@apostrophecms/rich-text': { ...headingToolbar, }, diff --git a/website/modules/asset/ui/src/index.scss b/website/modules/asset/ui/src/index.scss index 53bac250..bea3e0b5 100644 --- a/website/modules/asset/ui/src/index.scss +++ b/website/modules/asset/ui/src/index.scss @@ -28,3 +28,4 @@ @import './scss/_vacancies'; @import './scss/search'; @import './scss/_animation'; +@import './scss/_big-block-widget'; diff --git a/website/modules/asset/ui/src/scss/_big-block-widget.scss b/website/modules/asset/ui/src/scss/_big-block-widget.scss new file mode 100644 index 00000000..12f9ac9a --- /dev/null +++ b/website/modules/asset/ui/src/scss/_big-block-widget.scss @@ -0,0 +1,545 @@ +/* Big Block Widget Styles - Based on Figma Design Tokens */ +/* Centered, polished layout using the S&F design system */ + +.sf-big-block-widget { + background: linear-gradient(135deg, #FFFFFF 0%, #F8F9FA 25%, #EFF5FF 50%, #F0F9F8 75%, #FFFFFF 100%); + color: #040406; + font-family: 'Poppins', sans-serif; + padding: 120px 100px; + line-height: 1.5; + text-align: center; + position: relative; + overflow: hidden; + border-radius: 24px; + opacity: 0; + transform: translateY(20px); + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 20% 50%, rgba(1, 115, 215, 0.06) 0%, transparent 50%), + radial-gradient(circle at 80% 80%, rgba(0, 168, 150, 0.05) 0%, transparent 50%), + radial-gradient(circle at 50% 0%, rgba(50, 155, 255, 0.04) 0%, transparent 50%); + pointer-events: none; + z-index: 0; + } +} + +.sf-big-block-widget__container { + max-width: 1100px; + margin: 0 auto; + position: relative; + z-index: 2; +} + +/* Shared eyebrow / section label */ +.sf-big-block-widget__eyebrow, +.sf-big-block-widget__section-label { + display: inline-flex; + align-items: center; + gap: 10px; + font-family: 'Poppins', sans-serif; + font-weight: 600; + font-size: 12px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: #828388; + margin: 0 0 28px 0; + padding: 8px 16px; + border: 1px solid #DEDFE4; + border-radius: 999px; + background-color: #FFFFFF; +} + +.sf-big-block-widget__pulse { + width: 8px; + height: 8px; + min-width: 8px; + min-height: 8px; + max-width: 8px; + max-height: 8px; + border-radius: 50%; + background-color: #22C55F; /* Changed from red to green for more positive feel */ + box-shadow: 0 0 0 0 rgba(34, 197, 95, 0.5); + animation: sf-big-block-pulse 2s infinite; + flex-shrink: 0; +} + +@keyframes sf-big-block-pulse { + 0% { box-shadow: 0 0 0 0 rgba(34, 197, 95, 0.5); } + 70% { box-shadow: 0 0 0 10px rgba(34, 197, 95, 0); } + 100% { box-shadow: 0 0 0 0 rgba(34, 197, 95, 0); } +} + +/* Hero Section */ +.sf-big-block-widget__hero { + margin-bottom: 32px; + padding: 0 0 80px; + position: relative; + z-index: 2; +} + +.sf-big-block-widget__hero-title { + font-family: 'Poppins', sans-serif !important; + font-weight: 800 !important; + font-size: 65px !important; + line-height: 1.15 !important; + color: #040406 !important; + margin: 0 auto 48px !important; + max-width: 1100px !important; + letter-spacing: -0.04em !important; + position: relative; + z-index: 2; + word-spacing: 0.1em; +} + +.sf-big-block-widget__hero-line { + display: block; +} + +.sf-big-block-widget__hero-accent { + background: linear-gradient(135deg, #0173D7 0%, #329BFF 50%, #00A896 100%); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + color: transparent; + position: relative; + z-index: 2; + display: inline-block; + font-weight: 800; + animation: sf-big-block-gradient-pulse 3s ease-in-out infinite; +} + +@keyframes sf-big-block-gradient-pulse { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.85; + } +} + +.sf-big-block-widget__cta { + display: inline-block; + font-family: 'Poppins', sans-serif; + font-weight: 700; + font-size: 18px; + color: #040406; + text-decoration: none; + border-bottom: 2px solid #040406; + padding-bottom: 6px; + transition: color 0.3s ease, border-color 0.3s ease, transform 0.2s ease; + position: relative; + animation: sf-big-block-cta-float 3s ease-in-out infinite; + + &:hover { + color: #329BFF; + border-color: #329BFF; + transform: translateY(-2px); + animation: none; + } +} + +@keyframes sf-big-block-cta-float { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-4px); + } +} + +/* Body Section */ +.sf-big-block-widget__body { + margin: 0 auto 120px; + max-width: 760px; + position: relative; + z-index: 2; +} + +.sf-big-block-widget__intro { + font-family: 'Poppins', sans-serif; + font-weight: 400; + font-size: 22px; + line-height: 1.6; + color: #040406; + margin: 0 0 28px 0; + + & + .sf-big-block-widget__intro { + margin-top: 0; + } +} + +.sf-big-block-widget__intro-line { + display: block; +} + +.sf-big-block-widget__description { + font-family: 'Poppins', sans-serif; + font-weight: 500; + font-size: 20px; + line-height: 1.6; + color: #828388; + margin: 0; +} + +/* Purpose Built Section */ +.sf-big-block-widget__purpose { + margin: 0 auto 120px; + padding: 80px 60px; + border: 1px solid rgba(222, 223, 228, 0.8); + border-radius: 20px; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(239, 245, 255, 0.8) 50%, rgba(240, 249, 248, 0.8) 100%); + backdrop-filter: blur(10px); + max-width: 1000px; + position: relative; + z-index: 2; + box-shadow: 0 8px 32px rgba(1, 115, 215, 0.08); + + &::before { + content: ''; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 80px; + height: 4px; + background: linear-gradient(90deg, #0173D7 0%, #329BFF 50%, #00A896 100%); + border-radius: 0 0 4px 4px; + z-index: 3; + } +} + +.sf-big-block-widget__purpose-title { + font-family: 'Poppins', sans-serif; + font-weight: 700; + font-size: 48px; + line-height: 1.2; + color: #040406; + margin: 0 0 32px 0; + letter-spacing: -0.02em; +} + +.sf-big-block-widget__purpose-text { + font-family: 'Poppins', sans-serif; + font-weight: 500; + font-size: 24px; + line-height: 1.5; + color: #040406; + margin: 0 auto 24px; + max-width: 680px; +} + +.sf-big-block-widget__purpose-description { + font-family: 'Poppins', sans-serif; + font-weight: 400; + font-size: 20px; + line-height: 1.6; + color: #828388; + margin: 0 auto 24px; + max-width: 680px; +} + +.sf-big-block-widget__purpose-footer { + font-family: 'Poppins', sans-serif; + font-weight: 600; + font-size: 20px; + line-height: 1.6; + color: #040406; + margin: 0 auto; + max-width: 680px; +} + +/* Testimonials Section */ +.sf-big-block-widget__testimonials { + margin-bottom: 120px; + position: relative; + z-index: 2; +} + +.sf-big-block-widget__testimonials-title { + font-family: 'Poppins', sans-serif; + font-weight: 700; + font-size: 36px; + line-height: 1.3; + color: #040406; + margin: 0 0 64px 0; + letter-spacing: -0.01em; +} + +.sf-big-block-widget__testimonial-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 32px; +} + +.sf-big-block-widget__testimonial { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.98) 0%, rgba(248, 249, 250, 0.95) 100%); + padding: 36px 32px; + border-radius: 16px; + border: 1px solid rgba(222, 223, 228, 0.6); + text-align: left; + transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease, background 0.25s ease; + position: relative; + backdrop-filter: blur(8px); + + &::before { + content: '\201C'; + position: absolute; + top: 8px; + right: 16px; + font-family: 'Poppins', sans-serif; + font-weight: 700; + font-size: 64px; + line-height: 1; + background: linear-gradient(135deg, #0173D7 0%, #329BFF 100%); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + color: transparent; + pointer-events: none; + opacity: 0.3; + z-index: 0; + } + + &:hover { + transform: translateY(-6px); + box-shadow: 0 16px 40px rgba(1, 115, 215, 0.12); + border-color: rgba(1, 115, 215, 0.3); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.99) 0%, rgba(239, 245, 255, 0.9) 100%); + } +} + +.sf-big-block-widget__testimonial-text { + font-family: 'Poppins', sans-serif; + font-weight: 400; + font-size: 16px; + line-height: 1.65; + color: #232429; + margin: 0 0 28px 0; + font-style: italic; + position: relative; + z-index: 1; +} + +.sf-big-block-widget__testimonial-author { + border-top: 1px solid #DEDFE4; + padding-top: 18px; + text-align: left; +} + +.sf-big-block-widget__testimonial-name { + font-family: 'Poppins', sans-serif; + font-weight: 700; + font-size: 16px; + line-height: 1.4; + color: #040406; + margin: 0 0 4px 0; +} + +.sf-big-block-widget__testimonial-title { + font-family: 'Poppins', sans-serif; + font-weight: 500; + font-size: 14px; + line-height: 1.4; + color: #828388; + margin: 0 0 4px 0; +} + +.sf-big-block-widget__testimonial-company { + font-family: 'Poppins', sans-serif; + font-weight: 500; + font-size: 14px; + line-height: 1.4; + color: #828388; + margin: 0 0 4px 0; +} + +.sf-big-block-widget__testimonial-url { + font-family: 'Poppins', sans-serif; + font-weight: 400; + font-size: 13px; + line-height: 1.4; + color: #329BFF; + margin: 0; + text-decoration: none; + + &:hover { + text-decoration: underline; + } +} + +/* Final CTA Section */ +.sf-big-block-widget__final-cta { + text-align: center; + padding: 80px 60px; + background: linear-gradient(135deg, #0173D7 0%, #329BFF 30%, #00A896 70%, #50E4D2 100%); + border-radius: 20px; + color: #FFFFFF; + position: relative; + overflow: hidden; + z-index: 2; + box-shadow: 0 20px 60px rgba(1, 115, 215, 0.25); + + &::before { + content: ''; + position: absolute; + top: -50%; + right: -20%; + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%); + pointer-events: none; + z-index: 1; + } + + &::after { + content: ''; + position: absolute; + bottom: -50%; + left: -20%; + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%); + pointer-events: none; + z-index: 1; + } +} + +.sf-big-block-widget__final-cta-label { + display: inline-block; + font-family: 'Poppins', sans-serif; + font-weight: 600; + font-size: 12px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.85); + margin: 0 0 20px 0; + padding: 6px 14px; + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 999px; + position: relative; + z-index: 1; +} + +.sf-big-block-widget__final-cta-title { + font-family: 'Poppins', sans-serif; + font-weight: 700; + font-size: 40px; + line-height: 1.2; + color: #FFFFFF; + margin: 0 0 36px 0; + letter-spacing: -0.01em; + position: relative; + z-index: 1; +} + +.sf-big-block-widget__final-cta-button { + display: inline-block; + font-family: 'Poppins', sans-serif; + font-weight: 600; + font-size: 18px; + color: #040406; + background-color: #FFFFFF; + text-decoration: none; + padding: 18px 40px; + border-radius: 999px; + transition: transform 0.2s ease, box-shadow 0.25s ease; + position: relative; + z-index: 1; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 12px 28px rgba(0, 0, 0, 0.2); + } +} + +/* Responsive Design */ +@media (max-width: 1024px) { + .sf-big-block-widget { + padding: 80px 40px; + } + + .sf-big-block-widget__hero-title { + font-size: 40px !important; + } + + .sf-big-block-widget__purpose { + padding: 60px 32px; + } + + .sf-big-block-widget__purpose-title { + font-size: 36px; + } + + .sf-big-block-widget__testimonial-grid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .sf-big-block-widget { + padding: 56px 12px; + } + + .sf-big-block-widget__container { + max-width: 100%; + } + + .sf-big-block-widget__hero { + margin-bottom: 24px; + padding: 0 0 48px; + } + + .sf-big-block-widget__hero-title { + font-size: 28px !important; + } + + .sf-big-block-widget__intro { + font-size: 18px; + } + + .sf-big-block-widget__description { + font-size: 17px; + } + + .sf-big-block-widget__purpose { + padding: 48px 24px; + margin-bottom: 80px; + } + + .sf-big-block-widget__purpose-title { + font-size: 28px; + } + + .sf-big-block-widget__purpose-text { + font-size: 20px; + } + + .sf-big-block-widget__testimonials-title { + font-size: 28px; + margin-bottom: 40px; + } + + .sf-big-block-widget__testimonial { + padding: 28px 32px 28px 24px; + } + + .sf-big-block-widget__final-cta { + padding: 56px 24px; + } + + .sf-big-block-widget__final-cta-title { + font-size: 28px; + } + + .sf-big-block-widget__final-cta-button { + font-size: 16px; + padding: 14px 30px; + } +} diff --git a/website/modules/big-block-widget/index.js b/website/modules/big-block-widget/index.js new file mode 100644 index 00000000..f6e9bb78 --- /dev/null +++ b/website/modules/big-block-widget/index.js @@ -0,0 +1,18 @@ +module.exports = { + extend: '@apostrophecms/widget-type', + options: { + label: 'Test Big Block', + icon: 'dots-vertical-icon', + className: 'sf-big-block-widget', + styles: true, + scripts: [ + { + name: 'big-block-animations', + source: 'ui/src/index.js', + }, + ], + }, + fields: { + // No fields - content is hardcoded in template + }, +}; diff --git a/website/modules/big-block-widget/ui/src/index.js b/website/modules/big-block-widget/ui/src/index.js new file mode 100644 index 00000000..088a0905 --- /dev/null +++ b/website/modules/big-block-widget/ui/src/index.js @@ -0,0 +1,153 @@ +import { ScrollTrigger } from 'gsap/ScrollTrigger'; +// eslint-disable-next-line import/no-named-as-default +import gsap from 'gsap'; + +gsap.registerPlugin(ScrollTrigger); + +const animateWidget = (widget) => { + // Animate the main widget container on scroll + gsap.to(widget, { + scrollTrigger: { + trigger: widget, + start: 'top 80%', + end: 'top 20%', + toggleActions: 'play none none reverse', + }, + opacity: 1, + // eslint-disable-next-line id-length + y: 0, + duration: 0.8, + ease: 'power2.out', + }); +}; + +const animateHeroLines = (widget) => { + const heroLines = widget.querySelectorAll('.sf-big-block-widget__hero-line'); + if (heroLines.length) { + gsap.from(heroLines, { + scrollTrigger: { + trigger: widget, + start: 'top 80%', + }, + opacity: 0, + // eslint-disable-next-line id-length + y: 20, + duration: 0.7, + stagger: 0.15, + ease: 'power2.out', + }); + } +}; + +const animateCta = (widget) => { + const cta = widget.querySelector('.sf-big-block-widget__cta'); + if (cta) { + gsap.from(cta, { + scrollTrigger: { + trigger: widget, + start: 'top 80%', + }, + opacity: 0, + // eslint-disable-next-line id-length + y: 20, + duration: 0.8, + delay: 0.2, + ease: 'power2.out', + }); + + // Add hover animation to CTA + cta.addEventListener('mouseenter', () => { + gsap.to(cta, { + scale: 1.05, + duration: 0.3, + ease: 'power2.out', + }); + }); + + cta.addEventListener('mouseleave', () => { + gsap.to(cta, { + scale: 1, + duration: 0.3, + ease: 'power2.out', + }); + }); + } +}; + +const animateBodyText = (widget) => { + const introText = widget.querySelector('.sf-big-block-widget__intro'); + if (introText) { + gsap.from(introText, { + scrollTrigger: { + trigger: widget, + start: 'top 80%', + }, + opacity: 0, + // eslint-disable-next-line id-length + y: 20, + duration: 0.8, + delay: 0.3, + ease: 'power2.out', + }); + } +}; + +const animateTestimonials = (widget) => { + const testimonials = widget.querySelectorAll( + '.sf-big-block-widget__testimonial', + ); + if (testimonials.length) { + gsap.from(testimonials, { + scrollTrigger: { + trigger: widget, + start: 'top 60%', + }, + opacity: 0, + // eslint-disable-next-line id-length + y: 30, + duration: 0.8, + stagger: 0.15, + ease: 'power2.out', + }); + } +}; + +const animateFinalCta = (widget) => { + const finalCta = widget.querySelector('.sf-big-block-widget__final-cta'); + if (finalCta) { + gsap.from(finalCta, { + scrollTrigger: { + trigger: finalCta, + start: 'top 80%', + }, + opacity: 0, + // eslint-disable-next-line id-length + y: 30, + duration: 0.8, + ease: 'power2.out', + }); + } +}; + +const initBigBlockWidget = () => { + const widgets = document.querySelectorAll('.sf-big-block-widget'); + + widgets.forEach((widget) => { + animateWidget(widget); + animateHeroLines(widget); + animateCta(widget); + animateBodyText(widget); + animateTestimonials(widget); + animateFinalCta(widget); + }); +}; + +// Default export function required by ApostropheCMS +export default () => { + // Initialize when DOM is ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initBigBlockWidget); + } else { + initBigBlockWidget(); + } +}; diff --git a/website/modules/big-block-widget/views/widget.html b/website/modules/big-block-widget/views/widget.html new file mode 100644 index 00000000..03a967f0 --- /dev/null +++ b/website/modules/big-block-widget/views/widget.html @@ -0,0 +1,148 @@ +
+
+ +
+ Let's build something great together +

+ You need software + that can handle + + complexity — + in the tech and in the team. + +

+ + Let's explore what that could look like → + +
+ + +
+

+ Most software projects don't fail because the tech is wrong. + They fail because complexity is underestimated, and the human side of the work is left unsupported. +

+

+ That's why we design systems that evolve with your mission and the people building it with you. +

+
+ + +
+ +

+ Purpose-built software
+ for meaningful change +

+

+ You have a bold vision for impact. We build software that moves that vision forward. +

+

+ Purpose-built technology doesn't just solve problems — it changes systems, organizations, and people for the better. +

+ +
+ + +
+ +

Trusted by visionary leaders

+ +
+ +
+

"The Developmental Sprint® app enables individuals and teams to overcome hurdles to success. Within three months of our initial conversation with S&F, we had our first beta-version to test with a client. Within six months, we were using it as a cornerstone of our business expansion."

+
+

Andy Fleming

+

CEO & Founding Principal

+

The Developmental Edge

+ developmentaledge.com +
+
+ + +
+

"Thanks for being such a perfect mix of joyfulness and professionalism, which makes it such a treat to work with you."

+
+

Stephanie Delbecque

+

Lead Product Manager

+

Wikimedia Foundation

+ wikimediafoundation.org +
+
+ + +
+

"S&F never brought a problem to O3. You bring solutions! Great ability to implement design well, manage project/product, and problem solve. The cultural influence of S&F on our own team is great."

+
+

Mahesh Gaitonde

+

Chief Digital Officer

+

O3 World

+ o3world.com +
+
+ + +
+

"Speed & Function has provided the engineering backbone of our product infrastructure — not just in a technical capacity, but architecturally and strategically too. Their commitment to our project has been critical. We wouldn't have gotten this far if we hadn't been able to work with them. Everybody has been thoughtful, fun and professional. They'll always let you know when something goes wrong and work with you to improve it."

+
+

Lane Becker

+

President

+

Wikimedia LLC

+ wikimediafoundation.org +
+
+ + +
+

"Speed & Function connects the dots. Unfortunately, other parts of the world give you only what you ask for. You don't get connecting the dots, problem-solving, or creativity."

+
+

Robert Scanlon

+

President of Scanlon Consulting Group LLC

+
+
+ + +
+

"The team at Speed & Function own this project as much as I own it. They also speak up and voice their ideas. It's rare to get that from an external firm. There's lots of knowledge in the team and even though they are external, they work with us as a team rather than contractors."

+
+

Ryan Brounley

+

Product Advisor

+

Wikimedia Foundation

+ wikimediafoundation.org +
+
+ + +
+

"S&F is a solid business partner. Nick and his team are willing to do whatever it takes to make a project successful and to keep the customer satisfied. They are professional and thorough."

+
+

Chris Allison

+

Managing Partner

+

Turnberry Solutions

+ turnberrysolutions.com +
+
+ + +
+

"Nick and team are the best. They've basically turned our digital business around. Fast, efficient, cost-effective, communicative, and collaborative."

+
+

Shai Reichert

+

Managing Director, Technology

+

W2O Group

+
+
+
+
+ + +
+ Ready when you are +

See How We Build for Change

+ Start the conversation +
+
+