backbase.com backbase.com - De score is 63/100

Website beoordeling backbase.com

 Gegenereerd op Oktober 16 2026 05:45 AM

De score is 63/100





Advertisement

SEO Content

Title

Backbase - AI-native Banking OS for the whole frontline

Lengte : 55

Perfect, uw title tag bevat tussen de 40 en 70 karakters.

Description

Digital channels start the work; a Unified Frontline finishes it. Backbase coordinates customers, employees and AI agents on the systems you already run.

Lengte : 153

Perfect, uw meta description bevat tussen de 90 en 160 karakters.

Keywords

Erg slecht. We hebben geen meta keywords gevonden in uw website. Gebruik deze gratis online meta tags generator om keywords te genereren.

Og Meta Properties

Goed, uw page maakt gebruik van Og Properties.

Property Content
type website

Headings

H1 H2 H3 H4 H5 H6
1 7 10 0 0 0
  • [H1] and visual are the LCP candidates and any opacity: 0 start delays the largest contentful paint by the length of the entrance. The user approved doing the same for the other six heroes on 2026-09-21 ("Go ahead" — references/plans/2026-09-21-animation-consistency.md, decision 1). Both the opacity: 0 initial state and the @keyframes v3-rise it depended on are gone; there is no longer ANY rule in this component that can set opacity on a hero-v3_* or home-v3_hero_* selector, so no hero can be left invisible by a surviving initial state. The heroes carry no [data-reveal*] attributes either (verified in the 2026-09-21 audit), so they do not animate at all now — which is what "heroes have no reveal animation" means. [data-reveal-css] stays on the homepage hero root above: it is what makes the GSAP runtime skip that subtree, and it is unrelated to this ladder. */ /* ── Ambient: the CTA's gradient headline drifts ──────────────────────────── .home-v3_cta2_gradient is background-clip:text over linear-gradient(90deg,#83a2ff,#e7edff), so panning the gradient moves the light through the letterforms. The stop list is repeated (A,B,A) and the pan runs "alternate", so there is no snap at the loop point either way. 220% size gives the gradient room to travel. The same treatment would suit .closing-banner-v3_title on Digital Banking — not applied, nobody asked for it there. */ @media (prefers-reduced-motion: no-preference){ html .home-v3_cta2_gradient{ background-image: linear-gradient(90deg, #83a2ff, #e7edff, #83a2ff); background-size: 220% 100%; animation: v3-gradient-drift 7s ease-in-out infinite alternate; } } @keyframes v3-gradient-drift { from { background-position: 0% 50% } to { background-position: 100% 50% } } /* ── Shared float, used by the page layers below ──────────────────────────── Set --v3-float-y on the element to change the amplitude. */ @keyframes v3-float { 0%,100% { transform: translateY(0) } 50% { transform: translateY(var(--v3-float-y,-8px)) } } /* ── Proof tabs: the open tab shows its logo in colour ───────────────────── MCP | Proof Tab carries two images: .home-v3_proof_tab_logo (black; it sizes the tab) and .home-v3_proof_tab_logo_colour (absolute on top, opacity 0 from its class, prop "Active logo (colour)"). The Proof in Production script marks the open tab with .home-v3_proof_tab-active; until it runs, tab 1 is the open one. Added 2026-09-28 (user: "make sure the current logo is also colored"). The transform in the transition keeps the homepage layer's hover lift (embed 11). */ html .home-v3_proof_tab .home-v3_proof_tab_logo{transition:opacity .25s ease, transform .35s var(--v3-ease)} html .home-v3_proof_tab-active .home-v3_proof_tab_logo_colour, html .home-v3_proof_tabs:not(:has(.home-v3_proof_tab-active)) .home-v3_proof_tab:first-child .home-v3_proof_tab_logo_colour{opacity:1} html .home-v3_proof_tab-active:has(.home-v3_proof_tab_logo_colour) .home-v3_proof_tab_logo, html .home-v3_proof_tabs:not(:has(.home-v3_proof_tab-active)) .home-v3_proof_tab:first-child:has(.home-v3_proof_tab_logo_colour) .home-v3_proof_tab_logo{opacity:0} @media (prefers-reduced-motion: reduce){ html .home-v3_proof_tab .home-v3_proof_tab_logo, html .home-v3_proof_tab .home-v3_proof_tab_logo_colour{transition:none} } // Updates navigation colors based on the section underneath. // Pairs with the CSS in embed 01. Returns immediately on a page with no // [data-wrap="light"] section, so it is inert where it is not needed. document.addEventListener('DOMContentLoaded', () => { const navbars = document.querySelectorAll('.nav_wrap'); const lightSections = document.querySelectorAll('[data-wrap="light"]'); const breadcrumbElements = document.querySelectorAll('.breadcrumbs_name, ' + '.breadcrumbs_divider, ' + '.breadcrumbs_link.is-current'); const navButtonLines = document.querySelectorAll('.nav_btn_line'); if (!navbars.length || !lightSections.length) return; let ticking = false; function setOverWhite(isActive) { navbars.forEach((navbar) => { navbar.classList.toggle('is-over-white', isActive); }); breadcrumbElements.forEach((element) => { element.classList.toggle('is-over-white', isActive); }); navButtonLines.forEach((element) => { element.classList.toggle('is-over-white', isActive); }); } function isMenuOpen() { return Array.from(navbars).some((navbar) => { return navbar.querySelector('.nav_dropdown_mega_wrap.w--open, ' + '.nav_links_link.w--open, ' + '.style2-0_nav_dropdown_toggle.w--open, ' + '.w-nav-button.w--open'); }); } function getVisibleNavbar() { return Array.from(navbars).find((navbar) => { const styles = getComputedStyle(navbar); return styles.display !== 'none' && styles.visibility !== 'hidden' && navbar.getBoundingClientRect().height > 0; }); } function updateColors() { if (isMenuOpen()) { setOverWhite(false); ticking = false; return; } const visibleNavbar = getVisibleNavbar(); if (!visibleNavbar) { ticking = false; return; } const navbarRect = visibleNavbar.getBoundingClientRect(); const isOverLightSection = Array.from(lightSections).some((section) => { const sectionRect = section.getBoundingClientRect(); return sectionRect.top < navbarRect.bottom && sectionRect.bottom > navbarRect.top; }); setOverWhite(isOverLightSection); ticking = false; } function requestUpdate() { if (ticking) return; ticking = true; requestAnimationFrame(updateColors); } const menuObserver = new MutationObserver(requestUpdate); navbars.forEach((navbar) => { navbar.querySelectorAll('.nav_dropdown_mega_wrap, ' + '.nav_links_link, ' + '.style2-0_nav_dropdown_toggle, ' + '.w-nav-button').forEach((element) => { menuObserver.observe(element, { attributes: true, attributeFilter: ['class', 'aria-expanded'], }); }); }); updateColors(); window.addEventListener('scroll', requestUpdate, { passive: true }); window.addEventListener('resize', requestUpdate); }); /* GSAP reveal runtime — see embed 00 for the attribute reference. Source of truth: references/gsap-reveal/reveal.src.js (readable) -> reveal.min.js (this). Wrapped in a DOM-ready guard because this component sits at the TOP of the body, not in the page footer: without the guard it would run before the sections exist, find zero targets and switch the gate off. 2026-09-18 retune — the motion now matches the 90-day CTA timeline: ease power2.out (was power3.out), default duration 0.5s (was 0.9s), default travel 10px (was 32px), default stagger 0.12 (was 0.1). SplitText is fetched only when the page actually has a lines/words target. 2026-09-18 — count-up safety net. A number must never be left sitting at 0. settle() rewrites the ORIGINAL string (not a re-rounded copy) on complete, on the tween's onInterrupt AND on the timeline's onInterrupt (killing a timeline does not fire its children's), plus a watchdog on load and at 8s for a stall that kills nothing. Worst case the number does not animate; it can no longer be wrong. 2026-09-28: a display:contents child without .u-display-contents is set to visibility: inherit before its children are tweened — the pre-hide CSS hid it, and its children inherited that for good (Analyst Recognition, Quote lead). 2026-09-28: desktop only. Below 992px (the Webflow tablet breakpoint and down) the runtime releases the gate exactly as it does under reduced motion: nothing is hidden, nothing moves, this runtime fetches no GSAP, count-ups show their final number. */ (function(r){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",r):r()})(function(){ !function(){var e=document.documentElement,t="data-v3-anim",r="data-reveal";if(!window.__v3r){window.__v3r=1;var n=function(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e)).filter(function(e){return!e.closest("["+r+"-css]")})},a=!1;if("off"===e.getAttribute(t)||matchMedia("(prefers-reduced-motion: reduce), (max-width: 991px)").matches)l();else if(n("["+r+"],["+r+"-stagger],[data-parallax]").length){e.setAttribute(t,"on");var i=setTimeout(l,6e3),o=[];window.ScrollTrigger||o.push("ScrollTrigger"),!window.SplitText&&document.querySelector("["+r+'="lines"],['+r+'="words"]')&&o.push("SplitText");var s=1+o.length;o.forEach(function(e){u(e,c)}),function(e){if(window.gsap)return e();var t=document.querySelector('script[src*="/gsap.min.js"]');if(t)return t.addEventListener("load",function(){window.gsap?e():u("gsap",e)}),void t.addEventListener("error",function(){u("gsap",e)});u("gsap",e)}(c)}else l()}function l(){a||(a=!0,e.setAttribute(t,"off"))}function u(e,t){var r=document.createElement("script");r.src="https://cdn.jsdelivr.net/npm/gsap@"+(window.gsap?window.gsap.version:"3.13.0")+"/dist/"+e+".min.js",r.onload=t,r.onerror=l,document.head.appendChild(r)}function c(){--s||function(){if(a)return;clearTimeout(i),window.__v3rInit=1;var e=window.gsap,t=window.ScrollTrigger;e.registerPlugin(t),window.SplitText&&e.registerPlugin(window.SplitText);var o="power2.out";function s(e,n,a){var i=!e.hasAttribute(r+"-repeat");t.create({trigger:e,start:e.getAttribute(r+"-start")||"top 85%",once:i,animation:n,toggleActions:i?"play none none none":"play none none reverse"})}var l=function(e){return{delay:d(e,"delay",0),duration:d(e,"duration",.5),ease:o}};function u(t,r){for(var n,a,i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);(n=i.nextNode())&&!(a=/-?\d[\d,]*(\.\d+)?/.exec(n.data)););var o=e.timeline({paused:!0,delay:r.delay});if(o.fromTo(t,{autoAlpha:0,y:10},{autoAlpha:1,y:0,duration:r.duration,ease:r.ease},0),a){var l=a[0],u=parseFloat(l.replace(/,/g,"")),c=(l.split(".")[1]||"").length,d=l.indexOf(",")>-1,p=n.data.slice(0,a.index),f=n.data.slice(a.index+l.length),g={n:0},h=function(){n.data=p+l+f},v=function(){!o.isActive()&&o.progress().home-v3_btn-fx{ display:block;position:absolute;inset:0;z-index:0;pointer-events:none; background-color:var(--_button-style---background-hover); opacity:0;transform:scaleX(0);transform-origin:left center; transition:transform .36s cubic-bezier(.33,1,.68,1),opacity .22s; } .style2-0_button_main_wrap:hover>.home-v3_btn-fx{ opacity:1;transform:scaleX(1); transition:transform .36s cubic-bezier(.33,1,.68,1),opacity 0s; } /* The one variant that sets its :hover background DIRECTLY instead of through the token, so the token would give it the wrong (solid white) wipe. */ .style2-0_button_main_wrap:where(.w-variant-a134a4fb-541a-7c0e-b919-f06129d82680)>.home-v3_btn-fx{ background-color:var(--swatch--pure-white-15); } /* the wrap's own colour switches instantly - the per-character spans below do the visible fade, so the sweep can track the wipe edge instead of the clock */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx){ transition:border-color .2s,color 0s,background-color 0s; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover{ transition:border-color .2s,color 0s,background-color 0s .36s; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .style2-0_button_main_text{ transition:color 0s; } /* before the splitter runs, or if it ever fails: one smooth fade for the whole label */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .style2-0_button_main_text:not(:has(.fxc)){ transition:color .24s cubic-bezier(.33,1,.68,1) .06s; } /* each character eases as the wipe reaches it; leaving is uniform so the label never sits dark on an uncovered background */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .style2-0_button_main_text .fxc{ transition:color .18s linear;transition-delay:0s; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_text .fxc{ transition:color .24s cubic-bezier(.33,1,.68,1); transition-delay:calc(var(--i) / var(--n) * .19s); } /* The arrow sits at the far right, so it must be the LAST thing to change colour. The wipe edge reaches it at ~.24-.30s (measured off the .36s easeOutCubic), and the stroke is fully erased at its own crossover: .27s shaft, .30s head. Switching at .29s lands inside both, so the arrow is invisible at the moment it changes and simply redraws already in the hover colour - no visible flip. */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .style2-0_button_main_icon{ position:relative;z-index:1; transition:color .18s linear; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_icon{ transition:color 0s .29s; } /* the arrow redraws itself: the stroke clears away, then draws back in. --l and --ln are each path's length and its negation, both set by the script from the fixed lengths in ARROWS. Do NOT write calc(var(--l) * -1) here: Chrome cannot interpolate between a plain 0 and an unresolved calc(), and the erase half silently degrades to a discrete jump. Measured, not guessed. Timing is per-keyframe; a single global ease front-loads both halves and reads as a blink. */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .style2-0_button_main_icon .fxd{ stroke-dasharray:var(--l);stroke-dashoffset:0; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_icon .fxd{ animation:home-v3-btn-draw .6s linear; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_icon .fxd-head{ animation-delay:.03s; } /* corner ticks step outward - the component's own motif */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .style2-0_button_main_corner{ transition:transform .36s cubic-bezier(.33,1,.68,1); } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_corner.is-top-left{transform:translate(-2px,-2px)} .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_corner.is-top-right{transform:translate(2px,-2px)} .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_corner.is-bottom-right{transform:translate(2px,2px)} .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .style2-0_button_main_corner.is-bottom-left{transform:translate(-2px,2px)} } @keyframes home-v3-btn-draw{ 0% {stroke-dashoffset:0; animation-timing-function:cubic-bezier(.5,0,.9,.4)} 45% {stroke-dashoffset:var(--ln)} 45.01% {stroke-dashoffset:var(--l); animation-timing-function:cubic-bezier(.15,.8,.3,1)} 100% {stroke-dashoffset:0} } /* home-v3 arrow + label enhancer for opted-in elements only: 1. splits the label into per-character spans so the colour sweep follows the wipe edge 2. swaps the arrow's two FILLED paths for stroked paths on the same centreline, so the line can be drawn with stroke-dashoffset. The element itself is kept, so its u-svg class and any per-variant rotate() survive untouched. The label and the icon both carry aria-hidden="true" (the accessible name lives in .clickable_text.u-sr-only), so neither change affects assistive tech. Idempotent, and re-runs on load in case anything else rewrote the button. 2026-09-18: also serves Style2.0 - Text Link, which opts in the same way (a hidden .home-v3_link-fx flag driven by its own Hover FX prop). It gets the arrow only — a text link has no wipe for a per-character colour sweep to track. Its CSS is in embed 11; the @keyframes and this script stay here, the single source for both. 2026-09-21: also serves MCP | Mono Arrow Link, whose arrow became this same inline svg. It has no opt-in flag - it is ours, so every instance is enhanced. Its CSS is in embed 12, which is ungated and reaches all seven pages. */ (function(){ if(!window.matchMedia)return; if(!matchMedia('(hover:hover)').matches)return; if(matchMedia('(prefers-reduced-motion:reduce)').matches)return; var NS='http://www.w3.org/2000/svg'; function label(wrap){ var t=wrap.querySelector('.style2-0_button_main_text'); if(!t||t.querySelector('.fxc'))return; var s=t.textContent;if(!s)return; var n=s.length,out=''; for(var i=0;i .home-v3_link-fx), the component's own "Hover FX" flag, so gating it here meant the six other pages kept the component's own :hover, whose colour resolves to white — invisible on a light section. What stayed is genuinely this page's: the proof tabs and the bento toggle, all on home-v3_* classes that only [SEPT] Homepage places. Deliberately NOT here: .home-v3_gap_card and .home-v3_proof_stat. Both have their link prop switched off on this page, so they are not clickable and a hover cue on them would promise something that is not there. Global | Nav and Global | Footer are site-owned and shared with the live site. */ /* ── plain text links ───────────────────────────────────────────── "Read story" / "Read the report" are own classes whose arrow is a text character, not an SVG, so they get the project's underline motif instead (see .pillars-v3_link). */ html .home-v3_proof_story_link, html .home-v3_proof_note_link{ background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat; padding-bottom:2px; transition:background-size var(--v3-underline) var(--v3-ease),color .25s ease; } /* ── bento cards ──────────────────────────────────────────────── 2026-09-22 (user): "Remove hover from this card. I only want the hover to be on the link and it's already there through the link component itself." So the CARD has no hover of its own any more. Removed here: .home-v3_bento_card:hover .arrow-link-v3_icon (card-wide arrow slide) .home-v3_bento_card:hover .home-v3_bento_card_media (preview scale 1.015) the two rules for the legacy anchor .home-v3_bento_card_link, which is visibility:false since 2026-09-21 and renders nothing. The only hover left inside a bento card is the MCP | Mono Arrow Link's own — underline wipe + arrow redraw, embed 12b/12c, ungated, fired by the LINK. The card itself never moved anyway: the four cards are transparent windows over one gradient on .home-v3_bento_rows. */ html .home-v3_bento_toggle_item{cursor:pointer;transition:color .25s ease,background-color .25s ease} /* ── proof tabs ────────────────────────────────────────*/ html .home-v3_proof_tab{cursor:pointer;transition:opacity .25s ease} html .home-v3_proof_tab_logo{transition:transform .35s var(--v3-ease)} /* ── hover state ───────────────────────────────────────*/ @media (hover:hover){ html .home-v3_proof_story_link:hover, html .home-v3_proof_note_link:hover{background-size:100% 1px;text-decoration:none} html .home-v3_bento_toggle_item:not(.home-v3_bento_toggle_item-active):hover{ color:#fff;background-color:rgba(255,255,255,.12); } html .home-v3_proof_tab:not(.home-v3_proof_tab-active):hover{opacity:.72} html .home-v3_proof_tab:hover .home-v3_proof_tab_logo{transform:translateY(-2px)} } /* ── reduced motion ──────────────────────────────────────*/ @media (prefers-reduced-motion:reduce){ html .home-v3_proof_story_link, html .home-v3_proof_note_link, html .home-v3_bento_toggle_item, html .home-v3_proof_tab, html .home-v3_proof_tab_logo{ transition:none!important;transform:none!important; } } /* ── corner marks ─────────────────────────────────── 2026-09-25 (user): the top-right rail mark of MCP | Proof in Production is not in the homepage design. The mark lives in the shared definition and other pages need it, so it is hidden here — this embed renders on this page only. */ html .home-v3_proof_section .rail-v3_wrap-top > .rail-mark-v3_mark-right{display:none} /* ── 12 · Smaller text link, scoped to the recognition note ────────────────── 2026-09-21. The Forrester note link was a bespoke at .875rem; it is now a Style2.0 - Text Link instance, which renders at 1rem. Scoped by OUR OWN wrapper class, not by a flag inside the component. An earlier attempt used a "Size small" boolean prop plus a hidden flag div and :has() — that made links render small everywhere, so the prop and both flag divs were removed and the component is back to its previous structure. Do not reintroduce that mechanism without first verifying on a PUBLISHED page what Webflow actually emits for an element whose visibility is bound to a false boolean prop. */ .home-v3_proof_note_linkwrap .style2-0_text_link_text{ font-size:.875rem; } .home-v3_proof_note_linkwrap .style2-0_text_link_icon{ width:.875rem;height:.875rem;min-width:.875rem;min-height:.875rem; } /* ── 12b · MCP | Mono Arrow Link — hover ──────────────────────────────── The class arrow-link-v3_link carries NO :hover of its own — only a focus-visible outline — so the component had nothing to inherit but the arrow nudge in embed 06. That read as dead next to Style2.0 - Text Link. The underline wipe is drawn with currentColor, so ONE rule serves every variant: Base (#1d1d1b), Brand (#3367ff) and Solutions (a theme variable on a dark card). No variant needs its own hover, and nothing here assumes a colour, which is what would otherwise break on the dark Solutions card. The class itself is untouched (rule 1) — this lives in the embed, like every other hover on this site. */ html .arrow-link-v3_link > span{ background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat; padding-bottom:2px; /* …and take that 2px straight back out of the LAYOUT (2026-09-22, user: the text is not centred with the arrow because "the line that is not yet there also counts"). The link is a flex row with align-items:center, so the room reserved for the underline counted in the centring and lifted the text 1px above the arrow — measured in headless Chrome, text centre 81 vs arrow centre 82; 82 / 82 with this margin. The gap between text and line is unchanged: the negative margin only hides the padding from flex alignment. */ margin-bottom:-2px; /* …and then DOWN, optical (2026-09-22). The label is all CAPS, so its ink stops at the baseline while the line box keeps the empty descender room underneath: a box that centres exactly still reads high. Measured in the REAL PP Supply Mono (woff2 pulled from the site's own font entry, canvas ink box at 12px): cap ascent 8.4px, descent 0. top line-box centre CAP INK centre arrow centre 0px 82 80.8 82 1px 83 81.8 82 3px 85 83.8 82 5px 87 85.8 82 ← set here By ink alone 1px was already level (81.8 vs 82). It is at 5px because the user asked for it three times running ("83 or 84" → "another pixel or two" → "another 2 pixels"); their eye on the real page beats the measurement. This one value is the whole knob; nothing else depends on it. Worth knowing if this comes up again: nothing in the fixture explains why the label reads high on the real page at 1px, where the ink is level. If a later pass finds the Designer was showing a stale embed, re-judge from 1px rather than inheriting 5px. relative/top moves the glyphs and the underline together, so the gap under the text never changes. */ position:relative; top:5px; transition:background-size var(--v3-underline) var(--v3-ease); } @media (hover:hover){ html .arrow-link-v3_link:hover > span{background-size:100% 1px} } /* ── 12c · MCP | Mono Arrow Link — the arrow REDRAW, ungated ──────────────── 2026-09-21 (second pass). User: "Mono link has no arrow animation like the style2.0 link. Can you add it?" Why it could not have one before: the component's arrow was an Image element bound to an `Arrow` asset prop — an pointing at an SVG file. CSS cannot reach inside an , so no stroke can be erased or redrawn there, and the only motion available was a translateX. The Image is gone; the arrow is now the SAME inline svg the Text Link carries (viewBox 0 0 16 16, two filled paths on currentColor), which embed 10's script swaps for stroked paths carrying numeric --l / --ln. Definition element b3543ec0-8f3d-6373-095d-25f85dce242b. currentColor is the point: the component has four colour variants (Base #1d1d1b, Brand #3367ff, Solutions theme-variable, White #ffffff) and the arrow now follows the text on all four from one rule. The per-instance `Arrow` asset overrides that existed only to get a differently-coloured copy of the same glyph are now redundant — listed in references/consistency-2026-09-21/fix-16-mono-arrow-redraw.md. THE SLIDE IS GONE, deliberately. Style2.0 - Text Link redraws and underlines on hover and does NOT translate; the ask was for the two to read the same, so the 6 px translateX that used to live here was removed rather than stacked on top. The transition below stays: embed 06 and embed 11 still slide this icon from a PARENT card's hover (a card nudging its own inner arrow), which is those pages' card behaviour, not this component's own hover, and those rules need it. DEPENDS ON EMBED 10 for @keyframes home-v3-btn-draw and for the path swap. Embed 10 is unconditional on every page, so the dependency always resolves. */ html .arrow-link-v3_icon{transition:transform .35s var(--v3-ease),background-color .25s ease,color .25s ease} html .arrow-link-v3_icon .fxd{stroke-dasharray:var(--l);stroke-dashoffset:0} @media (prefers-reduced-motion:no-preference) and (hover:hover){ html .arrow-link-v3_link:hover .arrow-link-v3_icon .fxd{animation:home-v3-btn-draw .6s linear} html .arrow-link-v3_link:hover .arrow-link-v3_icon .fxd-head{animation-delay:.03s} } /* ── 12d · Style2.0 - Text Link — hover, ungated ──────────────────────────── 2026-09-21. Moved verbatim out of embed 11, which is gated to the "Hover FX: Homepage" prop. That gating was a live bug, not just drift: the first rule below is the ONE that outranks the component's own :hover, whose colour resolves through --_theme---button-primary--text-hover to WHITE. On the six pages where embed 11 was off, every Style2.0 - Text Link therefore turned white on hover on a light section — invisible. That is the unexplained "white hover returning" recorded in decisions/components/style2-text-link.md. Everything here keys off .style2-0_text_link_wrap:has(> .home-v3_link-fx) — the component's own "Hover FX" flag div — so it is still opt-in per instance and is not scoped to any page or section wrapper. Nothing page-specific came with it; the bento, proof-tab and toggle rules stayed behind the prop in embed 11. The component's OWN :hover sets color to --_theme---button-primary--text-hover, which resolves through button-primary--text to WHITE. That is right for a label sitting on a filled blue button and wrong for a standalone link on a light section. Verified by resolving the token, not by eye. We cannot edit that class (it is site-owned and on 12 instances), so we outrank it here — and only for opted-in instances: .style2-0_text_link_wrap:has(> .home-v3_link-fx):hover is 0,3,1 against its 0,2,0. The hover fires from the LINK ONLY (user, 2026-09-21). It fired from the whole .home-v3_logos_quote pill between 2026-09-18 and 2026-09-21; the pill is a div and only the link is a click target, so a pill-wide hover promised a click the pill never took. DEPENDS ON EMBED 10 for @keyframes home-v3-btn-draw and for the script that turns an arrow's filled paths into stroked ones. Embed 10 is unconditional on every page, so that dependency always resolves — which is exactly why this block is safe to run everywhere. */ html .style2-0_text_link_wrap:has(> .home-v3_link-fx):hover{ color:var(--v3-accent-deep); } /* the flag element itself never renders — it only marks an opted-in instance */ html .home-v3_link-fx{display:none} /* Underline back at the user's request (2026-09-18) - it runs together with the arrow redraw, not instead of it. */ html .style2-0_text_link_wrap:has(> .home-v3_link-fx) .style2-0_text_link_text{ background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat; padding-bottom:2px; transition:background-size var(--v3-underline) var(--v3-ease); } /* The arrow redraws itself, the same motion as the button: the stroke clears from the tail, then draws back in, head trailing the shaft by .03s. --l / --ln are the path's getTotalLength() and its negation, both set by embed 10's script. No colour-delay trick here: a text link has no wipe, so the whole thing changes colour at once and the arrow has nothing to wait for. */ html .style2-0_text_link_wrap:has(> .home-v3_link-fx) .style2-0_text_link_icon .fxd{ stroke-dasharray:var(--l);stroke-dashoffset:0; } @media (hover:hover){ html .style2-0_text_link_wrap:has(> .home-v3_link-fx):hover .style2-0_text_link_text{ background-size:100% 1px;text-decoration:none; } } @media (prefers-reduced-motion:no-preference) and (hover:hover){ html .style2-0_text_link_wrap:has(> .home-v3_link-fx):hover .style2-0_text_link_icon .fxd{ animation:home-v3-btn-draw .6s linear; } html .style2-0_text_link_wrap:has(> .home-v3_link-fx):hover .style2-0_text_link_icon .fxd-head{ animation-delay:.03s; } } /* ── reduced motion, for everything in this embed ───────────────────────────*/ @media (prefers-reduced-motion:reduce){ html .arrow-link-v3_link > span{transition:none!important;background-size:0 1px!important} html .arrow-link-v3_icon{transition:none!important;transform:none!important} html .arrow-link-v3_icon .fxd{animation:none!important} html .style2-0_text_link_wrap .style2-0_text_link_text{transition:none!important} html .style2-0_text_link_wrap .style2-0_text_link_icon .fxd{animation:none!important} } /* ── 14 · Stretched card links — UNGATED, on every page ────────────────────── 2026-09-21, links round 3. WHY THIS EXISTS Some cards used to BE the link: the component's root element was a Webflow Link, so the whole card rendered as one . That made it impossible to put a real MCP | Mono Arrow Link instance inside — an start tag inside an open runs the HTML parser's adoption-agency algorithm and CLOSES the outer one, href or no href, which tears the card's DOM in half. A component root's element type cannot be changed through the API (measured: set_tag returns "Element does not support setTag", and a root has no sibling position), so such a card has to be rebuilt on a div root. MCP | Product Tile was rebuilt that way (b07d0fe5-be98-c4a3-77ca-b325c69c8e80; the old anchor-rooted definition 6de38fed-… is renamed "(card-anchor, retired)"). This block gives the whole-card click target back: the arrow link's ::after covers the card. One anchor per card, valid nesting, the same hit area. NOT a class edit — .product-suite-v3_tile is untouched (hard rule 1). Ungated on purpose: a click target is not a hover effect. The tiles sit on [SEPT] Conversational Banking and [SEPT] Relationship Intelligence, and the selector matches nothing anywhere else. ADD A CARD HERE when you rebuild another whole-card-anchor component — MCP | Suite Card and MCP | Segment Link Card are still on their Link roots, because all 11 of their placements are on [TIM EXP] Online & Mobile Banking. Record: references/consistency-2026-09-21/fix-13-links-round3.md */ html .product-suite-v3_tile{ position:relative } html .product-suite-v3_tile .arrow-link-v3_link::after{ content:""; position:absolute; inset:0; } /* 2026-09-28 — MCP | Solution Path cards ([SEPT] Solutions). The six MCP | Gap Card instances in .path-v3_cards link to the product pages (Show link on, page instance props only). Figma draws their mono link blue, the Gap Card nests MCP | Mono Arrow Link on Base (dark) and a variant cannot reach a nested instance's class, so the colour is set here, scoped to this slot only — the other Gap Cards (Homepage, OMB, RI, CO, EW) are untouched. The arrow follows through currentColor. The whole card is the click target, as above. */ html .path-v3_cards .home-v3_gap_card{ position:relative } html .path-v3_cards .home-v3_gap_card .arrow-link-v3_link{ color:#3366ff } html .path-v3_cards .home-v3_gap_card .arrow-link-v3_link::after{ content:""; position:absolute; inset:0; } /* tabs-v3 autoplay — the ONE engine for every [data-tabs-v3] strip that moves on its own (v4). Lives in MCP | Custom Code (embed 15), the first element in Body on every [SEPT] page, so it loads before any tab component. Each tab component still carries its own older copy (v1, BAR, v2, v3); every copy begins with "if (window.topicTabsAuto) … return", so on a [SEPT] page they all hand over to this one. A page without MCP | Custom Code falls back to its components' copies. Built 2026-09-17 for MCP | Topic Tabs; generalised 2026-09-21; v2 (2026-09-23) added the line on any strip; v3 (2026-09-24) synced tabs to code components; v4 (2026-09-24) moved it page-wide. Drives the strip by calling tab.click(), after tabs-v3.js has set the strip up. Three modes, chosen from the markup — no attribute picks them, the strip's own shape does: - LINE — the root holds .topic-tabs-v3_tab tabs. A blue span grows along the active tab (FILL), then its tail follows to the end (EXIT), then the next tab opens. 6 s + 6 s. - BAR — the root carries data-tabs-v3-auto AND its one [data-tabs-v3-indicator] is a thin underline (computed height = 4) { window.topicTabsAuto.init(); return; } var FILL = 6000, EXIT = 6000; /* line mode: head travels FILL, tail follows EXIT */ var DWELL = 6000; /* plain and bar mode: one dwell per tab */ var BAR_MAX = 6; /* px: an indicator taller than this is a pill, not an underline */ var RESUME = 10000; /* a pointer click pauses for this long, then autoplay resumes */ var POINTER_WINDOW = 700; /* focus landing this soon after a pointerdown came from the pointer */ var HOLD = 2000; /* SYNC: a play-once component keeps its last frame this long */ var READY_WAIT = 10000; /* SYNC: no answer by then → the tab falls back to the dwell */ /* SYNC: [src pattern, play length in ms, kind]. kind 'loop' = the tab lasts one loop; 'once' (default) = it plays once, the tab adds HOLD; 'free' = plays once and cannot be paused. Measured 2026-09-24 in headless Chrome from the live builds, first frame to last state (references/relationship-intelligence/tab-sync/). Not listed = static, or cycles forever with no end (Everyday banking, Tailored value propositions, the retired all-in-one components): those tabs keep the strip's own dwell. */ var MINI = [ [/buyer-journeys-/, 16000, 'loop'], [/understanding-savings-buffer/, 32100], [/understanding-maturing-deposit/, 35400], [/understanding-financial-support/, 35100], [/understanding-first-home/, 33700], [/understanding-relationship-repair/, 36700], [/from-question-to-done-/, 5000], [/resolution-workflow-payment-recall/, 44000, 'free'], [/resolution-workflow-card-dispute/, 44400, 'free'], [/resolution-workflow-mortgage-support/, 44900, 'free'], [/resolution-workflow-payment-authority/, 47600, 'free'], [/resolution-workflow-private-banking/, 45600, 'free'] ]; var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; var row = window.matchMedia ? window.matchMedia('(max-width: 991px)') : { matches: false }; var now = function () { return Date.now(); }; /* the code component renders its iframe inside an open shadow root */ function frameIn(panel) { var f = panel.querySelector('iframe'); if (f) return f; var all = panel.querySelectorAll('*'); for (var i = 0; i < all.length; i++) { if (all[i].shadowRoot && (f = all[i].shadowRoot.querySelector('iframe'))) return f; } return null; } function miniOf(f) { var src = f && f.getAttribute('src'); if (!src) return null; for (var i = 0; i < MINI.length; i++) { if (MINI[i][0].test(src)) { var kind = MINI[i][2] || 'once'; return { len: MINI[i][1] + (kind === 'loop' ? 0 : HOLD), free: kind === 'free', src: src }; } } return null; } function setup(root) { if ((root.__ttAuto && root.__ttAuto !== 'v2') || !root.getAttribute('data-tabs-v3-ready')) return; var lineAxis = root.getAttribute('data-tabs-v3-line'); /* v2: 'x' | 'y' draws LINE on any strip */ if (lineAxis !== 'x' && lineAxis !== 'y') lineAxis = null; var topicLine = !!root.querySelector('.topic-tabs-v3_tab[data-tabs-v3-tab]'); var lineMode = topicLine || !!lineAxis; if (!lineMode && !root.hasAttribute('data-tabs-v3-auto')) return; var sel = topicLine ? '.topic-tabs-v3_tab[data-tabs-v3-tab]' : '[data-tabs-v3-tab]'; var tabs = [].slice.call(root.querySelectorAll(sel)).filter(function (t) { return t.style.display !== 'none'; }); var n = tabs.length; if (n < 2) return; var dwell = parseInt(root.getAttribute('data-tabs-v3-auto'), 10); if (!(dwell > 0)) dwell = DWELL; root.__ttAuto = true; root.setAttribute('data-tt-auto', ''); var lines = lineMode ? tabs.map(function (tab) { var s = document.createElement('span'); s.className = 'topic-tabs-v3_line'; s.setAttribute('aria-hidden', 'true'); tab.appendChild(s); return s; }) : []; /* BAR mode: the strip's single sliding indicator becomes the progress line */ var bar = lineMode ? null : root.querySelector('[data-tabs-v3-indicator]'); if (bar) { var bstyle = window.getComputedStyle(bar); if (bstyle.display === 'none' || !(parseFloat(bstyle.height) 0; /* engines where click is not a PointerEvent */ } function keyboardFocus(el) { if (now() - pointerAt >= POINTER_WINDOW) return true; try { if (el && el.matches && el.matches(':focus-visible')) return true; } catch (err) { } return false; } tabs.forEach(function (tab, i) { if (tab.getAttribute('aria-selected') === 'true') active = i; tab.addEventListener('click', function (e) { var prev = active; var trusted = e && e.isTrusted; /* SYNC: re-clicking the open tab must not rewind the line under a running component */ if (synced && trusted && i === prev && pointerDriven(e)) return; active = i; rewind(); if (synced && i !== prev) { if (minis[prev]) restart(minis[prev]); opened(i); } if (!trusted) { paint(); syncFrames(); return; } /* the engine's own advance */ if (!pointerDriven(e)) stop(); else if (!synced) pause(); else { paint(); syncFrames(); } /* SYNC: play this tab from the start, then carry on */ }); tab.addEventListener('keydown', function (e) { var k = e.key; if (!e.isTrusted) return; if (k === 'Enter' || k === ' ' || k === 'ArrowUp' || k === 'ArrowDown' || k === 'ArrowLeft' || k === 'ArrowRight' || k === 'Home' || k === 'End') stop(); }); }); var panels = root.querySelector('[data-tabs-v3-panels]'); if (panels) { panels.addEventListener('mouseenter', function () { hover = true; }); panels.addEventListener('mouseleave', function () { hover = false; last = null; }); } root.addEventListener('pointerdown', function () { pointerAt = now(); }, true); /* keyboard focus inside the strip is a stop; focus a click just moved is not */ root.addEventListener('focusin', function (e) { if (!keyboardFocus(e && e.target)) return; held = true; stop(); }); root.addEventListener('focusout', function () { held = false; last = null; }); if ('IntersectionObserver' in window) { new IntersectionObserver(function (e) { inView = e[0].isIntersecting; }, { threshold: 0.2 }).observe(root); /* SYNC: the component pauses itself below 10 % visible, so the clock must as well */ if (synced && panels) { new IntersectionObserver(function (e) { panelsInView = e[0].isIntersecting; }, { threshold: 0.1 }).observe(panels); } } function paint() { if (barMode) return paintBar(); if (!lineMode) return; var h = lineAxis ? lineAxis === 'x' : row.matches; var p = phase ? 1 - t / exitOf(active) : t / fillOf(active); if (stopped || paused) p = 0; if (p < 0) p = 0; else if (p > 1) p = 1; lines.forEach(function (l, j) { var v = j === active ? p : 0; l.style.transformOrigin = h ? (phase ? 'right center' : 'left center') : (phase ? 'center bottom' : 'center top'); l.style.transform = h ? 'scaleX(' + v + ')' : 'scaleY(' + v + ')'; }); } /* the head/tail worm, in the indicator's own coordinates (offsets inside the track) */ function paintBar() { var tab = tabs[active]; if (!tab) return; var live = !stopped && !paused; var head = live ? (phase ? 1 : t / fillOf(active)) : 1; var tail = live ? (phase ? t / exitOf(active) : 0) : 0; if (head > 1) head = 1; else if (head < 0) head = 0; if (tail > head) tail = head; else if (tail < 0) tail = 0; var w = tab.offsetWidth; /* per-frame values must not be eased; the class transition comes back for the resting bar, so a click still slides it from tab to tab the way it always did */ bar.style.transition = live ? 'none' : barIdle; bar.style.left = Math.round(tab.offsetLeft + w * tail) + 'px'; bar.style.width = Math.max(0, Math.round(w * (head - tail))) + 'px'; } function frame(nw) { var dt = last === null ? 0 : Math.min(nw - last, 100); last = nw; if (synced) follow(); syncFrames(); /* SYNC: the mini-embed answers __bbEmbedPing with its height; ask until it does */ minis.forEach(function (x) { if (!x || x.ready || x.failed || nw - x.ping < 50) return; x.ping = nw; var f = frameOf(x); try { if (f && f.contentWindow) f.contentWindow.postMessage({ __bbEmbedPing: true }, '*'); } catch (err) { } }); var m = minis[active]; if (m && stopped) m.ran = 1; /* it plays on its own now; leaving must still restart it */ if (counting()) { /* SYNC: the clock waits for the component to be on screen and ready */ if (m && !m.ready && !m.failed) { m.wait += dt; if (m.wait >= READY_WAIT) { m.failed = true; syncFrames(); } dt = 0; } if (m && dt) m.ran += dt; t += dt; if (!lineMode && !barMode) { if (t >= lenOf(active)) tabs[(active + 1) % n].click(); } else if (phase === 0 && t >= fillOf(active)) { phase = 1; t = 0; } else if (phase === 1 && t >= exitOf(active)) { tabs[(active + 1) % n].click(); } paint(); } window.requestAnimationFrame(frame); } paint(); window.requestAnimationFrame(frame); } /* A sideways-scrolling tab row with scroll-padding (19i, embed 28): tabs-v3.js scrolls a picked tab flush to the scroller's edge. Where the scroller sets scroll-padding, keep that gap, so the tab stops on the title's edge and not on the rail. Nothing happens without scroll-padding or while the row fits. Runs under reduced motion too (then without the smooth scroll). 2026-09-30: the row scrolls on the track's parent (Capabilities Tabs) or on the track itself (Topic Tabs, Proposition Tabs "Dark, row"); tabs-v3.js only ever scrolls the parent, so on the second kind a picked tab never came into view. Take whichever one scrolls, at click time. */ function inset(root) { if (root.__ttInset) return; var track = root.querySelector('[data-tabs-v3-track]'); if (!track || !track.parentElement) return; root.__ttInset = true; function fit() { var box = /auto|scroll/.test(window.getComputedStyle(track).overflowX) ? track : track.parentElement; var pad = parseFloat(window.getComputedStyle(box).scrollPaddingLeft) || 0; if (!pad || box.scrollWidth s + box.clientWidth) t = r + pad - box.clientWidth; if (t === null) return; if (box.scrollTo) box.scrollTo({ left: t, behavior: reduce ? 'auto' : 'smooth' }); else box.scrollLeft = t; } function later() { window.requestAnimationFrame(fit); } root.addEventListener('click', later); root.addEventListener('keydown', later); } function init() { [].forEach.call(document.querySelectorAll('[data-tabs-v3]'), inset); if (reduce) return; if (window.tabsV3) window.tabsV3.init(); [].forEach.call(document.querySelectorAll('[data-tabs-v3]'), setup); } window.topicTabsAuto = { init: init, v: 4 }; if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); })(); /* 15 · Gap Card video hover — UNGATED, on every page. 2026-09-22. Figma: Resolution gap / Story card / Video hover, node 2472:7034. Full commentary in references/custom-code-component/embeds/15-gap-card-video-hover.html MCP | Gap Card gained a Background slot (e312bb63-…) inside .home-v3_gap_card_media (6e28c2da-…) plus a navy overlay (8433d847-…). Put a video, image or iframe in that slot and the card dissolves to it on hover in 200 ms: copy stays put and turns light, the icon inverts, 56% navy sits between video and text. NOT A VARIANT: Gap Card already has three and they are single-select, so homepage card 3 would have had to give up its tablet width. Keyed to slot CONTENT instead — it composes with every variant and is self-gating, so the 14 cards with an empty slot match none of these rules. NOT A CLASS EDIT — .home-v3_gap_card and its children are untouched (rule 1). UNGATED per the 2026-09-21 rule: it keys off the component's own classes. */ html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])){ position:relative; } html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) > *:not(.home-v3_gap_card_media){ position:relative; z-index:1; } html .home-v3_gap_card_media video, html .home-v3_gap_card_media img, html .home-v3_gap_card_media iframe, html .home-v3_gap_card_media .w-background-video, html .home-v3_gap_card_media [data-gap-bg]{ display:block; width:100%; height:100%; object-fit:cover; } @media (hover: hover){ html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) .home-v3_gap_card_media{ transition:opacity 200ms ease; } html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])):hover .home-v3_gap_card_media{ opacity:1; } html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) .home-v3_gap_card_label, html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) .home-v3_gap_card_title, html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) .home-v3_gap_card_text, html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) .arrow-link-v3_link{ transition:color 200ms ease; } html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])):hover .home-v3_gap_card_label, html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])):hover .home-v3_gap_card_title, html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])):hover .home-v3_gap_card_text, html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])):hover .arrow-link-v3_link{ color:#f5f7fb; } /* the corner mark is #0B1E3A and the glyph is dark line art; brightness(0) invert(1) turns both white and leaves the 10% white plate at its alpha. */ html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])) .home-v3_gap_card_icon{ transition:filter 200ms ease; } html .home-v3_gap_card:has(.home-v3_gap_card_media :is(video,img,iframe,[data-gap-bg])):hover .home-v3_gap_card_icon{ filter:brightness(0) invert(1); } } @media (prefers-reduced-motion: reduce){ html .home-v3_gap_card .home-v3_gap_card_media, html .home-v3_gap_card .home-v3_gap_card_label, html .home-v3_gap_card .home-v3_gap_card_title, html .home-v3_gap_card .home-v3_gap_card_text, html .home-v3_gap_card .arrow-link-v3_link, html .home-v3_gap_card .home-v3_gap_card_icon{ transition-duration:0s; } } /* 15b · Gap Card background video: play on hover only. Figma: "video starts muted from the beginning on each hover". It is also what makes this affordable — three Webflow Background Videos per page autoplay and loop by default, decoding behind an opacity:0 box. Paused at rest, rewound and played on pointer enter, paused on leave. Never arms on touch or under reduced motion: there the card shows the first frame. */ (function () { var canHover = window.matchMedia && matchMedia('(hover: hover)').matches; var still = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches; if (!canHover || still) return; function bind(card) { if (card.__gapBgBound) return; var box = card.querySelector('.home-v3_gap_card_media'); if (!box) return; var vids = box.querySelectorAll('video'); if (!vids.length) return; card.__gapBgBound = 1; Array.prototype.forEach.call(vids, function (v) { v.muted = true; v.loop = true; v.playsInline = true; v.setAttribute('muted', ''); v.setAttribute('playsinline', ''); try { v.pause(); } catch (e) {} }); var each = function (fn) { Array.prototype.forEach.call(vids, function (v) { try { fn(v); } catch (e) {} }); }; card.addEventListener('pointerenter', function () { each(function (v) { v.currentTime = 0; var p = v.play(); if (p && p.catch) p.catch(function () {}); }); }); card.addEventListener('pointerleave', function () { each(function (v) { v.pause(); }); }); } function scan() { Array.prototype.forEach.call(document.querySelectorAll('.home-v3_gap_card'), bind); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', scan); else scan(); window.addEventListener('load', scan); })(); /* MCP | Gap Card, Checklist variant: three rows always render; collapse the unused ones. */ .home-v3_gap_card_check:has(> .home-v3_gap_card_check_label:empty) { display: none; } .home-v3_gap_card_check_sub:empty { display: none; } /* MCP | Product Suite: optional Lede and Footnote. */ .product-suite-v3_lede:empty { display: none; } .product-suite-v3_note:empty { display: none; } /* MCP | 90-Day CTA: the action row holds two stock buttons and a Buttons slot. Hide the row when none of the three is present, so an instance that turns both buttons off and leaves the slot empty does not leave a gap. */ .home-v3_cta2_actions:not(:has(.style2-0_button_main_wrap)) { display: none; } .button-v3_lead-icon[style*="--lead-icon"]{ background-color:currentColor; -webkit-mask:var(--lead-icon) center / contain no-repeat; mask:var(--lead-icon) center / contain no-repeat; } .button-v3_lead-icon[style*="--lead-icon"] > .button-v3_lead-icon_src{ visibility:hidden; } @media (prefers-reduced-motion:no-preference) and (hover:hover){ /* The wipe starts at the left edge, where this mark sits, so it changes with the first character of the label rather than with the arrow at the far right: same .24s ease in, same .18s linear out, no delay. */ .style2-0_button_main_wrap:has(>.home-v3_btn-fx) .button-v3_lead-icon{ transition:background-color .18s linear; } .style2-0_button_main_wrap:has(>.home-v3_btn-fx):hover .button-v3_lead-icon{ transition:background-color .24s cubic-bezier(.33,1,.68,1); } } (function(){ function paint(){ document.querySelectorAll('.button-v3_lead-icon > .button-v3_lead-icon_src').forEach(function(img){ var src = img.currentSrc || img.getAttribute('src'); if (!src || !img.parentElement) return; img.parentElement.style.setProperty('--lead-icon', 'url("' + src + '")'); }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', paint); else paint(); })(); /* 16 CTA drift: Banking OS (user 2026-09-24: "animate the gradient in this cta, so it kind of rotates/moves"). Scoped to pages that carry MCP | Banking OS Hero, so the closing CTA elsewhere stays still. The backdrop is the CTA's image; it is scaled past the edges so the slow turn never shows a corner. The section is a wide strip (~1800x480), where a turn lifts the far edge by W/2*sin(angle): keep the turn at +-2deg about the centre. 2026-09-28: +-5deg about 72% 28% showed a 68px wedge at 33%. Corner cover measured 7px or more from 2560x380 to 320x760. CSS only, off under reduced motion. The CTA's own timeline embed is not touched. */ @media (prefers-reduced-motion: no-preference){ body:has(.os-hero-v3_section) .home-v3_cta2_section{overflow:hidden} body:has(.os-hero-v3_section) .home-v3_cta2_backdrop{ transform-origin:50% 50%; animation:bos-cta-drift 18s ease-in-out infinite; will-change:transform } } @keyframes bos-cta-drift{ 0%,100%{transform:scale(1.3) rotate(0deg) translate3d(0,0,0)} 33%{transform:scale(1.38) rotate(-2deg) translate3d(-2%,2%,0)} 66%{transform:scale(1.34) rotate(2deg) translate3d(2%,-2%,0)} } /* Layer demo fit: Banking OS (user 2026-09-24: "Make sure the height goes together with the embed instead of making embed scrollable"). The six BB / Banking OS / ... layer code components render ; two of them (Orchestration, Connectivity) carry a min-width wider than a phone card and scroll sideways. This scales such a demo down with CSS zoom until it fits the card width. zoom changes layout size, so the card's height follows the scaled demo. Demos that already fit keep zoom 1. Re-fits when the card width changes. Scoped to pages with MCP | Banking OS Hero. The code components themselves are not changed. */ (function () { if (window.__bosLayerFit) return; window.__bosLayerFit = true; function run() { if (!document.querySelector('.os-hero-v3_section')) return; var seen = new WeakMap(); function hosts() { var out = []; document.querySelectorAll('.proposition-v3_media code-island').forEach(function (ci) { if (ci.shadowRoot) ci.shadowRoot.querySelectorAll('banking-os-layers').forEach(function (h) { out.push(h); }); }); return out; } function fit(h) { var sr = h.shadowRoot, vis = sr && sr.querySelector('.visual'); if (!vis) return false; h.style.zoom = ''; var avail = h.clientWidth; if (!avail) return false; var need = vis.scrollWidth; sr.querySelectorAll('.canvas').forEach(function (c) { need = Math.max(need, c.scrollWidth + (vis.clientWidth - c.clientWidth)); }); if (need > avail + 1) h.style.zoom = (avail / need).toFixed(4); return true; } function check() { var pending = 0; hosts().forEach(function (h) { var w = (h.getRootNode().host || h).parentElement; w = w && w.closest('.proposition-v3_media'); var width = w ? Math.round(w.clientWidth) : 0; if (seen.get(h) === width) return; if (fit(h)) seen.set(h, width); else pending++; }); return pending; } var tries = 0; (function poll() { var left = check(); if ((left || !hosts().length) && ++tries < 40) setTimeout(poll, 400); })(); var t; window.addEventListener('resize', function () { clearTimeout(t); t = setTimeout(check, 150); }); var busy = false; /* code components can hydrate late, when scrolled near: check again while scrolling */ window.addEventListener('scroll', function () { if (busy) return; busy = true; setTimeout(function () { busy = false; check(); }, 300); }, { passive: true }); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run); else run(); })(); /* ── 17 · [SEPT] layout fixes, ungated ───────────────────────────────────── 2026-09-25, [SEPT] Agentic Banking fine-tune. Layout only, no hover, no motion. Things a class cannot do on this site: a CSS custom property (update_style rejects --names), an nth-child pattern, and one value that overrides embed 12 without retyping it (set_settings replaces a whole embed). 17a · Section lines at Figma's weight. User: "This lines on sections are too dark. Use our Grid variable color. Not only this section, but in general." The lines already WERE the Grid variable: --_theme---grid = off-black-30 #ced2d7 (sampled in the user's screenshot and on the page). User chose Figma's line colour over changing the site-wide variable: Figma draws the rails and top rules at rgba(29,29,27,.1) / rgba(0,0,0,.1). Every light [SEPT] section sits in an unclassed [data-wrap="light"] wrapper (decisions/site.md, 2026-09-21), so redefining the variable there reaches every u-border-* rail, rule and section bottom inside it, and nothing else. Dark sections switch theme mode on their own class, which re-sets the variable lower down, so they keep theirs. The Grid variable itself is untouched. */ [data-wrap="light"]{--_theme---grid:rgba(29,29,27,.1)} /* 17b · Solutions agents on phones: each column head above its own agents. The matrix is one 3-column grid (3 heads, then 9 agents row by row) inside a display:contents slot wrapper. At one column that stacked all three heads with nothing between them (user: "Fix spacing here on mobile, it's bad"). Child n of every row belongs to column n, so ordering by 3n+1 / 3n+2 / 3n regroups them: head 1, its three agents, head 2, … Source order, and so reading order for assistive tech, is unchanged; only the phone layout moves. */ @media (max-width:767px){ .solutions-v3_matrix > .u-display-contents > :nth-child(3n+1){order:1} .solutions-v3_matrix > .u-display-contents > :nth-child(3n+2){order:2} .solutions-v3_matrix > .u-display-contents > :nth-child(3n){order:3} } /* 17c · MCP | Mono Arrow Link: text back level with the arrow. Overrides embed 12b's top:5px (same selector, later in source). User: "Text and arrow don't align visually in the middle." Their screenshot: text ink 3.5px below the arrow. Re-measured on the live page, real PP Supply Mono, 4x: top 5px → text ink centre +3.9px vs arrow · 1px → −0.13 · 1.5px renders as 1px · 2px → +0.9. 1px is level. The 12b comment explains the history. */ html .arrow-link-v3_link > span{top:1px} /* 17d · [SEPT] Agentic Banking hero edge — the bottom-left tab the other [SEPT] heroes have. User 2026-09-29: "In this hero too". Same geometry as embeds 19h and 21–23: 455 x 36 with a 50 px slope, 208 x 24 on phones. White, like the Split List under it. Gated on MCP | Split List sitting right under the hero, which only this page does (checked on the eleven live [SEPT] pages); the hero's variant is shared with four pages that draw their own edge. */ .hero-v3_section:has(+ .split-list-v3_section)::after{ content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#fff;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} @media (max-width:767px){ .hero-v3_section:has(+ .split-list-v3_section)::after{ width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} } /* ── 18 · [SEPT] Digital Banking fine-tune, ungated ───────────────────────── 2026-09-25. Layout only, no hover, no motion. 18a · MCP | Priority Callout: a code component in the "Visual" slot replaces the image. User: "Make sure I can place code components inside this cards. Add slots for that." The slot (u-display-contents) sits after the Image inside .callouts-v3_media. An empty slot matches nothing, so the four cards keep their image until something is dropped in. */ .callouts-v3_media:has(> .u-display-contents > *) > .callouts-v3_img{display:none} /* 18b · MCP | Proof in Production, variants "Stats and stories" and "Stats and stories, top rule": quote bottom-aligned at desktop too. User: "A little less spacing" (Read story → tab line). The slides share one grid cell sized by the longest quote, so a shorter quote left 74px above the tabs. Medium and below already bottom-align (home-v3_proof_story_slide, 2026-09-25); this extends it to desktop for this variant: every quote now sits 40px above the tabs (the Figma slide's 40 padding). DB moved to the "top rule" variant the same day (the Figma rule at 104 + left notch), so both variants are listed; that also reaches DB v2 and CB. The variant class sits on .home-v3_proof_contain; the slide lives in the nested MCP | Proof Story, which a variant style cannot reach. */ .w-variant-b4654fb2-0dd2-1009-f9c9-d193a8b3f179 .home-v3_proof_story_slide, .w-variant-af75493b-fd80-c6bc-3026-b5855992a107 .home-v3_proof_story_slide{justify-content:flex-end} /* 18c · (2026-09-29: :has() skips w-condition-invisible — the Designer keeps prop-hidden elements, the published page omits them; without it the canvas clipped a section that had the rule switched off.) MCP | Proof in Production, "Top rule (line + left corner)" property (default off). User: "This line and corner are not needed sometimes. Make sure it's hidden by default and can be turned on in properties." The prop is bound to .proof-rule-v3_wrap's visibility, so the element is absent unless switched on. Its rule is 100vw wide; only the "top rule" variant clipped the section, so clip horizontally wherever the line is present (y stays visible: the top-right mark hangs 8px above the section). */ .home-v3_proof_section:has(.proof-rule-v3_wrap:not(.w-condition-invisible,.w-condition-invisible *)){overflow-x:clip} /* 18d · MCP | Agentic Hero "Slot visual" — the bottom-left hero edge the other [SEPT] heroes have. User 2026-09-29: "Yes" (add it to Digital Banking). Same geometry as 17d, 19h and 21–23: 455 x 36 with a 50 px slope, 208 x 24 on phones. White, like the Pillars section under it. The variant is placed on this page only (checked on the eleven live [SEPT] pages). */ .hero-v3_section[data-wf--mcp-agentic-hero--variant="slot-visual"]::after, .hero-v3_section:has(> .hero-v3_bg.w-variant-8ddcb9c2-574c-bebc-208c-5caeac00266e)::after{ content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#fff;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} @media (max-width:767px){ .hero-v3_section[data-wf--mcp-agentic-hero--variant="slot-visual"]::after, .hero-v3_section:has(> .hero-v3_bg.w-variant-8ddcb9c2-574c-bebc-208c-5caeac00266e)::after{ width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} } /* ── 19 · [SEPT] Online & Mobile Banking fine-tune, gated by OMB-only variants ── 2026-09-25. Layout only, no hover, no motion. Plan: references/plans/2026-09-25-omb-finetune.md. Every selector below is keyed on a component variant that renders on this page only (grepped on all eight staging pages the same day), so it reaches no other page unless a later page places the same variant. The one exception is 19e's blue-link rule — read it. Things a class cannot do here: a :has() scope, a pseudo-element mark, a rule on the aria-hidden state the tab engine writes, and a style on a combo class a variant misses. */ /* 19a · MCP | Segment Grid "Icon cards" — one line on top, and a corner where it meets the rail. User: "Double line, why?" — the tabs section's border-bottom (full width) sat 1 px above this section's own inner border-top (between the rails): 2 px. The inner rule goes; the full-width line stays. User: "Please set a corner in this corner" — the rail-mark geometry (8 px, 4 px arms, off-black) drawn outside the top-left crossing. The mark pokes 8 px above the section, which clipped it (overflow:clip); nothing in this section is wider than its container, so it is let out. */ .segment-grid-v3_section:has(.w-variant-685513b7-0ae1-a146-2ac6-1549f1ab9d5b){overflow:visible} .segment-grid-v3_section:has(.w-variant-685513b7-0ae1-a146-2ac6-1549f1ab9d5b) .section-body-v3_inner{border-top-width:0} .segment-grid-v3_section:has(.w-variant-685513b7-0ae1-a146-2ac6-1549f1ab9d5b) > .segment-grid-v3_contain::before{ content:"";position:absolute;top:-.5rem;left:-.5rem;width:.5rem;height:.5rem;pointer-events:none; border-right:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} /* 19b · MCP | Numbered Grid "No intro, with button" — mirrored to Figma 2927:4195. User: "Corner on the wrong side." The top rule ran from the left rail to the right page edge with the mark at the right rail; Figma runs it from the left page edge with the mark at the left rail. User: "Corner is there, but line is missing" — the section had no bottom border, so the proof section's top-right mark sat on white. Phone: "Too much spacing" above the button — item 16 + gap 48 + foot 20 = 84 px, now 32. */ .numbered-grid-v3_section:has(.w-variant-902588a9-2dea-0f4a-cf99-c9d4f7827f9a){border-bottom:1px solid var(--_theme---grid)} .numbered-grid-v3_section:has(.w-variant-902588a9-2dea-0f4a-cf99-c9d4f7827f9a) .numbered-grid-v3_inner{ margin-left:calc(50% - 50vw);padding-left:calc(2rem + 50vw - 50%);padding-right:2rem} .numbered-grid-v3_section:has(.w-variant-902588a9-2dea-0f4a-cf99-c9d4f7827f9a) .numbered-grid-v3_mark{ right:auto;left:-.5rem;border-left-width:0;border-right:.25rem solid var(--_theme---text-primary)} @media (max-width:991px){ .numbered-grid-v3_section:has(.w-variant-902588a9-2dea-0f4a-cf99-c9d4f7827f9a) .numbered-grid-v3_inner{ padding-left:calc(1.5rem + 50vw - 50%);padding-right:1.5rem} } @media (max-width:767px){ .numbered-grid-v3_section:has(.w-variant-902588a9-2dea-0f4a-cf99-c9d4f7827f9a) .numbered-grid-v3_inner{ padding-left:calc(1rem + 50vw - 50%);padding-right:1rem} .numbered-grid-v3_section:has(.w-variant-902588a9-2dea-0f4a-cf99-c9d4f7827f9a) .numbered-grid-v3_foot{ margin-top:-2rem;padding-top:0} } /* 19c · MCP | Proof in Production "Stories only" — the blue words run on after the black. User: "Make sure blue text is next to black." Both spans were display:block. The space between them is drawn here because the two props carry none. */ .home-v3_proof_contain.w-variant-300eb3b7-b1b1-362c-f3e4-052e11d621e7 .home-v3_proof_title_line, .home-v3_proof_contain.w-variant-300eb3b7-b1b1-362c-f3e4-052e11d621e7 .home-v3_proof_title_accent{display:inline} .home-v3_proof_contain.w-variant-300eb3b7-b1b1-362c-f3e4-052e11d621e7 .home-v3_proof_title_accent::before{content:" "} /* 19d · MCP | FAQ Accordion "Dark eyebrow" — less air above the eyebrow. User: "Too much spacing." 104 (proof bottom) + 104 + 32 = 240 px of white above it. Now the section line + 32, like the proof and segment sections on this page, at every width. */ .accordion-v3_contain:has(> .accordion-v3_layout.w-variant-da81bf1a-df9f-dab6-11e5-a8a22125b767){padding-top:0} /* 19e · MCP | Product Suite "Equal groups, grey" — the suite section redrawn in Figma 2927:36217. User: "Replace this section with one in Figma." The new drawing is the Product Suite pattern (two tinted groups of three product tiles), so the section is that component, not a new one. Grey page band #f7f7f7 (painted on the Background Color cover too, which sits on top of the section), no eyebrow, a one-line title (the stack is 33.5rem for CB's two-line title), the "Rail mark (left, inner)" rule at 104 with its mark moved to the right rail as drawn, and Figma's 104 bottom padding at desktop. */ .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a), .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) > .background_wrap{background-color:#f7f7f7} .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) .product-suite-v3_stack{max-width:47rem} .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) .product-suite-v3_eyebrow{display:none} .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) .rail-v3_wrap-offset > .rail-mark-v3_mark{ left:auto;right:-2.5rem;border-right-width:0;border-left:.25rem solid var(--_theme---text-primary)} /* Phones: the contain's side padding is 1rem there (product-suite-v3_contain, small), so the mark comes back 1rem to stay on the right rail. It sat 39 px past the rail (clipped) until 2026-09-29. */ @media (max-width:767px){ .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) .rail-v3_wrap-offset > .rail-mark-v3_mark{right:-1.5rem} } @media (min-width:992px){ .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) .product-suite-v3_contain{padding-bottom:6.5rem} } /* The Agentic tiles' Explore link in blue, as Figma draws it (Digital stays dark). MCP | Product Tile "Badge, brand link" writes #3367ff onto arrow-link-v3_link, but that element is a nested MCP | Mono Arrow Link, and Webflow puts the tile's variant class only on the tile's own elements — measured on RI 2026-09-25: the class is on .product-suite-v3_tile-product, never on the link, so the link rendered dark. This rule keys on the badge that does carry it. UNGATED BY PAGE: it also turns Relationship Intelligence's two Agentic tiles blue, which is what that variant was made for. */ .product-suite-v3_tile:has(> .product-suite-v3_tile-product.w-variant-928cb9d3-4130-f016-db7c-e614b181ab5d) .arrow-link-v3_link{color:#3367ff} /* 19f · MCP | Capabilities Tabs — on tablet and phone the panel height follows the open tab. User: "Way too much spacing every time the tab changes. Can we make it adapt?" The engine stacks every panel in one grid cell, so the cell is as tall as the tallest panel. A closed panel (aria-hidden, set by the engine) leaves the flow and keeps its crossfade on top. */ @media (max-width:991px){ .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 > [data-tabs-v3-panels]{position:relative} .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 [data-tabs-v3-panel][aria-hidden="true"]{ position:absolute;top:0;left:0;right:0} } /* 19g · MCP | Proposition Tabs "Plain list" — one compact row of tabs on phones. User: "a kinda dropdown tabs? Or maybe just smaller tabs in a row without paragraph? Check what's better and do that." Row, not dropdown: all five segments stay visible and swipeable, and the engine already scrolls a picked tab into view in its parent (the nav) — a dropdown would hide the choices and need a second widget. Icon + name only; the intro and the one-line subs go (the section heading and lede already say it). */ @media (max-width:767px){ .proposition-v3_nav.w-variant-b2fba63f-6104-2d32-caba-77e54369509d{ overflow-x:auto;scrollbar-width:none;margin:0 -1rem;padding:0 1rem} .proposition-v3_nav.w-variant-b2fba63f-6104-2d32-caba-77e54369509d::-webkit-scrollbar{display:none} .proposition-v3_nav.w-variant-b2fba63f-6104-2d32-caba-77e54369509d > .proposition-v3_intro{display:none} .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d{flex-direction:row;column-gap:.5rem;width:max-content} .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d .proposition-v3_tab{ flex:0 0 auto;min-height:0;padding:.375rem .875rem .375rem .375rem;column-gap:.5rem} .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d .proposition-v3_tab-icon{flex-basis:2rem;width:2rem;height:2rem} .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d .proposition-v3_tab-img{width:1.125rem;height:1.125rem} .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d .proposition-v3_tab-title{font-size:1rem;white-space:nowrap} .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d .proposition-v3_tab-sub{display:none} /* 2026-09-30 · the progress line sits under the tab name, not across the icon. User: "the line in active tab is not cleanly in the tab". The shared rule (1.0625rem in, .5rem up) is sized for the 100 px desktop card; on this 46 px tab it started under the icon and crossed its lower edge. left = 6 padding + 32 icon + 8 gap; right = the 14 px end padding; its bottom edge meets the icon tile's bottom edge. [data-tabs-v3-line] outranks the shared rule, which loads later. */ [data-tabs-v3-line] .proposition-v3_track.w-variant-b2fba63f-6104-2d32-caba-77e54369509d .proposition-v3_tab .topic-tabs-v3_line{ left:2.875rem;right:.875rem;bottom:.375rem} } /* 19h · MCP | Agentic Hero "Light, image visual" — the bottom-left hero edge the other [SEPT] heroes have. User 2026-09-29: "add the same edge we have on all hero's to this hero". Same geometry as embeds 21–23: tab 455 x 36 with a 50 px slope, 208 x 24 on phones. White, like the section under it. The variant renders on this page only (checked on the live Agentic Hero pages). */ .hero-v3_section[data-wf--mcp-agentic-hero--variant="light-image-visual"]::after, .hero-v3_section:has(> .hero-v3_bg.w-variant-3fb3aca8-b490-f50f-67e1-d29f7600b9f3)::after{ content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#fff;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} @media (max-width:767px){ .hero-v3_section[data-wf--mcp-agentic-hero--variant="light-image-visual"]::after, .hero-v3_section:has(> .hero-v3_bg.w-variant-3fb3aca8-b490-f50f-67e1-d29f7600b9f3)::after{ width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} } /* 19i · MCP | Capabilities Tabs (Underline) — phones: the strip lines up with the title. User 2026-09-29: "I want the slides wrap to have the padding on the left and right removed to outline with title", then "This still needs to be a swiper on mobile. Just from left line to right line". The panel copy got 20 px from the base combo's phone rule (.tabs-v3_copy-card, 1.25rem), which outranks the Plain variant's 0 by source order. The tab row stays one swipeable row; the menu reaches out over the inner's 1rem to the rails and the track takes that 1rem back as padding, so the first tab sits on the title's edge at rest and the row scrolls rail to rail. Tabs lose their side padding (the gap spaces them). A picked tab scrolls in and stops 1rem inside the rail (scroll-padding, honoured by inset() in embed 15). */ @media (max-width:767px){ .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 .tabs-v3_menu{margin:0 -1rem;scroll-padding-inline:1rem;scrollbar-width:none} .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 .tabs-v3_menu::-webkit-scrollbar{display:none} .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 .tabs-v3_track{padding:0 1rem;column-gap:1.25rem} .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 .tabs-v3_tab{padding-left:0;padding-right:0} .tabs-v3_wrap.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836 .tabs-v3_copy-card{padding:0} } /* 20 · [SEPT] Conversational Banking fine-tune 2026-09-25. Layout only. Gate: html:has(.topic-tabs-v3_section) - Topic Tabs is on this page only. Source + notes: references/custom-code-component/embeds/20-cb-finetune.html, references/plans/2026-09-25-cb-finetune.md */ /* 20a hero edge #f7f7f7 (Figma 3522:18006) */ html:has(.topic-tabs-v3_section) .hero-v3_section::after{ content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#f7f7f7;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} @media (max-width:767px){ html:has(.topic-tabs-v3_section) .hero-v3_section::after{width:13rem;height:1.5rem; clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} } /* 20b Channel Cards: rule 104 + left corner, inline dark/blue heading, lede right, blue chips, no card text; phone: title no longer squeezed */ html:has(.topic-tabs-v3_section) .channel-cards-v3_contain{padding-top:8.5rem;padding-bottom:6.5rem;row-gap:2.625rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain::before{ content:"";position:absolute;top:6.5rem;left:calc(50% - 50vw);width:100vw;height:1px; background:var(--_theme---grid);pointer-events:none} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain::after{ content:"";position:absolute;top:6rem;left:-.5rem;width:.5rem;height:.5rem;pointer-events:none; border-right:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain > .intro-v3_stack{ display:block;position:relative;max-width:none;padding-right:calc(50% + 2rem)} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_eyebrow{display:none} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title, html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title-accent{ display:inline;font-family:"Ppneuemontreal Book",Arial,sans-serif;font-size:2.5rem;line-height:1.35;color:#1d1d1b} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title-accent{color:#3367ff} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title-accent::before{content:" ";display:inline;margin:0} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title-accent::after{content:none} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_lede{ position:absolute;top:0;right:0;width:calc(50% - 2rem);max-width:none; font-size:1.25rem;line-height:1.35;color:#0b1e3a} html:has(.topic-tabs-v3_section) .channel-cards-v3_grid{gap:1rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_card{border-radius:.25rem;padding:1.5rem;row-gap:0} html:has(.topic-tabs-v3_section) .channel-cards-v3_card > *{flex-shrink:0} html:has(.topic-tabs-v3_section) .channel-cards-v3_label{ align-self:flex-start;background:#83a2ff;color:#fff;padding:.3125rem;font-size:.875rem;line-height:1.0625rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_title{min-height:0;margin-top:.5rem;font-size:1.5rem;line-height:1.2;color:#111} html:has(.topic-tabs-v3_section) .channel-cards-v3_text{display:none} html:has(.topic-tabs-v3_section) .channel-cards-v3_visual{margin-top:1rem;height:auto;flex:1 0 auto;padding-top:0;border-radius:.25rem} @media (max-width:991px){ html:has(.topic-tabs-v3_section) .channel-cards-v3_contain{padding-top:6rem;padding-bottom:4rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain::before{top:4rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain::after{top:3.5rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain > .intro-v3_stack{padding-right:0} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_lede{position:static;display:block;width:auto;margin-top:1rem} } @media (max-width:767px){ html:has(.topic-tabs-v3_section) .channel-cards-v3_contain{padding-top:5rem;padding-bottom:3rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain::before{top:3rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain::after{top:2.5rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title, html:has(.topic-tabs-v3_section) .channel-cards-v3_contain .intro-v3_title-accent{font-size:2rem} html:has(.topic-tabs-v3_section) .channel-cards-v3_card{padding:1.25rem} } /* 20c Topic Tabs redesign (Figma 3095:44434) */ html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain{padding-top:2rem;padding-bottom:6.5rem;row-gap:1.125rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain > .intro-v3_stack{display:block;max-width:none} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_eyebrow{display:none} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title, html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title-accent{ display:inline;font-family:"Ppneuemontreal Book",Arial,sans-serif;font-size:2.5rem;line-height:1.35;color:#1d1d1b} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title-accent{color:#3367ff} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title-accent::before{content:" ";display:inline;margin:0} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title-accent::after{content:none} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_lede{ display:block;margin-top:1rem;max-width:46.875rem;font-family:"Ppneuemontreal Book",Arial,sans-serif; font-size:1.25rem;line-height:1.4;color:#0b1e3a} html:has(.topic-tabs-v3_section) .topic-tabs-v3_foot{display:none} html:has(.topic-tabs-v3_section) .topic-tabs-v3_body{grid-template-columns:10.25rem minmax(0,1fr);column-gap:2.625rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_tab{min-height:4rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_num{display:none} /* label size lives on the class (1.5rem/2rem, small 1.25rem) - native, not here (2026-09-30) */ html:has(.topic-tabs-v3_section) .topic-tabs-v3_label{color:rgba(165,174,186,.4)} html:has(.topic-tabs-v3_section) .topic-tabs-v3_tab-active .topic-tabs-v3_label, html:has(.topic-tabs-v3_section) [data-tabs-v3]:not([data-tabs-v3-ready]) .topic-tabs-v3_tab:first-child .topic-tabs-v3_label{color:#3366ff} html:has(.topic-tabs-v3_section) .topic-tabs-v3_panel{column-gap:2.625rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_panel-title{font-size:2rem;line-height:2.125rem;color:#0b1e3a} html:has(.topic-tabs-v3_section) .topic-tabs-v3_panel-text{line-height:1.75rem;color:#0b1e3a} html:has(.topic-tabs-v3_section) .topic-tabs-v3_chat{background-color:#efefef;border-radius:.625rem} @media (max-width:991px){ html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain{padding-bottom:4rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_body{grid-template-columns:minmax(0,1fr)} } @media (max-width:767px){ html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain{padding-bottom:3rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title, html:has(.topic-tabs-v3_section) .topic-tabs-v3_contain .intro-v3_title-accent{font-size:2rem} html:has(.topic-tabs-v3_section) .topic-tabs-v3_panel-title{font-size:1.625rem;line-height:1.2} } /* 20d Controls Showcase: no eyebrow, heading 32 below the line, top-left corner */ html:has(.topic-tabs-v3_section) .controls-showcase-v3_section{overflow-x:clip;overflow-y:visible} html:has(.topic-tabs-v3_section) .controls-showcase-v3_eyebrow{display:none} html:has(.topic-tabs-v3_section) .controls-showcase-v3_contain{padding-top:2rem;padding-bottom:6.5rem} html:has(.topic-tabs-v3_section) .controls-showcase-v3_contain::before{ content:"";position:absolute;top:-.5rem;left:-.5rem;width:.5rem;height:.5rem;pointer-events:none; border-right:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} @media (max-width:991px){html:has(.topic-tabs-v3_section) .controls-showcase-v3_contain{padding-bottom:4rem}} @media (max-width:767px){html:has(.topic-tabs-v3_section) .controls-showcase-v3_contain{padding-bottom:3rem}} /* 20e Conversation Bento: rule + right corner (Figma 3095:46450) */ html:has(.topic-tabs-v3_section) .card-grid-v3_contain > .section-body-v3_inner{position:relative} html:has(.topic-tabs-v3_section) .card-grid-v3_contain > .section-body-v3_inner::before{ content:"";position:absolute;top:0;left:calc(50% - 50vw);width:100vw;height:1px; background:var(--_theme---grid);pointer-events:none} html:has(.topic-tabs-v3_section) .card-grid-v3_contain > .section-body-v3_inner::after{ content:"";position:absolute;top:-.5rem;right:-.5rem;width:.5rem;height:.5rem;pointer-events:none; border-left:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} /* 20f Product Suite: rail mark at the left rail, no eyebrow, 750 title, white tags, phone inset */ html:has(.topic-tabs-v3_section) .product-suite-v3_eyebrow{display:none} html:has(.topic-tabs-v3_section) .product-suite-v3_stack{max-width:46.875rem} html:has(.topic-tabs-v3_section) .product-suite-v3_contain{padding-bottom:6.5rem} html:has(.topic-tabs-v3_section) .product-suite-v3_contain > .rail-v3_wrap-offset > .rail-mark-v3_mark{left:-2.5rem} html:has(.topic-tabs-v3_section) .product-suite-v3_tile-product{color:#fff} @media (max-width:991px){ html:has(.topic-tabs-v3_section) .product-suite-v3_contain{padding-bottom:4rem} html:has(.topic-tabs-v3_section) .product-suite-v3_contain > .rail-v3_wrap-offset{margin-top:0} } @media (max-width:767px){ html:has(.topic-tabs-v3_section) .product-suite-v3_contain{padding-left:1rem;padding-right:1rem;padding-bottom:3rem} html:has(.topic-tabs-v3_section) .product-suite-v3_contain > .rail-v3_wrap-offset > .rail-mark-v3_mark{left:-1.5rem} } @media (max-width:479px){ html:has(.topic-tabs-v3_section) .product-suite-v3_group, html:has(.topic-tabs-v3_section) .product-suite-v3_group-blue, html:has(.topic-tabs-v3_section) .product-suite-v3_tile{padding:.75rem} html:has(.topic-tabs-v3_section) .product-suite-v3_grid{gap:.5rem} html:has(.topic-tabs-v3_section) .product-suite-v3_tile-product{font-size:.75rem;letter-spacing:.075rem} } /* 20g Conversation Card Visual slot hides the image - UNGATED */ .card-grid-v3_card:has(> .u-display-contents > *) > .card-grid-v3_preview{display:none} /* 21 — [SEPT] Customer Operations fine-tune (2026-09-25). Layout only. Gate = the Solutions "Matrix only, 4 columns" variant, placed on this page alone (grepped on all [SEPT] staging pages). If another page ever places that variant, these rules follow it there. */ html:has(.w-variant-0ad50369-2f1d-9ef1-4d66-42fb8de1ba03,[data-wf--mcp-solutions--variant="matrix-only-4-columns"]){ /* Tabs: hover + focus, carried over from embed 13 (the RI layer is off on this page). */ @media (hover:hover){ .tabs-v3_tab{transition:color .2s var(--v3-ease)} .tabs-v3_tab:not(.tabs-v3_tab-active):hover{color:var(--v3-accent)} } .tabs-v3_tab:focus-visible{outline:2px solid var(--v3-accent);outline-offset:-2px} @media (prefers-reduced-motion:reduce){.tabs-v3_tab{transition:none!important}} /* 1. Hero edge (Figma 3247:4243): bottom-left tab, 455 x 36, 50 px slope. It takes the colour of the section under it: grey under the grey Statement Band, else white. */ .hero-v3_section::after{content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:var(--co-hero-edge,#fff);clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} .hero-v3_section:has(+ .statement-band-v3_section .statement-band-v3_fill.w-variant-5ce6bbf3-2265-b842-d94d-5af9f84ffae2), .hero-v3_section:has(+ .statement-band-v3_section[data-wf--mcp-statement-band--variant="grey-rails"]){--co-hero-edge:#efefef} @media (max-width:767px){ .hero-v3_section::after{width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} } /* 2. Statement Band (Figma 3247:4594): text starts on the section edge like every other section; the corner sits outside the right rail, on the line. */ .statement-band-v3_grid{padding-left:0;padding-right:0} .statement-band-v3_marks .rail-mark-v3_mark-right{left:auto;right:-2.5625rem} @media (max-width:767px){ .section_contain.u-container.u-border-left.u-border-right.statement-band-v3_contain{padding-left:1rem;padding-right:1rem} .statement-band-v3_marks .rail-mark-v3_mark-right{right:-1.5625rem} } /* 3. Capabilities Tabs (Figma 3247:4604): full-bleed line at the top of the body, corner outside the left rail on it; the lede starts level with the heading. */ .underline-tabs-v3_contain > .section-body-v3_inner{position:relative} .underline-tabs-v3_contain > .section-body-v3_inner::before{content:"";position:absolute;top:-1px;left:-100vw;right:-100vw;height:1px;background:var(--_theme---grid);pointer-events:none} .underline-tabs-v3_contain > .section-body-v3_inner::after{content:"";position:absolute;top:-.5rem;left:-.5rem;z-index:1;width:.5rem;height:.5rem;pointer-events:none; border-right:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} .underline-tabs-v3_contain .section-head-v3_lede.section-head-v3_lede-muted{align-self:start} /* 4. Resolution Gap "Accent first" (Figma 3261:15723): grey section, white cards; line with the corner outside the right rail; the eyebrow 32 px below the line; the checklists start on one level in every card. */ .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)){background-color:#f7f7f7} .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_card{background-color:#fff} .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_head{position:relative;padding-top:2rem} .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_head::before{content:"";position:absolute;top:-1px;left:-100vw;right:-100vw;height:1px;background:var(--_theme---grid);pointer-events:none} .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_head::after{content:"";position:absolute;top:-.5rem;right:-2.5625rem;z-index:1;width:.5rem;height:.5rem;pointer-events:none; border-left:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_card_body{flex-grow:1} @media (min-width:768px){ .home-v3_gap_card_checks{min-height:6.3125rem} } @media (max-width:767px){ .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_head{padding-top:1.5rem} .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_head::after{right:-1.5625rem} } /* The Resolution Gap's bottom-left notch follows its own Bottom notch prop: off on "Elastic operations", on under "Powered by Banking OS" (user 2026-09-29). */ /* 4b. Resolution Gap "Two columns" (Figma 3254:10757): the Rail mark (right) corner sits on the right rail, mirroring the bottom-left notch. Its wrapper is inside the contain's 2rem (phones 1rem) padding, so the class's -0.5rem left it that far inside the rail. */ .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="two-columns"],:has(.w-variant-0300120a-3f28-9f10-901e-dee662cb1396)) .rail-v3_wrap-gap .rail-mark-v3_mark{right:-2.5rem} @media (max-width:767px){ .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="two-columns"],:has(.w-variant-0300120a-3f28-9f10-901e-dee662cb1396)) .rail-v3_wrap-gap .rail-mark-v3_mark{right:-1.5rem} } /* 5. Solutions (Figma 3254:9550): 110 px of dark above a full-bleed line, the white corner on it, the eyebrow 32 px below; a little more room between agent icon and name. */ .solutions-v3_grid{padding-top:8.875rem} .solutions-v3_grid_head{position:relative} .solutions-v3_grid_head::before{content:"";position:absolute;top:-2rem;left:-100vw;right:-100vw;height:1px;background:var(--_theme---grid);pointer-events:none} .solutions-v3_mark{top:6.375rem} .solutions-v3_cell_icon{margin-bottom:.5rem} @media (max-width:991px){ .solutions-v3_grid{padding-top:6rem} .solutions-v3_mark{top:3.5rem} } @media (max-width:767px){ .solutions-v3_grid{padding-top:5rem} .solutions-v3_mark{top:2.5rem} } /* 7. Product Suite: no corner, no extra top space (user); an empty eyebrow takes no gap. */ .product-suite-v3_eyebrow:empty{display:none} /* 8. 90-Day CTA: the closing now sits in the same section as the timeline (one instance, Base variant). Its lede gets Figma's gap under the heading. */ .home-v3_cta2_closing .closing-cta-v3_text{margin-top:2.5rem} /* Product Suite on phones: 1 rem inset so the groups stop touching the rails, and tile / tag sizes that keep the tags inside their tiles (carried over from embed 13). */ @media (max-width:767px){ .product-suite-v3_contain{padding-left:1rem;padding-right:1rem} } @media (max-width:479px){ .product-suite-v3_group, .product-suite-v3_group-blue, .product-suite-v3_tile{padding:.75rem} .product-suite-v3_grid{gap:.5rem} .product-suite-v3_tile-product{font-size:.75rem;letter-spacing:.075rem} } } /* 22 — [SEPT] Customer Onboarding fine-tune (2026-09-25). Layout only. 22a is gated on MCP | Systems Map, which is placed on this page alone (grepped on all [SEPT] staging pages). 22b (slots) is ungated: it only matches a filled slot. 2026-09-25 (later): Employee Workspaces also places MCP | Systems Map, so the gate now excludes a page that carries Capabilities Tabs too — that page has its own embed 23. The spacing system on this page: line 104 below the section top (64 on phones), content 32 below the line, 104 (64) from the last content to the section end. */ html:has(.systems-map-v3_stage):not(:has(.card-tabs-v3_section)){ /* Hero edge (Figma 3527:18195): bottom-left white tab, 455 x 36, 50 px slope. */ .hero-v3_section::after{content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#fff;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} /* No line on the section boundaries — Figma has none. Each section's own line (with its corner) is the only one. The line above Proof in Production stays: its corner sits on it. */ .u-section.u-border-bottom:is(.card-grid-v3_section,.home-v3_gap_section,.home-v3_proof_section,.product-suite-v3_section,.accordion-v3_section):not(:has(.systems-map-v3_stage)){border-bottom-width:0} /* Numbered Grid: line to badge 32 (the item carries 28), 104 under the last text. */ .numbered-grid-v3_inner{padding-top:.25rem} .section_contain.u-container.u-border-left.u-border-right.numbered-grid-v3_contain{padding-top:6.5rem;padding-bottom:4.75rem} /* 2026-10-05: its corner sits on that line (the class puts it at 96 / 56 / 40, made for other paddings) */ .numbered-grid-v3_contain > .numbered-grid-v3_mark{top:6rem} /* Resolution Gap: 104 / 104 at every width above phones; corners outside the rails, as in Figma — right on "Make complex cases", left on "Don't let a request". */ .section_contain.u-container.u-border-left.u-border-right.home-v3_gap_contain{padding-top:6.5rem;padding-bottom:6.5rem} .home-v3_gap_section .rail-v3_wrap-gap .rail-mark-v3_mark{left:auto;right:-2.5rem} .home-v3_gap_section:has(.w-variant-eb09e1cd-dc82-6787-66b3-c0feb06ed44a) .rail-v3_wrap-gap .rail-mark-v3_mark{right:auto;left:-2.5rem;transform:scaleX(-1)} .home-v3_gap_notch{display:none} /* Proof in Production: eyebrow 32 under its line, 104 under the quote tabs. */ .section_contain.u-container.u-border-left.u-border-right.home-v3_proof_contain{padding-top:2.5rem;padding-bottom:3.8125rem} /* Product Suite: corner outside the left rail; empty eyebrow takes no room (heading 32 under the line); 104 under the note; product tags stay inside their tiles. */ .product-suite-v3_eyebrow:empty{display:none} .section_contain.u-container.u-border-left.u-border-right.product-suite-v3_contain{padding-bottom:6.5rem} .product-suite-v3_contain > .rail-v3_wrap-offset > .rail-mark-v3_mark{left:-2.5rem} .product-suite-v3_tile-product{max-width:100%;overflow-wrap:anywhere} /* FAQ: line 104 below the top at every width above phones, 104 under the last question. */ .section_contain.u-container.u-border-left.u-border-right.accordion-v3_contain{padding-top:6.5rem;padding-bottom:6.5rem} .accordion-v3_layout{padding-bottom:0} @media (min-width:768px) and (max-width:991px){ .section_contain.u-container.u-border-left.u-border-right.home-v3_proof_contain{padding-bottom:4.8125rem} } @media (max-width:767px){ .hero-v3_section::after{width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} .section_contain.u-container.u-border-left.u-border-right.numbered-grid-v3_contain{padding-top:4rem;padding-bottom:3rem} .numbered-grid-v3_contain > .numbered-grid-v3_mark{top:3.5rem} .section_contain.u-container.u-border-left.u-border-right.home-v3_gap_contain{padding-top:4rem;padding-bottom:4rem} .home-v3_gap_section .rail-v3_wrap-gap .rail-mark-v3_mark{right:-1.5rem} .home-v3_gap_section:has(.w-variant-eb09e1cd-dc82-6787-66b3-c0feb06ed44a) .rail-v3_wrap-gap .rail-mark-v3_mark{left:-1.5rem} .section_contain.u-container.u-border-left.u-border-right.home-v3_proof_contain{padding-top:2.375rem;padding-bottom:2.3125rem} .section_contain.u-container.u-border-left.u-border-right.product-suite-v3_contain{padding:4rem 1rem} .product-suite-v3_contain > .rail-v3_wrap-offset{margin-top:0} .product-suite-v3_contain > .rail-v3_wrap-offset > .rail-mark-v3_mark{left:-1.5rem} .section_contain.u-container.u-border-left.u-border-right.accordion-v3_contain{padding-top:4rem;padding-bottom:4rem} .accordion-v3_layout{padding-top:2rem} } @media (max-width:479px){ .product-suite-v3_group,.product-suite-v3_group-blue,.product-suite-v3_tile{padding:.75rem} .product-suite-v3_grid{gap:.5rem} .product-suite-v3_tile-product{font-size:.75rem;letter-spacing:.075rem} } } /* 22b — slots for code components (ungated: a filled slot only exists where someone filled it). MCP | Segment Card "Visual" slot: the preview image steps aside. MCP | Systems Map "Diagram" slot: the drawn diagram steps aside, and the grey box with it, so the component gets the whole area. Nothing is removed from either definition. */ .card-grid-v3_card:has(> .u-display-contents > *) > .card-grid-v3_preview{display:none} .card-grid-v3_card > .u-display-contents > *,.systems-map-v3_stage > .u-display-contents:first-child > *{align-self:stretch;width:100%} .systems-map-v3_stage:has(> .u-display-contents:first-child > *){padding:0;background:none;border-radius:0} .systems-map-v3_stage:has(> .u-display-contents:first-child > *) > :not(:first-child){display:none} /* 23 — [SEPT] Employee Workspaces fine-tune (2026-09-25). Layout only. Gated on Capabilities Tabs + Systems Map together: this page is the only one with both (grepped on all [SEPT] staging pages; Online & Mobile / TIM EXP have the tabs, Customer Onboarding has the map). Embed 22's gate excludes this page for the same reason. Figma 3288:19345: one line per section, 104 below its top, corner outside the rail, alternating right / left; no line on any section boundary; white tab at the hero's bottom-left. Spacing: line 104, content 32 below it, 104 from the last content to the section end (phones 64 / 32 / 64) — the Customer Onboarding system. 2026-09-25 (later): [SEPT] Banking OS also has both, so the gate excludes a page with MCP | Banking OS Hero — that page has its own embed 24. 2026-09-29: the Systems Map test skips w-condition-invisible. The Card Grid carries a prop-hidden map; the Designer keeps it in the canvas, so the gate was on there only and drew the old 104 px lines over the section-spacing layout. Published pages never had it. */ html:has(.card-tabs-v3_section):has(.systems-map-v3_stage:not(.w-condition-invisible,.w-condition-invisible *)):not(:has(.os-hero-v3_section)){ /* Hero edge: 455 x 36, 50 px slope. The 1 px strip under it covers the seam a fractional hero height leaves at the tab's foot. */ .hero-v3_section::after{content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#fff;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} .hero-v3_section + .home-v3_gap_section::before{content:"";position:absolute;left:0;top:-1px;z-index:3;width:28.125rem;height:1px;background:#fff;pointer-events:none} /* No boundary lines; the old marks (gap notch, rail marks, card-grid rule) step aside. */ :is(.home-v3_gap_section,.card-tabs-v3_section,.home-v3_proof_section,.card-grid-v3_section,.product-suite-v3_section,.accordion-v3_section){border-bottom-width:0;overflow-x:clip} .home-v3_gap_notch,.rail-mark-v3_mark,.rail-mark-v3_rule{display:none} /* One line + corner per section, drawn on the container. Right corner by default (line from the page edge to the right rail)... */ :is(.home-v3_gap_section,.card-tabs-v3_section,.home-v3_proof_section,.card-grid-v3_section,.product-suite-v3_section,.accordion-v3_section) > .section_contain::before{ content:"";position:absolute;top:6.5rem;left:-100vw;right:-1px;height:1px;background:var(--_theme---grid);pointer-events:none} :is(.home-v3_gap_section,.card-tabs-v3_section,.home-v3_proof_section,.card-grid-v3_section,.product-suite-v3_section,.accordion-v3_section) > .section_contain::after{ content:"";position:absolute;top:6rem;right:calc(-.5rem - 1px);width:.5rem;height:.5rem;pointer-events:none; border-left:.25rem solid var(--_theme---text-primary);border-bottom:.25rem solid var(--_theme---text-primary)} /* ...left corner on Capabilities Tabs, Proof and Product Suite (line from the left rail to the page edge). */ :is(.card-tabs-v3_section,.home-v3_proof_section,.product-suite-v3_section) > .section_contain::before{left:-1px;right:-100vw} :is(.card-tabs-v3_section,.home-v3_proof_section,.product-suite-v3_section) > .section_contain::after{right:auto;left:calc(-.5rem - 1px);border-left:0;border-right:.25rem solid var(--_theme---text-primary)} /* Spacing. Inner offsets already in the components: tabs / map / FAQ carry 32 on top, the suite heading 3, the proof logos sit 31 above their buttons' foot. */ .section_contain.u-container.u-border-left.u-border-right.home-v3_gap_contain{padding-top:8.5rem;padding-bottom:6.5rem} .section_contain.u-container.u-border-left.u-border-right.card-tabs-v3_contain{padding-top:6.5rem;padding-bottom:6.5rem} .section_contain.u-container.u-border-left.u-border-right.home-v3_proof_contain{padding-top:8.5rem;padding-bottom:4.5625rem} .section_contain.u-container.u-border-left.u-border-right.card-grid-v3_contain{padding-top:6.5rem;padding-bottom:6.5rem} .section_contain.u-container.u-border-left.u-border-right.product-suite-v3_contain{padding-top:8.3125rem;padding-bottom:6.5rem} .section_contain.u-container.u-border-left.u-border-right.accordion-v3_contain{padding-top:6.5rem;padding-bottom:6.5rem} .product-suite-v3_eyebrow:empty{display:none} .accordion-v3_layout{padding-bottom:0} .product-suite-v3_tile-product{max-width:100%;overflow-wrap:anywhere} /* Tablet: the three gap cards stay in one row (they broke 2 + 1). */ @media (min-width:768px) and (max-width:991px){ .home-v3_gap_cards{grid-template-columns:repeat(3,minmax(0,1fr))} } /* Phones: 64 / 32 / 64; suite tiles in one column (they broke 2 + 1 and squeezed the copy). */ @media (max-width:767px){ .hero-v3_section + .home-v3_gap_section::before{width:12.6875rem} .hero-v3_section::after{width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} :is(.home-v3_gap_section,.card-tabs-v3_section,.home-v3_proof_section,.card-grid-v3_section,.product-suite-v3_section,.accordion-v3_section) > .section_contain::before{top:4rem} :is(.home-v3_gap_section,.card-tabs-v3_section,.home-v3_proof_section,.card-grid-v3_section,.product-suite-v3_section,.accordion-v3_section) > .section_contain::after{top:3.5rem} .section_contain.u-container.u-border-left.u-border-right.home-v3_gap_contain{padding-top:6rem;padding-bottom:4rem} .section_contain.u-container.u-border-left.u-border-right.card-tabs-v3_contain{padding-top:4rem;padding-bottom:4rem} .section_contain.u-container.u-border-left.u-border-right.home-v3_proof_contain{padding-top:6rem;padding-bottom:2.625rem} .section_contain.u-container.u-border-left.u-border-right.card-grid-v3_contain{padding-top:4rem;padding-bottom:4rem} .section_contain.u-container.u-border-left.u-border-right.product-suite-v3_contain{padding-top:5.875rem;padding-bottom:4rem} .section_contain.u-container.u-border-left.u-border-right.accordion-v3_contain{padding-top:4rem;padding-bottom:4rem} .product-suite-v3_grid{grid-template-columns:minmax(0,1fr)} .product-suite-v3_tile,.product-suite-v3_tile-title{min-height:0} } } /* 23b · Hero edge, outside the gate above. 2026-09-29: the page no longer places MCP | Systems Map (a second Resolution Gap took its place), so the gate above matches nothing and the edge was gone. User: "Yes" (add it back). Keyed on the Agentic Hero variant "Demo below, centred", which only this page places (checked on the eleven live [SEPT] pages). The rest of this embed stays switched off. The 1 px strip covers the seam the hero's fractional height leaves at the tab's foot (measured: hero ends at 1317.5 px at 1440). */ .hero-v3_section[data-wf--mcp-agentic-hero--variant="demo-below-centred"]::after, .hero-v3_section:has(> .hero-v3_bg.w-variant-de702294-bfbd-d55b-f0f2-e3dfd074d8df)::after{ content:"";position:absolute;left:-.3125rem;bottom:0;z-index:3;width:28.4375rem;height:2.25rem; background:#fff;clip-path:polygon(0 0,calc(100% - 3.125rem) 0,100% 100%,0 100%);pointer-events:none} .hero-v3_section[data-wf--mcp-agentic-hero--variant="demo-below-centred"] + .home-v3_gap_section::before, .hero-v3_section:has(> .hero-v3_bg.w-variant-de702294-bfbd-d55b-f0f2-e3dfd074d8df) + .home-v3_gap_section::before{ content:"";position:absolute;left:0;top:-1px;z-index:3;width:28.125rem;height:1px;background:#fff;pointer-events:none} @media (max-width:767px){ .hero-v3_section[data-wf--mcp-agentic-hero--variant="demo-below-centred"]::after, .hero-v3_section:has(> .hero-v3_bg.w-variant-de702294-bfbd-d55b-f0f2-e3dfd074d8df)::after{ width:13rem;height:1.5rem;clip-path:polygon(0 0,calc(100% - 2.0833rem) 0,100% 100%,0 100%)} .hero-v3_section[data-wf--mcp-agentic-hero--variant="demo-below-centred"] + .home-v3_gap_section::before, .hero-v3_section:has(> .hero-v3_bg.w-variant-de702294-bfbd-d55b-f0f2-e3dfd074d8df) + .home-v3_gap_section::before{width:12.6875rem} } /* 24 — [SEPT] Banking OS fine-tune (2026-09-25). Layout only; the script only positions the hero art. No motion. Gated on MCP | Banking OS Hero, which is placed on this page alone. Figma 3513:88299. One spacing system: a full-bleed line 104 below the section top (64 on phones) with its corner on the rail, content 32 (24) below the line. Lines are drawn by ::before / corners by ::after on each section's contain, so the shared definitions are not touched. */ body:has(.os-hero-v3_section){ --bos-rule:6.5rem; --bos-gap:2rem; /* Hero: eyebrow 48 under the nav (Figma 51). The clear band follows the logo size: the code component draws it at min(43.75vw, 285px), scaled .8 on phones, plus 20 each side. --bos-art-y (script below) moves the component onto the band's centre. */ & .section_contain.u-container.u-border-left.u-border-right.os-hero-v3_contain{padding-top:3rem} & .os-hero-v3_mark{height:20.25rem} & .os-hero-v3_art{translate:0 var(--bos-art-y,0px)} /* Sections that carry a line + corner */ & :is(.numbered-grid-v3_section,.controls-showcase-v3_section,.home-v3_gap_section,.card-tabs-v3_section,.home-v3_proof_section,.recognition-v3_section){overflow-x:clip} & :is(.numbered-grid-v3_contain,.controls-showcase-v3_contain,.home-v3_gap_contain,.card-tabs-v3_contain,.home-v3_proof_contain,.recognition-v3_contain){ &::before{content:"";position:absolute;z-index:2;top:var(--bos-rule);left:50%;width:100vw;height:1px;margin-left:-50vw; background:rgba(29,29,27,.1);pointer-events:none} &::after{content:"";position:absolute;z-index:2;top:calc(var(--bos-rule) - .5rem);right:-.5rem;width:.5rem;height:.5rem; box-sizing:border-box;border-bottom:.25rem solid #000;border-left:.25rem solid #000;pointer-events:none} } /* corner on the left rail */ & :is(.controls-showcase-v3_contain,.card-tabs-v3_contain)::after{right:auto;left:-.5rem;border-left:0;border-right:.25rem solid #000} /* dark section */ & .card-tabs-v3_contain::before{background:rgba(255,255,255,.08)} & .card-tabs-v3_contain::after{border-color:#fff} /* no line on the section boundaries — Figma has none; each section's own line is the one */ & .u-section.u-border-bottom{border-bottom-width:0} /* the lines these components drew themselves: replaced by the ones above */ & .u-border-top.numbered-grid-v3_inner{border-top-width:0;padding-top:0} & :is(.numbered-grid-v3_mark,.home-v3_proof_section .rail-v3_wrap-top,.recognition-v3_rail){display:none} /* content 32 under the line */ & :is(.section_contain.u-container.u-border-left.u-border-right.numbered-grid-v3_contain, .section_contain.u-container.u-border-left.u-border-right.controls-showcase-v3_contain, .section_contain.u-container.u-border-left.u-border-right.home-v3_gap_contain, .section_contain.u-container.u-border-left.u-border-right.card-tabs-v3_contain, .section_contain.u-container.u-border-left.u-border-right.home-v3_proof_contain, .section_contain.u-container.u-border-left.u-border-right.recognition-v3_contain){padding-top:calc(var(--bos-rule) + 1px + var(--bos-gap))} & .card-tabs-v3_contain > .section-body-v3_inner{padding-top:0} /* Why Banking OS → Unified Frontline: one white field, no line between (Figma) */ & .section_contain.u-container.u-border-left.u-border-right.numbered-grid-v3_contain{padding-bottom:3.75rem} & .card-grid-v3_contain > .rail-mark-v3_rule{display:none} & .section_contain.u-container.u-border-left.u-border-right.card-grid-v3_contain{padding-top:.5rem} & .card-grid-v3_contain > .section-body-v3_inner{padding-top:0} /* Six layers: tabs and the 01–04 row flush with the text column */ & .proposition-v3_nav{padding-left:0;padding-right:0} & .proposition-v3_foot{padding-left:0;padding-right:0} /* Put AI to work: the Trust Centre image fades out 56 above the dark section (Figma) */ & .section_contain.u-container.u-border-left.u-border-right.home-v3_gap_contain{padding-bottom:3.5rem} /* Proof: 78 under the quote (Figma), not 118. The Standard Chartered SVG carries 26 px of empty canvas on its left; pull it back so all three logos start on the text edge. */ & .home-v3_proof_stories{padding-bottom:0} & .home-v3_proof_stat_logo[alt="Standard Chartered"]{margin-left:-1.625rem} /* Closing CTA: the three overrides (no rails, no inner line, 2-line lede) removed 2026-09-30 — the user wants the live CTA to look like the Designer. Old rules: backup/24-bos-finetune.2026-09-30-before-split.html */ } @media (min-width:768px){ body:has(.os-hero-v3_section) .proposition-v3_track{width:100%} } @media (max-width:767px){ body:has(.os-hero-v3_section){ --bos-rule:4rem; --bos-gap:1.5rem; & .os-hero-v3_mark{height:calc(min(35vw,14.25rem) + 2.5rem)} } } /* Hero: centre the code component on the clear band between the heading and the lede. The component sizes its iframe to its own content and draws the logo in its middle, and the iframe is centred on the section; so the band centre minus the section centre is the shift. Re-measured when the section resizes (fonts, wrapping, breakpoints). */ (function(){ if (window.__bosHero) return; window.__bosHero = true; function place(){ var s = document.querySelector('.os-hero-v3_section'); if (!s) return; var bg = s.querySelector('.os-hero-v3_bg'), band = s.querySelector('.os-hero-v3_mark'); if (!bg || !band) return; var b = bg.getBoundingClientRect(), m = band.getBoundingClientRect(); s.style.setProperty('--bos-art-y', Math.round((m.top + m.height / 2) - (b.top + b.height / 2)) + 'px'); } function run(){ place(); var s = document.querySelector('.os-hero-v3_section'); if (s && window.ResizeObserver) new ResizeObserver(place).observe(s); if (document.fonts && document.fonts.ready) document.fonts.ready.then(place); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run); else run(); })(); /* ── Section lines: one colour per theme, edge to edge ───────────────────── 2026-09-29. User, pages live: "make sure that all the lines in sections 1 - go through the whole page and don't stop at the end of the container, 2 - are the same color, both on the dark and light sections." Light = rgba(29,29,27,.1): the 2026-09-25 choice (17a) that [data-wrap="light"] already gives --_theme---grid. Dark = rgba(255,255,255,.1), the same weight in white: the user found 25 % "too bold" (Solutions head rule, Customer Operations). Audit, measurements and the harness: references/section-lines/. No class is edited; these rules only recolour lines and stretch them. */ :root{--line-v3-light:rgba(29,29,27,.1);--line-v3-dark:rgba(255,255,255,.1)} /* SL-a · Stretch a rail-to-rail line to both page edges. border-image with a 100vw outset: it paints past the box without taking part in layout or scrolling, and its width is 1 × the element's own border width, so a variant that turns the line off (width 0, display none) still has none. */ html body :is(.home-v3_cta2_intro,.home-v3_cta2_closing,.split-list-v3_inner, .solutions-v3_cards_inner,.solutions-v3_grid,.solutions-v3_colhead,.numbered-grid-v3_inner, .layers-v3_inner,.callout-grid-v3_inner,.closing-banner-v3_layout){ border-image:linear-gradient(var(--line-v3-c,var(--_theme---grid)) 0 0) 1/1 0 0 0/0 100vw} html body .solutions-v3_matrix{ border-image:linear-gradient(var(--line-v3-dark) 0 0) 1/0 0 1 0/0 100vw} /* dark ones */ html body :is(.home-v3_cta2_section,.solutions-v3_section,.closing-banner-v3_section){--line-v3-c:var(--line-v3-dark)} /* 2026-09-30: the Banking OS closing CTA line runs edge to edge like every other page (user); its old border-image:none exception is gone, and so are embed 24’s no-rails / no-line rules. */ /* SL-b · Solutions agents: the first cell of each row draws the row line from edge to edge (a border-image would drop the cells' left borders). The first cell of a row is the one without the left-border variant, at 3 columns (Agentic) or 4 (Customer Operations); on phones 17b stacks them, so every cell draws its own. */ html body .solutions-v3_cell{border-top-color:transparent;position:relative} html body .solutions-v3_cell::before{content:none;position:absolute;top:-1px;left:-100vw;right:-100vw;height:0;border-top:1px solid var(--line-v3-dark);pointer-events:none} html body .solutions-v3_cell:not(.w-variant-ee7dc246-1249-e836-8e91-de43eeae2885)::before{content:""} @media (max-width:767px){html body .solutions-v3_matrix > .u-display-contents > .solutions-v3_cell::before{content:""}} /* SL-c · Underline Tabs: one line, not a border inside the rails plus a bleed on top of it */ html body .underline-tabs-v3_contain > .section-body-v3_inner{border-top-color:transparent;position:relative} html body .underline-tabs-v3_contain > .section-body-v3_inner::before{ content:"";position:absolute;top:-1px;left:-100vw;right:-100vw;height:0;border-top:1px solid var(--_theme---grid);pointer-events:none} /* After a section that draws its own bottom line (Value Table on RI, Statement Band on Customer Operations) the contain's top border sat on the next pixel row: 2 px. Keep it only where the section above has no line (after a hero). Transparent, not 0: no shift. */ html body .u-border-bottom + .underline-tabs-v3_section > .underline-tabs-v3_contain{border-top-color:transparent} /* Resolution Gap "header only" variant: its own border under the bleed doubled the line */ html body .home-v3_gap_section .home-v3_gap_head.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21{border-top-color:transparent} /* SL-d · Dark sections: one dark value on rails, rules and section bottoms. Their contains re-set the Grid variable on their own combo chains, hence !important. */ html body :is(.home-v3_hero_section,.hero-v3_section:not(:has(.w-variant-3fb3aca8-b490-f50f-67e1-d29f7600b9f3)), .sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section, .card-tabs-v3_section.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144,.closing-banner-v3_section,.home-v3_cta2_section) .section_contain{--_theme---grid:var(--line-v3-dark)!important} html body :is(.home-v3_hero_section,.hero-v3_section:not(:has(.w-variant-3fb3aca8-b490-f50f-67e1-d29f7600b9f3)), .sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section, .card-tabs-v3_section.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144,.closing-banner-v3_section,.home-v3_cta2_section){--_theme---grid:var(--line-v3-dark)!important} html body .home-v3_cta2_section{border-bottom-color:var(--line-v3-dark)} html body:not(:has(.os-hero-v3_section)) .home-v3_cta2_contain{border-left-color:var(--line-v3-dark);border-right-color:var(--line-v3-dark)} html body .section_contain.u-container.u-border-left.u-border-right.solutions-v3_contain{border-left-color:var(--line-v3-dark);border-right-color:var(--line-v3-dark)} html body .solutions-v3_cell{border-left-color:var(--line-v3-dark)} html body:has(.os-hero-v3_section) .card-tabs-v3_section .card-tabs-v3_contain::before{background:var(--line-v3-dark)} /* SL-e · Light sections: the light value where it was missing or doubled */ html body :is(.u-section.u-border-bottom.home-v3_bento_section,.u-section.u-border-bottom.home-v3_front_section){--_theme---grid:var(--line-v3-light)} /* Online & Mobile hero: light blue, but its rails were 20 % white */ html body [data-wrap="light"] .section_contain.u-container.u-border-left.u-border-right.hero-v3_contain{border-left-color:var(--line-v3-light);border-right-color:var(--line-v3-light)} /* Statement Band "Grey, rails": the fill carries a second pair of rails over the first */ html body .statement-band-v3_rails{border-left-color:transparent;border-right-color:transparent} /* Card Grid on a white cover: the section's own grey showed under its bottom line; paint it the cover's colour */ html body .card-grid-v3_section:has(> .background_wrap[data-wf--background-color--background-color="main"]){background-color:var(--_theme---background)} /* SL-f · 90-Day CTA rails in line with every other section below 992 px: its container took 94 % / 92 % there, the others calc(100% - 2 × site margin), so the rails jogged 2–4 px outwards at the CTA. Same max-width as before, so desktop is unchanged. */ html body .home-v3_cta2_section .home-v3_cta2_contain{width:calc(100% - var(--site--margin)*2)} /* SL-g · The nav draws its rails straight into the hero and its bottom line over every section, so it follows: its lines all come from two swatches, re-pointed inside the nav only (pure-white-25/-20 on dark, off-black-30 when it turns light over a light section). */ html body .nav_component{--swatch--pure-white-25:var(--line-v3-dark);--swatch--pure-white-20:var(--line-v3-dark);--swatch--off-black-30:var(--line-v3-light)} /* SL-h · One device pixel, like the rails. A line drawn as a 1px-high background box is 1.25 device px at 125 % display scaling (Windows default on many laptops) and paints 2 full rows; a 1px border snaps to 1. User: "still the wrong color and too bold" — their screenshot: rail 1 row at 10 %, Solutions head rule 2 rows at 25 %. So every bleed line drawn by a ::before becomes a zero-height box with a border-top. The rules that drew them sit in other embeds at up to (0,3,1), hence !important. */ html body :is(.home-v3_gap_section .home-v3_gap_head,.solutions-v3_grid_head,.product-suite-v3_stack, .card-grid-v3_contain > .section-body-v3_inner,.underline-tabs-v3_contain > .section-body-v3_inner)::before{ height:0!important;background:none!important;border-top:1px solid var(--_theme---grid)!important} html body:has(.os-hero-v3_section) :is(.numbered-grid-v3_contain,.controls-showcase-v3_contain,.home-v3_gap_contain, .card-tabs-v3_contain,.home-v3_proof_contain,.recognition-v3_contain)::before{ height:0!important;background:none!important;border-top:1px solid var(--line-v3-light)!important} html body:has(.os-hero-v3_section) .card-tabs-v3_section.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144 .card-tabs-v3_contain::before{ border-top-color:var(--line-v3-dark)!important} /* SL-i · The left rail runs over the hero tab. User 2026-09-29: "make sure that in all hero's the edge is behind the side line". The tab (Agentic Hero ::after z 3, Solutions Hero img z 2) sits above the container (z 2) and cut the rail for 36 px. The tab cannot go under the container: on phones some hero visuals reach the bottom and would hide it. So the section draws the rail again, above the tab, in the light line colour (the dark rail, 10 % white, vanishes on a white tab). x = the container's left edge: width 100% - 2 x site margin, max var(--max-width--main) (80rem; 74.9375rem until 2026-10-12, when the switch-offs moved 81 px: 2000 → 2081, 2010 → 2091), centred. The rail clears the tab's flat top from 2081 px wide. 2026-09-30: the Homepage has a tab too (MCP | Hero, div.home-v3_hero_notch: SVG 455 x 36, 240 x 19 below 768, #f7f7f7, z 2, flat top to 405/455); its rail was cut the same way. Its flat top ends 5 px further right, so it switches off from 2091 px. */ html body :is(.hero-v3_section,.sol-hero-v3_section,.home-v3_hero_section)::before{ content:"";position:absolute;z-index:4;left:max(var(--site--margin),(100% - var(--max-width--main))/2);bottom:0; width:0;height:2.25rem;border-left:1px solid var(--line-v3-light);pointer-events:none} @media (max-width:767px){ html body .hero-v3_section::before{height:1.5rem} html body .sol-hero-v3_section::before{height:calc(14rem*36/454)} html body .home-v3_hero_section::before{height:calc(15rem*36/455)} } @media (min-width:2081px){html body :is(.hero-v3_section,.sol-hero-v3_section)::before{content:none}} @media (min-width:2091px){html body .home-v3_hero_section::before{content:none}} /* ── Section spacing: one rhythm between sections ───────────────────────────── 2026-09-29. User: "We need consistent spacing through all the pages. Right now it's somewhere bigger, somewhere smaller." Screens: 208 px of white above a line (Customer Onboarding ×3), 127 px under the logos (Digital Banking Proof), hero buttons touching. The homepage rhythm, now on every page (the most common measured values): last content → section line 104 / 64 / 48 px (desktop / ≤991 / ≤767) section line → first content ≈32 px The other pages added an empty 104 px band at the top of each section, drawn by a head rule + corner mark 104 px down. Where the section above draws the seam line (P below), the band closes: the rule moves onto the seam and its line is switched off, so the seam stays ONE 1 px line; the corner mark moves with it. After a hero or a dark section the first section keeps its top as it was (the hero's white edge tab runs into it). Lines and corner marks are never removed. Heroes, the 90-Day CTA, Closing Banner, the dark Solutions / Feature Split / Banking OS Card Tabs and the Statement Band keep their own padding. Audit, harness, before/after: references/spacing-2026-09-29/. No class edited. :has() tests skip w-condition-invisible: the Designer keeps prop-hidden elements, published HTML omits them (2026-09-29, references/designer-hidden-2026-09-29/). */ :root{--sp3-a:6.5rem} @media (max-width:991px){:root{--sp3-a:4rem}} @media (max-width:767px){:root{--sp3-a:3rem}} /* SP-a · every light section ends in the seam line (the 10 % light line of the section-lines embed); marks on its top edge are not clipped (x stays clipped for the 100vw rules) */ html body :is(.home-v3_logos_section,.home-v3_gap_section,.home-v3_bento_section,.home-v3_front_section,.home-v3_proof_section,.split-list-v3_section,.numbered-grid-v3_section,.layers-v3_section,.callout-grid-v3_section,.pillars-v3_section,.callouts-v3_section,.channel-cards-v3_section,.topic-tabs-v3_section,.controls-showcase-v3_section,.card-grid-v3_section,.product-suite-v3_section,.underline-tabs-v3_section,.segment-grid-v3_section,.card-tabs-v3_section:not(.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),.accordion-v3_section,.value-table-v3_section,.path-v3_section,.recognition-v3_section){ border-bottom:1px solid var(--line-v3-light,rgba(29,29,27,.1))!important;overflow-x:clip!important;overflow-y:visible!important} /* SP-b · P + section: the head rule that drew the band — line off, the seam line above is it */ html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + * :is(.split-list-v3_inner,.numbered-grid-v3_inner,.layers-v3_inner,.callout-grid-v3_inner){border-top-color:transparent!important;border-image:none!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + * :is(.section_contain > .rail-mark-v3_rule:first-child,[class*="rail-v3_wrap"] > .rail-mark-v3_rule,.value-table-v3_rail .rail-mark-v3_rule,.proof-rule-v3_wrap .rail-mark-v3_rule,.path-v3_rail .rail-mark-v3_rule,.path-v3_rail,.callouts-v3_head .rail-mark-v3_rule){border-top-color:transparent!important;background-color:transparent!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + * :is(.card-grid-v3_contain > .section-body-v3_inner,.underline-tabs-v3_contain > .section-body-v3_inner,.home-v3_gap_head,.product-suite-v3_stack,.channel-cards-v3_contain,.numbered-grid-v3_contain,.controls-showcase-v3_contain,.home-v3_gap_contain,.home-v3_proof_contain,.recognition-v3_contain)::before{content:none!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + * .section_contain.underline-tabs-v3_contain{border-top-color:transparent!important} /* SP-c · P + section: rules and marks that sat 104 px down by an offset — onto the seam */ html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .product-suite-v3_section .product-suite-v3_contain > :is(.rail-v3_wrap-offset,.product-suite-v3_stack){margin-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .product-suite-v3_section .product-suite-v3_contain > .product-suite-v3_stack{padding-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .path-v3_section .path-v3_contain > .path-v3_rail{margin-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .home-v3_proof_section .home-v3_proof_contain > .proof-rule-v3_wrap{top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + * :is(.split-list-v3_mark,.numbered-grid-v3_mark,.layers-v3_mark,.callout-grid-v3_mark,.rail-mark-v3_mark-inner){top:-.5rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .product-suite-v3_section .product-suite-v3_contain > .product-suite-v3_stack::after{top:-2.5rem!important} html body:has(.os-hero-v3_section) :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + * :is(.numbered-grid-v3_contain,.controls-showcase-v3_contain,.home-v3_gap_contain,.home-v3_proof_contain,.recognition-v3_contain)::after{top:-.5rem!important} /* SP-d · P + section: top padding — line → first content ≈32 (the rest of the 32 is inside the section) */ html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .home-v3_gap_section > .home-v3_gap_contain{padding-top:2.1875rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .home-v3_gap_section > .home-v3_gap_contain:has(> .rail-v3_wrap-gap:not(.w-condition-invisible,.w-condition-invisible *)){padding-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .home-v3_gap_section.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21 > .home-v3_gap_contain{padding-top:1px!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + :is(.home-v3_bento_section,.home-v3_front_section) > .section_contain{padding-top:2.1875rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .home-v3_proof_section > .home-v3_proof_contain{padding-top:2.125rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + :is(.split-list-v3_section,.callouts-v3_section,.value-table-v3_section,.segment-grid-v3_section,.underline-tabs-v3_section,.card-grid-v3_section,.numbered-grid-v3_section,.layers-v3_section,.callout-grid-v3_section,.pillars-v3_section,.accordion-v3_section,.path-v3_section) > .section_contain{padding-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .card-tabs-v3_section:not(.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144) > .card-tabs-v3_contain{padding-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + div > .channel-cards-v3_section > .channel-cards-v3_contain{padding-top:1.9375rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + :is(.topic-tabs-v3_section,.controls-showcase-v3_section) > .section_contain{padding-top:2rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .product-suite-v3_section > .product-suite-v3_contain{padding-top:2rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .product-suite-v3_section > .product-suite-v3_contain:has(> .rail-v3_wrap-offset:not(.w-condition-invisible,.w-condition-invisible *)){padding-top:0!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .recognition-v3_section > .recognition-v3_contain{padding-top:.25rem!important} html body:has(.os-hero-v3_section) :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + :is(.card-grid-v3_section,.home-v3_gap_section,.controls-showcase-v3_section,.home-v3_proof_section,.recognition-v3_section) > .section_contain{padding-top:2.125rem!important} html body :is(section:not(.hero-v3_section,.home-v3_hero_section,.sol-hero-v3_section,.os-hero-v3_section,.solutions-v3_section,.feature-split-v3_section,.home-v3_cta2_section,.closing-banner-v3_section,.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144),div:has(> .channel-cards-v3_section)) + .path-v3_section .path-v3_contain > .path-v3_row[class*="w-variant-d61a394b"]{margin-top:2rem!important} /* SP-e · bottom padding — last content → seam line = A. Where the section's own content adds space (a last item's padding, the Proof tab logos' 22 px margin), A minus that, measured per breakpoint. */ html body .home-v3_logos_section > .home-v3_logos_contain{padding-bottom:calc(var(--sp3-a) - 1px)!important} html body .home-v3_gap_section > .home-v3_gap_contain{padding-bottom:calc(var(--sp3-a) - 2px)!important} html body .home-v3_gap_section > .home-v3_gap_contain:has(> .rail-v3_wrap-gap:not(.w-condition-invisible,.w-condition-invisible *)){padding-bottom:var(--sp3-a)!important} html body .home-v3_gap_section.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21 > .home-v3_gap_contain{padding-bottom:calc(var(--sp3-a) - 1px)!important} html body :is(.home-v3_bento_section,.home-v3_front_section) > .section_contain{padding-bottom:calc(var(--sp3-a) - 1px)!important} html body :is(.split-list-v3_section,.callouts-v3_section,.value-table-v3_section,.segment-grid-v3_section,.underline-tabs-v3_section,.card-grid-v3_section,.product-suite-v3_section,.path-v3_section) > .section_contain{padding-bottom:var(--sp3-a)!important} html body .card-tabs-v3_section:not(.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144) > .card-tabs-v3_contain{padding-bottom:var(--sp3-a)!important} html body .numbered-grid-v3_section > .numbered-grid-v3_contain{padding-bottom:calc(var(--sp3-a) - 1.5rem)!important} html body .numbered-grid-v3_section:has([class*="w-variant-902588a9"]) > .numbered-grid-v3_contain{padding-bottom:calc(var(--sp3-a) - 3.3125rem)!important} html body .layers-v3_section > .layers-v3_contain{padding-bottom:calc(var(--sp3-a) - 1.75rem)!important} html body .pillars-v3_contain > .pillars-v3_quote{padding-bottom:calc(var(--sp3-a) - 1px)!important} html body .channel-cards-v3_contain{padding-bottom:calc(var(--sp3-a) - 1px)!important} html body :is(.topic-tabs-v3_section,.controls-showcase-v3_section) > .section_contain{padding-bottom:calc(var(--sp3-a) - 1px)!important} html body .accordion-v3_section > .accordion-v3_contain{padding-bottom:calc(var(--sp3-a) - 2.0625rem)!important} html body .accordion-v3_section > .accordion-v3_contain:has(> .rail-v3_wrap:not(.w-condition-invisible,.w-condition-invisible *)){padding-bottom:var(--sp3-a)!important} html body .recognition-v3_section > .recognition-v3_contain{padding-bottom:calc(var(--sp3-a) - 2.75rem)!important} html body:has(.os-hero-v3_section) :is(.home-v3_gap_section,.controls-showcase-v3_section,.recognition-v3_section) > .section_contain{padding-bottom:var(--sp3-a)!important} @media (max-width:991px){ html body .home-v3_logos_section > .home-v3_logos_contain{padding-bottom:calc(var(--sp3-a) - 9px)!important} } @media (min-width:768px) and (max-width:991px){ html body .recognition-v3_section > .recognition-v3_contain{padding-bottom:calc(var(--sp3-a) - 41px)!important} } @media (max-width:767px){ html body .numbered-grid-v3_section > .numbered-grid-v3_contain{padding-bottom:calc(var(--sp3-a) - .75rem)!important} html body .numbered-grid-v3_section:has([class*="w-variant-902588a9"]) > .numbered-grid-v3_contain{padding-bottom:calc(var(--sp3-a) - 2.0625rem)!important} html body .topic-tabs-v3_section > .topic-tabs-v3_contain{padding-bottom:calc(var(--sp3-a) - 9px)!important} html body .recognition-v3_section > .recognition-v3_contain{padding-bottom:calc(var(--sp3-a) - 1px)!important} } /* Proof in Production, per variant: plain (homepage), stories ×2, stats + quote (Onboarding; Banking OS differs) */ html body .home-v3_proof_section > .home-v3_proof_contain{padding-bottom:55px!important} html body .home-v3_proof_section > .home-v3_proof_contain:is([class*="w-variant-300eb3b7"],[class*="w-variant-af75493b"]){padding-bottom:81px!important} html body .home-v3_proof_section > .home-v3_proof_contain[class*="w-variant-f4552013"]{padding-bottom:61px!important} html body:has(.os-hero-v3_section) .home-v3_proof_section > .home-v3_proof_contain{padding-bottom:89px!important} @media (max-width:991px){ html body .home-v3_proof_section > .home-v3_proof_contain{padding-bottom:39px!important} html body .home-v3_proof_section > .home-v3_proof_contain[class*="w-variant-300eb3b7"]{padding-bottom:41px!important} html body .home-v3_proof_section > .home-v3_proof_contain[class*="w-variant-af75493b"]{padding-bottom:37px!important} html body .home-v3_proof_section > .home-v3_proof_contain[class*="w-variant-f4552013"]{padding-bottom:38px!important} html body:has(.os-hero-v3_section) .home-v3_proof_section > .home-v3_proof_contain{padding-bottom:62px!important} } @media (max-width:767px){ html body .home-v3_proof_section > .home-v3_proof_contain{padding-bottom:39px!important} html body .home-v3_proof_section > .home-v3_proof_contain:is([class*="w-variant-300eb3b7"],[class*="w-variant-af75493b"]){padding-bottom:34px!important} html body .home-v3_proof_section > .home-v3_proof_contain[class*="w-variant-f4552013"]{padding-bottom:22px!important} html body:has(.os-hero-v3_section) .home-v3_proof_section > .home-v3_proof_contain{padding-bottom:46px!important} } /* SP-f · hero buttons 16 px apart, like every other button pair (were 8 px; on phones they touched) */ html body :is(.hero-v3_actions,.home-v3_hero_actions,.sol-hero-v3_actions){row-gap:1rem!important;column-gap:1rem!important} /* ── Eyebrows: one style on every page ─────────────────────────────────────── 2026-09-29. User: "Make sure the eyebrow styling is the same across all pages. This one" (Customer Onboarding, "KEEP APPLICATIONS MOVING", .home-v3_gap_eyebrow) "not this one" ("BANKING DEPTH ACROSS FIVE SEGMENTS", 11 px navy .section-head-v3_eyebrow-small). The reference: Ppsupplymono 400, 14 px (12 px ≤479), 0.1em tracking, uppercase, #1d1d1b. Section eyebrows on light sections get all of it. Hero and dark-section eyebrows get the type only and keep their own colour (white / blue on dark). Line-height and margins are not touched, so the section spacing rhythm (embed "Section spacing (CSS)") stays as it is. Not eyebrows, so left alone: card labels, tab titles, numbered-grid numbers, Product Suite group labels, tab-panel eyebrows (proposition-v3), the "Powered by" band label. :root:root lifts this above the class combos (up to 3 classes) and the variant styles. Audit and before/after: references/eyebrow-2026-09-29/. No class edited. */ :root:root :is( .home-v3_gap_eyebrow, .home-v3_bento_eyebrow, .home-v3_front_eyebrow, .home-v3_proof_eyebrow, .section-head-v3_eyebrow, .callouts-v3_eyebrow, .product-suite-v3_eyebrow, .controls-showcase-v3_eyebrow, .intro-v3_eyebrow, .split-list-v3_head > .style2-0_label, .numbered-grid-v3_head > .style2-0_label, .layers-v3_head > .style2-0_label, .callout-grid-v3_head > .style2-0_label, .home-v3_hero_eyebrow, .hero-v3_eyebrow, .sol-hero-v3_eyebrow, .os-hero-v3_eyebrow, .home-v3_cta2_eyebrow, .style2-0_label.solutions-v3_eyebrow ){ font-family: Ppsupplymono, Arial, sans-serif; font-weight: 400; font-size: .875rem; letter-spacing: .1em; text-transform: uppercase; } @media (max-width:479px){ :root:root :is( .home-v3_gap_eyebrow, .home-v3_bento_eyebrow, .home-v3_front_eyebrow, .home-v3_proof_eyebrow, .section-head-v3_eyebrow, .callouts-v3_eyebrow, .product-suite-v3_eyebrow, .controls-showcase-v3_eyebrow, .intro-v3_eyebrow, .split-list-v3_head > .style2-0_label, .numbered-grid-v3_head > .style2-0_label, .layers-v3_head > .style2-0_label, .callout-grid-v3_head > .style2-0_label, .home-v3_hero_eyebrow, .hero-v3_eyebrow, .sol-hero-v3_eyebrow, .os-hero-v3_eyebrow, .home-v3_cta2_eyebrow, .style2-0_label.solutions-v3_eyebrow ){ font-size: .75rem; } } /* Light sections: the reference colour. The dark "split intro" Channel Cards eyebrow stays white. */ :root:root :is( .home-v3_front_eyebrow, .home-v3_proof_eyebrow, .section-head-v3_eyebrow, .callouts-v3_eyebrow, .product-suite-v3_eyebrow, .controls-showcase-v3_eyebrow, .intro-v3_eyebrow:not(.w-variant-cbe1ed4b-8cd4-aaa7-c488-909818220646), .split-list-v3_head > .style2-0_label, .numbered-grid-v3_head > .style2-0_label, .layers-v3_head > .style2-0_label, .callout-grid-v3_head > .style2-0_label ){ color: #1d1d1b; } /* Two-colour headings read as one sentence (user, 2026-09-29: "all texts that have two colors in them are seen as one text and are not separated"). Every two-colour heading is one h1–h6 whose coloured parts are direct children. Eleven components drew a part as display:block (gap, bento, proof, solutions, numbered grid, controls showcase, value table, recognition, Banking OS hero, CTA closing title, two section-head variants), so it always started a new line. Here every such span is inline, whatever its class or variant says, and the parts wrap as one text. The spaces: most copy has none at the join (a block never needed one). A generated space on both edges of each span fixes that without touching copy: next to a real space it collapses into it, at a line start or end it is dropped, so it can never double a gap or indent a wrapped line (the   bug on Customer Operations). Three titles faked that space with a 0.25em side margin (home front title, 90-day CTA title, layers title); the margin goes, or the gap would be doubled. Audit and proof: references/two-colour-text/. */ :is(main,.page_main) :is(h1,h2,h3,h4,h5,h6) > span{display:inline !important;margin-left:0 !important;margin-right:0 !important} :is(main,.page_main) :is(h1,h2,h3,h4,h5,h6) > span::before, :is(main,.page_main) :is(h1,h2,h3,h4,h5,h6) > span::after{content:" "} /* 25 — Tag fit (2026-09-29). Ungated: keys off MCP | Product Tile's own tag class. User: "if the text doesn't fully fit in the tag in this card, the text inside tag becomes a little smaller to fit in". The tag is 14 px mono with 1.4 px tracking; in a 165 px tile "CONVERSATIONAL" needs 149 px against 133 px and ran out of the card. CSS: the tag is never wider than its tile. Script: per tag, font-size and tracking shrink together just enough that the longest word fits (1 px margin), never below 70 %. Words still wrap between each other as before; a tag whose words all fit is not touched. Only a tag that is still too wide at 70 % may break inside a word. Words are measured on a hidden copy of the tag inside its own tile, so variant and page fine-tune styles are respected. Re-fits when a tile changes width and once the web font has loaded. */ .product-suite-v3_tile-product{max-width:100%} (function(){ var SEL='.product-suite-v3_tile-product', MIN=0.7, seen=new WeakMap(); function px(v){return parseFloat(v)||0} function fit(el){ var tile=el.parentElement;if(!tile)return; el.style.fontSize='';el.style.letterSpacing='';el.style.overflowWrap='normal'; var cs=getComputedStyle(el), ts=getComputedStyle(tile); var avail=tile.clientWidth-px(ts.paddingLeft)-px(ts.paddingRight)-1; var fs=px(cs.fontSize), ls=cs.letterSpacing==='normal'?0:px(cs.letterSpacing); var words=(el.textContent||'').trim().split(/\s+/); var c=el.cloneNode(false);c.removeAttribute('id');c.setAttribute('aria-hidden','true'); c.style.cssText='position:absolute;left:0;top:0;visibility:hidden;pointer-events:none;white-space:nowrap;max-width:none;width:auto'; tile.appendChild(c); function widest(s){ if(s!==1){c.style.fontSize=(fs*s).toFixed(2)+'px';if(ls)c.style.letterSpacing=(ls*s).toFixed(2)+'px'} var m=0;for(var i=0;iavail&&avail>0){ var pad=px(cs.paddingLeft)+px(cs.paddingRight)+px(cs.borderLeftWidth)+px(cs.borderRightWidth); var s=Math.max(MIN,Math.floor((avail-pad)/(need-pad)*100)/100); for(var i=0;iMIN&&widest(s)>avail;i++)s=Math.max(MIN,s-0.01); el.style.fontSize=(fs*s).toFixed(2)+'px'; if(ls)el.style.letterSpacing=(ls*s).toFixed(2)+'px'; if(savail)el.style.overflowWrap='anywhere'; } c.remove(); } function run(){document.querySelectorAll(SEL).forEach(fit)} function init(){ var tags=document.querySelectorAll(SEL);if(!tags.length)return; run(); if(document.fonts&&document.fonts.ready)document.fonts.ready.then(run); if('ResizeObserver' in window){ var ro=new ResizeObserver(function(entries){ entries.forEach(function(en){ var t=en.target,w=Math.round(en.contentRect.width); if(seen.get(t)===w)return;seen.set(t,w); t.querySelectorAll(':scope > '+SEL).forEach(fit); }); }); tags.forEach(function(tag){ro.observe(tag.parentElement)}); }else{addEventListener('resize',run)} } document.readyState==='loading'?document.addEventListener('DOMContentLoaded',init):init(); })(); /* 28 · Tab rows that scroll sideways run from rail to rail (phones and tablets, ≤ 991 px). User 2026-09-30, Customer Operations crop: "if tabs are scrollable on mobile, they all go from line to line across all pages". Same treatment 19i gave OMB's everyday-banking row on 2026-09-29 ("Just from left line to right line"): the scroller reaches out over the inner padding to the section rails and takes that padding back on the inside, so at rest the first tab sits on the title's edge and a swipe runs under the rails. scroll-padding makes embed 15's inset() stop a picked tab on the title's edge. Inner padding: 2rem ≤ 991, 1rem ≤ 767 (Topic Tabs too since its contain went to 1rem on phones, 2026-09-30, references/cb-mobile-gutter/). Audit, fixture and screenshots: references/tabs-rail-to-rail/. No class or definition edited. */ @media (max-width:991px){ /* MCP | Capabilities Tabs "Underline + lede" (RI ×2, Customer Operations) and "Underline" (OMB; 19i covers its phones). Tabs lose their side padding, the gap spaces them; the grey baseline is the menu's own inset shadow, so it now runs rail to rail too. */ .tabs-v3_wrap:is(.w-variant-29d628cd-9c32-bdec-29d7-1983f67994ae,.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836) .tabs-v3_menu{ margin-left:-2rem;margin-right:-2rem;scroll-padding-inline:2rem;scrollbar-width:none} .tabs-v3_wrap:is(.w-variant-29d628cd-9c32-bdec-29d7-1983f67994ae,.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836) .tabs-v3_menu::-webkit-scrollbar{display:none} .tabs-v3_wrap:is(.w-variant-29d628cd-9c32-bdec-29d7-1983f67994ae,.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836) .tabs-v3_track{padding-left:2rem;padding-right:2rem;column-gap:1.25rem} .tabs-v3_wrap:is(.w-variant-29d628cd-9c32-bdec-29d7-1983f67994ae,.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836) .tabs-v3_tab{padding-left:0;padding-right:0} /* MCP | Topic Tabs (Conversational Banking) — the rail itself scrolls. Tabs lose their 20 px sides (their blue underline now spans the word); the old 40 px between words becomes the gap. The rail draws the grey baseline itself, so it runs under the gaps and out to the rails. */ .topic-tabs-v3_rail{margin-left:-2rem;margin-right:-2rem;padding-left:2rem;padding-right:2rem; scroll-padding-inline:2rem;column-gap:2.5rem;scrollbar-width:none;box-shadow:inset 0 -1px 0 #e0e3e8} .topic-tabs-v3_rail::-webkit-scrollbar{display:none} .topic-tabs-v3_rail .topic-tabs-v3_tab{padding-left:0;padding-right:0} /* MCP | Proposition Tabs "Dark, row" (Banking OS) — the track itself scrolls; the tab boxes keep their padding, the first box's edge sits on the title's edge. Embed 24 fixes its width at 100% from 768 px (body:has(.os-hero-v3_section) …), so html body + width:auto let the margins widen it instead of shifting it. */ html body .proposition-v3_track.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144{width:auto;max-width:none; margin-left:-2rem;margin-right:-2rem;padding-left:2rem;padding-right:2rem;scroll-padding-inline:2rem} /* MCP | Proposition Tabs "Underline list" (Employee Workspaces) — user 2026-09-30: "make this a side scroll like we have with other tabs". The stacked list becomes one row; the track itself scrolls (as "Dark, row"), the intro stays above it. The grey 2px baseline is the track's own inset shadow, so it runs rail to rail under the gaps; each tab keeps its 2px bottom border for the blue bar and the line. */ .proposition-v3_track.w-variant-646560aa-5ff5-3019-679d-d7435ff47c4d{flex-direction:row;overflow-x:auto;overflow-y:hidden; margin-left:-2rem;margin-right:-2rem;padding-left:2rem;padding-right:2rem;scroll-padding-inline:2rem; column-gap:1.5rem;scrollbar-width:none;box-shadow:inset 0 -2px 0 #dbe3ed} .proposition-v3_track.w-variant-646560aa-5ff5-3019-679d-d7435ff47c4d::-webkit-scrollbar{display:none} .proposition-v3_track.w-variant-646560aa-5ff5-3019-679d-d7435ff47c4d .proposition-v3_tab{flex:0 0 auto} .proposition-v3_track.w-variant-646560aa-5ff5-3019-679d-d7435ff47c4d .proposition-v3_tab-title{white-space:nowrap} } @media (max-width:767px){ .tabs-v3_wrap:is(.w-variant-29d628cd-9c32-bdec-29d7-1983f67994ae,.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836) .tabs-v3_menu{ margin-left:-1rem;margin-right:-1rem;scroll-padding-inline:1rem} .tabs-v3_wrap:is(.w-variant-29d628cd-9c32-bdec-29d7-1983f67994ae,.w-variant-23c2d2f4-340a-d873-ff7d-b69573414836) .tabs-v3_track{padding-left:1rem;padding-right:1rem} html body .proposition-v3_track.w-variant-1cd2d6a2-284d-6ac6-6d77-6025bad6d144{ margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem;scroll-padding-inline:1rem} /* MCP | Proposition Tabs "Plain list" (OMB, 19g): already rail to rail; the scroll-padding makes a picked tab stop on the title's edge instead of on the rail. */ .proposition-v3_nav.w-variant-b2fba63f-6104-2d32-caba-77e54369509d{scroll-padding-inline:1rem} /* MCP | Topic Tabs: follows its contain (1rem on phones). */ .topic-tabs-v3_rail{margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem;scroll-padding-inline:1rem} /* Proposition Tabs "Underline list": follows its inner padding (1rem on phones). */ .proposition-v3_track.w-variant-646560aa-5ff5-3019-679d-d7435ff47c4d{margin-left:-1rem;margin-right:-1rem;padding-left:1rem;padding-right:1rem;scroll-padding-inline:1rem} /* The icon box keeps the tablet size (1.25rem); Tile's phone size (2.75rem) leaked into Underline and made the row 74 px tall with a wide gap before the name. */ .proposition-v3_track.w-variant-646560aa-5ff5-3019-679d-d7435ff47c4d .proposition-v3_tab-icon{flex-basis:1.25rem;width:1.25rem;height:1.25rem} } /* ── 29 · Grey sections sit between no lines ────────────────────────────────── 2026-10-05. User: "When a section has gray bg, I would like it to have no bottom line. And a section above it to also have no bottom line, so the gray-ish section is not between lines." Approved with the corner marks on those two seams (a mark without its line would float). Rails stay. Lines INSIDE a grey section (a head rule further down, card borders) stay. Grey = #efefef / #f7f7f7 fill. Census, selectors and harness: references/grey-seams-2026-10-05/. A new grey section type or variant must be added to GS-a, GS-b and, if it has a corner on a seam, GS-c / GS-d. Lines go transparent, not 0 wide: nothing moves. !important: embed 19 (SP-a) sets every section bottom with !important (0,2,2); every rule here is (0,3,2) or more, so the embed order does not matter. Designer: variant classes (w-variant-…) next to the live data-wf attributes. */ /* GS-a · the grey section's own bottom line */ html body .u-section:is(.home-v3_logos_section,.callouts-v3_section,.statement-band-v3_section, .value-table-v3_section,.recognition-v3_section, .home-v3_gap_section.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21, .home-v3_gap_section[data-wf--mcp-resolution-gap--variant="accent-first"]), html body .u-section.card-grid-v3_section:has(> .background_wrap:not(.w-variant-cd5f9287-5b9f-b1bf-cfe9-3449eb06f297)), html body .u-section.home-v3_gap_section:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8), html body .u-section.controls-showcase-v3_section:has(.controls-showcase-v3_fill.w-variant-80b9bcbd-ee90-ae35-5f89-53a19c7dba06), html body .u-section.product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a){border-bottom-color:transparent!important} /* GS-b · the bottom line of the section right above a grey one */ html body .u-section:has(+ :is(.home-v3_logos_section,.callouts-v3_section,.statement-band-v3_section, .value-table-v3_section,.recognition-v3_section, .home-v3_gap_section.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21, .home-v3_gap_section[data-wf--mcp-resolution-gap--variant="accent-first"]), + .card-grid-v3_section > .background_wrap:not(.w-variant-cd5f9287-5b9f-b1bf-cfe9-3449eb06f297), + .home-v3_gap_section .w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8, + .controls-showcase-v3_section .controls-showcase-v3_fill.w-variant-80b9bcbd-ee90-ae35-5f89-53a19c7dba06, + .product-suite-v3_section .w-variant-9764459d-eeea-f439-a927-239596e3bb4a){border-bottom-color:transparent!important} /* GS-c · corner marks on the TOP seam (they belong to the grey section) */ html body .home-v3_logos_section .home-v3_logos_notch, html body .callouts-v3_head > .rail-mark-v3_mark, html body .value-table-v3_rail > .rail-mark-v3_mark, html body .product-suite-v3_section:has(.w-variant-9764459d-eeea-f439-a927-239596e3bb4a) .rail-v3_wrap-offset > .rail-mark-v3_mark{display:none} html body .card-grid-v3_section:has(> .background_wrap:not(.w-variant-cd5f9287-5b9f-b1bf-cfe9-3449eb06f297)) > .card-grid-v3_contain > .section-body-v3_inner::after, html body .home-v3_gap_section.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21 .home-v3_gap_head::after, html body .controls-showcase-v3_section:has(.controls-showcase-v3_fill.w-variant-80b9bcbd-ee90-ae35-5f89-53a19c7dba06) > .controls-showcase-v3_contain::after, html body .recognition-v3_section > .recognition-v3_contain::after{content:none} /* GS-d · corner marks on the BOTTOM seam (they belong to the section below the grey one) */ html body .callouts-v3_section + .home-v3_proof_section :is(.rail-v3_wrap-top,.proof-rule-v3_wrap) > .rail-mark-v3_mark, html body .card-grid-v3_section:has(> .background_wrap:not(.w-variant-cd5f9287-5b9f-b1bf-cfe9-3449eb06f297)) + .product-suite-v3_section .rail-v3_wrap-offset > .rail-mark-v3_mark, html body .card-grid-v3_section:has(> .background_wrap:not(.w-variant-cd5f9287-5b9f-b1bf-cfe9-3449eb06f297)) + .home-v3_gap_section .rail-v3_wrap-gap > .rail-mark-v3_mark{display:none} html body :is(.value-table-v3_section,.statement-band-v3_section) + .underline-tabs-v3_section > .underline-tabs-v3_contain > .section-body-v3_inner::after, html body .home-v3_gap_section.w-variant-2d7401df-db3d-a91b-7569-e854f77d3d21 + .product-suite-v3_section .product-suite-v3_stack::after, html body .controls-showcase-v3_section:has(.controls-showcase-v3_fill.w-variant-80b9bcbd-ee90-ae35-5f89-53a19c7dba06) + .home-v3_gap_section > .home-v3_gap_contain::after{content:none} /* 2026-10-05 (later): two marks that already floated, 104 px / 40 px off a head rule embed 19 had switched off because the seam line stood in for it — now the seam line is gone too: Channel Cards under the Statement Band (Conversational Banking), and the Resolution Gap "Accent first" head (Customer Operations). */ html body .statement-band-v3_section + * .channel-cards-v3_contain::after, html body .statement-band-v3_section + .channel-cards-v3_section > .channel-cards-v3_contain::after, html body .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) .home-v3_gap_head::after{content:none!important} /* GS-e · a line the section below draws on the seam: the Solutions matrix top rule right under the grey Resolution Gap (Customer Operations) */ html body .home-v3_gap_section:is([data-wf--mcp-resolution-gap--variant="accent-first"],:has(.w-variant-152bed33-8566-a8cc-13a9-784a61bf26b8)) + .solutions-v3_section .solutions-v3_grid{border-image:none!important;border-top-color:transparent!important} :root { --grid-breakout: [full-start] minmax(0, 1fr) [content-start] repeat(var(--site--column-count), minmax(0, var(--site--column-width))) [content-end] minmax(0, 1fr) [full-end]; --grid-breakout-single: [full-start] minmax(0, 1fr) [content-start] minmax(0, calc(100% - var(--site--margin) * 2)) [content-end] minmax(0, 1fr) [full-end]; } ::before, ::after { box-sizing: border-box; } .w-embed:before, .w-embed:after, .w-richtext:before, .w-richtext:after { content: unset; } /* At some pages the classes below didn't work, that's why we add them manually with !important to work */ /* Margin Top */ .u-mt-0 { margin-top: var(--_spacing---space--0) !important; } .u-mt-1 { margin-top: var(--_spacing---space--1) !important; } .u-mt-2 { margin-top: var(--_spacing---space--2) !important; } .u-mt-3 { margin-top: var(--_spacing---space--3) !important; } .u-mt-4 { margin-top: var(--_spacing---space--4) !important; } .u-mt-5 { margin-top: var(--_spacing---space--5) !important; } .u-mt-6 { margin-top: var(--_spacing---space--6) !important; } .u-mt-7 { margin-top: var(--_spacing---space--7) !important; } .u-mt-8 { margin-top: var(--_spacing---space--8) !important; } /* Margin Bottom */ .u-mb-0 { margin-bottom: var(--_spacing---space--0) !important; } .u-mb-1 { margin-bottom: var(--_spacing---space--1) !important; } .u-mb-2 { margin-bottom: var(--_spacing---space--2) !important; } .u-mb-3 { margin-bottom: var(--_spacing---space--3) !important; } .u-mb-4 { margin-bottom: var(--_spacing---space--4) !important; } .u-mb-5 { margin-bottom: var(--_spacing---space--5) !important; } .u-mb-6 { margin-bottom: var(--_spacing---space--6) !important; } .u-mb-7 { margin-bottom: var(--_spacing---space--7) !important; } .u-mb-8 { margin-bottom: var(--_spacing---space--8) !important; } /* Padding Top */ .u-pt-0 { padding-top: var(--_spacing---space--0) !important; } .u-pt-1 { padding-top: var(--_spacing---space--1) !important; } .u-pt-2 { padding-top: var(--_spacing---space--2) !important; } .u-pt-3 { padding-top: var(--_spacing---space--3) !important; } .u-pt-4 { padding-top: var(--_spacing---space--4) !important; } .u-pt-5 { padding-top: var(--_spacing---space--5) !important; } .u-pt-6 { padding-top: var(--_spacing---space--6) !important; } .u-pt-7 { padding-top: var(--_spacing---space--7) !important; } .u-pt-8 { padding-top: var(--_spacing---space--8) !important; } /* Padding Bottom */ .u-pb-0 { padding-bottom: var(--_spacing---space--0) !important; } .u-pb-1 { padding-bottom: var(--_spacing---space--1) !important; } .u-pb-2 { padding-bottom: var(--_spacing---space--2) !important; } .u-pb-3 { padding-bottom: var(--_spacing---space--3) !important; } .u-pb-4 { padding-bottom: var(--_spacing---space--4) !important; } .u-pb-5 { padding-bottom: var(--_spacing---space--5) !important; } .u-pb-6 { padding-bottom: var(--_spacing---space--6) !important; } .u-pb-7 { padding-bottom: var(--_spacing---space--7) !important; } .u-pb-8 { padding-bottom: var(--_spacing---space--8) !important; } html { background-color: var(--_theme---background); } button { background-color: unset; padding: unset; text-align: inherit; } button:not(:disabled) { cursor: pointer; } video { width: 100%; object-fit: cover; } /* remove padding of empty element */ .wf-empty { padding: 0; } svg { max-width: 100%; } @media (prefers-color-scheme: light) { option { color: black; } } img::selection { background: transparent; } /* Typography */ body { text-transform: var(--_text-style---text-transform); font-smoothing: antialiased; -webkit-font-smoothing: antialiased; } /* Clear Defaults */ a:not([class]) { text-decoration: underline; } h1,h2,h3,h4,h5,h6,p,blockquote,label { font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; letter-spacing: inherit; text-transform: inherit; text-wrap: inherit; margin-top: 0; margin-bottom: 0; } select:has(option[value=""]:checked) { color: color-mix(in lab, currentcolor 60%, transparent) } /* Selection Color */ ::selection { background-color: var(--_theme---selection--background); color: var(--_theme---selection--text); } /* Margin Trim */ :is(.u-margin-trim,.u-rich-text) > :not(:not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim) ~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim)), :is(.u-margin-trim,.u-rich-text) > :not(:not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim) ~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim)).u-display-contents > :first-child { margin-top: 0; } :is(.u-margin-trim,.u-rich-text) > :not(:has(~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim))), :is(.u-margin-trim,.u-rich-text) > :not(:has(~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim))).u-display-contents > :last-child { margin-bottom: 0; } :is(.u-margin-trim,.style2-0_faq_dropdown_rich-text) > :not(:has(~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim))), :is(.u-margin-trim,.style2-0_faq_dropdown_rich-text) > :not(:has(~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim))).u-display-contents > :last-child { margin-bottom: 0; } :is(.u-margin-trim,.style2-0_rich-text) > :not(:has(~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim))), :is(.u-margin-trim,.style2-0_rich-text) > :not(:has(~ :not(.w-condition-invisible,.u-cover-absolute,.u-ignore-trim))).u-display-contents > :last-child { margin-bottom: 0; } /* Line Height Trim */ :is(h1,h2,h3,h4,h5,h6,p):not(.u-text-trim-off,:has([class*="u-text-style-"]))::before, [class*="u-text-style-"]:not(.u-text-trim-off,:has(h1,h2,h3,h4,h5,h6,p))::before { content: ""; display: table; margin-bottom: calc(-0.5lh + var(--_text-style---trim-top)); } :is(h1,h2,h3,h4,h5,h6,p):not(.u-text-trim-off,:has([class*="u-text-style-"]))::after, [class*="u-text-style-"]:not(.u-text-trim-off,:has(h1,h2,h3,h4,h5,h6,p))::after { content: ""; display: table; margin-bottom: calc(-0.5lh + var(--_text-style---trim-bottom)); } /* Rich Text Links */ .w-richtext a { position: relative; z-index: 4; } /* Line Clamp */ .u-line-clamp-1, .u-line-clamp-2, .u-line-clamp-3, .u-line-clamp-4 { -webkit-line-clamp: 1; -webkit-box-orient: vertical; } .u-line-clamp-2 { -webkit-line-clamp: 2; } .u-line-clamp-3 { -webkit-line-clamp: 3; } .u-line-clamp-4 { -webkit-line-clamp: 4; } /* Child Contain */ .u-child-contain > * { width: 100%; max-width: inherit !important; margin-inline: 0 !important; margin-top: 0 !important; } /* Hide */ .u-hide-if-empty:empty, .u-hide-if-empty:not(:has(> :not(.w-condition-invisible))), .u-hide-if-empty-cms:not(:has(.w-dyn-item)), .u-embed-js, .u-embed-css { display: none !important; } /* Focus State */ a, button, :where([tabindex]), [data-outline] { outline-offset: var(--focus--offset-outer); } a:focus-visible, button:focus-visible, [tabindex]:focus-visible, label:has(input:focus-visible) [data-outline] { outline-color: var(--_theme---background-inverse); outline-width: var(--focus--width); outline-style: solid; } /* Global / Clickable Component */ .wf-design-mode .clickable_wrap { z-index: 0; } .clickable_wrap a[href="#"] { display: none; } .clickable_wrap a[href="#"] ~ button { display: block; } /* Responsive Above */ @container threshold-large (width >= 62em) { .u-order-unset-above { order: unset !important; } .u-all-unset-above { all: unset !important; } .u-grid-below { display: flex !important; } } @container threshold-medium (width >= 48em) { .u-order-unset-above { order: unset !important; } .u-all-unset-above { all: unset !important; } .u-grid-below { display: flex !important; } } @container threshold-small (width >= 30em) { .u-order-unset-above { order: unset !important; } .u-all-unset-above { all: unset !important; } .u-grid-below { display: flex !important; } } /* Responsive Below */ @container threshold-large (width < 62em) { .u-order-unset-below { order: unset !important; } .u-all-unset-below { all: unset !important; } .u-grid-above { display: flex !important; } } @container threshold-medium (width < 48em) { .u-order-unset-below { order: unset !important; } .u-all-unset-below { all: unset !important; } .u-grid-above { display: flex !important; } } @container threshold-small (width < 30em) { .u-order-unset-below { order: unset !important; } .u-all-unset-below { all: unset !important; } .u-grid-above { display: flex !important; } } /* Form Radio */ .form_main_radio_label:has(input:checked) .form_main_radio_circle_inner { opacity: 1; } /* Form Checkbox */ .form_main_checkbox_label:has(input:checked) .form_main_checkbox_box { background-color: currentColor; } [data-wf--form-fields-checkbox--variant="dark"] .form_main_checkbox_label:has(input:checked) .form_main_checkbox_box { background-color: #97B1FF26; } .form_main_checkbox_label:has(input:checked) .form_main_checkbox_icon { opacity: 1; } label:has(input:focus) .form_main_label, label:has(input:not(:placeholder-shown)) .form_main_label { margin-left: .25rem; padding-left: .5rem; padding-right: .5rem; top: 0%; } label:has(input:focus) .form_main_label_text, label:has(input:not(:placeholder-shown)) .form_main_label_text { font-size: 0.75rem; } /* Start rive icons convert */ /* ------------------------------------------------------- BUTTONS ------------------------------------------------------- */ /* Button Primary */ .button_main_wrap[data-wf--button-main--style="primary"] .button_main_icon { filter: invert(var(--_theme---button-primary--icon-inverted)); } /* Button Secondary */ .button_main_wrap[data-wf--button-main--style="secondary"] .button_main_icon { filter: invert(var(--_theme---button-secondary--icon-inverted)); } /* Button Tertiary */ .button_main_wrap[data-wf--button-main--style="tertiary"] .button_main_icon { filter: invert(var(--_theme---button-tertiary--icon-inverted)); } /* Button Primary hover */ .button_main_wrap[data-wf--button-main--style="primary"]:hover .button_main_icon { filter: invert(var(--_theme---button-primary--icon-inverted-hover)); } /* ------------------------------------------------------- NORMALIZE (tegen roze/grijze zweem) ------------------------------------------------------- */ :root { --_theme---icons-logo-normalize: brightness(0) saturate(100%) grayscale(100%) contrast(1000%); } /* ------------------------------------------------------- NAV LOGO (Rive) ------------------------------------------------------- */ .nav_logo_wrap canvas, .nav_logo_wrap svg, .nav_logo_wrap .rive, .nav_logo_wrap .w-embed > canvas { filter: var(--_theme---icons-logo-normalize) invert(var(--_theme---icons-logo-inverted)); transition: filter .3s ease; } /* ------------------------------------------------------- NAV SEARCH ICON ------------------------------------------------------- */ .nav_search_icon { filter: var(--_theme---icons-logo-normalize) invert(var(--_theme---icons-logo-inverted)); transition: filter .3s ease; } /* ------------------------------------------------------- NAV LINKS CHEVRON (gebruikt inverse variabele) ------------------------------------------------------- */ .nav_links_svg.is-chevron { filter: var(--_theme---icons-logo-normalize) invert(var(--_theme---icons-logo-inverted)); transition: filter .3s ease; } /* ------------------------------------------------------- LANGUAGE ICON (Rive) ------------------------------------------------------- */ .language-icon-rive { filter: var(--_theme---icons-logo-normalize) invert(var(--_theme---icons-logo-inverted)); transition: filter .3s ease; } /* ------------------------------------------------------- CHEVRON ICON (Rive) ------------------------------------------------------- */ .chevron-icon-rive { filter: var(--_theme---icons-logo-normalize) invert(var(--_theme---icons-logo-inverted)); transition: filter .3s ease; } /* ------------------------------------------------------- Accessibility: reduce motion ------------------------------------------------------- */ @media (prefers-reduced-motion: reduce) { .button_main_wrap[data-wf--button-main--style] .button_main_icon, .nav_logo_wrap canvas, .nav_logo_wrap svg, .nav_logo_wrap img, .nav_logo_wrap iframe, .nav_links_svg.is-chevron, .nav_search_icon, .language-icon-rive, .chevron-icon-rive { transition: none !important; } } /* END rive icons convert */ /* START Logo Sizes */ .logo_section_logo_image.size-64 { max-height: clamp(3.5rem, 7vw, 5.5rem) !important; } .logo_section_logo_image.size-56 { max-height: clamp(2.5rem, 6vw, 4.5rem) !important; } .logo_section_logo_image.size-48 { max-height: clamp(2rem, 5vw, 3.5rem) !important; } .logo_section_logo_image.size-40 { max-height: clamp(1.5rem, 4vw, 2.5rem) !important; } .logo_section_logo_image.size-32 { max-height: clamp(1.25rem, 3vw, 2rem) !important; } .logo_section_logo_image.size-24 { max-height: clamp(1rem, 2.5vw, 1.5rem) !important; } .logo_section_logo_image.size-14 { max-height: clamp(0.625rem, 2vw, 0.875rem) !important; } .engage_sponsors_logo.size-64 { max-height: clamp(3.5rem, 7vw, 5.5rem) !important; } .engage_sponsors_logo.size-56 { max-height: clamp(2.5rem, 6vw, 4.5rem) !important; } .engage_sponsors_logo.size-48 { max-height: clamp(2rem, 5vw, 3.5rem) !important; } .engage_sponsors_logo.size-40 { max-height: clamp(1.5rem, 4vw, 2.5rem) !important; } .engage_sponsors_logo.size-32 { max-height: clamp(1.25rem, 3vw, 2rem) !important; } .engage_sponsors_logo.size-24 { max-height: clamp(1rem, 2.5vw, 1.5rem) !important; } .engage_sponsors_logo.size-14 { max-height: clamp(0.625rem, 2vw, 0.875rem) !important; } /* END Logo sizes */ /* START Inner Borders */ /* Create inner borders in grid */ .u-grid-inner-borders > * { border-right: var(--border-width--main) solid var(--_theme---grid); border-bottom: var(--border-width--main) solid var(--_theme---grid); } .u-grid-inner-borders-top > * { border-top: var(--border-width--main) solid var(--_theme---grid); } /* Inner borders only */ .u-grid-inner-borders > *.no-left-border { border-left: none !important; } .u-grid-inner-borders > *.no-right-border { border-right: none !important; } .u-grid-inner-borders > *.no-top-border { border-top: none !important; } .u-grid-inner-borders > *.no-bottom-border { border-bottom: none !important; } /* END Inner Borders */ /* Start Card & Pagination hover */ /* card & pagination arrow hover animtion */ .card-link_wrap:hover .card-link_content { background-color: var(--swatch--off-black-10); } .engage_slider_card:hover .engage_card-link_content { background-color: rgba(211, 222, 255, 0.2); } /* Backbase didn't liked the zoom in .card-link_wrap:hover .card-link_visual_inner { transform: scale(1.1); } */ .card-link_wrap:hover .card-link_arrow_icon.u-icon-small, .pagination_arrow_wrap:hover .card-link_arrow_icon.u-icon-small { transform: translateX(2rem); } .card-link_wrap:hover .card-link_arrow_icon.u-icon-small.is-hover, .pagination_arrow_wrap:hover .card-link_arrow_icon.u-icon-small.is-hover { transform: translateX(0rem); } .card-link_wrap:hover .card-link_arrow_contain, .pagination_arrow_wrap:hover .card-link_arrow_contain, .engage_slider_card:hover .engage_card-link_arrow_contain { color: var(--_theme---background); background-color: var(--_theme---brand); } /* Startpositie voor het 'tweede' pijltje */ .card-link_arrow_icon.u-icon-small.is-hover { transform: translateX(-2rem); } /* Transitions (algemeen toepassen, niet meer gescoped) */ .card-link_content, .engage_card-link_content { transition: background-color .3s cubic-bezier(0.25, 0.1, 0.25, 1); } /* .card-link_visual_inner { transition: transform .3s cubic-bezier(0.25, 0.1, 0.25, 1); } */ .card-link_arrow_icon.u-icon-small { transition: transform .5s cubic-bezier(0.25, 0.1, 0.25, 1); } .card-link_arrow_contain { transition: color .3s, background-color .3s; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); } /* client card hover animation */ .client-card_wrap:hover .client-card_content { background-color: var(--swatch--off-black-10); } .client-card_wrap:hover .client-card_arrow_icon.u-icon-small { transform: translateX(2rem); } .client-card_wrap:hover .client-card_arrow_icon.u-icon-small.is-hover { transform: translateX(0rem); } .client-card_wrap:hover .client-card_arrow_contain { color: var(--_theme---background); background-color: var(--_theme---brand); } .client-card_arrow_icon.u-icon-small.is-hover { transform: translateX(-2rem); } .client-card_content { transition: background-color .3s cubic-bezier(0.25, 0.1, 0.25, 1); } .client-card_arrow_icon.u-icon-small { transition: transform .5s cubic-bezier(0.25, 0.1, 0.25, 1); } .client-card_arrow_contain, .engage_card-link_arrow_contain { transition: color .3s, background-color .3s; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); } /* END Card & Pagination hover */ /* Remove chevron on select input field */ select { appearance: none; -webkit-appearance: none; /* Voor Safari/Chrome */ -moz-appearance: none; /* Voor Firefox */ } select:has(option[value=""]:checked) { color: color-mix(in lab, currentcolor 100%, transparent); } /* Dim alle nav-items bij hover, behalve de actieve */ .nav_links:hover.nav_links_item {opacity:.6;transition:opacity .2s;} .nav_links_item:hover, .nav_links_item:focus-within, .nav_links_item:has(.w-dropdown-list:hover){opacity:1;} .underline-link::before, .underline-link.is--alt::before, .underline-link.is--alt::after{ content: ""; position: absolute; bottom: 0em; left: 0; width: 100%; height: 0.125em; background-color: var(--_button-style---underline); transition: transform 0.735s cubic-bezier(0.625, 0.05, 0, 1); transform-origin: right; transform: scaleX(0) rotate(0.001deg); } .underline-link:hover::before { transform-origin: left; transform: scaleX(1) rotate(0.001deg); } .button_main_wrap[data-wf--button-main--style="tertiary"] .clickable_btn::before, .button_main_wrap[data-wf--button-main--style="tertiary"] .clickable_btn.is--alt::before, .button_main_wrap[data-wf--button-main--style="tertiary"] .clickable_btn.is--alt::after { content: ""; position: absolute; bottom: 0em; left: 0; width: 100%; height: 0.125em; background-color: var(--_button-style---underline); transition: transform 0.735s cubic-bezier(0.625, 0.05, 0, 1); transform-origin: right; transform: scaleX(0) rotate(0.001deg); } .button_main_wrap[data-wf--button-main--style="tertiary"] .clickable_btn:hover::before { transform-origin: left; transform: scaleX(1) rotate(0.001deg); } /* Alt */ .underline-link.is--alt::before { transform-origin: left; transform: scaleX(1) rotate(0.001deg); transition-delay: 0.3s; } .underline-link.is--alt:hover::before { transform-origin: right; transform: scaleX(0) rotate(0.001deg); transition-delay: 0s; } .underline-link.is--alt::after { transform-origin: right; transform: scaleX(0) rotate(0.001deg); transition-delay: 0s; } .underline-link.is--alt:hover::after { transform-origin: left; transform: scaleX(1) rotate(0.001deg); transition-delay: 0.3s; } /* END Text Link Hover */ /* START Testimonial Swiper Slides Pointer Event */ /* Scope alleen binnen testimonial_cms_wrap */ .testimonial_cms_wrap .swiper-slide { pointer-events: none; z-index: 1; } .testimonial_cms_wrap .swiper-slide.is-active { pointer-events: auto; z-index: 10; } /* Optional: prevent overlapping wrapper issues */ .testimonial_cms_wrap { pointer-events: none; } .testimonial_cms_wrap .swiper-slide.is-active { pointer-events: auto; } .u-justify-content-end { display: flex; justify-content: flex-end; } .u-gap-1 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--1); } .u-gap-2 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--2); } .u-gap-3 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--3); } .u-gap-4 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--4); } .u-gap-5 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--5); } .u-gap-6 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--6); } .u-gap-7 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--7); } .u-gap-8 { grid-column-gap: var(--_gap---size); grid-row-gap: var(--_gap---size); --_gap---size: var(--_spacing---space--8); } /* Max Width */ .u-max-width-60ch { max-width: 60ch; } .home_hero_anim_wrapper canvas { object-fit: contain !important; } /* Hide on tablet and smaller */ @media screen and (max-width: 991px) { .nav_links_link-bg { display: none !important; } } /* Light/default */ .form_main_field::placeholder { opacity: .5!important; /* 50% */ } .label { display: flex; align-items: center; .card-no-link_wrap[data-wf--card-non-clickable--theme="leader"] .card-no-link_content:hover .card-no-link_heading { border-color: var(--_theme---text-primary); } .card-no-link_wrap[data-wf--card-non-clickable--theme="leader"] { border-right: none; } @media screen and (min-width: 540px) and (max-width: 792px) { .card-no-link_wrap[data-wf--card-non-clickable--theme="leader"]:nth-child(2n) .card-link_content { border-right: none !important; } } @media screen and (min-width: 793px) and (max-width: 1045px) { .card-no-link_wrap[data-wf--card-non-clickable--theme="leader"]:nth-child(3n) .card-link_content { border-right: none !important; } } @media screen and (min-width: 1046px) and (max-width: 1297px) { .card-no-link_wrap[data-wf--card-non-clickable--theme="leader"]:nth-child(4n) .card-link_content { border-right: none !important; } } @media screen and (min-width: 1298px) { .card-no-link_wrap[data-wf--card-non-clickable--theme="leader"]:nth-child(5n) .card-link_content { border-right: none !important; } } .tabs_menu::-webkit-scrollbar { display: none; } .tabs_menu .tabs_menu_link:not(:first-child) { margin-left: -1px; } input, input:hover, input:focus, input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus { -webkit-box-shadow: 0 0 0 1000px transparent inset !important; box-shadow: 0 0 0 1000px transparent inset !important; -webkit-text-fill-color: inherit !important; transition: background-color 9999s ease-in-out 0s, color 9999s ease-in-out 0s; } .hp-field { position: absolute !important; left: -9999px !important; height: 0; width: 0; overflow: hidden; opacity: 0; pointer-events: none; } [contains="table"] .w-embed { padding-left: var(--_spacing---space--4); padding-right: var(--_spacing---space--4); } /* Empty Image */ .u-check-for-image:has(.u-cms-image[src*="placeholder"]).u-hide-if-empty-image, .u-check-for-image:has(.u-cms-image[src*="placeholder"]) .u-hide-if-empty-image, .u-check-for-image:not(:has(.u-cms-image[src*="placeholder"])).u-show-if-empty-image, .u-check-for-image:not(:has(.u-cms-image[src*="placeholder"])) .u-show-if-empty-image, /* Empty Text */ .u-check-for-text:has(.u-cms-text:empty).u-hide-if-empty-text, .u-check-for-text:has(.u-cms-text:empty) .u-hide-if-empty-text, .u-check-for-text:has(.u-cms-text:not(:empty)).u-show-if-empty-text, .u-check-for-text:has(.u-cms-text:not(:empty)) .u-show-if-empty-text, /* Empty Link */ .u-check-for-link:has(.u-cms-link a[href="#"]).u-hide-if-empty-link, .u-check-for-link:has(.u-cms-link a[href="#"]) .u-hide-if-empty-link, .u-check-for-link:has(.u-cms-link a:not([href="#"])).u-show-if-empty-link, .u-check-for-link:has(.u-cms-link a:not([href="#"])) .u-show-if-empty-link, /* Toggle */ .u-check-for-toggle:has(.u-cms-toggle:not(.w-condition-invisible)).u-hide-if-toggled, .u-check-for-toggle:has(.u-cms-toggle:not(.w-condition-invisible)) .u-hide-if-toggled, .u-check-for-toggle:has(.u-cms-toggle.w-condition-invisible).u-show-if-toggled, .u-check-for-toggle:has(.u-cms-toggle.w-condition-invisible) .u-show-if-toggled { display: none; } /* CUSTOM Empty CMS Generic (text, image, or any empty CMS field) */ .u-hide-if-empty-cms:has(.u-cms:empty), .u-hide-if-empty-cms:has(.u-cms:empty) { display: none; } :root { --nav--height: 4rem; --nav--banner-height: 2.4rem; --nav--height-total: var(--nav--height); --nav--icon-thickness: 0.15rem; --nav--hamburger-thickness: var(--nav--icon-thickness); --nav--hamburger-gap: 0.375rem; --nav--hamburger-rotate: 45; --nav--menu-open-duration: 200ms; --nav--menu-close-duration: 150ms; --nav--dropdown-duration: 600ms; --nav--dropdown-open-duration: 200ms; /* 👇 delay die alleen bij sluiten geldt (we overschrijven openen naar 0ms) */ --nav--dropdown-delay: 300ms; } /* adds height only to pages with submenu for sticky scroller */ body.has-submenu { --nav--submenu-height: 7.063rem; } @media screen and (min-width: 992px) { body.has-submenu .section_sticky_image_block { top: calc(38% - var(--nav--height)) !important; } } /* on smaller screens */ @media (width < 60em) { body:has(.nav_component .w-nav-button.w--open) { overflow: hidden; } } /* on larger screens */ @container (min-width: 60em) { .nav_wrap.is-desktop, .nav_dropdown_backdrop { display: block; } .nav_wrap.is-mobile, .nav_menu_backdrop { display: none; } } /* dropdown list: initial (closed) state */ html:not(.wf-design-mode) .nav_dropdown_component > .w-dropdown-list { /* zorg dat Webflow's display:none niet in de weg zit */ display: grid !important; grid-template-columns: minmax(0, 1fr); grid-template-rows: 0fr; /* gebruik longhand zodat delay niet overschreven wordt */ transition-property: grid-template-rows, opacity, visibility; transition-duration: var(--nav--dropdown-duration), 0ms, 0ms; transition-timing-function: ease, ease, linear; /* 👇 hier zetten we de sluit-delay */ transition-delay: var(--nav--dropdown-delay), var(--nav--dropdown-delay), var(--nav--dropdown-delay); visibility: hidden; opacity: 0; /* perf */ will-change: grid-template-rows, opacity; pointer-events: none; } /* open state (via .w--open op list) */ html:not(.wf-design-mode) .nav_dropdown_component > .w-dropdown-list.w--open { visibility: visible; opacity: 1; pointer-events: auto; /* 👇 openen zonder delay */ transition-delay: 0ms, 0ms, 0ms; } /* open state (via aria-expanded op toggle) */ .nav_dropdown_component:has(> .w-dropdown-toggle[aria-expanded="true"]) > .w-dropdown-list { --nav--dropdown-duration: var(--nav--dropdown-open-duration); grid-template-rows: 1fr; visibility: visible; opacity: 1; pointer-events: auto; /* 👇 openen zonder delay */ transition-delay: 200ms, 200ms, 200ms; } /* sets list child to overflow hidden to enable css height transition */ .nav_dropdown_component > .w-dropdown-list > * { overflow: hidden; } /* ❗ Verwijderd/Neutralized: desktop-regel die delay overschreef Als je toch een open-delay wilt bij "switchen" tussen dropdowns, voeg dan specifiek hier weer een delay toe, maar laat ‘m op 0 om sluit-delay te behouden. */ .nav_wrap.is-desktop:has(.nav_dropdown_component > .w-dropdown-toggle.w--open[aria-expanded="false"]) .nav_dropdown_component:has(> .w--open[aria-expanded="true"]) > .w-dropdown-list { /* geen override meer op transition-delay */ } /* reveal dropdown backdrop when dropdown open */ .nav_dropdown_backdrop { transition: opacity var(--nav--dropdown-duration); } body:has(.nav_dropdown_component > [aria-expanded="true"]) .nav_dropdown_backdrop { opacity: 1; } /* rotate arrow inside open dropdown */ .w-dropdown-toggle[aria-expanded="true"] .nav_links_svg { transform: rotate(-180deg); } /* animate first hamburger line when opened */ .nav_component .w-nav-button.w--open > * > :first-child { transform: translateY(calc(var(--nav--hamburger-thickness) * 0.5 + var(--nav--hamburger-gap) * 0.5)) rotate(calc(var(--nav--hamburger-rotate) * -1deg)); } /* animate second hamburger line when opened */ .nav_component .w-nav-button.w--open > * > :last-child { transform: translateY(calc(var(--nav--hamburger-thickness) * -0.5 + var(--nav--hamburger-gap) * -0.5)) rotate(calc(var(--nav--hamburger-rotate) * 1deg)); } /* reveal mobile menu backdrop on menu open */ .nav_menu_backdrop { transition: opacity var(--nav--menu-close-duration); } .nav_component:has(.w-nav-button.w--open) .nav_menu_backdrop { opacity: 1; } /* menu animations */ @keyframes menuOpen { from { clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); } to { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); } } @keyframes menuClose { from { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); } to { clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); } } /* menu open */ .nav_component:has(.w-nav-button.w--open) .w-nav-menu { animation: menuOpen var(--nav--menu-open-duration) ease-in-out forwards; } /* menu close */ .nav_component:has(.w-nav-button:not(.w--open)) .w-nav-menu { animation: menuClose var(--nav--menu-close-duration) ease-in-out forwards; } /* position overflow to top of screen */ .nav_component .w-nav-overlay { top: 0; min-height: 100vh; } /* search focus underline */ .nav_search_wrap:has(input:focus-visible) { border-color: var(--_theme---text); } /* open dropdown on mobile */ .nav_wrap.is-mobile [data-open-on-mobile] > .w-dropdown-toggle { display: none; } .nav_wrap.is-mobile [data-open-on-mobile] > .w-dropdown-list { visibility: visible; opacity: 1; display: block; grid-template-rows: 1fr; /* mobile: geen sluit-delay nodig (optioneel) */ transition-delay: 0ms, 0ms, 0ms; } /* Rotate Nav Banner Arrow When External Link */ a[target="_blank"] .nav_banner_svg { transform: rotate(-45deg); } /* nav banner */ html:has(.nav_banner_wrap:not(.w-condition-invisible)):not(.hide-nav-banner) { --nav--height-total: calc(var(--nav--banner-height) + var(--nav--height)); } .hide-nav-banner .nav_banner_wrap { display: none; } /* engage nav */ .nav_engage_links_list:hover .nav_engage_links_item { opacity: 0.5; } .nav_engage_links_list .nav_engage_links_item:hover { opacity: 1; } /* nav item hover animatie */ @media screen and (min-width: 992px) { .nav_dropdown_link:hover .nav_dropdown_icon { transform: scale(1); margin-right: .5rem; } } @media screen and (min-width: 992px) and (max-width: 1151px) { .nav_links_link { padding: 0px var(--_spacing---space--1); } .nav_links_component { grid-column-gap: var(--_spacing---space--1); } .nav_logo_wrap { width: 7rem; } } /* MCP | Global | Nav — variant behaviour (source: embeds/nav-v3/nav-v3-style.html). The is-over-white script (MCP | Custom Code, embed 08) flips EVERY .nav_wrap to the light theme over a [data-wrap="light"] section. Only Transparent should follow it. */ /* Dark never switches: take the dark theme back from the component root. */ .nav_component.nav-v3_component.w-variant-9f85e983-c7c7-d200-13a8-cabf98b3e5ff .nav_wrap.is-over-white.is-over-white { --_theme---background: inherit; --_theme---text-primary: inherit; --_theme---text-secundary: inherit; --_theme---background-inverse: inherit; --_theme---background-secondary: inherit; --_theme---background-hover: inherit; --_theme---grid: inherit; --_theme---text-link--text: inherit; --_theme---text-link--text-hover: inherit; --_theme---text-link--border: inherit; --_theme---text-link--border-hover: inherit; --_theme---selection--text: inherit; --_theme---selection--background: inherit; --_theme---nav-style-2-0--icon-color: inherit; --_theme---nav-style-2-0--bg-color: inherit; --_theme---nav-style-2-0--text-color: inherit; --_theme---announcement-bar--color: inherit; --_theme---icons-logo-inverted: inherit; --_theme---icon-background: inherit; --_theme---icon-background-hover: inherit; --_theme---nav-search-icon-hover-bg: inherit; --_theme---sub-navigation--icon-bg: inherit; --_theme---sub-navigation--icon-bg-hover: inherit; --_theme---button-primary--background: inherit; --_theme---button-primary--text: inherit; --_theme---button-primary--background-hover: inherit; --_theme---button-primary--text-hover: inherit; --_theme---button-primary--icon-inverted: inherit; --_theme---button-primary--icon-inverted-hover: inherit; --_theme---button-secondary--background: inherit; --_theme---button-secondary--text: inherit; --_theme---button-secondary--background-hover: inherit; --_theme---button-secondary--text-hover: inherit; --_theme---button-secondary--icon-inverted: inherit; --_theme---button-secondary--icon-inverted-hover: inherit; --_theme---button-tertiary--text: inherit; --_theme---button-tertiary--underline: inherit; --_theme---button-tertiary--icon-inverted: inherit; --_theme---button-tertiary--icon-inverted-hover: inherit; color: inherit; } /* The CTA is this component's own Style2.0 - Button (Hover FX on), in .nav_button_wrap. Nav | Link Items carries its own copy without the flag and is shared site-wide, so its copy is hidden here instead of edited. Desktop only. */ .nav_component.nav-v3_component .nav_wrap.is-desktop .nav_actions_wrap .nav_buttons_item.is-btn { display: none; } /* Transparent over a light section: light tint instead of the dark one. */ .nav_component.nav-v3_component.w-variant-93d5f291-dfe9-fd64-0713-61caf1df2400:has(.nav_wrap.is-over-white) { background-color: rgba(255, 255, 255, 0.4); } /* Container width = the section rails = the Lumos container, var(--max-width--main) 80rem (74.9375rem until 2026-10-12). nav-v3_contain is a combo on .nav_contain.u-container, but the published page CSS writes it as bare .nav-v3_contain (0,1,0), so the site's .nav_contain.u-container 85rem (0,2,0) won and the logo and CTA sat outside the rails above 1280 px (2026-09-28). */ .nav_component.nav-v3_component .nav_contain.nav-v3_contain { max-width: var(--max-width--main); } /* Link font = Figma 2472:6633: PP Neue Montreal, 0.1em tracking (2026-09-29). The links come from Nav | Link Items (shared site-wide), so they are restyled here, not edited. 2026-10-14 (user): typed casing ("Solutions", "Banking OS") instead of caps; Medium, which exists only in the Ppneuemontreal family (Ppneuemontreal Book is 400 alone); 15 / 13 / 12 px at >=1280 / 1100-1279 / .nav-v3_search-fx) .nav_links_link_search::before { content: ""; position: absolute; inset: 0; z-index: 0; background-color: var(--_theme---text-primary); opacity: 0; transform: scaleX(0); transform-origin: left center; transition: transform .36s cubic-bezier(.33, 1, .68, 1), opacity .22s; pointer-events: none; } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search:hover::before { opacity: 1; transform: scaleX(1); transition: transform .36s cubic-bezier(.33, 1, .68, 1), opacity 0s; } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search > .u-icon-small { position: relative; z-index: 1; transition: color .18s linear; } /* the icon sits mid-box, so it turns as the wipe edge passes it */ .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search:hover > .u-icon-small { color: var(--_theme---nav-style-2-0--bg-color); transition: color .12s linear .14s; } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search .style2-0_button_main_corner { transition: transform .36s cubic-bezier(.33, 1, .68, 1); } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search:hover .style2-0_button_main_corner.is-top-left { transform: translate(-2px, -2px); } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search:hover .style2-0_button_main_corner.is-top-right { transform: translate(2px, -2px); } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search:hover .style2-0_button_main_corner.is-bottom-right { transform: translate(2px, 2px); } .nav_component.nav-v3_component:has(> .nav-v3_search-fx) .nav_links_link_search:hover .style2-0_button_main_corner.is-bottom-left { transform: translate(-2px, 2px); } } /* MCP | Global | Nav — per-variant rules that set_variant_styles cannot write (source: references/nav-v3/nav-v3-variants-style.html; second HtmlEmbed in the definition, after the main style embed 24b06c2b-…). Keyed on the root's variant class, which Webflow adds because the root carries an override in that variant. */ /* Engage d5cf8938 (2026-10-15): copied from the old Global | Nav Engage variant for the /engage pages. The dark translucent bar (#041326b3) sits on the root as a variant override; the mobile wrapper must then be transparent, but the site's .nav_wrap.is-mobile.u-border-bottom (≤991, 0,3,0) paints it with --_theme---nav-style-2-0--bg-color, and that chain ends in a utility, so it is not addressable by name through the API. 0,5,0 here wins. */ @media screen and (max-width: 991px) { .nav_component.nav-v3_component.w-variant-d5cf8938-8ba2-e712-3abb-aad32fd6bd37 .nav_wrap.is-mobile.u-border-bottom { background-color: transparent; } } Skip to main contentAmericasEMEASolutionsSolutionsDigital BankingOnline & Mobile BankingCustomer OnboardingEmployee WorkspacesAgentic BankingConversational BankingRelationship IntelligenceCustomer OperationsSegmentsSegmentsRetail bankingOnboarding & loan originationDigital & personal bankingDigital investingTailored value propositionsBranch & customer serviceSmall business bankingOnboarding & loan originationDigital services & engagementPayments & international tradeRelationship manager productivityBeyond-banking servicesCommercial bankingOnboarding & loan originationPayments & treasury managementInternational tradeDigital services & open bankingRelationship & service managementPrivate bankingClient onboardingWhite-glove digital servicesRelationship manager productivityPremium banking servicesHolistic wealth management propositionsWealth managementClient onboardingAdvisor performanceDigital investingHolistic wealth propositionsExternal advisor enablementBanking OSMarketplaceCustomersInsightsInsightsContent hubAnalyst recognitionsBlogEvents & conferencesGuidesReportsPodcastsVideosBrochuresWhitepapersSearchSearchSearch .nav_search_wrap:has(input:focus-visible) { border-color: var(--_theme---text-link--border); } Request a demoRequest a demoRequest a demoRequest a demoRequest a demoRequest a demoBook a strategy callBook a strategy callBook a strategy callSolutionsSolutionsOverviewDigital BankingOnline & Mobile BankingCustomer OnboardingEmployee WorkspacesAgentic BankingConversational BankingRelationship IntelligenceCustomer OperationsSegmentsSegmentsRetail bankingOnboarding & loan originationDigital & personal bankingDigital investingTailored value propositionsBranch & customer serviceSmall business bankingOnboarding & loan originationDigital services & engagementPayments & international tradeRelationship manager productivityBeyond-banking servicesCommercial bankingOnboarding & loan originationPayments & treasury managementInternational tradeDigital services & open bankingRelationship & service managementPrivate bankingClient onboardingWhite-glove digital servicesRelationship manager productivityPremium banking servicesHolistic wealth management propositionsWealth managementClient onboardingAdvisor performanceDigital investingHolistic wealth propositionsExternal advisor enablementLorem ipsum dolor sit ametLearn moreLearn moreLearn moreServicesCustomer successValue consultingImplementation servicesManaged hostingManaged servicesTraining & supportDeveloper resourcesTraining and certificationUX resourcesProduct supportBanking OSMarketplaceCustomersInsightsInsightsContent hubAnalyst recognitionsBlogEvents & conferencesGuidesReportsPodcastsVideosBrochuresWhitepapersSearchSearchSearch .nav_search_wrap:has(input:focus-visible) { border-color: var(--_theme---text-link--border); } Request a demoRequest a demoRequest a demoAmericasEuropeAsiaSearchSearchSearchAI-native and built for bankingThe Banking OS that unifies your frontline.
  • [H2] Digital channels start the work.A Unified Frontline finishes it.
  • [H2] Four solutions.One Banking OS.
  • [H2] The bank they see. The work they don’t.Running as one.
  • [H2] Move the numbersyour board already tracks.
  • [H2] Give us 90 days.Put one consequential AI use case to work.
  • [H2] Bring us the AI use caseyour board wants in production.
  • [H2] The first AI-powered growth platform for banks.
  • [H3] Filed in the app in 30 seconds
  • [H3] Started online in minutes
  • [H3] Updated in the app in one tap
  • [H3] Digital Banking
  • [H3] Conversational Banking
  • [H3] Relationship Intelligence
  • [H3] Customer Operations
  • [H3] Commit
  • [H3] Build
  • [H3] Launch

Afbeeldingen

We vonden 45 afbeeldingen in de pagina.

7 alt attributen ontbreken. Voeg alternatieve text toe zodat zoekmachines beter kunnen beoordelen wat het onderwerp van de afbeeldingen is.

Text/HTML Ratio

Ratio : 2%

De ratio van text tot HTML code is below 20 procent, dit betekent dat uw pagina waarschijnlijk meer tekst nodig heeft.

Iframe

Jammer, u heeft Iframes in uw website, dit betekent dat deze content niet kan worden geïndexeerd.

Herschreven URL

Perfect. Uw links zien er vriendelijk uit!

Underscores in de URLs

Perfect! Geen underscores gevonden in uw URLs.

In-page links

We vonden een totaal van 5 links inclusie 0 link(s) naar bestanden

Ankertekst Type samenstelling
- Intern doFollow
- Intern doFollow
Global • English Intern doFollow
Italy • Italian Intern doFollow
Latin America • Español Intern doFollow
Advertisement

SEO Keywords

Keywords Cloud

onboarding      customer      story      banking      read      digital      demo      see      request      services     

Keywords Consistentie

Keyword Content Title Keywords Description Headings
banking 44
read 20
customer 20
digital 18
onboarding 14

Bruikbaarheid

Url

Domein : backbase.com

Lengte : 12

Favicon

Goed, uw website heeft een favicon.

Taal

Goed. Uw ingestelde taal is en.

Document

Doctype

HTML 5

Encoding

Perfect. Uw ingestelde Charset is UTF-8.

E-mail Privacy

Waarschuwing! Er is op zijn minst 1 e-mailadres gevonden als platte tekst. (voorkom spam!). Gebruik deze gratis antispam protector om e-mailadressen te verbergen voor spammers.

Niet ondersteunde HTML

Geweldig! We hebben geen niet meer ondersteunde HTMl tags gevonden in uw HTML.

Speed Tips

Jammer, uw website maakt gebruik van inline styles.
Geweldig, uw website heeft een correct aantal CSS bestanden.
Jammer, uw website heeft teveel JS bestanden (meer dan 6).
Jammer, uw website haalt geen voordeel uit gzip.

Mobile

Mobile Optimization

Apple Icon
Meta Viewport Tag
Advertisement

Optimalisatie

XML Sitemap

Geweldig, uw website heeft een XML sitemap.

https://www.backbase.com/sitemap.xml

Robots.txt

http://backbase.com/robots.txt

Geweldig uw website heeft een robots.txt bestand.

Analytics

Ontbrekend

We hadden niet op te sporen van een analytics tool op deze website geplaatst.

Web Analytics laat u toe de bezoekersactiviteit op uw website te meten. U zou minstens 1 Analytics tool geïnstalleerd moeten hebben en een extra tool voor de bevestiging van de resultaten.

AI Search Readiness

AI Crawlers

AI search crawlers are allowed, so the site can be shown and cited in AI answers (ChatGPT, Claude, Perplexity).

OAI-SearchBot ChatGPT search AI search
ChatGPT-User ChatGPT (user requests) AI search
Claude-SearchBot Claude search AI search
Claude-User Claude (user requests) AI search
PerplexityBot Perplexity AI search
GPTBot OpenAI training AI training
ClaudeBot Anthropic training AI training
Google-Extended Google Gemini training AI training
Applebot-Extended Apple AI training AI training
CCBot Common Crawl AI training

Blocking AI training crawlers is a common choice and doesn't affect the score. Only the AI search crawlers count.

Structured Data

The homepage describes itself with schema.org structured data, which helps search engines and AI tools understand it: WebPage, WebSite, Organization

Canonical Tag

No canonical tag found. Add <link rel="canonical"> so search engines know which URL is the main version and don't split ranking between duplicates.

llms.txt

This site has an llms.txt file, a short summary written for AI tools.

Security

HTTPS

The site loads over HTTPS, so connections are encrypted. Browsers and search engines expect this.

HSTS

No Strict-Transport-Security (HSTS) header. It tells browsers to always use HTTPS, which protects visitors from being downgraded to an insecure connection.

Security Headers

0 of 5 common security headers found. At least 2 are needed to pass.

Content-Security-Policy
X-Content-Type-Options
X-Frame-Options
Referrer-Policy
Permissions-Policy
Checked on 16 Oct 2026.

Domain Info

backbase.com was registered on 18 Nov 2002 with Amazon Registrar, Inc. and expires on 18 Nov 2027. It accepts email and has both SPF and DMARC records. The Wayback Machine first archived it in July 2003.

Registration

Registrar Amazon Registrar, Inc.
Registered 18 Nov 2002 (23 years ago)
Expires 18 Nov 2027
Last changed 16 May 2026
Nameservers edna.ns.cloudflare.com, tim.ns.cloudflare.com
DNSSEC Not signed

Hosting

IPv4 address 198.202.211.1
IPv6 support

Email Security

Mail servers: aspmx.l.google.com, alt1.aspmx.l.google.com, alt2.aspmx.l.google.com, alt3.aspmx.l.google.com, alt4.aspmx.l.google.com

SPF record
DMARC record (policy: quarantine)

Archive History

The Wayback Machine has snapshots of this site from 216 different months, from July 2003 to October 2026. View snapshots

Domain data checked on 16 Oct 2026. Sources: registry RDAP, public DNS, Internet Archive.

PageSpeed Insights


Device
Categorieën

Advertisement

GoInfosystems

Website review is een gratis tool waarmee u eenvoudig uw website kunt analyseren