n[data-surface][data-surface-join] { padding-top: 64px; } .hero > .container, .quick-wins > .container, .sales-letter > .container, .about > .container, .consultancy > .container, .techniques > .container, .development > .container, .fit > .container, .rebuild-quiz > .container, .platforms > .container, .speed > .container, .latest-posts > .container, .faq > .container { max-width: 768px; } } /* ========================================================================== Buttons — skeuomorphic: bevelled, glossy, physically pressable Single button: … (light key) … (blue key) Button group:
…
(first button = primary) Sizes: --sm ========================================================================== */ .btn-group { display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem; } .btn-group > .btn { flex: 1; min-width: fit-content; } /* Base — a raised, light plastic key */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.85rem 1.6rem; font: inherit; font-weight: 700; line-height: 1; text-align: center; text-decoration: none; white-space: nowrap; cursor: pointer; color: #1a1a1a; /* fixed — the button key stays light in both themes */ border: 1px solid rgba(0, 0, 0, 0.22); border-radius: var(--radius); background-image: linear-gradient(180deg, #ffffff 0%, #ece6d8 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.32); /* key base — same colour as primary so heights read equal */ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); } /* Contextual CTA icons */ .btn[href="#free-call"]::before, .btn[href="#advisory"]::before, .btn[href="#pricing"]::before { content: ""; width: 1.05em; height: 1.05em; flex: 0 0 auto; background-color: currentColor; -webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain; mask-repeat: no-repeat; mask-position: center; mask-size: contain; } .btn[href="#free-call"]::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M164.9 24.6c-7.7-18.6-28-28.5-47.4-23.2l-88 24C12.1 30.2 0 46 0 64C0 311.4 200.6 512 448 512c18 0 33.8-12.1 38.6-29.5l24-88c5.3-19.4-4.6-39.7-23.2-47.4l-96-40c-16.3-6.8-35.2-2.1-46.3 11.6L304.7 368C234.3 334.7 177.3 277.7 144 207.3L193.3 167c13.7-11.2 18.4-30 11.6-46.3l-40-96z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M164.9 24.6c-7.7-18.6-28-28.5-47.4-23.2l-88 24C12.1 30.2 0 46 0 64C0 311.4 200.6 512 448 512c18 0 33.8-12.1 38.6-29.5l24-88c5.3-19.4-4.6-39.7-23.2-47.4l-96-40c-16.3-6.8-35.2-2.1-46.3 11.6L304.7 368C234.3 334.7 177.3 277.7 144 207.3L193.3 167c13.7-11.2 18.4-30 11.6-46.3l-40-96z'/%3E%3C/svg%3E"); } .btn[href="#advisory"]::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M128 0c17.7 0 32 14.3 32 32l0 32 128 0 0-32c0-17.7 14.3-32 32-32s32 14.3 32 32l0 32 48 0c26.5 0 48 21.5 48 48l0 48L0 160l0-48C0 85.5 21.5 64 48 64l48 0 0-32c0-17.7 14.3-32 32-32zM0 192l448 0 0 272c0 26.5-21.5 48-48 48L48 512c-26.5 0-48-21.5-48-48L0 192zM329 305c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-95 95-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L329 305z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M128 0c17.7 0 32 14.3 32 32l0 32 128 0 0-32c0-17.7 14.3-32 32-32s32 14.3 32 32l0 32 48 0c26.5 0 48 21.5 48 48l0 48L0 160l0-48C0 85.5 21.5 64 48 64l48 0 0-32c0-17.7 14.3-32 32-32zM0 192l448 0 0 272c0 26.5-21.5 48-48 48L48 512c-26.5 0-48-21.5-48-48L0 192zM329 305c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-95 95-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L329 305z'/%3E%3C/svg%3E"); } .btn[href="#pricing"]::before { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M0 80L0 229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7L48 32C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M0 80L0 229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7L48 32C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z'/%3E%3C/svg%3E"); } @media (prefers-reduced-motion: no-preference) { .btn { transition: transform 0.06s ease, box-shadow 0.12s ease, filter 0.12s ease; } } .btn:hover, .btn:focus { filter: brightness(1.03); text-decoration: none; } /* Physically depress onto the surface on click */ .btn:active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); } .btn:focus-visible { outline: 3px solid rgba(30, 122, 84, 0.5); outline-offset: 2px; } /* Type-coloured CTA keys — each CTA has its own colour. Free call = green · Advisory = amber · Pricing = blue. Base bar colour is shared (rgba black) so every key reads at the same height. */ .btn--primary, .btn[href="#free-call"] { color: #fff; border-color: rgba(0, 0, 0, 0.45); background-image: linear-gradient(180deg, #2fa36e 0%, #136b45 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 3px 0 rgba(0, 0, 0, 0.32); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.35); } .btn[href="#advisory"] { color: #fff; border-color: rgba(0, 0, 0, 0.4); background-image: linear-gradient(180deg, #d98324 0%, #a85e12 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 3px 0 rgba(0, 0, 0, 0.32); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); } .btn[href="#pricing"] { color: #fff; border-color: rgba(0, 0, 0, 0.4); background-image: linear-gradient(180deg, #3f83c9 0%, #23578f 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 3px 0 rgba(0, 0, 0, 0.32); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); } .btn--primary:hover, .btn--primary:focus, .btn[href="#free-call"]:hover, .btn[href="#free-call"]:focus, .btn[href="#advisory"]:hover, .btn[href="#advisory"]:focus, .btn[href="#pricing"]:hover, .btn[href="#pricing"]:focus { filter: brightness(1.06); } .btn--primary:active, .btn[href="#free-call"]:active, .btn[href="#advisory"]:active, .btn[href="#pricing"]:active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3); } /* Small */ .btn--sm { padding: 0.5rem 1rem; font-size: 0.9rem; border-radius: 8px; } /* Stack button groups full-width on mobile */ @media (max-width: 860px) { .btn-group, .hero__main .btn-group, .about__cta, .sales-letter__how-cta { flex-direction: column; align-items: stretch; width: 100%; max-width: 100%; } .btn-group > .btn { width: 100%; min-width: 0; white-space: normal; } } /* src/components/header/header.css */ /* ========================================================================== Header — skeuomorphic sticky bar ========================================================================== */ .site-header { position: fixed; top: 0; left: 0; right: 0; z-index: 100; /* Transparent, overlaying the hero — reads as part of it */ background-color: transparent; border-bottom: 1px solid transparent; transition: background-color 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease; } /* Condenses into a clean flat bar once scrolled (or menu open) */ .site-header.is-stuck { background-color: rgba(246, 240, 230, 0.85); backdrop-filter: saturate(140%) blur(10px); border-bottom: 1px solid rgba(0, 0, 0, 0.08); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } /* While the full-page menu is open, drop the backdrop-filter — otherwise it becomes the containing block for the fixed overlay and clips it to the bar */ .site-header.menu-open { -webkit-backdrop-filter: none; backdrop-filter: none; } /* With the menu open, keep only the close button in the header bar. */ .site-header.menu-open .site-header__logo { display: none; } .site-header__inner { display: flex; align-items: center; justify-content: space-between; min-width: 0; gap: 1.5rem; padding-top: 0.8rem; padding-bottom: 0.8rem; } .site-header__logo { flex-shrink: 0; } .site-header__logo img { display: block; height: 30px; width: auto; } /* Nav links */ .site-header__nav ul { list-style: none; display: flex; align-items: stretch; gap: 0; /* links sit flush against each other */ } .site-header__nav li { display: flex; align-items: stretch; } /* Full-height, full-bleed click areas */ .site-header__nav a:not(.btn) { display: flex; align-items: center; padding: 0 1.05rem; color: var(--colour-text); font-weight: 500; font-size: 0.95rem; border-radius: 0; transition: color 0.2s ease, background-color 0.2s ease; } .site-header__nav a:not(.btn):hover, .site-header__nav a:not(.btn):focus { color: var(--colour-accent); background-color: rgba(30, 122, 84, 0.12); text-decoration: none; } /* Keep the CTA at its natural size, set apart from the flush links */ .site-header__nav-cta { align-items: center; margin-left: 0.75rem; } .site-header__nav li.site-header__nav-cta-mobile { display: none; } /* Mobile-only navigation control */ .site-header__actions { display: none; align-items: center; gap: 0.6rem; } /* Matches the glossy button keys and stretches to their height */ .site-header__toggle { align-self: stretch; aspect-ratio: 1; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; border: 1px solid rgba(0, 0, 0, 0.22); border-radius: var(--radius); background-image: linear-gradient(180deg, #ffffff 0%, #ece6d8 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.24); } .site-header__toggle:active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); } .site-header__toggle-bars, .site-header__toggle-bars::before, .site-header__toggle-bars::after { display: block; width: 20px; height: 2px; border-radius: 2px; background: var(--colour-text); } .site-header__toggle-bars { position: relative; transition: background 0.2s ease; } .site-header__toggle-bars::before, .site-header__toggle-bars::after { content: ""; position: absolute; left: 0; transition: transform 0.25s ease; } .site-header__toggle-bars::before { top: -6px; } .site-header__toggle-bars::after { top: 6px; } /* Hamburger → X when open */ .site-header__toggle[aria-expanded="true"] .site-header__toggle-bars { background: transparent; } .site-header__toggle[aria-expanded="true"] .site-header__toggle-bars::before { transform: translateY(6px) rotate(45deg); } .site-header__toggle[aria-expanded="true"] .site-header__toggle-bars::after { transform: translateY(-6px) rotate(-45deg); } /* ---- Mobile ---- */ @media (max-width: 1200px) { /* Give the mobile bar a flat, solid background */ .site-header { background-color: rgba(246, 240, 230, 0.96); border-bottom: 1px solid rgba(0, 0, 0, 0.08); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } .site-header__inner { gap: 0.75rem; } .site-header__logo { position: relative; z-index: 2; flex: 1 1 auto; min-width: 0; } /* Smaller logo on mobile */ .site-header__logo img { width: min(100%, 168px); height: auto; } .site-header__actions { display: flex; position: relative; z-index: 2; /* close control stays above the overlay */ flex: 0 0 auto; margin-left: auto; /* keep the close button top-right even when logo is hidden */ } /* Full-page overlay menu */ .site-header__nav { position: fixed; inset: 0; z-index: 1; display: block; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: calc(4.75rem + env(safe-area-inset-top)) var(--spacing) calc(1.25rem + env(safe-area-inset-bottom)); background-color: var(--colour-bg); background-image: url("/img/paper.svg"); background-size: 360px 360px; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.25s ease, visibility 0.25s ease; } .site-header__nav.is-open { opacity: 1; visibility: visible; pointer-events: auto; } .site-header__nav ul { display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; width: min(100%, 34rem); min-height: calc(100vh - 6rem); min-height: calc(100dvh - 6rem); margin-inline: auto; gap: clamp(0.4rem, 1.2vh, 0.7rem); padding: 0; } .site-header__nav li { display: block; width: 100%; } /* Full-width menu keys use the available width without wrapping labels. */ .site-header__nav a:not(.btn) { display: flex; align-items: center; justify-content: center; width: 100%; min-height: clamp(2.8rem, 7vh, 3.6rem); padding: clamp(0.55rem, 1.35vh, 0.8rem) clamp(0.85rem, 3vw, 1.2rem); border: 1px solid rgba(0, 0, 0, 0.16); border-radius: var(--radius); background: rgba(255, 255, 255, 0.58); box-shadow: 0 2px 0 rgba(0, 0, 0, 0.12); font-family: var(--font-body); font-size: clamp(1rem, min(4.2vw, 2.7vh), 1.35rem); font-weight: 700; line-height: 1.1; text-align: center; white-space: nowrap; color: var(--colour-text); } .site-header__nav a:not(.btn):hover, .site-header__nav a:not(.btn):focus { color: var(--colour-accent); background: rgba(255, 255, 255, 0.9); border-color: rgba(30, 122, 84, 0.38); } .site-header__nav a.site-header__nav-book, .site-header__nav a.site-header__nav-book:hover, .site-header__nav a.site-header__nav-book:focus { color: #fff; border-color: rgba(0, 0, 0, 0.45); background-color: #136b45; background-image: linear-gradient(180deg, #2fa36e 0%, #136b45 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 2px 0 rgba(0, 0, 0, 0.28); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); } .site-header__nav a.site-header__nav-book:hover, .site-header__nav a.site-header__nav-book:focus { filter: brightness(1.06); } /* Swap the desktop CTA for the matching full-width mobile menu key. */ .site-header__nav li.site-header__nav-cta { display: none; } .site-header__nav li.site-header__nav-cta-mobile { display: block; } } @media (max-width: 620px) { .site-header__nav ul { align-content: start; min-height: 0; gap: clamp(0.38rem, 1.2vh, 0.6rem); padding-top: 0.75rem; } .site-header__nav a:not(.btn) { min-height: clamp(2.75rem, 7.5vh, 3.35rem); } } /* Short landscape phones need a compact, top-aligned list that can scroll. */ @media (max-width: 1200px) and (max-height: 560px) { .site-header__nav { padding-top: calc(4.25rem + env(safe-area-inset-top)); padding-bottom: calc(1rem + env(safe-area-inset-bottom)); } .site-header__nav ul { align-content: start; min-height: 0; gap: 0.4rem; } .site-header__nav a:not(.btn) { min-height: 2.65rem; padding-block: 0.5rem; font-size: 1rem; } } /* Subpages (blog, privacy) have no hero — the bar sits in flow and stays solid */ .subpage .site-header { position: sticky; background-color: rgba(246, 240, 230, 0.92); -webkit-backdrop-filter: saturate(140%) blur(10px); backdrop-filter: saturate(140%) blur(10px); border-bottom: 1px solid rgba(0, 0, 0, 0.08); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } /* A backdrop filter makes fixed descendants use the header as their containing block. Remove it while the mobile menu is open so the overlay fills the viewport on subpages as it does on the homepage. */ .subpage .site-header.menu-open { -webkit-backdrop-filter: none; backdrop-filter: none; } /* src/components/footer/footer.css */ /* ========================================================================== Footer newsletter and exit-intent signup ========================================================================== */ .site-footer { margin-top: 0; padding: clamp(3.5rem, 7vw, 6rem) 0 0.95rem; border-top: 1px solid rgba(255, 228, 92, 0.38); background: radial-gradient(105% 145% at 0% 0%, rgba(255, 255, 255, 0.055), transparent 55%), radial-gradient(80% 120% at 100% 100%, rgba(217, 131, 36, 0.09), transparent 58%), #292722; color: #f6eedf; } .footer__newsletter { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(25rem, 1.1fr); gap: clamp(2rem, 6vw, 6rem); align-items: end; padding-bottom: clamp(3rem, 6vw, 5rem); } .footer__newsletter-copy { max-width: 34rem; } .footer__newsletter-kicker, .newsletter-exit__eyebrow { margin: 0 0 0.75rem; color: #ffe45c; font-family: "Caveat", cursive; font-size: 1.35rem; font-weight: 700; line-height: 1; rotate: -1deg; } .footer__newsletter h2 { margin: 0; color: #fff; font-size: clamp(2rem, 3.5vw, 2.75rem); line-height: 1.05; } .footer__newsletter-copy > p:last-child { max-width: 31rem; margin: 1rem 0 0; color: rgba(246, 238, 223, 0.72); font-size: 1.0625rem; line-height: 1.65; } .newsletter-form label { display: block; margin-bottom: 0.6rem; color: inherit; font-size: 0.9375rem; font-weight: 700; } .newsletter-form__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.65rem; } .newsletter-form input[type="email"] { min-width: 0; width: 100%; min-height: 3.4rem; padding: 0.85rem 1rem; border: 2px solid rgba(255, 255, 255, 0.24); border-radius: 7px; background: rgba(255, 255, 255, 0.08); color: #fff; font-size: 1rem; transition: border-color 160ms ease, background-color 160ms ease; } .newsletter-form input[type="email"]::placeholder { color: rgba(255, 255, 255, 0.54); } .newsletter-form input[type="email"]:focus { outline: 3px solid rgba(255, 228, 92, 0.3); outline-offset: 2px; border-color: #ffe45c; background: rgba(255, 255, 255, 0.12); } .newsletter-form .btn { min-height: 3.4rem; padding: 0.85rem 1.2rem; font-size: 0.9375rem; white-space: nowrap; } .newsletter-form .btn:focus-visible, .newsletter-exit button:focus-visible { outline: 3px solid #ffe45c; outline-offset: 3px; } .newsletter-form__small { margin: 0.7rem 0 0; color: rgba(246, 238, 223, 0.58); font-size: 0.8125rem; line-height: 1.5; } .newsletter-form__small a { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; } .newsletter-success { padding: 1.1rem 1.2rem; border-left: 4px solid #ffe45c; background: rgba(255, 255, 255, 0.08); color: #fff; } .newsletter-success strong, .newsletter-success span { display: block; } .newsletter-success span { margin-top: 0.2rem; color: rgba(246, 238, 223, 0.72); } .footer__bar { display: flex; flex-direction: column; align-items: center; gap: 0.55rem; padding-top: 1.25rem; border-top: 1px solid rgba(255, 255, 255, 0.1); text-align: center; } .footer__logo { display: block; width: 118px; max-width: 100%; height: auto; } .footer__tagline { max-width: 44ch; color: rgba(246, 238, 223, 0.82); font-size: 0.78rem; line-height: 1.35; } .footer__location { color: rgba(246, 238, 223, 0.78); font-size: 0.88rem; } .footer__copyright { color: rgba(246, 238, 223, 0.62); font-size: 0.85rem; } .footer__meta { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0.45rem; color: rgba(246, 238, 223, 0.78); } .footer__meta > * + * { margin-left: 0; padding-left: 0.8rem; border-left: 1px solid rgba(255, 255, 255, 0.2); } .newsletter-exit { position: fixed; z-index: 10000; inset: 0; display: grid; place-items: center; padding: 1.25rem; } .newsletter-exit[hidden] { display: none; } .newsletter-exit__backdrop { position: absolute; inset: 0; background: rgba(18, 19, 22, 0.78); backdrop-filter: blur(4px); animation: newsletter-fade-in 180ms ease both; } .newsletter-exit__dialog { position: relative; z-index: 1; width: min(100%, 42rem); padding: clamp(2rem, 5vw, 3.75rem); border-top: 8px solid #ffe45c; border-radius: 5px; background: #f4efe4; box-shadow: 0 2rem 6rem rgba(0, 0, 0, 0.42); color: #1a1a1a; animation: newsletter-dialog-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1) both; } .newsletter-exit__close { position: absolute; top: 0.85rem; right: 0.85rem; display: grid; width: 2.75rem; height: 2.75rem; padding: 0; place-items: center; border-radius: 50%; background: transparent; color: #1a1a1a; font-size: 2rem; line-height: 1; cursor: pointer; } .newsletter-exit__close:hover { background: rgba(0, 0, 0, 0.06); } .newsletter-exit__eyebrow { color: #b64032; } .newsletter-exit h2 { max-width: 34rem; margin: 0; font-size: clamp(2rem, 5vw, 3.1rem); line-height: 1.04; } .newsletter-exit #newsletter-exit-description { max-width: 35rem; margin: 1.1rem 0 1.6rem; font-size: 1.0625rem; line-height: 1.65; } .newsletter-form--exit label { color: #1a1a1a; } .newsletter-form--exit input[type="email"] { border-color: rgba(26, 26, 26, 0.28); background: #fff; color: #1a1a1a; } .newsletter-form--exit input[type="email"]::placeholder { color: rgba(26, 26, 26, 0.46); } .newsletter-form--exit input[type="email"]:focus { background: #fff; } .newsletter-form--exit .newsletter-form__small { color: rgba(26, 26, 26, 0.62); } .newsletter-success--exit { background: rgba(26, 26, 26, 0.06); color: #1a1a1a; } .newsletter-success--exit span { color: rgba(26, 26, 26, 0.68); } .newsletter-exit__decline { display: block; margin: 1.1rem auto 0; padding: 0.25rem; background: transparent; color: rgba(26, 26, 26, 0.62); font-size: 0.875rem; text-decoration: underline; text-underline-offset: 0.2em; cursor: pointer; } html.newsletter-exit-open, html.newsletter-exit-open body { overflow: hidden; } @keyframes newsletter-fade-in { from { opacity: 0; } } @keyframes newsletter-dialog-in { from { opacity: 0; transform: translateY(1rem) scale(0.98); } } @media (max-width: 1200px) { .site-footer { padding-top: 3.5rem; } .footer__newsletter { grid-template-columns: 1fr; gap: 1.75rem; } .newsletter-form__row { grid-template-columns: 1fr; } .newsletter-form .btn { width: 100%; } } @media (prefers-reduced-motion: reduce) { .newsletter-exit__backdrop, .newsletter-exit__dialog { animation: none; } } /* src/components/forms-overlay/forms-overlay.css */ /* ========================================================================== Full-screen, one-question-at-a-time enquiry forms ========================================================================== */ .forms-overlay { position: fixed; inset: 0; z-index: 300; display: none; background: rgba(12, 10, 8, 0.6); backdrop-filter: blur(6px); } .forms-overlay.is-open { display: block; } .forms-overlay__modal { position: absolute; inset: 0; display: flex; width: 100%; height: 100%; overflow: auto; padding: clamp(4.5rem, 9vh, 7rem) clamp(1.25rem, 5vw, 4rem) clamp(2rem, 6vh, 4rem); border: 0; background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(242, 234, 217, 0.98)), url("/img/hero-texture.svg"); background-size: auto, 300px 300px; } .forms-overlay__modal[hidden], .forms-overlay__step[hidden] { display: none; } .forms-overlay__content { width: min(760px, 100%); margin: auto; } .forms-overlay__masthead { width: min(640px, 100%); margin-inline: auto; padding: clamp(1rem, 2.5vw, 1.35rem); border: 1px solid rgba(0, 0, 0, 0.11); border-left: 5px solid var(--form-accent, var(--colour-accent)); border-radius: 12px; background: rgba(255, 255, 255, 0.56); box-shadow: 0 10px 24px -24px rgba(20, 23, 38, 0.5); } .forms-overlay__title { color: var(--colour-text); font-size: clamp(1.3rem, 2.8vw, 1.7rem); font-weight: 750; line-height: 1.15; } .forms-overlay__subtext { max-width: 56ch; margin-top: 0.35rem; color: var(--colour-muted); font-size: clamp(0.84rem, 1.6vw, 0.94rem); line-height: 1.5; } .forms-overlay__progress { height: 4px; margin-top: 0.35rem; overflow: hidden; background: rgba(0, 0, 0, 0.1); border-radius: 2px; } .forms-overlay__progress-bar { position: relative; display: block; width: 0; height: 100%; background: var(--form-accent, var(--colour-accent)); transform-origin: left center; transition: width 260ms ease; } .forms-overlay__progress-text { min-height: 1.3em; margin-top: 0.8rem; color: var(--colour-muted); font-size: 0.76rem; font-weight: 700; letter-spacing: 0.06em; text-align: right; text-transform: uppercase; } .forms-overlay__form { width: min(640px, 100%); margin: clamp(1.6rem, 4vh, 2.6rem) auto 0; } .forms-overlay__step { animation: form-step-in 240ms ease both; } .forms-overlay__field-label { display: block; margin-bottom: clamp(1rem, 2.5vh, 1.5rem); color: var(--colour-text); font-size: clamp(1.5rem, 4vw, 2.5rem); font-weight: 600; line-height: 1.18; letter-spacing: -0.025em; } .forms-overlay__field-label b { display: inline-grid; width: 1.65rem; height: 1.65rem; margin-right: 0.4rem; place-items: center; translate: 0 -0.15em; color: #fff; background: var(--form-accent, var(--colour-accent)); border-radius: 5px; font-size: 0.72rem; letter-spacing: 0; } .forms-overlay__field-input, .forms-overlay__field-textarea { display: block; width: 100%; padding: 0.4rem 0 0.6rem; color: var(--colour-text); background: transparent; border: 0; border-bottom: 2px solid rgba(0, 0, 0, 0.25); border-radius: 0; outline: 0; font: inherit; font-size: clamp(1.25rem, 3vw, 1.9rem); line-height: 1.35; transition: border-color 180ms ease, box-shadow 180ms ease; } .forms-overlay__field-input::placeholder, .forms-overlay__field-textarea::placeholder { color: rgba(26, 26, 26, 0.34); } .forms-overlay__field-input:focus, .forms-overlay__field-textarea:focus { border-color: var(--form-accent, var(--colour-accent)); box-shadow: 0 2px 0 var(--form-accent, var(--colour-accent)); } .forms-overlay__field-textarea { min-height: 7rem; resize: vertical; } .forms-overlay__hint { margin-top: 0.65rem; color: var(--colour-muted); font-size: 0.88rem; } .forms-overlay__step-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem; margin-top: clamp(1.25rem, 3.5vh, 2rem); } .forms-overlay__step-actions > span { color: var(--colour-muted); font-size: 0.76rem; } .forms-overlay__step-actions .btn { width: auto; min-width: 7rem; margin: 0; padding-inline: 1.25rem; color: #fff; border-color: rgba(0, 0, 0, 0.4); background-image: linear-gradient(180deg, color-mix(in srgb, var(--form-accent, #1e7a54) 78%, #fff), var(--form-accent, #1e7a54)); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); } .forms-overlay__back { padding: 0.65rem 0.2rem; color: var(--colour-muted); background: transparent; border: 0; font: inherit; font-size: 0.9rem; font-weight: 700; cursor: pointer; } .forms-overlay__back:hover, .forms-overlay__back:focus { color: var(--colour-text); } .forms-overlay__consent { display: grid; grid-template-columns: auto 1fr; gap: 0.8rem; align-items: start; color: var(--colour-muted); font-size: clamp(0.9rem, 2vw, 1rem); font-weight: 500; line-height: 1.55; } .forms-overlay__consent-check { width: 1.35rem; height: 1.35rem; margin-top: 0.08rem; accent-color: var(--form-accent, var(--colour-accent)); cursor: pointer; } .forms-overlay__consent a { color: var(--colour-accent); font-weight: 700; } #modal-pricing { --form-accent: #2f70ae; } #modal-free-call { --form-accent: #1e7a54; } #modal-advisory { --form-accent: #bd6b1b; } .forms-overlay__close { position: fixed; top: clamp(0.8rem, 2vw, 1.5rem); right: clamp(0.8rem, 2vw, 1.5rem); z-index: 2; display: inline-flex; width: 44px; height: 44px; align-items: center; justify-content: center; color: #2d2d2d; background: rgba(255, 255, 255, 0.9); border: 1px solid rgba(0, 0, 0, 0.18); border-radius: 50%; box-shadow: 0 8px 20px -14px rgba(0, 0, 0, 0.45); cursor: pointer; } .forms-overlay__close::before { content: ""; width: 16px; height: 16px; background-color: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E%3Cpath d='M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E%3Cpath d='M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z'/%3E%3C/svg%3E") center / contain no-repeat; } .forms-overlay__success { width: min(640px, 100%); margin: clamp(1.6rem, 4vh, 2.6rem) auto 0; padding: clamp(1.4rem, 4vw, 2.2rem); border: 1px solid color-mix(in srgb, var(--form-accent, var(--colour-accent)) 28%, transparent); border-radius: 12px; background: rgba(255, 255, 255, 0.62); box-shadow: 0 18px 34px -30px rgba(20, 23, 38, 0.55); animation: form-step-in 240ms ease both; } .forms-overlay__success[hidden] { display: none; } .forms-overlay__success-mark { display: grid; width: 2.6rem; height: 2.6rem; margin-bottom: 1rem; place-items: center; color: #fff; background: var(--form-accent, var(--colour-accent)); border-radius: 8px; font-size: 1.35rem; font-weight: 800; } .forms-overlay__success-title { color: var(--colour-text); font-size: clamp(1.65rem, 4vw, 2.35rem); font-weight: 700; line-height: 1.15; outline: 0; } .forms-overlay__success-text { max-width: 52ch; margin-top: 0.7rem; color: var(--colour-muted); font-size: clamp(0.98rem, 2vw, 1.08rem); } .forms-overlay__success-close { margin-top: 1.4rem; color: #fff; border-color: rgba(0, 0, 0, 0.4); background-image: linear-gradient(180deg, color-mix(in srgb, var(--form-accent, #1e7a54) 78%, #fff), var(--form-accent, #1e7a54)); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); } @keyframes form-step-in { from { opacity: 0; translate: 0 0.6rem; } to { opacity: 1; translate: 0; } } @media (max-width: 560px) { .forms-overlay__modal { height: 100dvh; min-height: 100dvh; align-items: flex-start; padding: max(4.5rem, calc(env(safe-area-inset-top) + 3.75rem)) max(1.1rem, env(safe-area-inset-right)) max(1.5rem, env(safe-area-inset-bottom)) max(1.1rem, env(safe-area-inset-left)); } .forms-overlay__content { margin: 0 auto auto; } .forms-overlay__masthead { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; } .forms-overlay__title { font-size: 1.12rem; line-height: 1.2; } .forms-overlay__subtext { margin-top: 0.2rem; font-size: 0.78rem; line-height: 1.4; } .forms-overlay__progress-text { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .forms-overlay__progress { height: 3px; margin-top: 0.8rem; overflow: visible; border-radius: 999px; } .forms-overlay__progress-bar { border-radius: inherit; } .forms-overlay__progress-bar::after { content: ""; position: absolute; top: 50%; right: 0; width: 7px; height: 7px; border: 2px solid rgba(255, 255, 255, 0.92); border-radius: 50%; background: var(--form-accent, var(--colour-accent)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--form-accent, var(--colour-accent)) 38%, transparent); translate: 50% -50%; } .forms-overlay__modal:not([data-form-step="0"]) .forms-overlay__title, .forms-overlay__modal:not([data-form-step="0"]) .forms-overlay__subtext, .forms-overlay__modal.is-form-complete .forms-overlay__masthead { display: none; } .forms-overlay__modal:not([data-form-step="0"]):not(.is-form-complete) .forms-overlay__masthead { height: 3px; } .forms-overlay__modal:not([data-form-step="0"]) .forms-overlay__progress { margin-top: 0; } .forms-overlay__form { margin-top: 1.5rem; } .forms-overlay__step-actions .btn { flex: 1 1 auto; } } @media (prefers-reduced-motion: reduce) { .forms-overlay__step, .forms-overlay__success { animation: none; } .forms-overlay__progress-bar { transition: none; } } /* src/components/cookie-consent/cookie-consent.css */ /* ========================================================================== Cookie consent ========================================================================== */ .cookie-consent { position: fixed; left: 0; right: 0; bottom: 0; z-index: 250; display: flex; justify-content: center; padding: clamp(0.75rem, 2vw, 1.25rem); pointer-events: none; } .cookie-consent[hidden] { display: none; } .cookie-consent__panel { pointer-events: auto; width: min(560px, 100%); padding: clamp(1.1rem, 2.5vw, 1.5rem); background-color: var(--card); border: 1px solid rgba(0, 0, 0, 0.12); border-radius: 16px; box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.4); } .cookie-consent__title { font-family: var(--font-heading); font-size: 1.35rem; line-height: 1.1; margin-bottom: 0.35rem; color: var(--colour-text); } .cookie-consent__text { color: var(--colour-muted); font-size: 0.92rem; line-height: 1.5; } .cookie-consent__text a { color: var(--colour-accent); font-weight: 600; } .cookie-consent__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1rem; } .cookie-consent__actions .btn { flex: 1; min-width: fit-content; } /* Preferences categories */ .cookie-consent__categories { list-style: none; display: grid; gap: 0.75rem; margin-top: 1rem; } .cookie-consent__category { padding: 0.85rem 0.95rem; border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 12px; background: rgba(0, 0, 0, 0.015); } .cookie-consent__cat-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.35rem; } .cookie-consent__cat-name { font-weight: 700; color: var(--colour-text); } .cookie-consent__cat-always { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--colour-accent); } .cookie-consent__cat-desc { font-size: 0.85rem; line-height: 1.5; color: var(--colour-muted); } .cookie-consent__cat-desc code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.82em; padding: 0.05em 0.35em; border-radius: 5px; background: rgba(0, 0, 0, 0.06); } /* Toggle switch */ .cookie-consent__switch { position: relative; flex: 0 0 auto; width: 42px; height: 24px; cursor: pointer; } .cookie-consent__switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; } .cookie-consent__slider { position: absolute; inset: 0; border-radius: 999px; background: rgba(0, 0, 0, 0.22); transition: background 0.2s ease; } .cookie-consent__slider::before { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); transition: transform 0.2s ease; } .cookie-consent__switch input:checked + .cookie-consent__slider { background: var(--colour-accent); } .cookie-consent__switch input:checked + .cookie-consent__slider::before { transform: translateX(18px); } .cookie-consent__switch input:focus-visible + .cookie-consent__slider { outline: 3px solid rgba(30, 122, 84, 0.4); outline-offset: 2px; } /* Reopen trigger */ .cookie-consent__reopen { position: fixed; left: clamp(0.75rem, 2vw, 1.25rem); bottom: clamp(0.75rem, 2vw, 1.25rem); z-index: 240; padding: 0.5rem 0.85rem; font: inherit; font-size: 0.8rem; font-weight: 600; color: var(--colour-muted); background: var(--card); border: 1px solid rgba(0, 0, 0, 0.12); border-radius: 8px; box-shadow: 0 6px 18px -10px rgba(0, 0, 0, 0.4); cursor: pointer; opacity: 0.75; transition: opacity 0.2s ease; } .cookie-consent__reopen[hidden] { display: none; } .cookie-consent__reopen:hover { opacity: 1; } @media (max-width: 480px) { .cookie-consent__reopen { font-size: 0.72rem; padding: 0.4rem 0.7rem; } } /* src/blog/blog.css */ /* ========================================================================== Blog — listing grid + note-style article, sharing the site's tokens ========================================================================== */ /* --- Listing ------------------------------------------------------------- */ .blog { padding: clamp(2.4rem, 6vw, 4.25rem) 0 clamp(3rem, 7vw, 5rem); } .blog__head { max-width: 60ch; margin: 0 auto clamp(2rem, 4.5vw, 3rem); text-align: center; } .blog__title { font-family: var(--font-heading); font-size: clamp(2.1rem, 4.6vw, 3.1rem); line-height: 1.05; color: var(--colour-text); } .blog__intro { margin-top: 0.9rem; color: var(--colour-muted); font-size: 1.1rem; } /* Centred topic pills, replaced by a select only when they no longer fit. */ .blog__filter-carousel { position: relative; display: flex; justify-content: center; align-items: center; margin: 0 auto clamp(1.6rem, 3.5vw, 2.4rem); } .blog__filter-viewport { width: fit-content; max-width: 100%; min-width: 0; overflow: hidden; } .blog__filter-carousel.has-overflow .blog__filter-viewport { position: absolute; visibility: hidden; pointer-events: none; } .blog__filters { display: flex; flex-wrap: nowrap; gap: 0.65rem; overflow-x: hidden; padding: 0.15rem 0 0.3rem; scroll-behavior: smooth; scrollbar-width: none; -webkit-overflow-scrolling: touch; } .blog__filters::-webkit-scrollbar { display: none; } .blog__filter { flex: 0 0 auto; padding: 0.55rem 1rem; white-space: nowrap; border-radius: 999px; border: 1px solid rgba(0, 0, 0, 0.22); background-image: linear-gradient(180deg, #fff 0%, #ece6d8 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.24); color: #1a1a1a; font-weight: 700; font-size: 0.85rem; cursor: pointer; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); scroll-snap-align: center; transition: transform 0.06s ease, box-shadow 0.12s ease, filter 0.12s ease; } .blog__filter:hover { filter: brightness(1.03); } .blog__filter:active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); } .blog__filter:focus-visible, .blog__filter-select:focus-visible { outline: 3px solid rgba(30, 122, 84, 0.5); outline-offset: 2px; } .blog__filter.is-active { color: #fff; border-color: rgba(0, 0, 0, 0.45); background-image: linear-gradient(180deg, #2fa36e 0%, #136b45 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 3px 0 rgba(0, 0, 0, 0.32); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.35); } .blog__filter-select-wrap[hidden] { display: none; } .blog__filter-select-wrap { position: relative; width: min(100%, 330px); } .blog__filter-select-wrap::after { content: ""; position: absolute; top: 50%; right: 1.1rem; width: 0.55rem; height: 0.55rem; border-right: 2px solid #1a1a1a; border-bottom: 2px solid #1a1a1a; transform: translateY(-70%) rotate(45deg); pointer-events: none; } .blog__filter-select { width: 100%; min-height: 46px; padding: 0.72rem 3rem 0.72rem 1rem; appearance: none; cursor: pointer; color: #1a1a1a; background-image: linear-gradient(180deg, #fff 0%, #ece6d8 100%); border: 1px solid rgba(0, 0, 0, 0.22); border-radius: var(--radius); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.3); font-weight: 700; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); } .blog__filter-select:hover { filter: brightness(1.03); } .blog__empty { margin-top: 1.5rem; text-align: center; color: var(--colour-muted); } .blog__grid { list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(1.6rem, 3vw, 2.4rem); padding-top: 0.5rem; } @media (max-width: 1080px) { .blog__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 1200px) { .blog-card__note { transform: none; } } @media (max-width: 560px) { .blog__grid { grid-template-columns: 1fr; max-width: 420px; margin-inline: auto; } } .blog-card { display: flex; } .blog-card[hidden] { display: none; } /* Pinned post-it note — colour + tilt alternate down the grid */ .blog-card__note { position: relative; display: flex; flex-direction: column; width: 100%; padding: 2rem 1.5rem 1.5rem; color: #2a2620; background-image: linear-gradient(180deg, var(--note-hi) 0%, var(--note) 58%, var(--note-lo) 100%); border-radius: 3px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 14px 24px -16px rgba(20, 23, 38, 0.5); transform: rotate(var(--tilt, -1deg)); transition: transform 0.2s ease, box-shadow 0.2s ease; } .blog-card__note:hover { transform: rotate(0deg) translateY(-3px); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.14), 0 24px 32px -18px rgba(20, 23, 38, 0.5); } /* Pushpin */ .blog-card__note::before { content: ""; position: absolute; top: -10px; left: 50%; width: 20px; height: 20px; transform: translateX(-50%); border-radius: 50%; background: radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 42%), linear-gradient(180deg, color-mix(in srgb, var(--pin) 76%, #fff) 0%, var(--pin) 36%, color-mix(in srgb, var(--pin) 58%, #000) 82%, color-mix(in srgb, var(--pin) 42%, #000) 100%); box-shadow: 0 5px 7px -2px rgba(0, 0, 0, 0.45), inset 0 2px 2px rgba(255, 255, 255, 0.35), inset 0 -3px 4px rgba(0, 0, 0, 0.3); z-index: 3; } /* Four post-it colours, each with a pin colour that pops against it. The 8-card cycle runs the colours forward on one row (of four) then reversed on the next, so the colour order mirrors row to row. */ .blog-card__note--yellow, .blog-card:nth-child(8n+1) .blog-card__note, .blog-card:nth-child(8n+8) .blog-card__note { --note-hi: var(--colour-postit-hi); --note: var(--colour-postit); --note-lo: var(--colour-postit-lo); --pin: #e5384d; --tilt: -1.6deg; /* red on yellow */ } .blog-card:nth-child(8n+2) .blog-card__note, .blog-card:nth-child(8n+7) .blog-card__note { --note-hi: var(--postit-blue-hi); --note: var(--postit-blue); --note-lo: var(--postit-blue-lo); --pin: #ff7a1a; --tilt: 1.4deg; /* orange on blue */ } .blog-card:nth-child(8n+3) .blog-card__note, .blog-card:nth-child(8n+6) .blog-card__note { --note-hi: var(--postit-pink-hi); --note: var(--postit-pink); --note-lo: var(--postit-pink-lo); --pin: #12a594; --tilt: -0.8deg; /* teal on pink */ } .blog-card:nth-child(8n+4) .blog-card__note, .blog-card:nth-child(8n+5) .blog-card__note { --note-hi: var(--postit-green-hi); --note: var(--postit-green); --note-lo: var(--postit-green-lo); --pin: #8b3ff0; --tilt: 1.6deg; /* violet on lime */ } .blog-card__meta { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.8rem; } .blog-card__tag { padding: 0.2rem 0.55rem; border-radius: 999px; background: rgba(0, 0, 0, 0.1); color: rgba(0, 0, 0, 0.72); font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; } .blog-card__date { color: rgba(0, 0, 0, 0.55); font-size: 0.85rem; } .blog-card__title { font-family: var(--font-heading); font-size: 1.5rem; line-height: 1.12; color: #2a2620; } .blog-card__excerpt { margin-top: 0.6rem; color: rgba(0, 0, 0, 0.7); font-size: 0.98rem; line-height: 1.55; } /* CTA button, pinned to the bottom of the note */ .blog-card__cta { align-self: flex-start; margin-top: auto; padding-top: 1.2rem; /* breathing room above the button */ display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 700; font-size: 0.9rem; color: #1c1a15; text-decoration: none; } .blog-card__cta > span { display: inline-flex; align-items: center; justify-content: center; width: 1.55rem; height: 1.55rem; border-radius: 50%; background: #1c1a15; color: #fff; font-size: 0.9rem; line-height: 1; transition: transform 0.2s ease, background 0.2s ease; } .blog-card__cta:hover, .blog-card__cta:focus { text-decoration: none; } .blog-card__note:hover .blog-card__cta > span { transform: translateX(3px); background: var(--colour-accent); } /* Stretched link — the CTA makes the whole post-it clickable */ .blog-card__cta::after { content: ""; position: absolute; inset: 0; z-index: 2; } /* Keep the pin purely decorative */ .blog-card__note::before { pointer-events: none; } /* --- Article ------------------------------------------------------------- */ .blog-post { padding: clamp(2rem, 5vw, 3.5rem) 0 clamp(3rem, 7vw, 5rem); } .blog-post__inner { max-width: 72ch; margin: 0 auto; } /* Previous/next navigation beneath the article. */ .blog-post-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; gap: 0.8rem; margin-top: clamp(2.25rem, 5vw, 3.25rem); } .blog-post-nav__link { display: flex; justify-content: center; min-height: 4.5rem; padding: 0.85rem 1rem; border: 1px solid var(--border); border-radius: 10px; background: rgba(255, 255, 255, 0.42); color: var(--colour-text); text-decoration: none; transition: border-color 0.18s ease, background-color 0.18s ease, transform 0.18s ease; } .blog-post-nav__link { flex-direction: column; } .blog-post-nav__link--previous { grid-column: 1; } .blog-post-nav__link--next { grid-column: 2; text-align: right; } .blog-post-nav__link:hover, .blog-post-nav__link:focus { border-color: rgba(30, 122, 84, 0.35); background: rgba(30, 122, 84, 0.07); text-decoration: none; transform: translateY(-1px); } .blog-post-nav__label { display: block; margin-bottom: 0.25rem; color: var(--colour-accent); font-size: 0.7rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; } .blog-post-nav__title { display: -webkit-box; overflow: hidden; font-size: 0.92rem; font-weight: 700; line-height: 1.3; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } .blog-post-nav__empty { visibility: hidden; } .blog-post__back { display: inline-block; margin-bottom: 1.4rem; font-weight: 700; font-size: 0.9rem; color: var(--colour-accent); } .blog-post__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem; margin-bottom: 0.9rem; color: var(--colour-muted); font-size: 0.9rem; } .blog-post__meta .blog-card__tag { margin: 0; } .blog-post__title { font-family: var(--font-heading); font-size: clamp(2.1rem, 5vw, 3.1rem); line-height: 1.04; color: var(--colour-text); } .blog-post__lead { margin-top: 1rem; font-size: 1.2rem; line-height: 1.5; color: var(--colour-muted); } .blog-post__body { margin-top: clamp(1.6rem, 3.5vw, 2.4rem); color: var(--colour-text); font-size: 1.06rem; line-height: 1.7; } .blog-post__body > * + * { margin-top: 1.1rem; } .blog-post__body h2 { margin-top: 2.1rem; font-family: var(--font-heading); font-size: clamp(1.5rem, 3vw, 1.95rem); line-height: 1.15; color: var(--colour-text); } .blog-post__body h3 { margin-top: 1.6rem; font-family: var(--font-heading); font-size: 1.35rem; color: var(--colour-text); } .blog-post__body ul, .blog-post__body ol { padding-left: 1.5rem; color: var(--colour-text); } .blog-post__body ul { list-style: disc; } .blog-post__body ol { list-style: decimal; } .blog-post__body li { padding-left: 0.25rem; } .blog-post__body li::marker { color: var(--colour-accent); } .blog-post__body li + li { margin-top: 0.4rem; } .blog-post__body a { color: var(--colour-accent); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; } .blog-post__body blockquote { margin: 1.6rem 0; padding: 0.6rem 1.25rem; border-left: 3px solid var(--colour-accent); background: rgba(30, 122, 84, 0.06); border-radius: 0 8px 8px 0; font-family: var(--font-heading); font-size: 1.3rem; line-height: 1.35; color: var(--colour-text); } .blog-post__body blockquote p { margin: 0; } .blog-post__body code { padding: 0.12em 0.4em; border-radius: 5px; background: rgba(0, 0, 0, 0.06); font-size: 0.9em; } .blog-post__body pre { overflow-x: auto; padding: 1rem 1.15rem; border-radius: 10px; background: #10382a; color: #eaf3ee; } .blog-post__body pre code { padding: 0; background: none; color: inherit; } .blog-post__body img { max-width: 100%; height: auto; border-radius: 12px; } .blog-post__body hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; } /* End-of-post CTA */ .blog-post__cta { margin-top: clamp(2.4rem, 5vw, 3.25rem); padding-top: clamp(1.5rem, 3vw, 2rem); border-top: 1px solid var(--border); text-align: center; } .blog-post__cta p { margin-bottom: 1rem; font-family: var(--font-heading); font-size: clamp(1.35rem, 3vw, 1.8rem); color: var(--colour-text); } /* Full archive-style grid, shared across posts and filtered client-side. */ .blog-post__more { margin-top: clamp(4rem, 8vw, 6rem); padding-top: clamp(2.5rem, 5vw, 4rem); border-top: 1px solid var(--border); } .blog-post__more-head { max-width: 58ch; margin: 0 auto; text-align: center; } .blog-post__more-head h2 { font-family: var(--font-heading); font-size: clamp(2rem, 4vw, 2.75rem); line-height: 1.1; color: var(--colour-text); } .blog-post__more-head p { margin-top: 0.75rem; color: var(--colour-muted); font-size: 1.05rem; } .blog-post__more-target { margin-top: clamp(2rem, 4vw, 3rem); } .blog-post__more-loading, .blog-post__more-fallback { text-align: center; color: var(--colour-muted); } .blog-post__more-fallback a { color: var(--colour-accent); font-weight: 700; } @media (max-width: 680px) { .blog-post-nav__empty { display: none; } } /* --- Note layout (each post retains a personal greeting and sign-off) ---- */ .letter { position: relative; margin-top: 0; padding: clamp(1.6rem, 4vw, 2.75rem); background-color: var(--card); background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.6), rgba(244, 239, 228, 0.6)), url("/img/hero-texture.svg"); background-size: auto, 300px 300px; border: 1px solid var(--border); border-radius: 14px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 22px 44px -34px rgba(20, 23, 38, 0.45); } .letter__greeting { font-family: var(--font-heading); font-size: clamp(1.4rem, 3vw, 1.85rem); color: var(--colour-text); } .letter__signoff { margin-top: 2rem; } .letter__signoff > * + * { margin-top: 0.1rem; } .letter__valediction { color: var(--colour-muted); } .letter__signature { font-family: "Caveat", cursive; font-size: clamp(2rem, 4vw, 2.6rem); line-height: 1; color: var(--colour-accent); } .letter__role { color: var(--colour-muted); font-size: 0.9rem; } /* src/button-system.css */ /* ========================================================================== Button-system finishing layer Primary and secondary actions use the shared .btn keys in base.css. Compact controls keep their necessary shape, but use the same raised edge, highlight and physical pressed state. ========================================================================== */ /* Compact directional keys */ :is( .quick-wins__arrow, .lm-carousel__arrow, .fit__arrow, .latest-posts__arrow ) { border-color: rgba(0, 0, 0, 0.22); background: linear-gradient(180deg, #fff 0%, #ece6d8 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.28); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); transition: transform 0.06s ease, box-shadow 0.12s ease, filter 0.12s ease, opacity 0.2s ease; } :is( .quick-wins__arrow, .lm-carousel__arrow, .fit__arrow, .latest-posts__arrow ):not(:disabled):hover { background: linear-gradient(180deg, #fff 0%, #ece6d8 100%); filter: brightness(1.04); } :is( .quick-wins__arrow, .lm-carousel__arrow, .fit__arrow, .latest-posts__arrow ):not(:disabled):active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55); } :is( .quick-wins__arrow, .lm-carousel__arrow, .fit__arrow, .latest-posts__arrow ):focus-visible { outline: 3px solid rgba(30, 122, 84, 0.5); outline-offset: 2px; } /* Close controls read as small round keys, not flat floating icons. */ :is( .forms-overlay__close, .rebuild-diagnostic__close, .newsletter-exit__close ) { border: 1px solid rgba(0, 0, 0, 0.22); background: linear-gradient(180deg, #fff 0%, #ece6d8 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.28); transition: transform 0.06s ease, box-shadow 0.12s ease, filter 0.12s ease; } :is( .forms-overlay__close, .rebuild-diagnostic__close, .newsletter-exit__close ):hover { background: linear-gradient(180deg, #fff 0%, #ece6d8 100%); filter: brightness(1.04); } :is( .forms-overlay__close, .rebuild-diagnostic__close, .newsletter-exit__close ):active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55); } /* Tertiary actions intentionally remain text-like, but their focus and press behaviour is consistent across forms and overlays. */ :is( .forms-overlay__back, .rebuild-diagnostic__back, .rebuild-diagnostic__retake, .newsletter-exit__decline ):focus-visible { outline: 3px solid rgba(30, 122, 84, 0.5); outline-offset: 3px; border-radius: 4px; } :is( .forms-overlay__back, .rebuild-diagnostic__back, .rebuild-diagnostic__retake, .newsletter-exit__decline ):active { transform: translateY(1px); } /* The persistent cookie control is a compact secondary key rather than a pill. */ .cookie-consent__reopen { border: 1px solid rgba(0, 0, 0, 0.22); border-radius: 8px; background-image: linear-gradient(180deg, #fff 0%, #ece6d8 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 rgba(0, 0, 0, 0.28); color: #1a1a1a; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); transition: transform 0.06s ease, box-shadow 0.12s ease, filter 0.12s ease; } .cookie-consent__reopen:hover { filter: brightness(1.04); } .cookie-consent__reopen:active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55); } /* The forest footer uses the site's post-it yellow as its complementary action colour, while retaining the same raised-key construction. */ .site-footer .newsletter-form .btn--primary { color: #3f340a; border-color: rgba(0, 0, 0, 0.42); background-image: linear-gradient(180deg, #fff08a 0%, #e3bd32 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.58), 0 3px 0 rgba(0, 0, 0, 0.34); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.42); } .site-footer .newsletter-form .btn--primary:focus-visible { outline-color: rgba(255, 255, 255, 0.9); }

A calm way to set up GA4 that you will not regret

Dear founder,

I've lost count of the GA4 accounts I've opened to find events firing twice, purchases with no value attached, and internal traffic quietly inflating everything. None of that is GA4's fault. It's the fault of a setup done in an afternoon, under pressure, with the tag copied from a forum post.

Get the foundations right first

Before you touch a single custom event, sort the basics. They're dull, and they're the reason your numbers will make sense in six months.

  • Filter out your own traffic so your team's browsing doesn't pollute the data
  • Confirm the purchase event carries a value and currency — this is where most stores go wrong
  • Set your reporting time zone and currency to match how you actually run the business
  • Turn off Google Signals unless you genuinely need it and understand the reporting knock-ons

Test before you trust

The single habit that separates a reliable account from a mess is checking things fire correctly before you rely on them.

  1. Use the DebugView to watch events land in real time
  2. Place a real test order and confirm the value matches
  3. Wait a full day, then compare against your platform's own order count

If GA4 and your store disagree on how many orders you took, fix that before you look at anything else. Everything downstream depends on it.

Don't measure everything on day one

You do not need forty events to start. You need purchases, add to carts, and page views working perfectly. Add more only when you have a question they'll answer.

A quiet, careful setup is worth ten clever dashboards built on shaky data. If yours was thrown together and you no longer trust it, start with a FREE call and we'll work out whether to repair it or start clean.

Best,

Luke Michael

UK-based eCommerce Consultant & Developer

Got a live version of this on your store?

All the other notes

Browse every note except the one you are reading.

Loading the other notes…